UTL

Collection of self-contained header-only libraries for C++17

View on GitHub

utl::enum_reflect

<- to README.md

<- to implementation.hpp

utl::enum_reflect is a lean enum reflection library based around the map-macro.

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 ]

// 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  );