siplasplas
A library for C++ reflection and introspection
enum.hpp
1 #ifndef SIPLASPLAS_REFLECTION_STATIC_ENUM_HPP
2 #define SIPLASPLAS_REFLECTION_STATIC_ENUM_HPP
3 
4 #include <siplasplas/utility/meta.hpp>
5 #include <siplasplas/constexpr/arrayview.hpp>
6 #include <siplasplas/constexpr/meta.hpp>
7 #include <string>
8 #include <limits>
9 #include <array>
10 
11 namespace cpp
12 {
13 namespace static_reflection
14 {
15 namespace meta
16 {
17 
18 template<
19  typename SourceInfo,
20  typename EnumType,
21  typename Constants,
22  typename ConstantsNames
23 >
24 class Enum;
25 
26 #ifndef SIPLASPLAS_DOXYGEN_RUNNING // Doxygen shit
27 template<
28  typename SourceInfo_,
29  typename EnumType,
30  EnumType... Constants,
31  typename... ConstantsNames
32 >
33 class Enum<
34  SourceInfo_,
35  EnumType,
36  ::cpp::meta::list<std::integral_constant<EnumType, Constants>...>,
37  ::cpp::meta::list<ConstantsNames...>
38 >
39 #else
40 
49 class Enum
50 #endif // SIPLASPLAS_DOXYGEN_RUNNING
51 {
52 public:
56  using type = EnumType;
60  using Type = EnumType;
64  using UnderlyingType = typename std::underlying_type<EnumType>::type;
68  using SourceInfo = SourceInfo_;
72  using names_array_t = std::array<const char*, sizeof...(ConstantsNames)>;
76  using values_array_t = cpp::constexp::ConstArrayView<EnumType>;
77 
78  constexpr Enum() = default;
79 
83  static constexpr std::size_t count()
84  {
85  static_assert(sizeof...(Constants) == sizeof...(ConstantsNames), "");
86  return sizeof...(Constants);
87  }
88 
94  static constexpr const names_array_t& names()
95  {
96  return _namesArray;
97  }
98 
104  static constexpr values_array_t values()
105  {
106  return ::cpp::constexp::PackToArray<EnumType, Constants...>::get();
107  }
108 
128  static constexpr EnumType value(std::size_t i)
129  {
130  return values()[i];
131  }
132 
155  static constexpr const char* name(std::size_t i)
156  {
157  return names()[i];
158  }
159 
175  static constexpr const char* toString(const EnumType value)
176  {
177  return _toString(value, 0);
178  }
179 
192  static constexpr EnumType fromString(const char* name)
193  {
194  return _fromString(name, 0);
195  }
196 
207  static constexpr bool has(const char* name)
208  {
209  return _has(name, 0);
210  }
211 
217  static constexpr bool has(const UnderlyingType value)
218  {
219  return _has(value, 0);
220  }
221 
222 private:
223  static constexpr std::array<const char*, sizeof...(ConstantsNames)> _namesArray = {{
224  ::cpp::constexp::SequenceToString<ConstantsNames>::c_str()...
225  }};
226 
227  static constexpr bool streq(const char* lhs, const char* rhs)
228  {
229  return ((*rhs and *lhs) ? (*lhs == *rhs) and streq(lhs + 1, rhs + 1) : (not *lhs and not *rhs));
230  }
231 
232  static constexpr const char* _toString(const EnumType value, std::size_t i)
233  {
234  return (i < sizeof...(Constants)) ?
235  ((value == Enum::value(i)) ? Enum::name(i) : _toString(value, i + 1))
236  :
237  nullptr;
238  }
239 
240  static constexpr EnumType _fromString(const char* name, std::size_t i)
241  {
242  return (i < sizeof...(ConstantsNames)) ?
243  (streq(name, Enum::name(i)) ? Enum::value(i) : _fromString(name, i + 1))
244  :
245  static_cast<EnumType>(std::numeric_limits<typename std::underlying_type<EnumType>::type>::max());
246  }
247 
248  static constexpr bool _has(const char* name, std::size_t i)
249  {
250  return (i < sizeof...(ConstantsNames)) && (streq(name, Enum::name(i)) || _has(name, i + 1));
251  }
252 
253  static constexpr bool _has(const UnderlyingType value, std::size_t i)
254  {
255  return (i < sizeof...(Constants)) && ((value == static_cast<UnderlyingType>(Enum::value(i))) || _has(value, i + 1));
256  }
257 };
258 
259 template<typename SourceInfo, typename EnumType, EnumType... Constants, typename... ConstantsNames>
260 constexpr typename Enum<
261  SourceInfo,
262  EnumType,
263  ::cpp::meta::list<std::integral_constant<EnumType, Constants>...>,
264  ::cpp::meta::list<ConstantsNames...>
266  SourceInfo,
267  EnumType,
268  ::cpp::meta::list<std::integral_constant<EnumType, Constants>...>,
269  ::cpp::meta::list<ConstantsNames...>
270 >::_namesArray;
271 
272 } // namespace meta
273 
274 namespace codegen
275 {
276 
277 template<typename EnumType>
278 class Enum : public static_reflection::meta::Enum<
279  static_reflection::meta::EmptySourceInfo<Enum<EnumType>>,
280  EnumType,
281  ::cpp::meta::list<
282  std::integral_constant<EnumType, static_cast<EnumType>(0)>
283  >,
284  ::cpp::meta::list<
285  ::cpp::meta::string<>
286  >
287 >
288 {};
289 
290 }
291 
302 template<typename EnumType>
303 class Enum : public codegen::Enum<EnumType>
304 {};
305 
306 } // namespace static_reflection
307 } // namespace cpp
308 #endif // SIPLASPLAS_REFLECTION_STATIC_ENUM_HPP
static constexpr const char * name(std::size_t i)
Returns the name of the i-th constant of the enumeration.
Definition: enum.hpp:155
Definition: canary_allocator.hpp:7
constexpr const T & max(const T &lhs, const T &rhs)
Returns the greatest value of the two given.
Definition: algorithm.hpp:212
static constexpr bool has(const UnderlyingType value)
Checks if there&#39;s an enumeration constant with the given value.
Definition: enum.hpp:217
static constexpr std::size_t count()
Returns the number of constants declared in the enumeration type.
Definition: enum.hpp:83
static constexpr bool has(const char *name)
Checks if there&#39;s an enumeration constant with the given name.
Definition: enum.hpp:207
static constexpr const char * toString(const EnumType value)
Returns a string representation of the given enumeration value.
Definition: enum.hpp:175
static constexpr EnumType fromString(const char *name)
Returns an enumeration value from the given enumeration constant name.
Definition: enum.hpp:192
static constexpr values_array_t values()
Returns the set of enum constants values.
Definition: enum.hpp:104
Stores static reflection information of an enumeration type.
Definition: enum.hpp:24
static constexpr const names_array_t & names()
Returns the set of enum constants names.
Definition: enum.hpp:94
Returns static reflection information of the given enumeration type.
Definition: enum.hpp:303
static constexpr EnumType value(std::size_t i)
Returns the value of the i-th constant of the enumeration.
Definition: enum.hpp:128