diff --git a/README.md b/README.md index 9fe1e06..82fae9a 100644 --- a/README.md +++ b/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 values = { + static constexpr const std::array values = { /*enum values*/ }; - static constexpr const std::array names = { - /*enum names*/ + static constexpr const std::array 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 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 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 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 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 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 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 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 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); }; ``` diff --git a/headers/enum.hpp/enum.hpp b/headers/enum.hpp/enum.hpp index ae7aa7a..b9cd327 100644 --- a/headers/enum.hpp/enum.hpp +++ b/headers/enum.hpp/enum.hpp @@ -248,10 +248,11 @@ namespace enum_hpp::detail ENUM_HPP_GENERATE_FIELDS(Fields)\ };\ public:\ - using underlying_type = std::underlying_type_t;\ + using enum_type = Enum;\ + using underlying_type = std::underlying_type_t;\ static constexpr std::size_t size = ENUM_HPP_PP_SEQ_SIZE(Fields);\ \ - static constexpr const std::array values = {\ + static constexpr const std::array 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(e);\ }\ \ - static constexpr std::optional to_string(Enum e) noexcept {\ + static constexpr std::optional 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 from_string(std::string_view name) noexcept {\ + static constexpr std::optional 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 to_index(Enum e) noexcept {\ + static constexpr std::optional 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 from_index(std::size_t index) noexcept {\ + static constexpr std::optional 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;\ }\ diff --git a/untests/enum_examples.cpp b/untests/enum_examples.cpp index 10a7a35..3ee9f17 100644 --- a/untests/enum_examples.cpp +++ b/untests/enum_examples.cpp @@ -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("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("c") == ee::c); + } } diff --git a/untests/enum_tests.cpp b/untests/enum_tests.cpp index 07f05e4..cf1a9c0 100644 --- a/untests/enum_tests.cpp +++ b/untests/enum_tests.cpp @@ -82,6 +82,10 @@ TEST_CASE("enum") { std::underlying_type_t, 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>);