Generate multiple macro calls according to the number of arguments

前端 未结 1 399
有刺的猬
有刺的猬 2020-12-22 11:30

I\'m trying to call this function several times in a repeditive fashion.

template
void METADATA_METHODS_IMPL(std::string& metadata, const          


        
相关标签:
1条回答
  • 2020-12-22 12:24

    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;
    
    0 讨论(0)
提交回复
热议问题