#define VA_SIZE(...) INVOKE( VA_GET_SIZE VA_OB INVOKE(VA_SPEC##__VA_ARGS__()), 0, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 VA_CB ) #define VA_OB ( #define VA_CB ) #define VA_SPEC() 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34 #define VA_GET_SIZE(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_,n,...) n #define INVOKE( ... ) INVOKE_A( __VA_ARGS__ ) #define INVOKE_A( ... ) __VA_ARGS__ #define VA_FOR(macro,data,...) INVOKE( CAT(VA_FOR, VA_SIZE(__VA_ARGS__)) ( macro, data, VA_APPLY(VA_FIRST (__VA_ARGS__)), (VA_APPLY(VA_WO_FIRST (__VA_ARGS__))) ) ) #define VA_APPLY(x) x #define VA_FIRST(a, ...) a #define VA_WO_FIRST(a, ...) __VA_ARGS__ #define VA_FOR0(m,d,e,x) #define VA_FOR1(m,d,e,x) m( d, e ) #define VA_FOR2(m,d,e,x) m( d, e ) VA_FOR1( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR3(m,d,e,x) m( d, e ) VA_FOR2( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR4(m,d,e,x) m( d, e ) VA_FOR3( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR5(m,d,e,x) m( d, e ) VA_FOR4( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR6(m,d,e,x) m( d, e ) VA_FOR5( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR7(m,d,e,x) m( d, e ) VA_FOR6( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR8(m,d,e,x) m( d, e ) VA_FOR7( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR9(m,d,e,x) m( d, e ) VA_FOR8( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR10(m,d,e,x) m( d, e ) VA_FOR9( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR11(m,d,e,x) m( d, e ) VA_FOR10( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR12(m,d,e,x) m( d, e ) VA_FOR11( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR13(m,d,e,x) m( d, e ) VA_FOR12( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR14(m,d,e,x) m( d, e ) VA_FOR13( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR15(m,d,e,x) m( d, e ) VA_FOR14( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR16(m,d,e,x) m( d, e ) VA_FOR15( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR17(m,d,e,x) m( d, e ) VA_FOR16( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR18(m,d,e,x) m( d, e ) VA_FOR17( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR19(m,d,e,x) m( d, e ) VA_FOR18( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR20(m,d,e,x) m( d, e ) VA_FOR19( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR21(m,d,e,x) m( d, e ) VA_FOR20( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR22(m,d,e,x) m( d, e ) VA_FOR21( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR23(m,d,e,x) m( d, e ) VA_FOR22( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR24(m,d,e,x) m( d, e ) VA_FOR23( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR25(m,d,e,x) m( d, e ) VA_FOR24( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR26(m,d,e,x) m( d, e ) VA_FOR25( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR27(m,d,e,x) m( d, e ) VA_FOR26( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR28(m,d,e,x) m( d, e ) VA_FOR27( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR29(m,d,e,x) m( d, e ) VA_FOR28( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR30(m,d,e,x) m( d, e ) VA_FOR29( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR31(m,d,e,x) m( d, e ) VA_FOR30( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define VA_FOR32(m,d,e,x) m( d, e ) VA_FOR31( m, d, VA_APPLY(VA_FIRST x), (VA_APPLY(VA_WO_FIRST x))) #define CAT(x,y) CAT_A(x, y) #define CAT_A(x,y) x##y #define ENUM_IDENTITY(X,A) A, #define ENUM_STRING_TO_ENUM(X,A) X.insert(std::make_pair(#A,A)); #define ENUM_ENUM_TO_STRING(X,A) X.insert(std::make_pair(A,#A)); #define ENUM_TO_VECTOR(X,A) X.push_back(A); #define STRING_ENUM(name, ...) \ class name \ { \ public:\ enum Type { VA_FOR(ENUM_IDENTITY, fake, __VA_ARGS__) }; \ static const std::string &to_string( Type enumVal ) \ {\ static const std::map<Type,std::string> enumStringsMap = _make_enum_strings_map();\ auto it = enumStringsMap.find(enumVal);\ static std::string emptyString;\ if(it==enumStringsMap.end())\ return emptyString;\ return it->second;\ }\ static Type from_string(const std::string &value)\ {\ static const std::map<std::string,Type> stringsEnumMap = _make_strings_enum_map(); \ std::map<std::string,Type>::const_iterator it = stringsEnumMap.find(value);\ if(it==stringsEnumMap.end())\ return (Type)0;\ return it->second;\ }\ static const std::vector<Type>& values()\ {\ static const std::vector<Type> valueVector = _make_values();\ return valueVector;\ }\ private:\ static const std::vector<Type> _make_values()\ {\ std::vector<Type> valueVector;\ valueVector.reserve(VA_SIZE(__VA_ARGS__));\ VA_FOR(ENUM_TO_VECTOR, valueVector, __VA_ARGS__)\ return valueVector;\ }\ static std::map<Type,std::string> _make_enum_strings_map()\ {\ std::map<Type,std::string> enumStringsMap;\ VA_FOR(ENUM_ENUM_TO_STRING, enumStringsMap, __VA_ARGS__)\ return enumStringsMap;\ }\ static std::map<std::string,Type> _make_strings_enum_map()\ {\ std::map<std::string,Type> stringsEnumMap;\ VA_FOR(ENUM_STRING_TO_ENUM, stringsEnumMap, __VA_ARGS__)\ return stringsEnumMap;\ }\ };