Helper functions for contiguous enums.
Contiguous Enums
Contiguous enums are enums whose enumerator values form a range of 0
to max
, which means there is no gap in between the values. For example, if no enumerator values are specified, an enum is contiguous as in the following example:
enum class myenum
{
val1,
val2,
val3
};
It is often desirable to know the enum's maximum value, or its number of enumerators, for that matter. Unfortunately, C++ offers no introspection of any kind which makes it possible to query the maximum value. fcppt provides a trait class called fcppt::enum_::max_value which has the default behavior of setting the maximum value to the special enumerator value fcppt_maximum
, for example:
enum class myenum
{
val1,
val2,
fcppt_maximum = val2
};
Additionally, fcppt::enum_::max_value can also be specialized. Building on top of this, fcppt::enum_::size calculates the number of enumerators in an enum, setting it to fcppt::enum_::max_value<Enum> + 1
by default.
Enum Ranges
Given the above definition of contiguous enums, it is possible to create a range that iterates over an enum.
for (myenum const value : fcppt::enum_::make_range<myenum>())
{
print_enum(value);
}
fcppt::enum_::make_range creates an fcppt::enum_::range which uses fcppt::enum_::iterator. To create subranges of enums, there are fcppt::enum_::make_range_start and fcppt::enum_::make_range_start_end.
Array indexed with an enum
A contiguous enum is also a range of constant size, making it suitable as an index for an fcppt::array::object. fcppt::enum_::array is a class that wraps fcppt::array::object, replacing all indices by Enums, for example:
array const val{true, false};
std::cout << val[myenum::val1] << '\n';
Cast to enums
Casting an integral value to an enum might be needed when deserializing data. It is important, however, that the value must not fall outside of the enum's range. fcppt::enum_::from_int returns an empty optional in this case.
String conversion
Converting enums from and to strings is also often needed. Unfortunately, because C++ offers no introspection of any kind for enums, we have to provide our own mapping from enums to strings. To implement this for a custom enum type Enum
, we have to specialize the struct fcppt::enum_::to_string_impl and implement a member function std::string get(Enum)
. For example:
{
template <>
struct to_string_impl<myenum>
{
static std::string_view get(myenum const _value)
{
switch (_value)
{
case myenum::val1:
return "val1";
case myenum::val2:
return "val2";
}
}
};
}
We can now use fcppt::enum_::to_string to convert myenum
to a string:
myenum const test{myenum::val2};
Similarly, we can also try to convert a string to an enum: fcppt::enum_::from_string uses fcppt::enum_::from_string_impl, which by default simply goes through all possible enum names. If no enum name matches, an empty optional is returned:
fcppt::enum_::from_string<myenum>("test")};
fcppt::enum_::from_string<myenum>("val1")};
The functions fcppt::enum_::input and fcppt::enum_::output make use of fcppt::enum_::from_string and fcppt::enum_::to_string respectively. They can be used to implement operator>>
and operator<<
.
|
template<typename Enum > |
using | fcppt::enum_::has_maximum = typename fcppt::enum_::detail::has_maximum< Enum >::type |
| Tests if an enum has fcppt_maximum as a member. More...
|
|
template<typename Type , typename = std::enable_if_t<fcppt::enum_::is_object<Type>::value>> |
using | fcppt::enum_::max_value = std::integral_constant< Type, Type::fcppt_maximum > |
| The maximum enumerator in an enum. More...
|
|
template<typename Type , typename = std::enable_if_t<fcppt::enum_::is_object<Type>::value>> |
using | fcppt::enum_::min_value = std::integral_constant< Type, fcppt::cast::int_to_enum< Type >(0)> |
| The minimum enumerator in an enum. More...
|
|
template<typename Enum > |
using | fcppt::enum_::names_array = fcppt::enum_::array< Enum, std::string_view > |
| Array type for The names of an enum. More...
|
|
template<typename Type , typename = std::enable_if_t<fcppt::enum_::is_object<Type>::value>> |
using | fcppt::enum_::size = std::integral_constant< fcppt::enum_::size_type< Type >, fcppt::cast::enum_to_int< fcppt::enum_::size_type< Type > >(fcppt::enum_::max_value< Type >::value)+1U > |
| The number of enumerators in an enum. More...
|
|
template<typename Type > |
using | fcppt::enum_::size_type = typename fcppt::enum_::size_type_impl< Type >::type |
| The size type used to count the number of enumerators in an enum. More...
|
|
template<typename Enum > |
using | fcppt::mpl::list::enum_range = fcppt::mpl::list::enum_range_start_end< fcppt::enum_::min_value< Enum >, fcppt::enum_::max_value< Enum > > |
| An mpl::list::object over an enum. More...
|
|
template<fcppt::type_traits::enum_constant_concept Start, fcppt::type_traits::enum_constant_concept Max> |
using | fcppt::mpl::list::enum_range_start_end = typename fcppt::mpl::list::detail::enum_range_start_end< Start, Max >::type |
| An mpl::list::object over enums from a minimum to a maximum. More...
|
|
|
template<typename Enum , typename Value > |
bool | fcppt::enum_::operator== (fcppt::enum_::array< Enum, Value > const &_a, fcppt::enum_::array< Enum, Value > const &_b) |
| Compares two enum arrays for equality. More...
|
|
template<typename Enum , typename Value > |
bool | fcppt::enum_::operator!= (fcppt::enum_::array< Enum, Value > const &_a, fcppt::enum_::array< Enum, Value > const &_b) |
| Compares two enum arrays for inequality. More...
|
|
template<typename Array , typename Function > |
Array | fcppt::enum_::array_init (Function const &_function) |
| Constructs an array by calling a function with static enumerators. More...
|
|
template<typename Ch , typename Traits , typename Enum , typename Value , typename = std::enable_if_t<fcppt::enum_::is_object<Enum>::value>> |
std::basic_ostream< Ch, Traits > & | fcppt::enum_::operator<< (std::basic_ostream< Ch, Traits > &_stream, fcppt::enum_::array< Enum, Value > const &_array) |
| Outputs an enum array. More...
|
|
template<typename Enum , typename Value , typename = std::enable_if_t< std::conjunction_v<std::is_unsigned<Value>, fcppt::enum_::is_object<Enum>>>> |
fcppt::optional::object< Enum > | fcppt::enum_::from_int (Value const &_value) noexcept |
| Cast an unsigned value to an enum. More...
|
|
template<typename Enum , typename = std::enable_if_t<fcppt::enum_::is_object<Enum>::value>> |
fcppt::optional::object< Enum > | fcppt::enum_::from_string (std::string_view const _string) |
| Converts a string to an enum. More...
|
|
template<typename Enum , typename Value > |
fcppt::optional::object< Enum > | fcppt::enum_::index_of_array (fcppt::enum_::array< Enum, Value > const &_array, Value const &_value) |
| Returns the enum of the first element found in an enum array. More...
|
|
template<typename Ch , typename Traits , typename Enum , typename = std::enable_if_t<fcppt::enum_::is_object<Enum>::value>> |
std::basic_istream< Ch, Traits > & | fcppt::enum_::input (std::basic_istream< Ch, Traits > &_stream, Enum &_result) |
| Reads an enum value from a stream. More...
|
|
template<typename Enum > |
fcppt::enum_::range< Enum > | fcppt::enum_::make_range () noexcept |
| Creates an enum range over the whole enum. More...
|
|
template<typename Enum > |
fcppt::enum_::range< Enum > | fcppt::enum_::make_range_start (Enum const _start) noexcept |
| Creates an enum range with a custom start value. More...
|
|
template<typename Enum > |
fcppt::enum_::range< Enum > | fcppt::enum_::make_range_start_end (Enum const _start, Enum const _end) noexcept |
| Creates a closed enum range. More...
|
|
template<typename Enum , typename = std::enable_if_t<fcppt::enum_::is_object<Enum>::value>> |
fcppt::enum_::names_array< Enum > | fcppt::enum_::names () |
| The names of an enum type. More...
|
|
template<typename Ch , typename Traits , typename Enum , typename = std::enable_if<fcppt::enum_::is_object<Enum>::value>> |
std::basic_ostream< Ch, Traits > & | fcppt::enum_::output (std::basic_ostream< Ch, Traits > &_stream, Enum const _value) |
| Outputs an enum value to a stream. More...
|
|
template<typename Enum , typename Function , typename = std::enable_if_t<fcppt::enum_::is_object<Enum>::value>> |
decltype(auto) | fcppt::enum_::to_static (Enum const _enum, Function const &_function) |
| Converts a runtime enum value into a compile time one, passing it to a function. More...
|
|
template<typename Enum , typename = std::enable_if<fcppt::enum_::is_object<Enum>::value>> |
std::string_view | fcppt::enum_::to_string (Enum const _enum) |
| Converts an enum to a string. More...
|
|
◆ FCPPT_ENUM_TO_STRING_CASE
#define FCPPT_ENUM_TO_STRING_CASE |
( |
|
type, |
|
|
|
name |
|
) |
| case type::name: return #name |
◆ enum_range
◆ enum_range_start_end
An mpl::list::object over enums from a minimum to a maximum.
Let Start = std::integral_constant<Enum,S>
and Max = std::integral_constant<Enum,M>
. Then the result is
◆ has_maximum
Tests if an enum has fcppt_maximum as a member.
◆ max_value
template<typename Type , typename = std::enable_if_t<fcppt::enum_::is_object<Type>::value>>
The maximum enumerator in an enum.
This class defines the maximum enumerator (the enumerator with the biggest integral value) in the enum denoted by Type. The default behaviour is to use Type::fcppt_maximum
. Specialize this class to change that.
- Note
- Unfortunately, there is no way to automatically retrieve the maximum enumerator in an enum in C++.
- Template Parameters
-
◆ min_value
template<typename Type , typename = std::enable_if_t<fcppt::enum_::is_object<Type>::value>>
The minimum enumerator in an enum.
- Template Parameters
-
◆ names_array
Array type for The names of an enum.
- Template Parameters
-
Enum | Must be an enum type. |
◆ size
template<typename Type , typename = std::enable_if_t<fcppt::enum_::is_object<Type>::value>>
The number of enumerators in an enum.
This class defines the number of enumerators in the enum denoted by Type. The default behavior is to set it to use fcppt::enum_::max_value<Type> + 1
. Specialize this class to change that.
- Note
- Unfortunately, there is no way to automatically retrieve the number of enumerators in an enum in C++.
- Template Parameters
-
◆ size_type
The size type used to count the number of enumerators in an enum.
The size type used to count the number of enumerators in Type.
- Template Parameters
-
◆ array_init()
template<typename Array , typename Function >
Array fcppt::enum_::array_init |
( |
Function const & |
_function | ) |
|
|
inline |
Constructs an array by calling a function with static enumerators.
Constructs an enum array of type Array by calling _function(std::integral_constant<Array::enum_type,E>)
for every enumerator E
.
- Template Parameters
-
Array | Must be an fcppt::enum_::array. |
Function | Must be a function callable as Array::value_type (std::integral_constant<Array::enum_type,E>) . |
- See also
- fcppt::array::init
◆ from_int()
template<typename Enum , typename Value , typename = std::enable_if_t< std::conjunction_v<std::is_unsigned<Value>, fcppt::enum_::is_object<Enum>>>>
Cast an unsigned value to an enum.
Casts the unsigned value _value to Enum. Returns an empty optional if the cast fails.
- Parameters
-
_value | The value to cast from |
- Template Parameters
-
Enum | Must be an enum type |
Value | Must be an unsigned type |
◆ from_string()
template<typename Enum , typename = std::enable_if_t<fcppt::enum_::is_object<Enum>::value>>
◆ index_of_array()
template<typename Enum , typename Value >
Returns the enum of the first element found in an enum array.
Searches for _value in _array and returns the index of the first occurrence as an enum if there is any, otherwise returns the empty optional.
◆ input()
template<typename Ch , typename Traits , typename Enum , typename = std::enable_if_t<fcppt::enum_::is_object<Enum>::value>>
std::basic_istream< Ch, Traits > & fcppt::enum_::input |
( |
std::basic_istream< Ch, Traits > & |
_stream, |
|
|
Enum & |
_result |
|
) |
| |
Reads an enum value from a stream.
Uses fcppt::enum_::from_string to read an enum from _stream and store it in _result. In case this fails, the failbit of _stream is set. This function is useful to implement operator>>
for an enum type.
- Template Parameters
-
- Returns
- _stream
◆ make_range()
Creates an enum range over the whole enum.
Creates the enum range [fcppt::enum_::min_value<Enum>::value, fcppt::enum_::max_value<Enum>::value]
.
◆ make_range_start()
Creates an enum range with a custom start value.
Creates the closed range [_start, enum_max_value<Enum>::value].
- Parameters
-
_start | The first element of the range. |
◆ make_range_start_end()
template<typename Enum >
fcppt::enum_::range< Enum > fcppt::enum_::make_range_start_end |
( |
Enum const |
_start, |
|
|
Enum const |
_end |
|
) |
| |
|
inlinenoexcept |
Creates a closed enum range.
Creates the enum range [_start,_end]. The range must be closed because there is no "one past the end" enum value.
- Parameters
-
_start | The first element of the range. |
_end | The last element of the range. |
◆ names()
template<typename Enum , typename = std::enable_if_t<fcppt::enum_::is_object<Enum>::value>>
The names of an enum type.
- Template Parameters
-
◆ operator!=()
template<typename Enum , typename Value >
Compares two enum arrays for inequality.
- Template Parameters
-
Value | Must be equality-comparable. |
◆ operator<<()
template<typename Ch , typename Traits , typename Enum , typename Value , typename = std::enable_if_t<fcppt::enum_::is_object<Enum>::value>>
std::basic_ostream< Ch, Traits > & fcppt::enum_::operator<< |
( |
std::basic_ostream< Ch, Traits > & |
_stream, |
|
|
fcppt::enum_::array< Enum, Value > const & |
_array |
|
) |
| |
◆ operator==()
template<typename Enum , typename Value >
Compares two enum arrays for equality.
- Template Parameters
-
Value | Must be equality-comparable. |
◆ output()
template<typename Ch , typename Traits , typename Enum , typename = std::enable_if<fcppt::enum_::is_object<Enum>::value>>
std::basic_ostream< Ch, Traits > & fcppt::enum_::output |
( |
std::basic_ostream< Ch, Traits > & |
_stream, |
|
|
Enum const |
_value |
|
) |
| |
Outputs an enum value to a stream.
Uses fcppt::enum_::to_string to output _value to _stream. This function is useful to implement operator<<
for an enum type.
- Template Parameters
-
- Returns
- _stream
◆ to_static()
template<typename Enum , typename Function , typename = std::enable_if_t<fcppt::enum_::is_object<Enum>::value>>
decltype(auto) fcppt::enum_::to_static |
( |
Enum const |
_enum, |
|
|
Function const & |
_function |
|
) |
| |
|
inline |
Converts a runtime enum value into a compile time one, passing it to a function.
- Template Parameters
-
Function | A function callable as R (std::integal_constant<Enum,E>) , where R is the result type. |
◆ to_string()
template<typename Enum , typename = std::enable_if<fcppt::enum_::is_object<Enum>::value>>
std::string_view fcppt::enum_::to_string |
( |
Enum const |
_enum | ) |
|
|
inline |