intro/enum_simple: improve parsing for multi-level namespaces
This commit is contained in:
parent
5dd58a93b3
commit
2d1374192f
@ -19,7 +19,7 @@ namespace cruft::introspection {
|
|||||||
///
|
///
|
||||||
/// It must include an enum literal.
|
/// It must include an enum literal.
|
||||||
template <typename EnumT, EnumT Value>
|
template <typename EnumT, EnumT Value>
|
||||||
static constexpr
|
static consteval
|
||||||
std::string_view
|
std::string_view
|
||||||
enum_pretty_function (void)
|
enum_pretty_function (void)
|
||||||
{
|
{
|
||||||
@ -39,20 +39,22 @@ namespace cruft::introspection {
|
|||||||
/// namespace. Testing is _essential_.
|
/// namespace. Testing is _essential_.
|
||||||
template <typename EnumT, EnumT Value>
|
template <typename EnumT, EnumT Value>
|
||||||
requires (std::is_enum_v<EnumT>)
|
requires (std::is_enum_v<EnumT>)
|
||||||
constexpr std::string_view
|
consteval std::string_view
|
||||||
to_string [[maybe_unused]] (void)
|
to_string [[maybe_unused]] (void)
|
||||||
{
|
{
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
// std::string_view cruft::introspection::detail::enum_pretty_function() [EnumT = enum_t, Value = main()::value0]
|
// std::string_view cruft::introspection::detail::enum_pretty_function() [EnumT = enum_t, Value = main()::value0]
|
||||||
//
|
//
|
||||||
// std::string_view enum_pretty_function() [EnumT = enum_t, Value = (enum_t)42]
|
// std::string_view enum_pretty_function() [EnumT = enum_t, Value = (enum_t)42]
|
||||||
|
//
|
||||||
|
// "std::string_view cruft::introspection::detail::enum_pretty_function() [EnumT = enum_t, Value = test_local(cruft::TAP::logger &)::value0]"
|
||||||
|
|
||||||
auto const signature = detail::enum_pretty_function<EnumT, Value> ();
|
auto const signature = detail::enum_pretty_function<EnumT, Value> ();
|
||||||
|
|
||||||
auto const comma = signature.find (',');
|
auto const comma = signature.find (',');
|
||||||
auto const coloncolon = signature.find ("::", comma + 1);
|
|
||||||
auto const equals = signature.find ('=', comma + 1);
|
|
||||||
auto const close = signature.find (']', comma + 1);
|
auto const close = signature.find (']', comma + 1);
|
||||||
|
auto const coloncolon = signature.rfind ("::", close);
|
||||||
|
auto const equals = signature.find ('=', comma + 1);
|
||||||
|
|
||||||
auto const first = coloncolon == std::string_view::npos ? equals + 2 : coloncolon + 2;
|
auto const first = coloncolon == std::string_view::npos ? equals + 2 : coloncolon + 2;
|
||||||
|
|
||||||
@ -64,11 +66,13 @@ namespace cruft::introspection {
|
|||||||
// "constexpr std::string_view cruft::introspection::detail::enum_pretty_function() [with EnumT = main()::enum_t; EnumT Value = main::value1; std::string_view = std::basic_string_view<char>]"
|
// "constexpr std::string_view cruft::introspection::detail::enum_pretty_function() [with EnumT = main()::enum_t; EnumT Value = main::value1; std::string_view = std::basic_string_view<char>]"
|
||||||
//
|
//
|
||||||
// consteval std::string_view enum_pretty_function() [with EnumT = enum_t; EnumT Value = (enum_t)42; std::string_view = std::basic_string_view<char>]
|
// consteval std::string_view enum_pretty_function() [with EnumT = enum_t; EnumT Value = (enum_t)42; std::string_view = std::basic_string_view<char>]
|
||||||
|
//
|
||||||
|
// "constexpr std::string_view cruft::introspection::detail::enum_pretty_function() [with EnumT = test_local(cruft::TAP::logger&)::enum_t; EnumT Value = test_local::value0; std::string_view = std::basic_string_view<char>]"
|
||||||
|
|
||||||
auto const signature = detail::enum_pretty_function<EnumT, Value> ();
|
auto const signature = detail::enum_pretty_function<EnumT, Value> ();
|
||||||
auto const semicolon0 = signature.find (';');
|
auto const semicolon0 = signature.find (';');
|
||||||
auto const semicolon1 = signature.find (';', semicolon0 + 1);
|
auto const semicolon1 = signature.find (';', semicolon0 + 1);
|
||||||
auto const coloncolon = signature.find ("::", semicolon0 + 1);
|
auto const coloncolon = signature.rfind ("::", semicolon1);
|
||||||
auto const equals = signature.find ('=', semicolon0);
|
auto const equals = signature.find ('=', semicolon0);
|
||||||
|
|
||||||
// static_assert (equals > semicolon0);
|
// static_assert (equals > semicolon0);
|
||||||
@ -121,11 +125,11 @@ namespace cruft::introspection {
|
|||||||
// If the bounds here are incorrect then the result will never be found.
|
// If the bounds here are incorrect then the result will never be found.
|
||||||
// It should be possible to change this search range fairly easily, though
|
// It should be possible to change this search range fairly easily, though
|
||||||
// for larger values you might run into compile time recursion limits.
|
// for larger values you might run into compile time recursion limits.
|
||||||
static
|
static constexpr
|
||||||
EnumT
|
EnumT
|
||||||
from (std::string_view name)
|
from (std::string_view name)
|
||||||
{
|
{
|
||||||
return _from<EnumT (0), EnumT (128)> (name);
|
return _from<EnumT (0), EnumT (5)> (name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -147,7 +151,8 @@ namespace cruft::introspection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string_view
|
static constexpr
|
||||||
|
std::string_view
|
||||||
to (EnumT val)
|
to (EnumT val)
|
||||||
{
|
{
|
||||||
return _to<EnumT (0), EnumT (128)> (val);
|
return _to<EnumT (0), EnumT (128)> (val);
|
||||||
@ -158,6 +163,7 @@ namespace cruft::introspection {
|
|||||||
|
|
||||||
template <typename EnumT>
|
template <typename EnumT>
|
||||||
requires (std::is_enum_v<EnumT>)
|
requires (std::is_enum_v<EnumT>)
|
||||||
|
constexpr
|
||||||
EnumT
|
EnumT
|
||||||
from_string (std::string_view str)
|
from_string (std::string_view str)
|
||||||
{
|
{
|
||||||
@ -167,6 +173,7 @@ namespace cruft::introspection {
|
|||||||
|
|
||||||
template <typename EnumT>
|
template <typename EnumT>
|
||||||
requires (std::is_enum_v<EnumT>)
|
requires (std::is_enum_v<EnumT>)
|
||||||
|
constexpr
|
||||||
std::string_view
|
std::string_view
|
||||||
to_string (EnumT val)
|
to_string (EnumT val)
|
||||||
{
|
{
|
||||||
|
@ -4,18 +4,63 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
namespace foo::bar {
|
||||||
|
enum qux_t {
|
||||||
|
qux0,
|
||||||
|
qux1,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
static void
|
||||||
|
test_local (cruft::TAP::logger &tap)
|
||||||
|
{
|
||||||
|
enum enum_t { value0 = 0, value1 = 1, value3 = 3, };
|
||||||
|
|
||||||
|
tap.expect_eq (cruft::introspection::from_string<enum_t> ("value1"), value1, "from_string, dynamic");
|
||||||
|
tap.expect_eq (cruft::introspection::to_string<enum_t, value1> (), "value1", "to_string, static");
|
||||||
|
tap.expect_eq (cruft::introspection::to_string (value1), "value1", "to_string, dynamic");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
static void
|
||||||
|
test_namespaced (cruft::TAP::logger &tap)
|
||||||
|
{
|
||||||
|
auto const val = cruft::introspection::to_string<foo::bar::qux_t, foo::bar::qux1> ();
|
||||||
|
(void)val;
|
||||||
|
|
||||||
|
tap.expect_eq (
|
||||||
|
cruft::introspection::from_string<foo::bar::qux_t> ("qux1"),
|
||||||
|
foo::bar::qux1,
|
||||||
|
"namespaced: from_string, dynamic"
|
||||||
|
);
|
||||||
|
tap.expect_eq (
|
||||||
|
cruft::introspection::to_string<
|
||||||
|
foo::bar::qux_t,
|
||||||
|
foo::bar::qux1
|
||||||
|
> (),
|
||||||
|
"qux1",
|
||||||
|
"namespaced: to_string, static"
|
||||||
|
);
|
||||||
|
tap.expect_eq (
|
||||||
|
cruft::introspection::to_string(foo::bar::qux1),
|
||||||
|
"qux1",
|
||||||
|
"namespaced: to-string, dynamic"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
int
|
int
|
||||||
main ()
|
main ()
|
||||||
{
|
{
|
||||||
cruft::TAP::logger tap;
|
cruft::TAP::logger tap;
|
||||||
|
|
||||||
enum enum_t { value0 = 0, value1 = 1, value3 = 3, };
|
test_local (tap);
|
||||||
|
test_namespaced (tap);
|
||||||
std::cout << cruft::introspection::detail::enum_pretty_function<enum_t, value0> () << '\n';
|
|
||||||
|
|
||||||
tap.expect_eq (cruft::introspection::from_string<enum_t> ("value1"), value1, "from_string, dynamic");
|
|
||||||
tap.expect_eq (cruft::introspection::to_string<enum_t, value1> (), "value1", "to_string, static");
|
|
||||||
tap.expect_eq (cruft::introspection::to_string (value1), "value1", "to_string, dynamic");
|
|
||||||
|
|
||||||
return tap.status ();
|
return tap.status ();
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user