среда, 22 мая 2019 г.

суббота, 18 мая 2019 г.

Именованные параметры на GNU C

Компилируется на диалекте GNU языка С (можно проверить на
https://wandbox.org/ ).

#include <stdio.h>  
#include <stdbool.h>
 
typedef struct {
  bool bIsSolt;
  bool bIsPepper;
  bool bIsPoison;
} SoupParams;

#define GET_OVERRIDE(dummy, ARG_1, ARG_2, ARG_3, ACTION, ...) ACTION

#define PARAM_0(...)
#define PARAM_1(ARG_1)       .ARG_1  
#define PARAM_2(ARG_1, ...)  .ARG_1, PARAM_1(__VA_ARGS__)
#define PARAM_3(ARG_1, ...)  .ARG_1, PARAM_2(__VA_ARGS__)

#define SOUP_PARAMS(...) \
  GET_OVERRIDE("dummy_param", ##__VA_ARGS__, PARAM_3, PARAM_2, PARAM_1, PARAM_0)(__VA_ARGS__)

static int make_soup_raw(const SoupParams *poSoupParams_)
{
  if ( !poSoupParams_ ) { return -1; }

  printf("   poSoupParams_->bIsSolt   = %s\n", poSoupParams_->bIsSolt   ? "true" : "false");
  printf("   poSoupParams_->bIsPepper = %s\n", poSoupParams_->bIsPepper ? "true" : "false");
  printf("   poSoupParams_->bIsPoison = %s\n", poSoupParams_->bIsPoison ? "true" : "false");

  return 0;
}

#define make_soup(...)                                     \
(                                                          \
  {                                                        \
    int nResult = -1;                                      \
    _Pragma("GCC diagnostic push")                         \
    _Pragma("GCC diagnostic ignored \"-Woverride-init\"")  \
    nResult = make_soup_raw(                               \
                            &(SoupParams)                  \
                            {                              \
                               .bIsSolt   = false,         \
                               .bIsPepper = false,         \
                               .bIsPoison = false,         \
                               SOUP_PARAMS(__VA_ARGS__)    \
                             }                             \
                            );                             \
    _Pragma("GCC diagnostic pop")                          \
    nResult;                                               \
  }                                                        \
)

int main(void)
{
  int nResult = 0;
 
  printf("\n make_soup(bIsSolt = true, bIsPoison = true, bIsPepper = true): \n");
  nResult = make_soup(bIsSolt = true, bIsPoison = true, bIsPepper = true);
  printf("   nResult: %d\n", nResult);
  
  printf("\n make_soup(bIsPepper = true, bIsSolt = true): \n");
  nResult = make_soup(bIsPepper = true, bIsSolt = true);
  printf("   nResult: %d\n", nResult);  

  printf("\n make_soup(bIsPoison = false): \n");
  nResult = make_soup(bIsPoison = false);
  printf("   nResult: %d\n", nResult);  
  
  printf("\n make_soup(): \n");
  nResult = make_soup();
  printf("   nResult: %d\n", nResult);    
  
  return 0;  
}