mirror of
https://github.com/BlackMATov/enum.hpp.git
synced 2026-02-04 23:43:00 +07:00
new value string functions
+ to_value_string + to_value_string_or_empty + to_value_string_or_throw + from_value_string + from_value_string_or_default + from_value_string_or_throw
This commit is contained in:
@@ -54,6 +54,11 @@ namespace enum_hpp
|
||||
return traits_t<Enum>::names;
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr const std::array<std::string_view, size<Enum>()>& value_names() noexcept {
|
||||
return traits_t<Enum>::value_names;
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr typename traits_t<Enum>::underlying_type to_underlying(Enum e) noexcept {
|
||||
return traits_t<Enum>::to_underlying(e);
|
||||
@@ -74,6 +79,21 @@ namespace enum_hpp
|
||||
return traits_t<Enum>::to_string_or_throw(e);
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr std::optional<std::string_view> to_value_string(Enum e) noexcept {
|
||||
return traits_t<Enum>::to_value_string(e);
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr std::string_view to_value_string_or_empty(Enum e) noexcept {
|
||||
return traits_t<Enum>::to_value_string_or_empty(e);
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
std::string_view to_value_string_or_throw(Enum e) {
|
||||
return traits_t<Enum>::to_value_string_or_throw(e);
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr std::optional<Enum> from_string(std::string_view name) noexcept {
|
||||
return traits_t<Enum>::from_string(name);
|
||||
@@ -89,6 +109,21 @@ namespace enum_hpp
|
||||
return traits_t<Enum>::from_string_or_throw(name);
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr std::optional<Enum> from_value_string(std::string_view name) noexcept {
|
||||
return traits_t<Enum>::from_value_string(name);
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr Enum from_value_string_or_default(std::string_view name, Enum def) noexcept {
|
||||
return traits_t<Enum>::from_value_string_or_default(name, def);
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
Enum from_value_string_or_throw(std::string_view name) {
|
||||
return traits_t<Enum>::from_value_string_or_throw(name);
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr std::optional<std::size_t> to_index(Enum e) noexcept {
|
||||
return traits_t<Enum>::to_index(e);
|
||||
@@ -144,26 +179,32 @@ namespace enum_hpp::detail
|
||||
}
|
||||
};
|
||||
|
||||
constexpr bool is_end_of_name(char ch) noexcept {
|
||||
switch ( ch ) {
|
||||
case ' ':
|
||||
case '=':
|
||||
case '\r':
|
||||
case '\n':
|
||||
case '\t':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
constexpr std::string_view trim_raw_name(std::string_view raw_name) noexcept {
|
||||
// "none" -> "none"
|
||||
// "color = 1 << 0" -> "color"
|
||||
// "alpha = 1 << 1" -> "alpha"
|
||||
// "all = color | alpha" -> "all"
|
||||
|
||||
if ( const auto pos = raw_name.find_first_of(" =\f\n\r\t\v"); pos != std::string_view::npos ) {
|
||||
return raw_name.substr(0, pos);
|
||||
}
|
||||
|
||||
return raw_name;
|
||||
}
|
||||
|
||||
constexpr std::string_view trim_raw_name(std::string_view raw_name) noexcept {
|
||||
for ( std::size_t i = 0; i < raw_name.size(); ++i ) {
|
||||
if ( is_end_of_name(raw_name[i]) ) {
|
||||
return raw_name.substr(0, i);
|
||||
constexpr std::string_view trim_raw_value_name(std::string_view raw_name) noexcept {
|
||||
// "none" -> ""
|
||||
// "color = 1 << 0" -> "1 << 0"
|
||||
// "alpha = 1 << 1" -> "1 << 1"
|
||||
// "all = color | alpha" -> "color | alpha"
|
||||
|
||||
if ( auto pos = raw_name.find('='); pos != std::string_view::npos ) {
|
||||
if ( pos = raw_name.find_first_not_of(" \f\n\r\t\v", pos + 1); pos != std::string_view::npos ) {
|
||||
return raw_name.substr(pos);
|
||||
}
|
||||
}
|
||||
return raw_name;
|
||||
|
||||
return std::string_view{};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,6 +238,16 @@ namespace enum_hpp::detail
|
||||
#define ENUM_HPP_GENERATE_NAMES(Fields)\
|
||||
ENUM_HPP_PP_SEQ_FOR_EACH(ENUM_HPP_GENERATE_NAMES_OP, _, Fields)
|
||||
|
||||
//
|
||||
// ENUM_HPP_GENERATE_VALUE_NAMES
|
||||
//
|
||||
|
||||
#define ENUM_HPP_GENERATE_VALUE_NAMES_OP(d, i, x)\
|
||||
::enum_hpp::detail::trim_raw_value_name(ENUM_HPP_PP_STRINGIZE(x)),
|
||||
|
||||
#define ENUM_HPP_GENERATE_VALUE_NAMES(Fields)\
|
||||
ENUM_HPP_PP_SEQ_FOR_EACH(ENUM_HPP_GENERATE_VALUE_NAMES_OP, _, Fields)
|
||||
|
||||
//
|
||||
// ENUM_HPP_GENERATE_VALUE_TO_NAME_CASES
|
||||
//
|
||||
@@ -207,6 +258,16 @@ namespace enum_hpp::detail
|
||||
#define ENUM_HPP_GENERATE_VALUE_TO_NAME_CASES(Enum, Fields)\
|
||||
ENUM_HPP_PP_SEQ_FOR_EACH(ENUM_HPP_GENERATE_VALUE_TO_NAME_CASES_OP, Enum, Fields)
|
||||
|
||||
//
|
||||
// ENUM_HPP_GENERATE_VALUE_TO_VALUE_NAME_CASES
|
||||
//
|
||||
|
||||
#define ENUM_HPP_GENERATE_VALUE_TO_VALUE_NAME_CASES_OP(Enum, i, x)\
|
||||
case values[i]: return value_names[i];
|
||||
|
||||
#define ENUM_HPP_GENERATE_VALUE_TO_VALUE_NAME_CASES(Enum, Fields)\
|
||||
ENUM_HPP_PP_SEQ_FOR_EACH(ENUM_HPP_GENERATE_VALUE_TO_VALUE_NAME_CASES_OP, Enum, Fields)
|
||||
|
||||
//
|
||||
// ENUM_HPP_GENERATE_VALUE_TO_INDEX_CASES
|
||||
//
|
||||
@@ -259,6 +320,9 @@ namespace enum_hpp::detail
|
||||
static constexpr const std::array<std::string_view, size> names = {\
|
||||
{ ENUM_HPP_GENERATE_NAMES(Fields) }\
|
||||
};\
|
||||
static constexpr const std::array<std::string_view, size> value_names = {\
|
||||
{ ENUM_HPP_GENERATE_VALUE_NAMES(Fields) }\
|
||||
};\
|
||||
public:\
|
||||
[[maybe_unused]] static constexpr underlying_type to_underlying(enum_type e) noexcept {\
|
||||
return static_cast<underlying_type>(e);\
|
||||
@@ -281,6 +345,24 @@ namespace enum_hpp::detail
|
||||
}\
|
||||
::enum_hpp::detail::throw_exception_with(#Enum "_traits::to_string_or_throw(): invalid argument");\
|
||||
}\
|
||||
[[maybe_unused]] static constexpr std::optional<std::string_view> to_value_string(enum_type e) noexcept {\
|
||||
switch ( e ) {\
|
||||
ENUM_HPP_GENERATE_VALUE_TO_VALUE_NAME_CASES(Enum, Fields)\
|
||||
default: return std::nullopt;\
|
||||
}\
|
||||
}\
|
||||
[[maybe_unused]] static constexpr std::string_view to_value_string_or_empty(enum_type e) noexcept {\
|
||||
if ( auto s = to_value_string(e) ) {\
|
||||
return *s;\
|
||||
}\
|
||||
return ::enum_hpp::empty_string;\
|
||||
}\
|
||||
[[maybe_unused]] static std::string_view to_value_string_or_throw(enum_type e) {\
|
||||
if ( auto s = to_value_string(e) ) {\
|
||||
return *s;\
|
||||
}\
|
||||
::enum_hpp::detail::throw_exception_with(#Enum "_traits::to_value_string_or_throw(): invalid argument");\
|
||||
}\
|
||||
[[maybe_unused]] 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] ) {\
|
||||
@@ -301,6 +383,26 @@ namespace enum_hpp::detail
|
||||
}\
|
||||
::enum_hpp::detail::throw_exception_with(#Enum "_traits::from_string_or_throw(): invalid argument");\
|
||||
}\
|
||||
[[maybe_unused]] static constexpr std::optional<enum_type> from_value_string(std::string_view value_name) noexcept {\
|
||||
for ( std::size_t i = 0; i < size; ++i) {\
|
||||
if ( value_name == value_names[i] ) {\
|
||||
return values[i];\
|
||||
}\
|
||||
}\
|
||||
return std::nullopt;\
|
||||
}\
|
||||
[[maybe_unused]] static constexpr enum_type from_value_string_or_default(std::string_view value_name, enum_type def) noexcept {\
|
||||
if ( auto e = from_value_string(value_name) ) {\
|
||||
return *e;\
|
||||
}\
|
||||
return def;\
|
||||
}\
|
||||
[[maybe_unused]] static enum_type from_value_string_or_throw(std::string_view value_name) {\
|
||||
if ( auto e = from_value_string(value_name) ) {\
|
||||
return *e;\
|
||||
}\
|
||||
::enum_hpp::detail::throw_exception_with(#Enum "_traits::from_value_string_or_throw(): invalid argument");\
|
||||
}\
|
||||
[[maybe_unused]] static constexpr std::optional<std::size_t> to_index(enum_type e) noexcept {\
|
||||
switch ( e ) {\
|
||||
ENUM_HPP_GENERATE_VALUE_TO_INDEX_CASES(Enum, Fields)\
|
||||
|
||||
@@ -262,6 +262,63 @@ TEST_CASE("enum") {
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("to_value_string") {
|
||||
{
|
||||
STATIC_CHECK(sn::color_traits::to_value_string(sn::color::red) == "2");
|
||||
STATIC_CHECK(sn::color_traits::to_value_string(sn::color::green) == "");
|
||||
STATIC_CHECK(sn::color_traits::to_value_string(sn::color::blue) == "red + 4");
|
||||
|
||||
STATIC_CHECK(sn::color_traits::to_value_string_or_empty(sn::color::red) == "2");
|
||||
STATIC_CHECK(sn::color_traits::to_value_string_or_empty(sn::color::green) == "");
|
||||
STATIC_CHECK(sn::color_traits::to_value_string_or_empty(sn::color::blue) == "red + 4");
|
||||
|
||||
CHECK(sn::color_traits::to_value_string_or_throw(sn::color::red) == "2");
|
||||
CHECK(sn::color_traits::to_value_string_or_throw(sn::color::green) == "");
|
||||
CHECK(sn::color_traits::to_value_string_or_throw(sn::color::blue) == "red + 4");
|
||||
|
||||
STATIC_CHECK_FALSE(sn::color_traits::to_value_string(sn::color(42)));
|
||||
STATIC_CHECK(sn::color_traits::to_value_string_or_empty(sn::color(42)) == "");
|
||||
#ifndef ENUM_HPP_NO_EXCEPTIONS
|
||||
CHECK_THROWS_AS(sn::color_traits::to_value_string_or_throw(sn::color(42)), enum_hpp::exception);
|
||||
#endif
|
||||
|
||||
STATIC_CHECK(enum_hpp::to_value_string(sn::color::red) == "2");
|
||||
STATIC_CHECK(enum_hpp::to_value_string(sn::color::green) == "");
|
||||
STATIC_CHECK(enum_hpp::to_value_string(sn::color::blue) == "red + 4");
|
||||
|
||||
STATIC_CHECK(enum_hpp::to_value_string_or_empty(sn::color::red) == "2");
|
||||
STATIC_CHECK(enum_hpp::to_value_string_or_empty(sn::color::green) == "");
|
||||
STATIC_CHECK(enum_hpp::to_value_string_or_empty(sn::color::blue) == "red + 4");
|
||||
|
||||
CHECK(enum_hpp::to_value_string_or_throw(sn::color::red) == "2");
|
||||
CHECK(enum_hpp::to_value_string_or_throw(sn::color::green) == "");
|
||||
CHECK(enum_hpp::to_value_string_or_throw(sn::color::blue) == "red + 4");
|
||||
|
||||
STATIC_CHECK_FALSE(enum_hpp::to_value_string(sn::color(42)));
|
||||
STATIC_CHECK(enum_hpp::to_value_string_or_empty(sn::color(42)) == "");
|
||||
#ifndef ENUM_HPP_NO_EXCEPTIONS
|
||||
CHECK_THROWS_AS(enum_hpp::to_value_string_or_throw(sn::color(42)), enum_hpp::exception);
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
STATIC_CHECK(sn::render::mask_traits::to_value_string(sn::render::mask::none) == "");
|
||||
STATIC_CHECK(sn::render::mask_traits::to_value_string(sn::render::mask::color) == "1 << 0");
|
||||
STATIC_CHECK(sn::render::mask_traits::to_value_string(sn::render::mask::alpha) == "1 << 1");
|
||||
STATIC_CHECK(sn::render::mask_traits::to_value_string(sn::render::mask::all) == "color | alpha");
|
||||
|
||||
STATIC_CHECK(sn::render::mask_traits::to_value_string_or_empty(sn::render::mask::none) == "");
|
||||
STATIC_CHECK(sn::render::mask_traits::to_value_string_or_empty(sn::render::mask::color) == "1 << 0");
|
||||
STATIC_CHECK(sn::render::mask_traits::to_value_string_or_empty(sn::render::mask::alpha) == "1 << 1");
|
||||
STATIC_CHECK(sn::render::mask_traits::to_value_string_or_empty(sn::render::mask::all) == "color | alpha");
|
||||
|
||||
CHECK(sn::render::mask_traits::to_value_string_or_throw(sn::render::mask::none) == "");
|
||||
CHECK(sn::render::mask_traits::to_value_string_or_throw(sn::render::mask::color) == "1 << 0");
|
||||
CHECK(sn::render::mask_traits::to_value_string_or_throw(sn::render::mask::alpha) == "1 << 1");
|
||||
CHECK(sn::render::mask_traits::to_value_string_or_throw(sn::render::mask::all) == "color | alpha");
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("from_string") {
|
||||
{
|
||||
STATIC_CHECK(sn::color_traits::from_string("red") == sn::color::red);
|
||||
@@ -307,6 +364,46 @@ TEST_CASE("enum") {
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("from_value_string") {
|
||||
{
|
||||
STATIC_CHECK(sn::render::mask_traits::from_value_string("") == sn::render::mask::none);
|
||||
STATIC_CHECK(sn::render::mask_traits::from_value_string("1 << 0") == sn::render::mask::color);
|
||||
STATIC_CHECK(sn::render::mask_traits::from_value_string("1 << 1") == sn::render::mask::alpha);
|
||||
STATIC_CHECK(sn::render::mask_traits::from_value_string("color | alpha") == sn::render::mask::all);
|
||||
|
||||
STATIC_CHECK(sn::color_traits::from_value_string_or_default("2", sn::color::green) == sn::color::red);
|
||||
STATIC_CHECK(sn::color_traits::from_value_string_or_default("", sn::color::red) == sn::color::green);
|
||||
STATIC_CHECK(sn::color_traits::from_value_string_or_default("red + 4", sn::color::red) == sn::color::blue);
|
||||
|
||||
#ifndef ENUM_HPP_NO_EXCEPTIONS
|
||||
CHECK(sn::color_traits::from_value_string_or_throw("2") == sn::color::red);
|
||||
CHECK(sn::color_traits::from_value_string_or_throw("") == sn::color::green);
|
||||
CHECK(sn::color_traits::from_value_string_or_throw("red + 4") == sn::color::blue);
|
||||
#endif
|
||||
|
||||
STATIC_CHECK_FALSE(sn::color_traits::from_value_string("42"));
|
||||
STATIC_CHECK(sn::color_traits::from_value_string_or_default("42", sn::color::red) == sn::color::red);
|
||||
#ifndef ENUM_HPP_NO_EXCEPTIONS
|
||||
CHECK_THROWS_AS(sn::color_traits::from_value_string_or_throw("42"), enum_hpp::exception);
|
||||
#endif
|
||||
}
|
||||
{
|
||||
STATIC_CHECK(enum_hpp::from_value_string<sn::render::mask>("") == sn::render::mask::none);
|
||||
STATIC_CHECK(enum_hpp::from_value_string<sn::render::mask>("1 << 0") == sn::render::mask::color);
|
||||
STATIC_CHECK(enum_hpp::from_value_string<sn::render::mask>("1 << 1") == sn::render::mask::alpha);
|
||||
STATIC_CHECK(enum_hpp::from_value_string<sn::render::mask>("color | alpha") == sn::render::mask::all);
|
||||
STATIC_CHECK_FALSE(enum_hpp::from_value_string<sn::render::mask>("42"));
|
||||
|
||||
STATIC_CHECK(enum_hpp::from_value_string_or_default("2", sn::color::green) == sn::color::red);
|
||||
STATIC_CHECK(enum_hpp::from_value_string_or_default("", sn::color::red) == sn::color::green);
|
||||
STATIC_CHECK(enum_hpp::from_value_string_or_default("red + 4", sn::color::red) == sn::color::blue);
|
||||
|
||||
CHECK(enum_hpp::from_value_string_or_throw<sn::color>("2") == sn::color::red);
|
||||
CHECK(enum_hpp::from_value_string_or_throw<sn::color>("") == sn::color::green);
|
||||
CHECK(enum_hpp::from_value_string_or_throw<sn::color>("red + 4") == sn::color::blue);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("to_index") {
|
||||
{
|
||||
STATIC_CHECK(sn::color_traits::to_index(sn::color::red) == 0u);
|
||||
|
||||
Reference in New Issue
Block a user