Reactions  0.1.1
Handling reaction trees and decays
pow_enum.hpp
Go to the documentation of this file.
1 
9 #pragma once
10 
11 #include <cstdlib>
12 #include <string>
13 #include <utility>
14 
18 
20  template <char... C> struct string_tpl {
21  static constexpr char chars[sizeof...(C) + 1] = {C..., '\0'};
22  };
23 
25  template <typename lambda_str_type> struct string_builder {
26  template <std::size_t... indices> struct produce {
27  typedef string_tpl<lambda_str_type{}.chars[indices]...> result;
28  };
29  };
30 
32  template <std::size_t count, template <std::size_t...> class meta_functor,
33  std::size_t... indices>
34  struct apply_range {
35  typedef typename apply_range<count - 1, meta_functor, count - 1,
36  indices...>::result result;
37  };
38 
40  template <template <std::size_t...> class meta_functor,
41  std::size_t... indices>
42  struct apply_range<0, meta_functor, indices...> {
43  typedef typename meta_functor<indices...>::result result;
44  };
45 
47  template <class... S> struct string_group {
48  static constexpr const char *chars[sizeof...(S) + 1] = {S::chars...,
49  nullptr};
50  };
51 
53  template <class... Strings, char... C>
55  string_tpl<>) {
56  return string_group<Strings..., string_tpl<C...>>{};
57  }
58 
60  template <class... Strings, char... Cp, char C0, char... C>
63  if constexpr (C0 == ' ' || C0 == '\t')
65  string_tpl<C...>{});
66  else if constexpr (C0 == ',')
67  return parse_string_impl(string_group<Strings..., string_tpl<Cp...>>{},
69  else
71  string_tpl<Cp..., C0>{}, string_tpl<C...>{});
72  }
73 
78  template <char... C> constexpr auto parse_string(string_tpl<C...> s) {
80  }
81 } // namespace reactions::pow_enum
82 
90 #define REACTIONS_POW_ENUM(enum_name, ...) \
91  enum enum_name : int { __VA_ARGS__ }; \
92  \
93  struct enum_name##_properties { \
94  \
95  static constexpr std::size_t size = \
96  std::initializer_list{__VA_ARGS__}.size(); \
97  \
98  static constexpr enum_name list[size] = {__VA_ARGS__}; \
99  \
100  template <enum_name E, std::size_t I = 0> \
101  static constexpr auto index_impl() { \
102  static_assert(I < size); \
103  if constexpr (list[I] == E) \
104  return I; \
105  else \
106  return index_impl<E, I + 1>(); \
107  } \
108  \
109  template <enum_name E> static constexpr auto index() { \
110  return index_impl<E>(); \
111  } \
112  }
113 // must use a comma
114 
125 #define REACTIONS_POW_ENUM_WITH_UNKNOWN(enum_name, ...) \
126  enum enum_name : int { unknown_##enum_name = 0, __VA_ARGS__ }; \
127  \
128  struct enum_name##_properties { \
129  \
130  static constexpr std::size_t size = \
131  std::initializer_list{__VA_ARGS__}.size(); \
132  \
133  static constexpr enum_name list[size] = {__VA_ARGS__}; \
134  \
135  template <enum_name E, std::size_t I = 0> \
136  static constexpr auto index_impl() { \
137  static_assert(I < size); \
138  if constexpr (list[I] == E) \
139  return I; \
140  else \
141  return index_impl<E, I + 1>(); \
142  } \
143  \
144  template <enum_name E> static constexpr auto index() { \
145  return index_impl<E>(); \
146  } \
147  \
148  static enum_name from_string(const char *s) { \
149  auto i = 0u; \
150  for (; i < size; ++i) \
151  if (strcmp( \
152  [] { \
153  struct constexpr_string_type { \
154  const char *chars = #__VA_ARGS__; \
155  }; \
156  return reactions::pow_enum::parse_string( \
157  reactions::pow_enum::apply_range< \
158  sizeof(#__VA_ARGS__) - 1, \
159  reactions::pow_enum::string_builder< \
160  constexpr_string_type>::produce>::result{}); \
161  }() \
162  .chars[i], \
163  s) == 0) \
164  return list[i]; \
165  return unknown_##enum_name; \
166  } \
167  \
168  static enum_name from_string(std::string const &s) { \
169  return from_string(s.c_str()); \
170  } \
171  \
172  static const char *to_c_string(enum_name e) { \
173  auto i = 0u; \
174  for (; i < size; ++i) \
175  if (list[i] == e) \
176  break; \
177  return [] { \
178  struct constexpr_string_type { \
179  const char *chars = #__VA_ARGS__; \
180  }; \
181  return reactions::pow_enum::parse_string( \
182  reactions::pow_enum::apply_range< \
183  sizeof(#__VA_ARGS__) - 1, \
184  reactions::pow_enum::string_builder< \
185  constexpr_string_type>::produce>::result{}); \
186  }() \
187  .chars[i]; \
188  } \
189  static std::string to_string(enum_name e) { return to_c_string(e); } \
190  }
191 // must use a comma
Group of string templates.
Definition: pow_enum.hpp:47
constexpr auto parse_string_impl(string_group< Strings... >, string_tpl< C... >, string_tpl<>)
Implementation of the function to parse a string.
Definition: pow_enum.hpp:54
String as a template of characters.
Definition: pow_enum.hpp:20
static constexpr char chars[sizeof...(C)+1]
Definition: pow_enum.hpp:21
Transform a template of characters into a string.
Definition: pow_enum.hpp:34
Helper struct to convert strings to templates of strings.
Definition: pow_enum.hpp:25
meta_functor< indices... >::result result
Definition: pow_enum.hpp:43
apply_range< count - 1, meta_functor, count - 1, indices... >::result result
Definition: pow_enum.hpp:36
Utilities to define smart enumeration types.
Definition: pow_enum.hpp:17
string_tpl< lambda_str_type{}.chars[indices]... > result
Definition: pow_enum.hpp:27
constexpr auto parse_string(string_tpl< C... > s)
Parse a string template and return it as an array of strings.
Definition: pow_enum.hpp:78