前置知识

C语言宏的定义和宏的使用方法

变长参数

  • 这里输出的是相同类型的参数日志,不同的需要特殊处理,或者直接自定义输出格式
  • 缺点:
    • 参数类型固定

#include <stdio.h>

double xxa = 1.0f;
double xxb = 1.2f;
double xxc = 1.3f;
double xxd = 1.4f;
double xxe = 1.5f;
double xxf = 1.6f;
double xxg = 1.7f;
double xxh = 1.8f;
double xxi = 1.9f;

#define DUMPVAR(VAR) #VAR "(%.2lf)"

#define FL_DOARG1(a, ...) DUMPVAR(a)
#define FL_DOARG2(a, v, ...) FL_DOARG1(a) ", " FL_DOARG1(v, __VA_ARGS__)
#define FL_DOARG3(a, v, ...) FL_DOARG1(a) ", " FL_DOARG2(v, __VA_ARGS__)
#define FL_DOARG4(a, v, ...) FL_DOARG1(a) ", " FL_DOARG3(v, __VA_ARGS__)
#define FL_DOARG5(a, v, ...) FL_DOARG1(a) ", " FL_DOARG4(v, __VA_ARGS__)
#define FL_DOARG6(a, v, ...) FL_DOARG1(a) ", " FL_DOARG5(v, __VA_ARGS__)
#define FL_DOARG7(a, v, ...) FL_DOARG1(a) ", " FL_DOARG6(v, __VA_ARGS__)
#define FL_DOARG8(a, v, ...) FL_DOARG1(a) ", " FL_DOARG7(v, __VA_ARGS__)
#define FL_DOARG9(a, v, ...) FL_DOARG1(a) ", " FL_DOARG8(v, __VA_ARGS__)

#define VA_NUM_ARGS_IMPL(x1, x2, x3, x4, x5, x6, x7, x8, x9, N, ...) N
#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1)

#define FL_CONCAT_(l, r) l##r
#define FL_CONCAT(l, r) FL_CONCAT_(l, r)
#define MAKE_VAR_MACRO(PREFIX, ...) FL_CONCAT(PREFIX, VA_NUM_ARGS(__VA_ARGS__))

#define FFFOM(...) MAKE_VAR_MACRO(FL_DOARG, __VA_ARGS__)(__VA_ARGS__)
#define DUMP(...)     \
  char costfac[1000]; \
  snprintf(costfac, 1000, FFFOM(__VA_ARGS__), ##__VA_ARGS__);

int main(int argc, char const *argv[])
{
  {
    // 输出保存在字符串中,有保存场景的时候使用
    DUMP(xxa,xxb,xxc,xxd,xxe,xxf,xxg,xxh,xxi);
    printf("%s", costfac);
  }
  return 0;
}

enum 定义


#define ENUM_DEFINE_ITEM(EnumType, EnumVal) EnumVal,

/** Used in defining EnumTypeToString(). */
#define ENUM_TO_STRING(EnumType, EnumVal) \
  case EnumType::EnumVal: {               \
    return #EnumVal;                      \
  }

/** Used in defining EnumTypeFromString(). Hardcoded to expect str to be in scope. */
#define ENUM_FROM_STRING(EnumType, EnumVal)                             \
  else if (str == #EnumVal) { /* NOLINT readability/braces confusion */ \
    return EnumType::EnumVal;                                           \
  }

#define ENUM_DEFINE(EnumName, EnumCppType, EnumValMacro)                                                              \
  enum class EnumName : EnumCppType { EnumValMacro(ENUM_DEFINE_ITEM) NUM_ENUM_ENTRIES };                              \
                                                                                                                      \
  /** @return String version of @p type. */                                                                           \
  inline std::string EnumName##ToString(EnumName type) { /* NOLINT inline usage */                                    \
    switch (type) {                                                                                                   \
      EnumValMacro(ENUM_TO_STRING);                                                                                   \
      default: {                                                                                                      \
        throw std::runtime_error(("No enum conversion for: " + std::to_string(static_cast<uint64_t>(type))).c_str()); \
      }                                                                                                               \
    }                                                                                                                 \
  }                                                                                                                   \
                                                                                                                      \
  /** @return Enum version of @p str. */                                                                              \
  inline EnumName EnumName##FromString(const std::string &str) { /* NOLINT inline usage */                            \
    if (false) { /* This check starts an if-else chain for the macro. */                                              \
    }                                                                                                                 \
    EnumValMacro(ENUM_FROM_STRING) else { /* NOLINT readability/braces confusion */                                   \
      throw std::runtime_error("No enum conversion for: " + str);                                                     \
    }                                                                                                                 \
  }


// use

#define DEFIN_SQLTYPE(T) \
  T(SqlType, T_INT)      \
  T(SqlType, T_DOUBLE)   \
  T(SqlType, T_STRING)   \
  T(SqlType, T_BOOL)

ENUM_DEFINE(SqlType, uint8_t, DEFIN_SQLTYPE);
#undef DEFIN_SQLTYPE