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
- _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.