refactor enum_type api for working with dynamic values

This commit is contained in:
BlackMATov
2024-08-08 03:08:23 +07:00
parent 11bc1c23b7
commit f90e8af84b
10 changed files with 175 additions and 86 deletions

View File

@@ -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);
}

View File

@@ -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

View 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}));
}
}

View File

@@ -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());

View File

@@ -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);

View File

@@ -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"));
}
}
}

View File

@@ -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);

View File

@@ -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> {

View File

@@ -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;
}
}

View File

@@ -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;
};
```