#ifndef RFL_INTERNAL_ENUMS_NAMES_HPP_ #define RFL_INTERNAL_ENUMS_NAMES_HPP_ #include #include #include #include #include #include #include "../../Literal.hpp" #include "../../define_literal.hpp" #include "../../make_named_tuple.hpp" #include "../StringLiteral.hpp" namespace rfl { namespace internal { namespace enums { template struct Names { /// Contains a collection of enums as compile-time strings. using Literal = LiteralType; /// The number of possible values constexpr static size_t size = N; /// A list of all the possible enums constexpr static std::array enums_ = std::array {_enums...}; static_assert( N == 0 || LiteralType::size() == N, "Size of literal and enum do not match." ); template using AddOneType = std::conditional_t< N == 0, Names, Names< EnumType, define_literal_t, N + 1, _enums..., _new_enum>>; }; template < class EnumType, size_t N, StringLiteral... _names, auto... _enums> auto names_to_enumerator_named_tuple(Names< EnumType, Literal<_names...>, N, _enums...>) { return make_named_tuple(Field<_names, EnumType> {_enums}...); } template < class EnumType, size_t N, StringLiteral... _names, auto... _enums> auto names_to_underlying_enumerator_named_tuple(Names< EnumType, Literal<_names...>, N, _enums...>) { return make_named_tuple( Field<_names, std::underlying_type_t> { static_cast>(_enums) }... ); } template < class EnumType, size_t N, StringLiteral... _names, auto... _enums> constexpr std::array, N> names_to_enumerator_array(Names< EnumType, Literal<_names...>, N, _enums...>) { return {std::make_pair( LiteralHelper<_names>::field_.string_view(), _enums )...}; } template < class EnumType, size_t N, StringLiteral... _names, auto... _enums> constexpr std::array< std::pair>, N> names_to_underlying_enumerator_array(Names< EnumType, Literal<_names...>, N, _enums...>) { return {std::make_pair( LiteralHelper<_names>::field_.string_view(), static_cast>(_enums) )...}; } } // namespace enums } // namespace internal } // namespace rfl #endif