mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-13 03:08:49 +07:00
refactor enum_type api for working with dynamic values
This commit is contained in:
@@ -60,8 +60,8 @@ TEST_CASE("meta/meta_examples/enum/usage") {
|
||||
const meta::enum_type align_type = meta::resolve_type(e);
|
||||
|
||||
// converts the enumerator to its name
|
||||
CHECK(align_type.value_to_name(e) == "center");
|
||||
CHECK(align_type.value_to_evalue(e).get_name() == "center");
|
||||
|
||||
// ... and back again
|
||||
CHECK(align_type.name_to_value("center").as<align>() == e);
|
||||
CHECK(align_type.name_to_evalue("center").get_value().as<align>() == e);
|
||||
}
|
||||
|
||||
@@ -3137,11 +3137,10 @@ namespace meta_hpp
|
||||
|
||||
[[nodiscard]] const evalue_list& get_evalues() const noexcept;
|
||||
|
||||
[[nodiscard]] evalue get_evalue(std::string_view name) const noexcept;
|
||||
|
||||
template < enum_kind Enum >
|
||||
[[nodiscard]] std::string_view value_to_name(Enum value) const;
|
||||
[[nodiscard]] const uvalue& name_to_value(std::string_view name) const noexcept;
|
||||
[[nodiscard]] evalue value_to_evalue(Enum value) const;
|
||||
[[nodiscard]] evalue value_to_evalue(const uvalue& value) const;
|
||||
[[nodiscard]] evalue name_to_evalue(std::string_view name) const noexcept;
|
||||
};
|
||||
|
||||
class function_type final : public type_base<function_type> {
|
||||
@@ -9148,7 +9147,36 @@ namespace meta_hpp
|
||||
return data_->evalues;
|
||||
}
|
||||
|
||||
inline evalue enum_type::get_evalue(std::string_view name) const noexcept {
|
||||
template < enum_kind Enum >
|
||||
evalue enum_type::value_to_evalue(Enum value) const {
|
||||
if ( *this != resolve_type<Enum>() ) {
|
||||
return evalue{};
|
||||
}
|
||||
|
||||
for ( const evalue& evalue : data_->evalues ) {
|
||||
if ( evalue.get_value().as<Enum>() == value ) {
|
||||
return evalue;
|
||||
}
|
||||
}
|
||||
|
||||
return evalue{};
|
||||
}
|
||||
|
||||
inline evalue enum_type::value_to_evalue(const uvalue& value) const {
|
||||
if ( *this != value.get_type() ) {
|
||||
return evalue{};
|
||||
}
|
||||
|
||||
for ( const evalue& evalue : data_->evalues ) {
|
||||
if ( evalue.get_value().equals(value) ) {
|
||||
return evalue;
|
||||
}
|
||||
}
|
||||
|
||||
return evalue{};
|
||||
}
|
||||
|
||||
inline evalue enum_type::name_to_evalue(std::string_view name) const noexcept {
|
||||
for ( const evalue& evalue : data_->evalues ) {
|
||||
if ( evalue.get_name() == name ) {
|
||||
return evalue;
|
||||
@@ -9156,29 +9184,6 @@ namespace meta_hpp
|
||||
}
|
||||
return evalue{};
|
||||
}
|
||||
|
||||
template < enum_kind Enum >
|
||||
std::string_view enum_type::value_to_name(Enum value) const {
|
||||
if ( resolve_type<Enum>() != *this ) {
|
||||
return std::string_view{};
|
||||
}
|
||||
|
||||
for ( const evalue& evalue : data_->evalues ) {
|
||||
if ( evalue.get_value().as<Enum>() == value ) {
|
||||
return evalue.get_name();
|
||||
}
|
||||
}
|
||||
|
||||
return std::string_view{};
|
||||
}
|
||||
|
||||
inline const uvalue& enum_type::name_to_value(std::string_view name) const noexcept {
|
||||
if ( const evalue& value = get_evalue(name) ) {
|
||||
return value.get_value();
|
||||
}
|
||||
static const uvalue empty_value;
|
||||
return empty_value;
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
|
||||
80
develop/untests/meta_issues/github_discussion_93.cpp
Normal file
80
develop/untests/meta_issues/github_discussion_93.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "https://github.com/blackmatov/meta.hpp"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2021-2024, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include <meta.hpp/meta_all.hpp>
|
||||
#include <doctest/doctest.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
enum class align {
|
||||
left,
|
||||
right,
|
||||
center,
|
||||
};
|
||||
|
||||
enum class color {
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_discussion/93") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::enum_<align>()
|
||||
.evalue_("left", align::left)
|
||||
.evalue_("right", align::right)
|
||||
.evalue_("center", align::center);
|
||||
|
||||
const meta::enum_type align_type = meta::resolve_type<align>();
|
||||
|
||||
{
|
||||
CHECK(align_type.name_to_evalue("left").get_name() == "left");
|
||||
CHECK(align_type.name_to_evalue("right").get_name() == "right");
|
||||
CHECK(align_type.name_to_evalue("center").get_name() == "center");
|
||||
}
|
||||
|
||||
{
|
||||
align v = align::right;
|
||||
|
||||
CHECK(align_type.value_to_evalue(v).get_name() == "right");
|
||||
CHECK(align_type.value_to_evalue(std::as_const(v)).get_name() == "right");
|
||||
CHECK(align_type.value_to_evalue(std::move(std::as_const(v))).get_name() == "right");
|
||||
CHECK(align_type.value_to_evalue(std::move(v)).get_name() == "right");
|
||||
|
||||
v = align::center;
|
||||
|
||||
CHECK(align_type.value_to_evalue(v).get_name() == "center");
|
||||
CHECK(align_type.value_to_evalue(std::as_const(v)).get_name() == "center");
|
||||
CHECK(align_type.value_to_evalue(std::move(std::as_const(v))).get_name() == "center");
|
||||
CHECK(align_type.value_to_evalue(std::move(v)).get_name() == "center");
|
||||
}
|
||||
|
||||
{
|
||||
meta::uvalue v = align::right;
|
||||
|
||||
CHECK(align_type.value_to_evalue(v).get_name() == "right");
|
||||
CHECK(align_type.value_to_evalue(std::as_const(v)).get_name() == "right");
|
||||
CHECK(align_type.value_to_evalue(std::move(std::as_const(v))).get_name() == "right");
|
||||
CHECK(align_type.value_to_evalue(std::move(v)).get_name() == "right");
|
||||
|
||||
v = align::center;
|
||||
|
||||
CHECK(align_type.value_to_evalue(v).get_name() == "center");
|
||||
CHECK(align_type.value_to_evalue(std::as_const(v)).get_name() == "center");
|
||||
CHECK(align_type.value_to_evalue(std::move(std::as_const(v))).get_name() == "center");
|
||||
CHECK(align_type.value_to_evalue(std::move(v)).get_name() == "center");
|
||||
}
|
||||
|
||||
{
|
||||
CHECK_FALSE(align_type.name_to_evalue(""));
|
||||
CHECK_FALSE(align_type.name_to_evalue("middle"));
|
||||
|
||||
CHECK_FALSE(align_type.value_to_evalue(color::red));
|
||||
CHECK_FALSE(align_type.value_to_evalue(meta::uvalue{color::red}));
|
||||
}
|
||||
}
|
||||
@@ -35,19 +35,19 @@ TEST_CASE("meta/meta_states/evalue") {
|
||||
const meta::evalue evalue;
|
||||
CHECK_FALSE(evalue);
|
||||
CHECK_FALSE(evalue.is_valid());
|
||||
CHECK(evalue == color_type.get_evalue("non-existent-evalue"));
|
||||
CHECK(evalue == color_type.name_to_evalue("non-existent-evalue"));
|
||||
}
|
||||
|
||||
SUBCASE("operators") {
|
||||
const meta::evalue blue_e = color_type.get_evalue("blue");
|
||||
const meta::evalue white_e = color_type.get_evalue("white");
|
||||
const meta::evalue blue_e = color_type.name_to_evalue("blue");
|
||||
const meta::evalue white_e = color_type.name_to_evalue("white");
|
||||
CHECK(blue_e == blue_e);
|
||||
CHECK(blue_e != white_e);
|
||||
CHECK((blue_e < white_e || white_e < blue_e));
|
||||
}
|
||||
|
||||
SUBCASE("green") {
|
||||
const meta::evalue evalue = color_type.get_evalue("green");
|
||||
const meta::evalue evalue = color_type.name_to_evalue("green");
|
||||
REQUIRE(evalue);
|
||||
|
||||
CHECK(evalue.get_index().get_type() == evalue.get_type());
|
||||
|
||||
@@ -77,7 +77,7 @@ TEST_CASE("meta/meta_states/metadata/enum") {
|
||||
}
|
||||
|
||||
SUBCASE("color::red") {
|
||||
const meta::evalue red_evalue = color_type.get_evalue("red");
|
||||
const meta::evalue red_evalue = color_type.name_to_evalue("red");
|
||||
REQUIRE(red_evalue);
|
||||
CHECK_FALSE(red_evalue.get_metadata().contains("desc1"));
|
||||
CHECK(red_evalue.get_metadata().at("desc2").as<std::string>() == "new-red-color"s);
|
||||
|
||||
@@ -83,12 +83,12 @@ TEST_CASE("meta/meta_types/enum_type") {
|
||||
CHECK(ecolor_type.get_evalues().size() == 4);
|
||||
}
|
||||
|
||||
SUBCASE("color/get_evalue") {
|
||||
SUBCASE("color/name_to_evalue") {
|
||||
const meta::enum_type color_type = meta::resolve_type<color>();
|
||||
REQUIRE(color_type);
|
||||
|
||||
{
|
||||
const meta::evalue green_value = color_type.get_evalue("green");
|
||||
const meta::evalue green_value = color_type.name_to_evalue("green");
|
||||
REQUIRE(green_value);
|
||||
|
||||
CHECK(green_value.get_value().as<color>() == color::green);
|
||||
@@ -96,17 +96,17 @@ TEST_CASE("meta/meta_types/enum_type") {
|
||||
}
|
||||
|
||||
{
|
||||
const meta::evalue yellow_value = color_type.get_evalue("yellow");
|
||||
const meta::evalue yellow_value = color_type.name_to_evalue("yellow");
|
||||
CHECK_FALSE(yellow_value);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("ecolor/get_evalue") {
|
||||
SUBCASE("ecolor/name_to_evalue") {
|
||||
const meta::enum_type ecolor_type = meta::resolve_type<ecolor>();
|
||||
REQUIRE(ecolor_type);
|
||||
|
||||
{
|
||||
const meta::evalue green_value = ecolor_type.get_evalue("green");
|
||||
const meta::evalue green_value = ecolor_type.name_to_evalue("green");
|
||||
REQUIRE(green_value);
|
||||
|
||||
CHECK(green_value.get_value().as<ecolor>() == ecolor_green);
|
||||
@@ -114,7 +114,7 @@ TEST_CASE("meta/meta_types/enum_type") {
|
||||
}
|
||||
|
||||
{
|
||||
const meta::evalue yellow_value = ecolor_type.get_evalue("yellow");
|
||||
const meta::evalue yellow_value = ecolor_type.name_to_evalue("yellow");
|
||||
CHECK_FALSE(yellow_value);
|
||||
}
|
||||
}
|
||||
@@ -123,18 +123,18 @@ TEST_CASE("meta/meta_types/enum_type") {
|
||||
const meta::enum_type color_type = meta::resolve_type<color>();
|
||||
REQUIRE(color_type);
|
||||
|
||||
CHECK(color_type.value_to_name(color::red) == "red");
|
||||
CHECK(color_type.value_to_name(color::blue) == "blue");
|
||||
CHECK(color_type.value_to_name(color{100500}).empty());
|
||||
CHECK(color_type.value_to_evalue(color::red).get_name() == "red");
|
||||
CHECK(color_type.value_to_evalue(color::blue).get_name() == "blue");
|
||||
CHECK_FALSE(color_type.value_to_evalue(color{100500}));
|
||||
}
|
||||
|
||||
SUBCASE("ecolor/value_to_name") {
|
||||
const meta::enum_type ecolor_type = meta::resolve_type<ecolor>();
|
||||
REQUIRE(ecolor_type);
|
||||
|
||||
CHECK(ecolor_type.value_to_name(ecolor_red) == "red");
|
||||
CHECK(ecolor_type.value_to_name(ecolor_blue) == "blue");
|
||||
CHECK(ecolor_type.value_to_name(ecolor{100500}).empty());
|
||||
CHECK(ecolor_type.value_to_evalue(ecolor_red).get_name() == "red");
|
||||
CHECK(ecolor_type.value_to_evalue(ecolor_blue).get_name() == "blue");
|
||||
CHECK_FALSE(ecolor_type.value_to_evalue(ecolor{100500}));
|
||||
}
|
||||
|
||||
SUBCASE("color/name_to_value") {
|
||||
@@ -142,12 +142,12 @@ TEST_CASE("meta/meta_types/enum_type") {
|
||||
REQUIRE(color_type);
|
||||
|
||||
{
|
||||
REQUIRE(color_type.name_to_value("blue"));
|
||||
CHECK(color_type.name_to_value("blue").as<color>() == color::blue);
|
||||
REQUIRE(color_type.name_to_evalue("blue"));
|
||||
CHECK(color_type.name_to_evalue("blue").get_value().as<color>() == color::blue);
|
||||
}
|
||||
|
||||
{
|
||||
REQUIRE_FALSE(color_type.name_to_value("yellow"));
|
||||
REQUIRE_FALSE(color_type.name_to_evalue("yellow"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,12 +156,12 @@ TEST_CASE("meta/meta_types/enum_type") {
|
||||
REQUIRE(ecolor_type);
|
||||
|
||||
{
|
||||
REQUIRE(ecolor_type.name_to_value("blue"));
|
||||
CHECK(ecolor_type.name_to_value("blue").as<ecolor>() == ecolor_blue);
|
||||
REQUIRE(ecolor_type.name_to_evalue("blue"));
|
||||
CHECK(ecolor_type.name_to_evalue("blue").get_value().as<ecolor>() == ecolor_blue);
|
||||
}
|
||||
|
||||
{
|
||||
REQUIRE_FALSE(ecolor_type.name_to_value("yellow"));
|
||||
REQUIRE_FALSE(ecolor_type.name_to_evalue("yellow"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ TEST_CASE("meta/meta_utilities/hash") {
|
||||
const meta::method ivec2_method = ivec2_type.get_method("add");
|
||||
|
||||
const meta::enum_type color_type = meta::resolve_type<color>();
|
||||
const meta::evalue red_color = color_type.get_evalue("red");
|
||||
const meta::evalue red_color = color_type.name_to_evalue("red");
|
||||
|
||||
const meta::scope local_scope = meta::local_scope_("local-scope")
|
||||
.variable_("pi_v", &pi_v);
|
||||
|
||||
@@ -291,11 +291,10 @@ namespace meta_hpp
|
||||
|
||||
[[nodiscard]] const evalue_list& get_evalues() const noexcept;
|
||||
|
||||
[[nodiscard]] evalue get_evalue(std::string_view name) const noexcept;
|
||||
|
||||
template < enum_kind Enum >
|
||||
[[nodiscard]] std::string_view value_to_name(Enum value) const;
|
||||
[[nodiscard]] const uvalue& name_to_value(std::string_view name) const noexcept;
|
||||
[[nodiscard]] evalue value_to_evalue(Enum value) const;
|
||||
[[nodiscard]] evalue value_to_evalue(const uvalue& value) const;
|
||||
[[nodiscard]] evalue name_to_evalue(std::string_view name) const noexcept;
|
||||
};
|
||||
|
||||
class function_type final : public type_base<function_type> {
|
||||
|
||||
@@ -39,7 +39,36 @@ namespace meta_hpp
|
||||
return data_->evalues;
|
||||
}
|
||||
|
||||
inline evalue enum_type::get_evalue(std::string_view name) const noexcept {
|
||||
template < enum_kind Enum >
|
||||
evalue enum_type::value_to_evalue(Enum value) const {
|
||||
if ( *this != resolve_type<Enum>() ) {
|
||||
return evalue{};
|
||||
}
|
||||
|
||||
for ( const evalue& evalue : data_->evalues ) {
|
||||
if ( evalue.get_value().as<Enum>() == value ) {
|
||||
return evalue;
|
||||
}
|
||||
}
|
||||
|
||||
return evalue{};
|
||||
}
|
||||
|
||||
inline evalue enum_type::value_to_evalue(const uvalue& value) const {
|
||||
if ( *this != value.get_type() ) {
|
||||
return evalue{};
|
||||
}
|
||||
|
||||
for ( const evalue& evalue : data_->evalues ) {
|
||||
if ( evalue.get_value().equals(value) ) {
|
||||
return evalue;
|
||||
}
|
||||
}
|
||||
|
||||
return evalue{};
|
||||
}
|
||||
|
||||
inline evalue enum_type::name_to_evalue(std::string_view name) const noexcept {
|
||||
for ( const evalue& evalue : data_->evalues ) {
|
||||
if ( evalue.get_name() == name ) {
|
||||
return evalue;
|
||||
@@ -47,27 +76,4 @@ namespace meta_hpp
|
||||
}
|
||||
return evalue{};
|
||||
}
|
||||
|
||||
template < enum_kind Enum >
|
||||
std::string_view enum_type::value_to_name(Enum value) const {
|
||||
if ( resolve_type<Enum>() != *this ) {
|
||||
return std::string_view{};
|
||||
}
|
||||
|
||||
for ( const evalue& evalue : data_->evalues ) {
|
||||
if ( evalue.get_value().as<Enum>() == value ) {
|
||||
return evalue.get_name();
|
||||
}
|
||||
}
|
||||
|
||||
return std::string_view{};
|
||||
}
|
||||
|
||||
inline const uvalue& enum_type::name_to_value(std::string_view name) const noexcept {
|
||||
if ( const evalue& value = get_evalue(name) ) {
|
||||
return value.get_value();
|
||||
}
|
||||
static const uvalue empty_value;
|
||||
return empty_value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,11 +308,10 @@ public:
|
||||
|
||||
const evalue_list& get_evalues() const noexcept;
|
||||
|
||||
evalue get_evalue(std::string_view name) const noexcept;
|
||||
|
||||
template < enum_kind Enum >
|
||||
std::string_view value_to_name(Enum value) const;
|
||||
const uvalue& name_to_value(std::string_view name) const noexcept;
|
||||
evalue value_to_evalue(Enum value) const;
|
||||
evalue value_to_evalue(const uvalue& value) const;
|
||||
evalue name_to_evalue(std::string_view name) const noexcept;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user