EventAnalysis  1.0.0
FactoryMacros.h
Go to the documentation of this file.
1 /*
2  * FactoryMacros.h
3  *
4  * Created on: 01 Aug 2017
5  * Author: Nicola Mori
6  */
7 
10 #ifndef FACTORYMACROS_H_
11 #define FACTORYMACROS_H_
12 
13 #include "Factory.h"
14 
15 #define GETOVERRIDE(_ignored, _1, _2, _3, _4, _5, NAME, ...) NAME
16 
17 // Macro to convert a variadic argument list consisting of a list of types in a list of argument names
18 // E.g. NAMEDARGS(float,int,char) -> float arg3, int arg2, char arg1
19 #define NAMEDARGS0()
20 #define NAMEDARGS1(type) type arg1
21 #define NAMEDARGS2(type, ...) type arg2, NAMEDARGS1(__VA_ARGS__)
22 #define NAMEDARGS3(type, ...) type arg3, NAMEDARGS2(__VA_ARGS__)
23 #define NAMEDARGS4(type, ...) type arg4, NAMEDARGS3(__VA_ARGS__)
24 #define NAMEDARGS5(type, ...) type arg5, NAMEDARGS4(__VA_ARGS__)
25 #define NAMEDARGS(...) \
26  GETOVERRIDE(ignored, ##__VA_ARGS__, NAMEDARGS5, NAMEDARGS4, NAMEDARGS3, NAMEDARGS2, NAMEDARGS1, NAMEDARGS0) \
27  (__VA_ARGS__)
28 
29 // Macro to produce a list of variable names according to a list of types (one variable per type)
30 // E.g. ARGNAMES(float,int,char) -> arg3, arg2, arg1
31 #define ARGNAMES0()
32 #define ARGNAMES1(type) arg1
33 #define ARGNAMES2(type, ...) arg2, ARGNAMES1(__VA_ARGS__)
34 #define ARGNAMES3(type, ...) arg3, ARGNAMES2(__VA_ARGS__)
35 #define ARGNAMES4(type, ...) arg4, ARGNAMES3(__VA_ARGS__)
36 #define ARGNAMES5(type, ...) arg5, ARGNAMES4(__VA_ARGS__)
37 #define ARGNAMES(...) \
38  GETOVERRIDE(ignored, ##__VA_ARGS__, ARGNAMES5, ARGNAMES4, ARGNAMES3, ARGNAMES2, ARGNAMES1, ARGNAMES0)(__VA_ARGS__)
39 
40 // Macro to produce a list of typenames to use in template definitions
41 // E.g. TYPENAMES(float,int,char) -> typename float, typename int, typename char
42 #define TYPENAMES0() typename T0
43 #define TYPENAMES1(type) typename T1, TYPENAMES0()
44 #define TYPENAMES2(type, ...) typename T2, TYPENAMES1(__VA_ARGS__)
45 #define TYPENAMES3(type, ...) typename T3, TYPENAMES2(__VA_ARGS__)
46 #define TYPENAMES4(type, ...) typename T4, TYPENAMES3(__VA_ARGS__)
47 #define TYPENAMES5(type, ...) typename T5, TYPENAMES4(__VA_ARGS__)
48 #define TYPENAMES(...) \
49  GETOVERRIDE(ignored, ##__VA_ARGS__, TYPENAMES5, TYPENAMES4, TYPENAMES3, TYPENAMES2, TYPENAMES1, TYPENAMES0) \
50  (__VA_ARGS__)
51 
59 #define RegisterClassAsImp(counter, baseClassName, className, aliasName, ...) \
60  baseClassName *className##Builder_##counter(NAMEDARGS(__VA_ARGS__)) { return new className(ARGNAMES(__VA_ARGS__)); } \
61  void className##Destroyer_##counter(className *p) { delete p; } \
62  class className##Proxy_##counter { \
63  public: \
64  className##Proxy_##counter() { \
65  EA::Factory<baseClassName, ##__VA_ARGS__>::GetInstance().RegisterBuilder(aliasName, \
66  className##Builder_##counter); \
67  } \
68  }; \
69  className##Proxy_##counter proxyFor##className##_##counter
70 
71 #define RegisterClassAsHelper(counter, baseClassName, className, aliasName, ...) \
72  RegisterClassAsImp(counter, baseClassName, className, aliasName, ##__VA_ARGS__)
73 #define RegisterClassAs(baseClassName, className, aliasName, ...) \
74  RegisterClassAsHelper(__COUNTER__, baseClassName, className, aliasName, ##__VA_ARGS__)
75 
77 #define RegisterClass(baseClassName, className, ...) \
78  RegisterClassAsHelper(__COUNTER__, baseClassName, className, #className, ##__VA_ARGS__)
79 #endif /* FACTORYMACROS_H_ */