mirror of
https://github.com/BlackMATov/enum.hpp.git
synced 2025-12-13 06:59:45 +07:00
add enum_type to traits
This commit is contained in:
33
README.md
33
README.md
@@ -213,34 +213,35 @@ ENUM_HPP_TRAITS_DECL(
|
||||
/*fields*/)
|
||||
|
||||
struct /*enum_name*/_traits {
|
||||
using enum_type = /*enum_name*/;
|
||||
using underlying_type = /*underlying_type*/;
|
||||
static constexpr std::size_t size = /*field_count*/;
|
||||
|
||||
static constexpr const std::array</*enum_name*/, /*field_count*/ > values = {
|
||||
static constexpr const std::array<enum_type, size> values = {
|
||||
/*enum values*/
|
||||
};
|
||||
|
||||
static constexpr const std::array<std::string_view, /*field_count*/> names = {
|
||||
/*enum names*/
|
||||
static constexpr const std::array<std::string_view, size> names = {
|
||||
/*enum value names*/
|
||||
};
|
||||
|
||||
static constexpr /*underlying_type*/ to_underlying(/*enum_name*/ e) noexcept;
|
||||
static constexpr underlying_type to_underlying(enum_type e) noexcept;
|
||||
|
||||
static constexpr std::optional<std::string_view> to_string(/*enum_name*/ e) noexcept;
|
||||
static constexpr std::string_view to_string_or_empty(/*enum_name*/ e) noexcept;
|
||||
static std::string_view to_string_or_throw(/*enum_name*/ e);
|
||||
static constexpr std::optional<std::string_view> to_string(enum_type e) noexcept;
|
||||
static constexpr std::string_view to_string_or_empty(enum_type e) noexcept;
|
||||
static std::string_view to_string_or_throw(enum_type e);
|
||||
|
||||
static constexpr std::optional</*enum_name*/> from_string(std::string_view name) noexcept;
|
||||
static constexpr /*enum_name*/ from_string_or_default(std::string_view name, /*enum_name*/ def) noexcept;
|
||||
static /*enum_name*/ from_string_or_throw(std::string_view name);
|
||||
static constexpr std::optional<enum_type> from_string(std::string_view name) noexcept;
|
||||
static constexpr enum_type from_string_or_default(std::string_view name, enum_type def) noexcept;
|
||||
static enum_type from_string_or_throw(std::string_view name);
|
||||
|
||||
static constexpr std::optional<std::size_t> to_index(/*enum_name*/ e) noexcept;
|
||||
static constexpr std::size_t to_index_or_invalid(/*enum_name*/ e) noexcept;
|
||||
static std::size_t to_index_or_throw(/*enum_name*/ e);
|
||||
static constexpr std::optional<std::size_t> to_index(enum_type e) noexcept;
|
||||
static constexpr std::size_t to_index_or_invalid(enum_type e) noexcept;
|
||||
static std::size_t to_index_or_throw(enum_type e);
|
||||
|
||||
static constexpr std::optional</*enum_name*/> from_index(std::size_t index) noexcept;
|
||||
static constexpr /*enum_name*/ from_index_or_default(std::size_t index, /*enum_name*/ def) noexcept;
|
||||
static /*enum_name*/ from_index_or_throw(std::size_t index);
|
||||
static constexpr std::optional<enum_type> from_index(std::size_t index) noexcept;
|
||||
static constexpr enum_type from_index_or_default(std::size_t index, enum_type def) noexcept;
|
||||
static enum_type from_index_or_throw(std::size_t index);
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
@@ -248,10 +248,11 @@ namespace enum_hpp::detail
|
||||
ENUM_HPP_GENERATE_FIELDS(Fields)\
|
||||
};\
|
||||
public:\
|
||||
using underlying_type = std::underlying_type_t<Enum>;\
|
||||
using enum_type = Enum;\
|
||||
using underlying_type = std::underlying_type_t<enum_type>;\
|
||||
static constexpr std::size_t size = ENUM_HPP_PP_SEQ_SIZE(Fields);\
|
||||
\
|
||||
static constexpr const std::array<Enum, size> values = {\
|
||||
static constexpr const std::array<enum_type, size> values = {\
|
||||
{ ENUM_HPP_GENERATE_VALUES(Enum, Fields) }\
|
||||
};\
|
||||
\
|
||||
@@ -259,30 +260,30 @@ namespace enum_hpp::detail
|
||||
{ ENUM_HPP_GENERATE_NAMES(Fields) }\
|
||||
};\
|
||||
public:\
|
||||
static constexpr underlying_type to_underlying(Enum e) noexcept {\
|
||||
static constexpr underlying_type to_underlying(enum_type e) noexcept {\
|
||||
return static_cast<underlying_type>(e);\
|
||||
}\
|
||||
\
|
||||
static constexpr std::optional<std::string_view> to_string(Enum e) noexcept {\
|
||||
static constexpr std::optional<std::string_view> to_string(enum_type e) noexcept {\
|
||||
switch ( e ) {\
|
||||
ENUM_HPP_GENERATE_VALUE_TO_NAME_CASES(Enum, Fields)\
|
||||
default: return std::nullopt;\
|
||||
}\
|
||||
}\
|
||||
static constexpr std::string_view to_string_or_empty(Enum e) noexcept {\
|
||||
static constexpr std::string_view to_string_or_empty(enum_type e) noexcept {\
|
||||
if ( auto s = to_string(e) ) {\
|
||||
return *s;\
|
||||
}\
|
||||
return ::enum_hpp::empty_string;\
|
||||
}\
|
||||
static std::string_view to_string_or_throw(Enum e) {\
|
||||
static std::string_view to_string_or_throw(enum_type e) {\
|
||||
if ( auto s = to_string(e) ) {\
|
||||
return *s;\
|
||||
}\
|
||||
::enum_hpp::detail::throw_exception_with(#Enum "_traits::to_string_or_throw(): invalid argument");\
|
||||
}\
|
||||
\
|
||||
static constexpr std::optional<Enum> from_string(std::string_view name) noexcept {\
|
||||
static constexpr std::optional<enum_type> from_string(std::string_view name) noexcept {\
|
||||
for ( std::size_t i = 0; i < size; ++i) {\
|
||||
if ( name == names[i] ) {\
|
||||
return values[i];\
|
||||
@@ -290,52 +291,52 @@ namespace enum_hpp::detail
|
||||
}\
|
||||
return std::nullopt;\
|
||||
}\
|
||||
static constexpr Enum from_string_or_default(std::string_view name, Enum def) noexcept {\
|
||||
static constexpr enum_type from_string_or_default(std::string_view name, enum_type def) noexcept {\
|
||||
if ( auto e = from_string(name) ) {\
|
||||
return *e;\
|
||||
}\
|
||||
return def;\
|
||||
}\
|
||||
static Enum from_string_or_throw(std::string_view name) {\
|
||||
static enum_type from_string_or_throw(std::string_view name) {\
|
||||
if ( auto e = from_string(name) ) {\
|
||||
return *e;\
|
||||
}\
|
||||
::enum_hpp::detail::throw_exception_with(#Enum "_traits::from_string_or_throw(): invalid argument");\
|
||||
}\
|
||||
\
|
||||
static constexpr std::optional<std::size_t> to_index(Enum e) noexcept {\
|
||||
static constexpr std::optional<std::size_t> to_index(enum_type e) noexcept {\
|
||||
switch ( e ) {\
|
||||
ENUM_HPP_GENERATE_VALUE_TO_INDEX_CASES(Enum, Fields)\
|
||||
default: return std::nullopt;\
|
||||
}\
|
||||
}\
|
||||
\
|
||||
static constexpr std::size_t to_index_or_invalid(Enum e) noexcept {\
|
||||
static constexpr std::size_t to_index_or_invalid(enum_type e) noexcept {\
|
||||
if ( auto i = to_index(e) ) {\
|
||||
return *i;\
|
||||
}\
|
||||
return ::enum_hpp::invalid_index;\
|
||||
}\
|
||||
static std::size_t to_index_or_throw(Enum e) {\
|
||||
static std::size_t to_index_or_throw(enum_type e) {\
|
||||
if ( auto i = to_index(e) ) {\
|
||||
return *i;\
|
||||
}\
|
||||
::enum_hpp::detail::throw_exception_with(#Enum "_traits::to_index_or_throw(): invalid argument");\
|
||||
}\
|
||||
\
|
||||
static constexpr std::optional<Enum> from_index(std::size_t index) noexcept {\
|
||||
static constexpr std::optional<enum_type> from_index(std::size_t index) noexcept {\
|
||||
if ( index < size ) {\
|
||||
return values[index];\
|
||||
}\
|
||||
return std::nullopt;\
|
||||
}\
|
||||
static constexpr Enum from_index_or_default(std::size_t index, Enum def) noexcept {\
|
||||
static constexpr enum_type from_index_or_default(std::size_t index, enum_type def) noexcept {\
|
||||
if ( auto e = from_index(index) ) {\
|
||||
return *e;\
|
||||
}\
|
||||
return def;\
|
||||
}\
|
||||
static Enum from_index_or_throw(std::size_t index) {\
|
||||
static enum_type from_index_or_throw(std::size_t index) {\
|
||||
if ( auto e = from_index(index) ) {\
|
||||
return *e;\
|
||||
}\
|
||||
|
||||
@@ -22,8 +22,35 @@ namespace
|
||||
ENUM_HPP_REGISTER_TRAITS(color)
|
||||
}
|
||||
|
||||
namespace some_namespace
|
||||
{
|
||||
ENUM_HPP_CLASS_DECL(color, unsigned,
|
||||
(red = 0xFF0000)
|
||||
(green = 0x00FF00)
|
||||
(blue = 0x0000FF)
|
||||
(white = red | green | blue))
|
||||
|
||||
ENUM_HPP_REGISTER_TRAITS(color)
|
||||
}
|
||||
|
||||
namespace external_ns
|
||||
{
|
||||
enum class external_enum : unsigned short {
|
||||
a = 10,
|
||||
b,
|
||||
c = a + b
|
||||
};
|
||||
|
||||
ENUM_HPP_TRAITS_DECL(external_enum,
|
||||
(a)
|
||||
(b)
|
||||
(c))
|
||||
|
||||
ENUM_HPP_REGISTER_TRAITS(external_enum)
|
||||
}
|
||||
|
||||
TEST_CASE("examples") {
|
||||
SUBCASE("traits_using") {
|
||||
SUBCASE("traits using") {
|
||||
// size
|
||||
static_assert(color_traits::size == 4);
|
||||
|
||||
@@ -47,16 +74,24 @@ TEST_CASE("examples") {
|
||||
static_assert(color_traits::from_index(42) == std::nullopt);
|
||||
|
||||
// names
|
||||
for ( auto n : color_traits::names ) {
|
||||
for ( std::string_view n : color_traits::names ) {
|
||||
std::cout << n << ",";
|
||||
} // stdout: red,green,blue,
|
||||
}
|
||||
|
||||
SUBCASE("generic_context") {
|
||||
SUBCASE("generic context") {
|
||||
using color = some_namespace::color;
|
||||
|
||||
// to string
|
||||
static_assert(enum_hpp::to_string(color::red) == "red");
|
||||
|
||||
// from string
|
||||
static_assert(enum_hpp::from_string<color>("red") == color::red);
|
||||
}
|
||||
|
||||
SUBCASE("external enums") {
|
||||
using ee = external_ns::external_enum;
|
||||
static_assert(enum_hpp::to_string(ee::a) == "a");
|
||||
static_assert(enum_hpp::from_string<ee>("c") == ee::c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +82,10 @@ TEST_CASE("enum") {
|
||||
std::underlying_type_t<sn::color>,
|
||||
unsigned>);
|
||||
|
||||
STATIC_CHECK(std::is_same_v<
|
||||
sn::color_traits::enum_type,
|
||||
sn::color>);
|
||||
|
||||
STATIC_CHECK(std::is_same_v<
|
||||
sn::color_traits::underlying_type,
|
||||
enum_hpp::underlying_type<sn::color>>);
|
||||
|
||||
Reference in New Issue
Block a user