enum.h
Go to the documentation of this file.
1 #ifndef MAP_MERGE_ENUM_H_
2 #define MAP_MERGE_ENUM_H_
3 
8 
10 #include <ostream>
11 #include <type_traits>
12 
13 #define NUM_ARGS_(_10, _9, _8, _7, _6, _5, _4, _3, _2, _1, N, ...) N
14 #define NUM_ARGS(...) NUM_ARGS_(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
15 #define FOREACH_MACRO(MACRO, ...) \
16  FOREACH_(NUM_ARGS(__VA_ARGS__), MACRO, __VA_ARGS__)
17 #define FOREACH_(N, M, ...) FOREACH_x(N, M, __VA_ARGS__)
18 #define FOREACH_x(N, M, ...) FOREACH_##N(M, __VA_ARGS__)
19 #define FOREACH_1(M, A) M(A)
20 #define FOREACH_2(M, A, ...) M(A), FOREACH_1(M, __VA_ARGS__)
21 #define FOREACH_3(M, A, ...) M(A), FOREACH_2(M, __VA_ARGS__)
22 #define FOREACH_4(M, A, ...) M(A), FOREACH_3(M, __VA_ARGS__)
23 #define FOREACH_5(M, A, ...) M(A), FOREACH_4(M, __VA_ARGS__)
24 #define FOREACH_6(M, A, ...) M(A), FOREACH_5(M, __VA_ARGS__)
25 #define FOREACH_7(M, A, ...) M(A), FOREACH_6(M, __VA_ARGS__)
26 #define FOREACH_8(M, A, ...) M(A), FOREACH_7(M, __VA_ARGS__)
27 #define STRINGIFY_(X) #X
28 #define STRINGIFY(X) STRINGIFY_(X)
29 
30 #define ENUM_CLASS(EnumType, ...) \
31  enum class EnumType { __VA_ARGS__ }; \
32  \
33  namespace enums \
34  { \
35  constexpr inline static const char *to_string(EnumType e) \
36  { \
37  const char *names[]{FOREACH_MACRO(STRINGIFY, __VA_ARGS__)}; \
38  static_assert(NUM_ARGS(__VA_ARGS__) == (sizeof(names) / sizeof(names[0])), \
39  "unsupported number of enum literals"); \
40  return names[static_cast<std::underlying_type_t<EnumType>>(e)]; \
41  } \
42  \
43  template <typename T> \
44  static std::enable_if_t<std::is_same<T, EnumType>::value, T> \
45  from_string(const std::string &s) \
46  { \
47  constexpr const static char *names[]{ \
48  FOREACH_MACRO(STRINGIFY, __VA_ARGS__)}; \
49  static_assert(NUM_ARGS(__VA_ARGS__) == (sizeof(names) / sizeof(names[0])), \
50  "unsupported number of enum literals"); \
51  std::underlying_type_t<EnumType> i = 0; \
52  for (auto name : names) { \
53  if (name == s) { \
54  return static_cast<EnumType>(i); \
55  } \
56  ++i; \
57  } \
58  throw std::runtime_error("from_string: " + s + \
59  " is invalid value for " \
60  "enum " #EnumType); \
61  } \
62  } /* namespace enums */ \
63  static inline std::ostream &operator<<(std::ostream &stream, EnumType value) \
64  { \
65  stream << enums::to_string(value); \
66  return stream; \
67  }
68 
70 
71 #endif // MAP_MERGE_ENUM_H_


map_merge_3d
Author(s): Jiri Horner
autogenerated on Mon Feb 28 2022 22:47:17