utl::enum_reflect¶
utl::enum_reflect is a lean enum reflection library based around the map-macro.
Important
When compiling with MSVC use /Zc:preprocessor to enable standard-compliant preprocessor. Default MSVC preprocessor is notoriously non-compliant due to legacy reasons and might not handle macro expansion properly.
Definitions¶
// Macros
#define UTL_ENUM_REFLECT(enum_name, ...)
// Reflection
template <class E> constexpr std::string_view type_name;
template <class E> constexpr std::size_t size;
template <class E> constexpr std::array<std::string_view, size<E>> names;
template <class E> constexpr std::array<E, size<E>> values;
template <class E> constexpr std::array<std::pair<std::string_view, E>, size<E>> entries;
template <class E> constexpr bool is_valid(E value) noexcept;
template <class E> constexpr auto to_underlying(E value) noexcept;
template <class E> constexpr std::string_view to_string(E value);
template <class E> constexpr E from_string(std::string_view str);
Methods¶
Macros¶
#define UTL_ENUM_REFLECT(enum_name, ...)
Registers reflection for the enum / enum class type enum_name with elements ....
Reflection¶
template <class E> constexpr std::string_view type_name;
Evaluates to stringified name of E enum.
template <class E> constexpr std::size_t size;
Evaluates to a number of elements in E enum.
template <class E> constexpr std::array<std::string_view, size<E>> names;
Evaluates to an array of stringified element names corresponding to E enum.
template <class E> constexpr std::array<E, size<E>> values;
Evaluates to an array of elements corresponding to E enum.
template <class E> constexpr std::array<std::pair<std::string_view, E>, size<E>> entries;
Evaluates to an array of name-value pairs corresponding to E enum.
template <class E> constexpr bool is_valid(E value) noexcept;
Returns whether enum-typed value is a valid element of E enum. See examples.
template <class E> constexpr auto to_underlying(E value) noexcept;
Equivalent to static_cast<std::underlying_type_t<E>>(value). In C++23 can be replaced with std::to_underlying().
Note: This particular function is included for convenience and does not require E to be reflected.
template <class E> constexpr std::string_view to_string(E value);
Returns string corresponding to a value from E enum.
Throws std::out_of_range if value is not a part of enum.
template <class E> constexpr E from_string(std::string_view str);
Returns value from E enum corresponding to a string str.
Throws std::out_of_range if str does not correspond to any element of the enum.
Examples¶
Reflecting an enum¶
[ Run this code ] [ Open source file ]
// Register enum & reflection
enum class Side { LEFT = -1, RIGHT = 1, NONE = 0 };
UTL_ENUM_REFLECT(Side, LEFT, RIGHT, NONE);
// Test reflection
using namespace utl;
using namespace std::string_view_literals;
static_assert( enum_reflect::type_name<Side> == "Side" );
static_assert( enum_reflect::size<Side> == 3 );
static_assert( enum_reflect::names<Side>[0] == "LEFT" );
static_assert( enum_reflect::names<Side>[1] == "RIGHT" );
static_assert( enum_reflect::names<Side>[2] == "NONE" );
static_assert( enum_reflect::values<Side>[0] == Side::LEFT );
static_assert( enum_reflect::values<Side>[1] == Side::RIGHT );
static_assert( enum_reflect::values<Side>[2] == Side::NONE );
static_assert( enum_reflect::entries<Side>[0] == std::pair{ "LEFT"sv, Side::LEFT } );
static_assert( enum_reflect::entries<Side>[1] == std::pair{ "RIGHT"sv, Side::RIGHT } );
static_assert( enum_reflect::entries<Side>[2] == std::pair{ "NONE"sv, Side::NONE } );
static_assert( enum_reflect::is_valid(Side{-1}) == true );
static_assert( enum_reflect::is_valid(Side{ 1}) == true );
static_assert( enum_reflect::is_valid(Side{ 0}) == true );
static_assert( enum_reflect::is_valid(Side{ 2}) == false );
static_assert( enum_reflect::to_underlying(Side::LEFT ) == -1 );
static_assert( enum_reflect::to_underlying(Side::RIGHT) == 1 );
static_assert( enum_reflect::to_underlying(Side::NONE ) == 0 );
static_assert( enum_reflect::to_string(Side::LEFT ) == "LEFT" );
static_assert( enum_reflect::to_string(Side::RIGHT) == "RIGHT" );
static_assert( enum_reflect::to_string(Side::NONE ) == "NONE" );
static_assert( enum_reflect::from_string<Side>("LEFT" ) == Side::LEFT );
static_assert( enum_reflect::from_string<Side>("RIGHT") == Side::RIGHT );
static_assert( enum_reflect::from_string<Side>("NONE" ) == Side::NONE );