OGLplus  (0.59.0) a C++ wrapper for rendering APIs

enum_class.hpp
Go to the documentation of this file.
1 
9 #ifndef EAGINE_ENUM_CLASS_HPP
10 #define EAGINE_ENUM_CLASS_HPP
11 
12 #include "assert.hpp"
13 #include "identifier_t.hpp"
14 #include "iterator.hpp"
15 #include "mp_list.hpp"
16 #include "nothing.hpp"
17 #include "type_identity.hpp"
18 #include "wrapping_container.hpp"
19 #include <tuple>
20 #include <type_traits>
21 
22 namespace eagine {
23 //------------------------------------------------------------------------------
34 template <typename T, typename ClassList, typename Tag = nothing_t>
35 struct enum_value;
36 
43 template <typename T, typename... Classes, typename Tag>
44 struct enum_value<T, mp_list<Classes...>, Tag> {
45  using type = enum_value;
46 
48  using value_type = T;
49 
51  using tag_type = Tag;
52 
54  const T value{};
55 
57  constexpr enum_value(value_type val) noexcept
58  : value{val} {}
59 
61  explicit constexpr operator value_type() const noexcept {
62  return value;
63  }
64 
66  explicit constexpr operator bool() const noexcept {
67  return true;
68  }
69 };
70 
71 template <typename... Classes, typename Tag>
72 struct enum_value<bool, mp_list<Classes...>, Tag> {
73  using type = enum_value;
74 
75  using value_type = bool;
76  using tag_type = Tag;
77 
78  const bool value{false};
79 
80  constexpr enum_value(bool val) noexcept
81  : value{val} {}
82 
83  explicit constexpr operator bool() const noexcept {
84  return value;
85  }
86 };
87 //------------------------------------------------------------------------------
98 template <typename T, typename ClassList, typename Tag = nothing_t>
100 
107 template <typename T, typename... Classes, typename Tag>
108 struct opt_enum_value<T, mp_list<Classes...>, Tag> {
109  using type = opt_enum_value;
110 
112  using value_type = T;
113 
115  using tag_type = Tag;
116 
118  const T value{};
119 
121  const bool is_valid{false};
122 
124  constexpr opt_enum_value(T val, bool valid) noexcept
125  : value{val}
126  , is_valid{valid} {}
127 
129  constexpr opt_enum_value(std::tuple<value_type, bool> init) noexcept
130  : value{std::get<0>(init)}
131  , is_valid{std::get<1>(init)} {}
132 
134  explicit constexpr operator value_type() const noexcept {
135  return value;
136  }
137 
140  explicit constexpr operator bool() const noexcept {
141  return is_valid;
142  }
143 };
144 
145 template <typename... Classes, typename Tag>
146 struct opt_enum_value<bool, mp_list<Classes...>, Tag> {
147  using type = opt_enum_value;
148 
149  using value_type = bool;
150  using tag_type = Tag;
151 
152  const bool value{};
153  const bool is_valid{false};
154 
155  constexpr opt_enum_value(bool val, bool valid) noexcept
156  : value(val)
157  , is_valid{valid} {}
158 
159  constexpr opt_enum_value(std::tuple<bool, bool> init) noexcept
160  : value(std::get<0>(init))
161  , is_valid{std::get<1>(init)} {}
162 
163  explicit constexpr operator bool() const noexcept {
164  return is_valid && value;
165  }
166 };
167 //------------------------------------------------------------------------------
176 template <typename T, typename Tag = nothing_t>
178  using type = no_enum_value;
179 
181  using value_type = T;
182 
184  using tag_type = Tag;
185 
186  const T value{};
187 
189  explicit constexpr operator T() const noexcept {
190  return value;
191  }
192 
194  explicit constexpr operator bool() const noexcept {
195  return false;
196  }
197 };
198 
199 template <typename Tag>
200 struct no_enum_value<bool, Tag> {
201  using type = no_enum_value;
202 
203  using value_type = bool;
204  using tag_type = Tag;
205 
206  explicit constexpr operator bool() const noexcept {
207  return false;
208  }
209 };
210 //------------------------------------------------------------------------------
211 template <identifier_t LibId>
213 
236 template <typename Self, typename T, identifier_t LibId, identifier_t Id>
237 struct enum_class {
238  using type = enum_class;
239 
241  using value_type = T;
242 
243  static constexpr const identifier_t lib_id = LibId;
244  static constexpr const identifier_t id = Id;
245 
246  value_type _value{};
247 
249  enum_class() = default;
250 
252  template <
253  typename Classes,
254  typename Tag,
255  typename = std::enable_if_t<mp_contains_v<Classes, Self>>>
257  : _value{ev.value} {}
258 
260  template <
261  typename Classes,
262  typename Tag,
263  typename = std::enable_if_t<mp_contains_v<Classes, Self>>>
265  : _value{ev.value} {
266  EAGINE_ASSERT(ev.is_valid);
267  }
268 
270  constexpr enum_class(no_enum_value<T>) noexcept {
271  EAGINE_UNREACHABLE();
272  }
273 
275  constexpr enum_class(const any_enum_value<LibId>& aev) noexcept
276  : _value{static_cast<T>(aev._value)} {
277  EAGINE_ASSERT(aev._type_id == Id);
278  }
279 
281  explicit constexpr enum_class(value_type value) noexcept
282  : _value{value} {}
283 
284  constexpr operator Self() const noexcept {
285  return Self{_value};
286  }
287 
289  explicit constexpr operator value_type() const noexcept {
290  return _value;
291  }
292 
294  friend constexpr auto operator==(enum_class a, enum_class b) noexcept {
295  return a._value == b._value;
296  }
297 
299  friend constexpr auto operator!=(enum_class a, enum_class b) noexcept {
300  return a._value != b._value;
301  }
302 
303  struct transform {
304  constexpr auto operator()(T value) noexcept {
305  return enum_class<Self, T, LibId, Id>{value};
306  }
307  };
308 };
309 //------------------------------------------------------------------------------
312 template <typename T>
313 struct is_enum_class : std::false_type {};
314 
319 template <typename T>
321 
322 template <typename Self, typename T, identifier_t LibId, identifier_t Id>
323 struct is_enum_class<enum_class<Self, T, LibId, Id>> : std::true_type {
324  static_assert(std::is_base_of_v<enum_class<Self, T, LibId, Id>, Self>);
325 };
326 //------------------------------------------------------------------------------
329 template <typename Class, typename Value>
330 struct is_enum_class_value : std::false_type {};
331 
338 template <typename C, typename V>
339 constexpr auto is_enum_class_value_v =
341 
342 template <
343  typename Self,
344  typename T,
345  typename Tag,
346  identifier_t LibId,
347  identifier_t Id>
348 struct is_enum_class_value<enum_class<Self, T, LibId, Id>, no_enum_value<T, Tag>>
349  : std::true_type {
350  static_assert(std::is_base_of_v<enum_class<Self, T, LibId, Id>, Self>);
351 };
352 
353 template <
354  typename Self,
355  typename T,
356  typename Classes,
357  typename Tag,
358  identifier_t LibId,
359  identifier_t Id>
360 struct is_enum_class_value<
361  enum_class<Self, T, LibId, Id>,
362  enum_value<T, Classes, Tag>> : mp_contains<Classes, Self> {
363  static_assert(std::is_base_of_v<enum_class<Self, T, LibId, Id>, Self>);
364 };
365 
366 template <
367  typename Self,
368  typename T,
369  typename Classes,
370  typename Tag,
371  identifier_t LibId,
372  identifier_t Id>
373 struct is_enum_class_value<
374  enum_class<Self, T, LibId, Id>,
375  opt_enum_value<T, Classes, Tag>> : mp_contains<Classes, Self> {
376  static_assert(std::is_base_of_v<enum_class<Self, T, LibId, Id>, Self>);
377 };
378 //------------------------------------------------------------------------------
384 template <identifier_t LibId>
386 
387  identifier_t _type_id{~identifier_t(0)};
388 
390  constexpr any_enum_class() noexcept = default;
391 
393  template <typename Self, typename T, identifier_t Id>
395  : _type_id{Id} {
396  static_assert(std::is_base_of_v<enum_class<Self, T, LibId, Id>, Self>);
397  }
398 
400  constexpr any_enum_class(const any_enum_value<LibId>& aev) noexcept
401  : _type_id{aev._type_id} {}
402 
404  explicit constexpr operator bool() const noexcept {
405  return _type_id != ~identifier_t(0);
406  }
407 
409  friend auto
410  operator==(const any_enum_class& a, const any_enum_class& b) noexcept {
411  return a._type_id == b._type_id;
412  }
413 
415  friend auto
416  operator!=(const any_enum_class& a, const any_enum_class& b) noexcept {
417  return a._type_id != b._type_id;
418  }
419 };
420 
426 template <identifier_t LibId>
427 struct any_enum_value {
428  long _value{0};
429  identifier_t _type_id{~identifier_t(0)};
430 
432  constexpr any_enum_value() noexcept = default;
433 
435  template <typename Self, typename T, identifier_t Id>
436  constexpr any_enum_value(enum_class<Self, T, LibId, Id> v) noexcept
437  : _value{long(v._value)}
438  , _type_id{Id} {
439  static_assert(std::is_base_of_v<enum_class<Self, T, LibId, Id>, Self>);
440  }
441 
443  explicit constexpr operator bool() const noexcept {
444  return _type_id != ~identifier_t(0);
445  }
446 
448  friend auto
449  operator==(const any_enum_value& a, const any_enum_value& b) noexcept {
450  return (a._value == b._value) && (a._type_id == b._type_id);
451  }
452 
454  friend auto
455  operator!=(const any_enum_value& a, const any_enum_value& b) noexcept {
456  return (a._value != b._value) || (a._type_id != b._type_id);
457  }
458 };
459 
463 template <identifier_t LibId>
464 static constexpr auto
466  return a._type_id == b._type_id;
467 }
468 //------------------------------------------------------------------------------
475 template <typename EnumClass, typename Container>
477  : public basic_wrapping_container<
478  Container,
479  EnumClass,
480  typename EnumClass::value_type> {
482  Container,
483  EnumClass,
484  typename EnumClass::value_type>;
485 
486 public:
487  using base::base;
488 
489  constexpr auto raw_enums() noexcept {
490  return this->raw_items();
491  }
492 
493  constexpr auto raw_enums() const noexcept {
494  return this->raw_items();
495  }
496 };
497 //------------------------------------------------------------------------------
502 template <typename EnumClass>
503 using enum_class_span =
505 
510 template <typename EnumClass>
511 using enum_class_view =
513 
518 template <typename EnumClass, std::size_t N>
519 using enum_class_array =
521 //------------------------------------------------------------------------------
522 } // namespace eagine
523 
524 #endif // EAGINE_ENUM_CLASS_HPP
value_type
Value tree value element data type enumeration.
Definition: interface.hpp:27
Class holding optional value of a (typically C-API) symbolic constant.
Definition: enum_class.hpp:99
Enum class for constants or enumerators (typically from a C-API).
Definition: enum_class.hpp:237
typename get_type< T, F >::type type_t
Template returning nested alias type of type T or void.
Definition: type_identity.hpp:49
constexpr enum_value(value_type val) noexcept
Initialization from the specified value.
Definition: enum_class.hpp:57
Common code is placed in this namespace.
Definition: eagine.hpp:21
constexpr bool is_enum_class_v
Trait indicating if type T is an enum_class.
Definition: enum_class.hpp:320
Class representing "none" / "nothing" values.
Definition: nothing.hpp:17
friend auto operator!=(const any_enum_value &a, const any_enum_value &b) noexcept
Nonequality comparison.
Definition: enum_class.hpp:455
Class representing undefined value of a (typically C-API) symbolic constant.
Definition: enum_class.hpp:177
Implementation of is_enum_class_value trait.
Definition: enum_class.hpp:330
constexpr any_enum_class() noexcept=default
Default constructor.
constexpr auto is_enum_class_value_v
Trait indicating if type T is an enum_value, opt_enum_value or no_enum_value.
Definition: enum_class.hpp:339
constexpr enum_class(value_type value) noexcept
Explicit initialization from argument of value type.
Definition: enum_class.hpp:281
constexpr enum_class(no_enum_value< T >) noexcept
Construction from a no_enum_value.
Definition: enum_class.hpp:270
T value_type
The constant or enumerator value type.
Definition: enum_class.hpp:181
constexpr friend auto operator!=(enum_class a, enum_class b) noexcept
Nonequality comparison.
Definition: enum_class.hpp:299
constexpr any_enum_class(const any_enum_value< LibId > &aev) noexcept
Construction from any_enum_value from the same "library" or API.
Definition: enum_class.hpp:400
constexpr friend auto operator==(enum_class a, enum_class b) noexcept
Equality comparison.
Definition: enum_class.hpp:294
T value_type
The constant or enumerator value type.
Definition: enum_class.hpp:241
constexpr opt_enum_value(std::tuple< value_type, bool > init) noexcept
Initialization from the specified value and validity indicator.
Definition: enum_class.hpp:129
constexpr enum_class(opt_enum_value< T, Classes, Tag > ev) noexcept
Construction from a related opt_enum_value.
Definition: enum_class.hpp:264
friend auto operator==(const any_enum_class &a, const any_enum_class &b) noexcept
Equality comparison.
Definition: enum_class.hpp:410
constexpr any_enum_value() noexcept=default
Default constructor.
constexpr enum_class(enum_value< T, Classes, Tag > ev) noexcept
Construction from a related enum_value.
Definition: enum_class.hpp:256
friend auto operator!=(const any_enum_class &a, const any_enum_class &b) noexcept
Nonequality comparison.
Definition: enum_class.hpp:416
constexpr enum_class(const any_enum_value< LibId > &aev) noexcept
Construction from an any_enum_value.
Definition: enum_class.hpp:275
constexpr any_enum_class(const enum_class< Self, T, LibId, Id > &) noexcept
Construction from enum_class from the same "library" or API.
Definition: enum_class.hpp:394
static auto transform(basic_span< T, P, S > spn, Transform function) -> basic_span< T, P, S >
Transforms the elements of a span with a function.
Definition: span_algo.hpp:572
Tag tag_type
The tag type specified as template argument.
Definition: enum_class.hpp:184
Type erasure for instantiations of enum_value from a specified library.
Definition: enum_class.hpp:212
static constexpr auto same_enum_class(any_enum_class< LibId > a, any_enum_class< LibId > b) noexcept
Tests if two instances of any_enum_class belong to the same enum class.
Definition: enum_class.hpp:465
Template for containers of enum_class.
Definition: enum_class.hpp:476
Implementation of is_enum_class trait.
Definition: enum_class.hpp:313
constexpr auto raw_items() noexcept
Returns view of the elements as they are stored, without transfomation.
Definition: wrapping_container.hpp:127
Compile-time type list template.
Definition: mp_list.hpp:20
std::uint64_t identifier_t
The underlying integer type for eagine::identifier.
Definition: identifier_t.hpp:19
Tag tag_type
The tag type specified as template argument.
Definition: enum_class.hpp:115
constexpr opt_enum_value(T val, bool valid) noexcept
Initialization from the specified value and validity indicator.
Definition: enum_class.hpp:124
Tag tag_type
The tag type specified as template argument.
Definition: enum_class.hpp:51
T value_type
The constant or enumerator value type.
Definition: enum_class.hpp:112
enum_class()=default
Default constructor.
Type erasure for instantiations of enum_class from a specified library.
Definition: enum_class.hpp:385
Template used in implementation of containers with wrapped elements.
Definition: wrapping_container.hpp:26
T value_type
The constant or enumerator value type.
Definition: enum_class.hpp:48
friend auto operator==(const any_enum_value &a, const any_enum_value &b) noexcept
Equality comparison.
Definition: enum_class.hpp:449
Class holding the value of a (typically C-API) symbolic constant.
Definition: enum_class.hpp:35

Copyright © 2015-2021 Matúš Chochlík.
<chochlik -at -gmail.com>
Documentation generated on Tue Apr 13 2021 by Doxygen (version 1.8.17).