- The best way to get started with Better Enums is to read the - project page and browse - the commented - - examples. This page gives reference documentation. -
- -The following declaration
- -#include <enum.h> -ENUM(Enum, underlying_type, A, B, C);- -
- generates a new type Enum. It is notionally similar to the type - created by this declaration: -
- -enum class Enum : underlying_type {A, B, C};
-
- - that is, it is an enumerated type with constants Enum::A, - Enum::B, and Enum::C, and is represented in memory by an - integer of type underlying_type. Just like with a built-in - enum class, it is possible to specify numeric values and aliases - for constants: -
- -ENUM(Enum, underlying_type, A = 1, B, C, D = A);- -
- Constant values are assigned by the compiler by exactly the same rules as - for a built-in enum, so in the above example, Enum::A == 1, - Enum::B == 2, Enum::C == 3, and Enum::D == 1. -
- -Member index
- --
-
- typename _Enumerated -
- Enum(_Enumerated) -
- operator +(_Enumerated) -
- operator _Enumerated() -
Internal enumerated type
--
-
- typename _Integral -
- _from_integral -
- _from_integral_unchecked -
- to_integral -
- _is_valid -
Integral type
--
-
- _from_string -
- _from_string_nocase -
- to_string -
- _name -
- _is_valid -
- _is_valid_nocase -
String conversions
--
-
Comparisons
--
-
Additional type safety
-- Internal enumerated type - index -
- - -typename Enum::_Enumerated
- -- The declared type Enum is built around an internal - C++ enumeration. Notionally, -
- -ENUM(Enum, int, A, B, C);- -
produces
- -class Enum {
- ...
- public:
- enum _Enumerated : int {A, B, C};
- ...
-};
-
- - _Enumerated is simply the name of the internal enumeration. The - user should not use this type name directly, but it is referred to in the - rest of the documentation. The name is exposed because a literal - Enum::A is not a value of type Enum, but a value of type - Enum::_Enumerated, which is convertible to Enum, in most - cases implicitly. -
- -- Note that _Enumerated is not a - C++11 - enum class. -
- - -- implicit constructor constexpr Enum(_Enumerated) -
- -- A converting constructor for promoting values of type _Enumerated - to values of type Enum. As mentioned above, this typically happens - automatically when you write a literal constant such as Enum::A in - a context where a value of type Enum is expected. For example: -
- -void do_something(Enum value) { ... }
-
-do_something(Enum::A); // converted silently
-
-
- - global unary constexpr operator +(_Enumerated) -
- -- For use when the compiler does not choose the implicit constructor above. - For example: -
- -(Enum::A).to_string()- -
- This expression does not compile because Enum::A is not an object, - and the compiler does not promote it. The promotion can be forced: -
- -(+Enum::A).to_string()- -
- This is easier to maintain than writing out a call to the converting - constructor: -
- -((Enum)Enum::A).to_string()- - -
- casting constexpr operator _Enumerated() const -
- -- Enables implicit conversion of Enum values down to - _Enumerated. The only purpose of this is to make Enum - values directly usable in switch statements for compiler-supported - case checking: -
- -switch(enum_value) {
- case Enum::A: ...; break;
- case Enum::B: ...; break;
- case Enum::C: ...; break;
-}
-
- - It is, unfortunately, a hole in the type safety of Enum, since it - allows implicit conversions to integral types (Enum to - _Enumerated, then _Enumerated to an integer). The user - should not rely on such conversions. They will probably be eliminated in the - future, perhaps by replacing this conversion with a conversion to an - enum class. -
- -- Underlying integral type - index -
- - -typename Enum::_Integral
- -- An alias for the underlying type that Enum was declared with. For - example, if the declaration is -
- -ENUM(Enum, uint32_t, A, B, C);- -
- Then Enum::_Integral is the same as uint32_t. -
- - -static constexpr Enum _from_integral(_Integral)
- -- Checked cast from a numeric value to an enum value. The function checks that - there is an enum constant with the given value. If not, it throws - std::runtime_error. The check takes time linear in the - number of constants in Enum. -
- - -- static constexpr Enum _from_integral_unchecked(_Integral) -
- -- Unchecked cast from a numeric value to an enum value. The function assumes - that there is an enum constant with the given value. The user has to ensure - that this assumption holds. If not, the behavior of subsequent operations - on the returned enum value is undefined. -
- - -- member constexpr - _Integral enum_value.to_integral() const -
- -- Returns the numeric representation of an enum value. -
- - -static constexpr bool _is_valid(_Integral)
- -- Checks that the given numeric value represents one of the constants in - Enum, as in _from_integral. Complexity is linear - in the number of constants. -
- -invariant sizeof(Enum) == sizeof(Enum::_Integral)
- -invariant alignof(Enum) == alignof(Enum::_Integral)
- -- String conversions - index -
- - -static constexpr Enum _from_string(const char*)
- -- Returns the enum constant given by the string. For example: -
- -Enum::_from_string("A") == Enum::A
-
- - Complexity is linear in the number of constants multiplied by the - length of the longest constant name. If the string does not name a constant, - throws std::runtime_error. -
- - -static constexpr Enum _from_string_nocase(const char*)
- -- The same as above, but lookup is case-insensitive. -
- - -- member constexpr const char* enum_value.to_string() - const -
- -- Returns the string representation of enum value on which the method is - called. If multiple constants have the same numeric value, the string - returned can be the representation any of the constants. Complexity is - linear in the number of constants. If the string does not name a - constant, throws std::runtime_error. -
- - -static constexpr const char *_name
- -- The name of the type, i.e., for -
- -ENUM(Enum, int, A, B, C);- -
- Enum::_name == "Enum" -
- - -static constexpr bool _is_valid(const char*)
- -- Checks that the given string is the name of one of the constants in - Enum, as in _from_string, with the same complexity. -
- - -static constexpr bool _is_valid_nocase(const char*)
- -- The same as above, but corresponding to _from_string_nocase. -
- -- Iteration - index -
- - -static constexpr _ValueIterable values
- -- An iterable container with all the defined constant values, in declaration - order. Suitable for use with range-based for loops: -
- -for (Enum value : Enum::_values) {
- // Will iterate over Enum::A, Enum::B, Enum::C
-}
-
- class _ValueIterable::iterator
- -- An iterator over defined constant values with a constexpr - dereference operator. Can be created explicitly by the constexpr - expressions -
- -Enum::_values::begin() -Enum::_values::end()- - -
static constexpr _NameIterable names
- -- An iterable container with the names of the defined constant values, in - declaration order. Suitable for use with range-based for loops: -
- -for (const char *name : Enum::_names) {
- // Will iterate over "A", "B", "C"
-}
-
- class _NameIterable::iterator
- -- An iterator over defined constant names with a constexpr - dereference operator. Can be created explicitly by the constexpr - expressions -
- -Enum::_names::begin() -Enum::_names::end()- -
- Range properties - index -
- - -static constexpr _Enumerated _first
- -- The first defined constant. For example, in -
- -ENUM(Enum, int, A = 1, B = 5, C = 0);- -
Enum::_first == Enum::A
- - -static constexpr _Enumerated _last
- -- The last defined constant, i.e. Enum::C in the above example. -
- - -static constexpr _Enumerated _min
- -- The defined constant with the smallest numeric value, i.e. Enum::C - in the above example. -
- - -static constexpr _Enumerated _max
- -- The defined constant with the greatest numeric value, i.e. Enum::B - in the above example. -
- - -static constexpr size_t _size
- -- The number of constants defined, i.e. 3 in the above example. -
- - -static constexpr _Integral _span
- -- The numeric span of the constants defined, i.e. _max - _min + 1, - which is 6 in the above example. -
- -- Comparisons - index -
- -- member constexpr bool operator ==(const Enum&) - const -
- -- member constexpr bool operator ==(_Enumerated) - const -
- -- member constexpr bool operator !=(const Enum&) - const -
- -- member constexpr bool operator !=(_Enumerated) - const -
- -- member constexpr bool operator <(const Enum&) - const -
- -- member constexpr bool operator <(_Enumerated) - const -
- -- member constexpr bool operator <=(const Enum&) - const -
- -- member constexpr bool operator <=(_Enumerated) - const -
- -- member constexpr bool operator >(const Enum&) - const -
- -- member constexpr bool operator >(_Enumerated) - const -
- -- member constexpr bool operator >=(const Enum&) - const -
- -- member constexpr bool operator >=(_Enumerated) - const -
- -- These define an ordering on values of types Enum and - Enum::_Enumerated. The ordering is according to the values' - numeric representations. That means that two values that have been aliased - will compare equal. Direct comparisons with all other types are forbidden; - this is enforced by deleted comparison operators for all other types. -
- -- Additional type safety - index -
- -default constructor Enum() = delete
- -- The default constructor is deleted to encourage initialization with valid - values only and to avoid undefined states. See - - example/6-traits.cc for an example of how to add an explicit notion of - default value. -
- -invariant no arithmetic
- -Arithmetic operators are explicitly deleted.
- -