3.8.0
Freundlich's C++ toolkit
Classes | Macros | Typedefs | Functions
fcppt.enum

Description

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,
};

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.

// Prints 0, 1
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:

namespace fcppt::enum_
{
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:

// Returns an empty optional
fcppt::enum_::from_string<myenum>("test")};
// Returns myenum::val1
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<<.

Classes

class  fcppt::enum_::array< Enum, Value >
 An array indexed with an enum. More...
 
class  fcppt::enum_::iterator< Enum >
 
class  fcppt::enum_::range< Enum >
 A range over a contiguous enum. More...
 
struct  fcppt::enum_::to_string_impl< Enum, Enable >
 Customization point for fcppt::enum_::to_string. More...
 

Macros

#define FCPPT_ENUM_TO_STRING_CASE(type, name)   case type::name: return #name
 Generates a case for the implementation of fcppt::enum_::to_string_impl. More...
 

Typedefs

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::metal::enum_range = fcppt::metal::enum_range_start_end< Enum, fcppt::enum_::min_value< Enum >::value, fcppt::enum_::max_value< Enum >::value >
 A metal range over enums. More...
 
template<typename Enum , Enum Start, Enum Max>
using fcppt::metal::enum_range_start_end = ::metal::transform< ::metal::bind< ::metal::lambda< fcppt::type_traits::integral_cast >, ::metal::always< Enum >, ::metal::always< fcppt::cast::int_to_enum_fun >, ::metal::_1 >, fcppt::metal::interval< std::underlying_type_t< Enum >, fcppt::cast::enum_to_int< std::underlying_type_t< Enum > >(Start), fcppt::cast::enum_to_int< std::underlying_type_t< Enum > >(Max)+fcppt::literal< std::underlying_type_t< Enum > >(1)> >
 A metal range over enums from a minimum to a maximum. More...
 

Functions

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

Macro Definition Documentation

◆ FCPPT_ENUM_TO_STRING_CASE

#define FCPPT_ENUM_TO_STRING_CASE (   type,
  name 
)    case type::name: return #name

Generates a case for the implementation of fcppt::enum_::to_string_impl.

Typedef Documentation

◆ enum_range

template<typename Enum >
using fcppt::metal::enum_range = typedef fcppt::metal::enum_range_start_end< Enum, fcppt::enum_::min_value<Enum>::value, fcppt::enum_::max_value<Enum>::value>

A metal range over enums.

◆ enum_range_start_end

template<typename Enum , Enum Start, Enum Max>
using fcppt::metal::enum_range_start_end = typedef ::metal::transform< ::metal::bind< ::metal::lambda<fcppt::type_traits::integral_cast>, ::metal::always<Enum>, ::metal::always<fcppt::cast::int_to_enum_fun>, ::metal::_1>, fcppt::metal::interval< std::underlying_type_t<Enum>, fcppt::cast::enum_to_int<std::underlying_type_t<Enum> >(Start), fcppt::cast::enum_to_int<std::underlying_type_t<Enum> >(Max) + fcppt::literal<std::underlying_type_t<Enum> >(1)> >

A metal range over enums from a minimum to a maximum.

◆ has_maximum

template<typename Enum >
using fcppt::enum_::has_maximum = typedef typename fcppt::enum_::detail::has_maximum<Enum>::type

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>>
using fcppt::enum_::max_value = typedef std::integral_constant<Type, Type::fcppt_maximum>

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
TypeMust be an enum type

◆ min_value

template<typename Type , typename = std::enable_if_t<fcppt::enum_::is_object<Type>::value>>
using fcppt::enum_::min_value = typedef std::integral_constant<Type, fcppt::cast::int_to_enum<Type>(0)>

The minimum enumerator in an enum.

Template Parameters
TypeMust be an enum type

◆ names_array

template<typename Enum >
using fcppt::enum_::names_array = typedef fcppt::enum_::array<Enum, std::string_view>

Array type for The names of an enum.

Template Parameters
EnumMust be an enum type.

◆ size

template<typename Type , typename = std::enable_if_t<fcppt::enum_::is_object<Type>::value>>
using fcppt::enum_::size = typedef 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.

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
TypeMust be an enum type

◆ size_type

template<typename Type >
using fcppt::enum_::size_type = typedef typename fcppt::enum_::size_type_impl<Type>::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
TypeMust be an enum type

Function Documentation

◆ 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
ArrayMust be an fcppt::enum_::array.
FunctionMust 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>>>>
fcppt::optional::object<Enum> fcppt::enum_::from_int ( Value const &  _value)
noexcept

Cast an unsigned value to an enum.

Casts the unsigned value _value to Enum. Returns an empty optional if the cast fails.

Parameters
_valueThe value to cast from
Template Parameters
EnumMust be an enum type
ValueMust be an unsigned type

◆ from_string()

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)
inline

Converts a string to an enum.

Uses fcppt::enum_::from_string_impl to convert a string to an enum.

Template Parameters
EnumMust be an enum type

◆ index_of_array()

template<typename Enum , typename Value >
fcppt::optional::object<Enum> fcppt::enum_::index_of_array ( fcppt::enum_::array< Enum, Value > const &  _array,
Value const &  _value 
)
inline

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
EnumMust be an enum type
Returns
_stream

◆ make_range()

template<typename Enum >
fcppt::enum_::range<Enum> fcppt::enum_::make_range ( )
inlinenoexcept

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()

template<typename Enum >
fcppt::enum_::range<Enum> fcppt::enum_::make_range_start ( Enum const  _start)
inlinenoexcept

Creates an enum range with a custom start value.

Creates the closed range [_start, enum_max_value<Enum>::value].

Parameters
_startThe 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
_startThe first element of the range.
_endThe last element of the range.

◆ names()

template<typename Enum , typename = std::enable_if_t<fcppt::enum_::is_object<Enum>::value>>
fcppt::enum_::names_array<Enum> fcppt::enum_::names ( )
inline

The names of an enum type.

Template Parameters
EnumMust be an enum type

◆ operator!=()

template<typename Enum , typename Value >
bool fcppt::enum_::operator!= ( fcppt::enum_::array< Enum, Value > const &  _a,
fcppt::enum_::array< Enum, Value > const &  _b 
)
inline

Compares two enum arrays for inequality.

Template Parameters
ValueMust 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 
)

Outputs an enum array.

◆ operator==()

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.

Template Parameters
ValueMust 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
EnumMust be an enum type
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.

◆ 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

Converts an enum to a string.

Uses fcppt::enum_::to_string_impl to convert an enum to a string.

Template Parameters
EnumMust be an enum type