From cfddb57d3a7541083ee70b0ae9d00331b9c95671 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 9 Sep 2023 18:52:41 +0300 Subject: [PATCH] Add an overload of enum_from_string that takes a string-like type (such as string_view). Fixes #41. --- include/boost/describe/enum_from_string.hpp | 24 +++++++ test/Jamfile | 2 + test/enum_from_string_test2.cpp | 78 +++++++++++++++++++++ 3 files changed, 104 insertions(+) create mode 100644 test/enum_from_string_test2.cpp diff --git a/include/boost/describe/enum_from_string.hpp b/include/boost/describe/enum_from_string.hpp index 3bdc4cf..f296cf0 100644 --- a/include/boost/describe/enum_from_string.hpp +++ b/include/boost/describe/enum_from_string.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #if defined(_MSC_VER) && _MSC_VER == 1900 # pragma warning(push) @@ -41,6 +42,29 @@ bool enum_from_string( char const* name, E& e ) noexcept return found; } +template, + class En = std::enable_if_t< + std::is_same::value && + std::is_same::value + > +> +bool enum_from_string( S const& name, E& e ) noexcept +{ + bool found = false; + + mp11::mp_for_each([&](auto D){ + + if( !found && name == D.name ) + { + found = true; + e = D.value; + } + + }); + + return found; +} + } // namespace describe } // namespace boost diff --git a/test/Jamfile b/test/Jamfile index 86e87cf..94fc27e 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -78,6 +78,8 @@ run pedantic_bases_test.cpp run pedantic_members_test.cpp : : : pedantic ; +run enum_from_string_test2.cpp ; + # examples obj describe_cxx14 : describe_cxx14.cpp ; diff --git a/test/enum_from_string_test2.cpp b/test/enum_from_string_test2.cpp new file mode 100644 index 0000000..cc3b3eb --- /dev/null +++ b/test/enum_from_string_test2.cpp @@ -0,0 +1,78 @@ +// Copyright 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if !defined(BOOST_DESCRIBE_CXX14) + +#include + +BOOST_PRAGMA_MESSAGE("Skipping test because C++14 is not available") +int main() {} + +#else + +enum E1 { v101 = 101, v102 = 102 }; +BOOST_DESCRIBE_ENUM(E1, v101, v102) + +enum class E2 { v201 = 201, v202 = 202 }; +BOOST_DESCRIBE_ENUM(E2, v201, v202) + +BOOST_DEFINE_ENUM(E3, v301, v302) +BOOST_DEFINE_ENUM_CLASS(E4, v401, v402) + +template void test() +{ + using boost::describe::enum_from_string; + + { + E1 w{}; + BOOST_TEST( enum_from_string( St( "v101" ), w ) ) && BOOST_TEST_EQ( w, v101 ); + BOOST_TEST( enum_from_string( St( "v102" ), w ) ) && BOOST_TEST_EQ( w, v102 ); + BOOST_TEST_NOT( enum_from_string( St( "v103" ), w ) ); + } + + { + E2 w{}; + BOOST_TEST( enum_from_string( St( "v201" ), w ) ) && BOOST_TEST_EQ( (int)w, (int)E2::v201 ); + BOOST_TEST( enum_from_string( St( "v202" ), w ) ) && BOOST_TEST_EQ( (int)w, (int)E2::v202 ); + BOOST_TEST_NOT( enum_from_string( St( "v203" ), w ) ); + } + + { + E3 w{}; + BOOST_TEST( enum_from_string( St( "v301" ), w ) ) && BOOST_TEST_EQ( w, v301 ); + BOOST_TEST( enum_from_string( St( "v302" ), w ) ) && BOOST_TEST_EQ( w, v302 ); + BOOST_TEST_NOT( enum_from_string( St( "v303" ), w ) ); + } + + { + E4 w{}; + BOOST_TEST( enum_from_string( St( "v401" ), w ) ) && BOOST_TEST_EQ( (int)w, (int)E4::v401 ); + BOOST_TEST( enum_from_string( St( "v402" ), w ) ) && BOOST_TEST_EQ( (int)w, (int)E4::v402 ); + BOOST_TEST_NOT( enum_from_string( St( "v403" ), w ) ); + } +} + +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) +# include +#endif + +int main() +{ + test(); + test(); + +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) + test(); +#endif + + return boost::report_errors(); +} + +#endif // !defined(BOOST_DESCRIBE_CXX14)