Generate multiple macro calls according to the number of arguments

时光毁灭记忆、已成空白 提交于 2019-11-29 18:37:14

Using these macros we can cause the preprocessor to keep rescanning and allow for recursive macros.

#define EVAL(...)  EVAL3(EVAL3(EVAL3(__VA_ARGS__)))
#define EVAL3(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__)))
#define EVAL2(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__)))
#define EVAL1(...) EVAL0(EVAL0(EVAL0(__VA_ARGS__)))
#define EVAL0(...) __VA_ARGS__

We can define some helper functions to build up concepts.

#define CAT(a, ...) PRIMITIVE_CAT(a,__VA_ARGS__)
#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__

#define EMPTY()
#define EAT(...)
#define IDENT(...) __VA_ARGS__
#define DEFER(id) id EMPTY()
#define OBSTRUCT(...) __VA_ARGS__ DEFER(EMPTY)()   

#define I_TRUE(t,f) t
#define I_FALSE(t,f) f
#define I_IS_DONE(a,b,...) b
#define TRUE_DONE() ~, I_TRUE
#define IS_DONE(b) OBSTRUCT(I_IS_DONE)(CAT(TRUE_,b)(),I_FALSE) 

And build this Macro Mapping function that carries the first parameter to each.

#define MM() MM_CALL
#define MM_NEXT(Macro,md,a,...) \
  IS_DONE(a)(                    \
     EAT                          \
  ,                                \
     OBSTRUCT(MM)()                 \
  )                                  \
  (Macro,md,a,__VA_ARGS__)
#define MM_CALL(Macro,md,a,...)   \
  Macro(md,a)                      \
  MM_NEXT(Macro,md,__VA_ARGS__)
#define MacroMap(Macro,md,...) EVAL(MM_CALL(Macro,md,__VA_ARGS__,DONE))

After defining the implementation related functions

#define METADATA_METHODS_IMPL_MACRO(md,a) \
  METADATA_METHODS_IMPL(md, a, #a);

#define METADATA_METHODS(md,...) \
  MacroMap(METADATA_METHODS_IMPL_MACRO,md,__VA_ARGS__) \
  return md

This:

METADATA_METHODS(metadata, F1, F2, F3);

Results in this (after adding some formatting):

METADATA_METHODS_IMPL(metadata, F1, "F1");
METADATA_METHODS_IMPL(metadata, F2, "F2");
METADATA_METHODS_IMPL(metadata, F3, "F3");
return metadata;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!