The documentation is now generated from markdown. Samples are generated from the tutorial pages. Testing is done by a Python script which runs the tests for a large number of compilers. This version is not very developer-friendly - the Python scripts need ways of limiting what compilers they try to run. If you don't have 15 compilers installed, you won't be able to run the tests in this commit. Fix coming soon.
9.4 KiB
API reference
Table of contents
Overview
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 $cxx11 declaration:
enum class Enum : underlying_type {A, B, C, ...};
that is, Enum is a scoped enumerated type with constants Enum::A, Enum::B,
Enum::C, and so on, with memory representation the same as underlying_type.
It is possible to supply initializers for any of the constants:
ENUM(Enum, underlying_type, A = 1, B = constant_expression, C, ...);
The initializers have the same meaning and constraints as in an enum class
declaration.
The principal differences between the types declared by the ENUM macro and
enum class are:
ENUMis available for $cxx98 for compilers supporting__VA_ARGS__,- the
ENUMtype is implicitly convertible to integral types, though this can be disabled when using $cxx11, How and - the
ENUMtype supports a set of reflective operations, detailed in the rest of this reference.
The types produced by the ENUM macro are sometimes called Better Enums in the
rest of this reference, and the running example declaration is
ENUM(Enum, int, A, B, C);
For the purposes of argument passing, Better Enums should be thought of as equivalent to their underlying type. This means that Better Enums are typically integers that fit into a register or a stack word, and should be passed by value.
All names declared in the scope of a Better Enum are prefixed with an underscore in order to avoid conflicts with potential constant names.
General
typedef _enumerated
An internal type used to declare constants. ENUM generates something similar
to
struct Enum {
enum _enumerated : int { A, B, C };
// ...
};
The user needs to be aware of this type in only one situation. A literal constant
such as Enum::A is an expression of type Enum::_enumerated, not Enum. It
is not possible to directly call a method on the value, as in
Enum::A._to_string(). This problem is addressed by operator + below.
non-member constexpr Enum unary operator +(_enumerated)
Forces promotion of Enum::_enumerated to Enum. Provided to solve the problem
described under _enumerated above. So, for example, it is necessary to write
(+Enum::A)._to_string() instead of Enum::A._to_string.
constexpr implicit constructor Enum(_enumerated)
A constructor that performs implicit conversions of Enum::_enumerated to
Enum. This allows code to use a literal constant where Enum is expected in
most situations — those where the compiler can do an implicit conversion.
For example, if there is a function void output(Enum), it can be called as
output(Enum::A), without having to write output(+Enum::A). This constructor
is also used for the typical initialization
Enum value = Enum::A;
The other constructors of Enum are the implicitly-generated copy and move
constructors. There is no default constructor.
static constexpr size_t _size
The number of constants declared. Enum::_size == 3.
typedef _value_iterable
Type of object that permits iteration over the constants. Has at least
constexpr begin(), end(), and size() methods, and operator[].
Iteration visits each declared constant, even if multiple constants have the
same value, and visits them in order of declaration. See usage examples under
_values.
typedef _value_iterator
Random-access iterator type for _value_iterable. Most operations, including
dereferencing, are constexpr. The exceptions are mutating operators such as
operator++. In constexpr code, that can be replaced with addition of 1.
static constexpr _value_iterable _values()
constexpr access to the collection of declared constants. For example:
for (size_t index = 0; index < Enum::_values().size(); ++index)
output(Enum::_values()[index]);
or, using iterators:
for (Enum::_value_iterator iterator = Enum::_values().begin();
iterator != Enum::_values().end(); ++iterator) {
output(*iterator);
}
or, in $cxx11:
for (Enum value : Enum::_values())
output(value);
non-member struct better_enums::optional
Optional Enum value. An optional value maybe can be in one of two states:
(bool)maybe == true, meaning that there isEnumvalue, and*maybeevaluates to it, and(bool)maybe == false, meaning noEnumvalue is available.
This type is referred to as simply optional in the rest of the reference, as
if using better_enums::optional; has been entered.
Strings
member constexpr? const char* _to_string() const
Returns the string representation of the Better Enum value on which it is
called. For example, if value == Enum::A, value._to_string() is the same
string as "A".
If two constants have the same numeric representation, and value is equal to
one of those constants, then it has that numeric representation, and it is
undefined which constant's name _to_string will choose.
If value is not equal to the representation of any declared constant, for
example if it was obtained using an unchecked cast such as:
Enum value = Enum::_from_integral_unchecked(0xbadc0de);
then the behavior of value._to_string is undefined.
Runnig time is linear in the number of declared constants.
This method is not constexpr by default because making it so entails a large
slowdown during compilation. See here for how to make it constexpr for
some or all Better Enums.
static constexpr Enum _from_string(const char*)
If the given string is the exact name of a declared constant, returns its value.
Otherwise, throws std::runtime_error. Running time is linear in the number of
declared constants multiplied by the length of the longest constant.
static constexpr optional _from_string_nothrow(const char*)
The same as _from_string, but does not throw an exception on failure. Returns
an optional value instead.
static constexpr Enum _from_string_nocase(const char*)
The same as _from_string, but comparison is up to case, in the usual sense in
the Latin-1 encoding.
static constexpr optional _from_string_nocase_nothrow(const char*)
Is to _from_string_nocase as _from_string_nothrow is to _from_string.
static constexpr bool _is_valid(const char*)
Evaluates to true if and only if the given string is the exact name of a
declared constant. Running time is the same as for _from_string.
static constexpr bool _is_valid_nocase(const char*)
The same as _is_valid, but comparison is done up to case as in
_from_string_nocase.
static constexpr const char* _name()
Evaluates to the name of the Better Enum type. Enum::_name() is the same
string as "Enum".
typedef _name_iterable
Type of object that permits iteration over names of declared constants. Has at
least constexpr begin(), end(), and size() methods. operator[] is also
available, but is constexpr if and only if _to_string is constexpr.
Iteration visits constants in order of declaration. See usage example under
_names.
typedef _name_iterator
Random-access iterator type for _name_iterable. Most operations are
constexpr, but dereferencing is constexpr if and only if _to_string is
constexpr. Mutating operators such as operator++ are not constexpr due to
their nature — adding 1 is a constexpr alternative.
static constexpr? _name_iterable _names()
Access to the collection of declared constant names. For example:
for (size_t index = 0; index < Enum::_names().size(); ++index)
std::cout << Enum::_names()[index] << std::endl;
or, using iterators:
for (Enum::_name_iterator iterator = Enum::_names().begin();
iterator != Enum::_names().end(); ++iterator) {
std::cout << *iterator << std::endl;
}
or, in $cxx11:
for (const char *name : Enum::_names())
std::cout << name << std::endl;
constexpr if and only if _to_string is constexpr.
Integers
typedef _integral
The underlying or representation type of the Better Enum. For example,
Enum::_integral is the same type as int. Each Better Enum has the same size
and alignment requirement as its representation type. This is true even under
$cxx98.
member constexpr _integral _to_integral() const
No-op conversion of a Better Enum to a value of its representation type. For
example, (+Enum::C)._to_integral() == 2.
static constexpr Enum _from_integral(_integral)
Checked conversion of an integer to a Better Enum value. The check runs in time
linear in the number of declared constants, but the conversion itself is a
no-op. Throws std::runtime_error if the given integer is not the numeric value
of one of the declared constants.
static constexpr Enum _from_integral_unchecked(_integral)
No-op unchecked conversion of an integer to a Better Enum value. If the given integer is not the numeric value of one of the declared constants, the behavior of all subsequent operations on the Better Enum value is undefined.
static constexpr optional _from_integral_nothrow(_integral)
Checked conversion as _from_integral, but does not throw an exception on
failure. Returns an optional value instead.
static constexpr bool _is_valid(_integral)
Evaluates to `true if and only if the given integer is the numeric value of one of the declared constants.