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 <string>
6 #include <limits>
7 #include <array>
8 
9 namespace cpp
10 {
11 namespace static_reflection
12 {
13 namespace meta
14 {
15 
16 template<
17  typename SourceInfo,
18  typename EnumType,
19  typename Constants,
20  typename ConstantsNames
21 >
22 class Enum;
23 
24 #ifndef SIPLASPLAS_DOXYGEN_RUNNING // Doxygen shit
25 template<
26  typename SourceInfo_,
27  typename EnumType,
28  EnumType... Constants,
29  typename... ConstantsNames
30 >
31 class Enum<
32  SourceInfo_,
33  EnumType,
34  ::cpp::meta::list<std::integral_constant<EnumType, Constants>...>,
35  ::cpp::meta::list<ConstantsNames...>
36 >
37 #else
38 
47 class Enum
48 #endif // SIPLASPLAS_DOXYGEN_RUNNING
49 {
50 public:
54  using type = EnumType;
58  using Type = EnumType;
62  using UnderlyingType = typename std::underlying_type<EnumType>::type;
66  using SourceInfo = SourceInfo_;
70  using names_array_t = std::array<const char*, sizeof...(ConstantsNames)>;
74  using values_array_t = const EnumType[sizeof...(Constants)];
75 
76  constexpr Enum() = default;
77 
81  static constexpr std::size_t count()
82  {
83  static_assert(sizeof...(Constants) == sizeof...(ConstantsNames), "");
84  return sizeof...(Constants);
85  }
86 
92  static constexpr const names_array_t& names()
93  {
94  return _namesArray;
95  }
96 
102  static constexpr const values_array_t& values()
103  {
104  return ::cpp::meta::PackToArray<EnumType, Constants...>::get();
105  }
106 
126  static constexpr EnumType value(std::size_t i)
127  {
128  return values()[i];
129  }
130 
153  static constexpr const char* name(std::size_t i)
154  {
155  return names()[i];
156  }
157 
173  static constexpr const char* toString(const EnumType value)
174  {
175  return _toString(value, 0);
176  }
177 
190  static constexpr EnumType fromString(const char* name)
191  {
192  return _fromString(name, 0);
193  }
194 
205  static constexpr bool has(const char* name)
206  {
207  return _has(name, 0);
208  }
209 
215  static constexpr bool has(const UnderlyingType value)
216  {
217  return _has(value, 0);
218  }
219 
220 private:
221  static constexpr std::array<const char*, sizeof...(ConstantsNames)> _namesArray = {{::cpp::meta::StringToArray<ConstantsNames>::c_str()...}};
222  static constexpr bool streq(const char* lhs, const char* rhs)
223  {
224  return ((*rhs and *lhs) ? (*lhs == *rhs) and streq(lhs + 1, rhs + 1) : (not *lhs and not *rhs));
225  }
226 
227  static constexpr const char* _toString(const EnumType value, std::size_t i)
228  {
229  return (i < sizeof...(Constants)) ?
230  ((value == Enum::value(i)) ? Enum::name(i) : _toString(value, i + 1))
231  :
232  nullptr;
233  }
234 
235  static constexpr EnumType _fromString(const char* name, std::size_t i)
236  {
237  return (i < sizeof...(ConstantsNames)) ?
238  (streq(name, Enum::name(i)) ? Enum::value(i) : _fromString(name, i + 1))
239  :
240  static_cast<EnumType>(std::numeric_limits<typename std::underlying_type<EnumType>::type>::max());
241  }
242 
243  static constexpr bool _has(const char* name, std::size_t i)
244  {
245  return (i < sizeof...(ConstantsNames)) && (streq(name, Enum::name(i)) || _has(name, i + 1));
246  }
247 
248  static constexpr bool _has(const UnderlyingType value, std::size_t i)
249  {
250  return (i < sizeof...(Constants)) && ((value == static_cast<UnderlyingType>(Enum::value(i))) || _has(value, i + 1));
251  }
252 };
253 
254 template<typename SourceInfo, typename EnumType, EnumType... Constants, typename... ConstantsNames>
255 constexpr typename Enum<
256  SourceInfo,
257  EnumType,
258  ::cpp::meta::list<std::integral_constant<EnumType, Constants>...>,
259  ::cpp::meta::list<ConstantsNames...>
261  SourceInfo,
262  EnumType,
263  ::cpp::meta::list<std::integral_constant<EnumType, Constants>...>,
264  ::cpp::meta::list<ConstantsNames...>
265 >::_namesArray;
266 
267 } // namespace meta
268 
269 namespace codegen
270 {
271 
272 template<typename EnumType>
273 class Enum : public static_reflection::meta::Enum<
274  static_reflection::meta::EmptySourceInfo<Enum<EnumType>>,
275  EnumType,
276  ::cpp::meta::list<
277  std::integral_constant<EnumType, static_cast<EnumType>(0)>
278  >,
279  ::cpp::meta::list<
280  ::cpp::meta::string<>
281  >
282 >
283 {};
284 
285 }
286 
297 template<typename EnumType>
298 class Enum : public codegen::Enum<EnumType>
299 {};
300 
301 } // namespace static_reflection
302 } // namespace cpp
303 #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:153
Definition: canary_allocator.hpp:7
static constexpr bool has(const UnderlyingType value)
Checks if there&#39;s an enumeration constant with the given value.
Definition: enum.hpp:215
static constexpr std::size_t count()
Returns the number of constants declared in the enumeration type.
Definition: enum.hpp:81
static constexpr bool has(const char *name)
Checks if there&#39;s an enumeration constant with the given name.
Definition: enum.hpp:205
static constexpr const char * toString(const EnumType value)
Returns a string representation of the given enumeration value.
Definition: enum.hpp:173
static constexpr const values_array_t & values()
Returns the set of enum constants values.
Definition: enum.hpp:102
static constexpr EnumType fromString(const char *name)
Returns an enumeration value from the given enumeration constant name.
Definition: enum.hpp:190
Stores static reflection information of an enumeration type.
Definition: enum.hpp:22
const EnumType[sizeof...(::cpp::meta::list< std::integral_constant< EnumType, static_cast< EnumType >(0)> >)] values_array_t
Array type returned by values()
Definition: enum.hpp:74
static constexpr const names_array_t & names()
Returns the set of enum constants names.
Definition: enum.hpp:92
Returns static reflection information of the given enumeration type.
Definition: enum.hpp:298
static constexpr EnumType value(std::size_t i)
Returns the value of the i-th constant of the enumeration.
Definition: enum.hpp:126