+ 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 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. Note that this + method is not constexpr. 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 dereference operator that is + not constexpr. 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.
+ +