Skip to content

Commit 6a2567b

Browse files
authored
Merge pull request #22 from contour-terminal/feature/NameOf-TypeNameOf
2 parents 477cfbd + 58a23f6 commit 6a2567b

File tree

2 files changed

+64
-56
lines changed

2 files changed

+64
-56
lines changed

include/reflection-cpp/reflection.hpp

Lines changed: 52 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ inline constexpr auto MemberNameOf = []() constexpr {
522522
}();
523523

524524
template <class T>
525-
constexpr auto TypeName = [] {
525+
constexpr auto TypeNameOf = [] {
526526
constexpr std::string_view name = detail::MangledName<T>();
527527
constexpr auto begin = name.find(detail::reflect_type::end);
528528
constexpr auto tmp = name.substr(0, begin);
@@ -589,7 +589,7 @@ namespace detail
589589
consteval std::string_view func_name_msvc()
590590
{
591591
std::string_view str = REFLECTION_PRETTY_FUNCTION;
592-
str = str.substr(str.rfind(TypeName<T>) + TypeName<T>.size());
592+
str = str.substr(str.rfind(TypeNameOf<T>) + TypeNameOf<T>.size());
593593
str = str.substr(str.find("::") + 2);
594594
return str.substr(0, str.find('('));
595595
}
@@ -604,11 +604,9 @@ namespace detail
604604
template <typename... Ts, typename F>
605605
constexpr void enumerate_types(F&& f)
606606
{
607-
[&f]<auto... Is>(std::index_sequence<Is...>)
608-
{
607+
[&f]<auto... Is>(std::index_sequence<Is...>) {
609608
(f.template operator()<Ts, Is>(), ...);
610-
}
611-
(std::index_sequence_for<Ts...> {});
609+
}(std::index_sequence_for<Ts...> {});
612610
}
613611

614612
template <auto... Xs, typename F>
@@ -627,67 +625,71 @@ constexpr void template_for(F&& f)
627625
{
628626
using t = std::common_type_t<decltype(B), decltype(E)>;
629627

630-
[&f]<auto... Xs>(std::integer_sequence<t, Xs...>)
631-
{
628+
[&f]<auto... Xs>(std::integer_sequence<t, Xs...>) {
632629
detail::for_values<(B + Xs)...>(f);
633-
}
634-
(std::make_integer_sequence<t, E - B> {});
630+
}(std::make_integer_sequence<t, E - B> {});
635631
}
636632

637633
template <typename ElementMask, typename F>
638634
constexpr void template_for(F&& f)
639635
{
640636
using t = typename ElementMask::value_type;
641-
[&f]<auto... Xs>(std::integer_sequence<t, Xs...>)
642-
{
637+
[&f]<auto... Xs>(std::integer_sequence<t, Xs...>) {
643638
Reflection::detail::for_values<(Xs)...>(f);
644-
}
645-
(ElementMask {});
639+
}(ElementMask {});
646640
}
647641

648-
template <auto P>
649-
requires(std::is_member_pointer_v<decltype(P)>)
650-
consteval std::string_view GetName()
642+
namespace detail
651643
{
652-
#if defined(_MSC_VER) && !defined(__clang__)
653-
if constexpr (std::is_member_object_pointer_v<decltype(P)>)
654-
{
655-
using T = detail::remove_member_pointer<std::decay_t<decltype(P)>>::type;
656-
constexpr auto p = P;
657-
return detail::get_name_msvc<T, &(detail::External<T>.*p)>();
658-
}
659-
else
644+
645+
template <auto P>
646+
requires(std::is_member_pointer_v<decltype(P)>)
647+
consteval std::string_view GetName()
660648
{
661-
using T = detail::remove_member_pointer<std::decay_t<decltype(P)>>::type;
662-
return detail::func_name_msvc<T, P>();
663-
}
649+
#if defined(_MSC_VER) && !defined(__clang__)
650+
if constexpr (std::is_member_object_pointer_v<decltype(P)>)
651+
{
652+
using T = detail::remove_member_pointer<std::decay_t<decltype(P)>>::type;
653+
constexpr auto p = P;
654+
return detail::get_name_msvc<T, &(detail::External<T>.*p)>();
655+
}
656+
else
657+
{
658+
using T = detail::remove_member_pointer<std::decay_t<decltype(P)>>::type;
659+
return detail::func_name_msvc<T, P>();
660+
}
664661
#else
665-
// TODO: Use std::source_location when deprecating clang 14
666-
// std::string_view str = std::source_location::current().function_name();
667-
std::string_view str = REFLECTION_PRETTY_FUNCTION;
668-
str = str.substr(str.find('&') + 1);
669-
str = str.substr(0, str.find(detail::pretty_function_tail));
670-
return str.substr(str.rfind("::") + 2);
662+
// TODO: Use std::source_location when deprecating clang 14
663+
// std::string_view str = std::source_location::current().function_name();
664+
std::string_view str = REFLECTION_PRETTY_FUNCTION;
665+
str = str.substr(str.find('&') + 1);
666+
str = str.substr(0, str.find(detail::pretty_function_tail));
667+
return str.substr(str.rfind("::") + 2);
671668
#endif
672-
}
669+
}
673670

674-
template <auto E>
675-
requires(std::is_enum_v<decltype(E)>)
676-
consteval auto GetName()
677-
{
671+
template <auto E>
672+
requires(std::is_enum_v<decltype(E)>)
673+
consteval auto GetName()
674+
{
678675
#if defined(_MSC_VER) && !defined(__clang__)
679-
std::string_view str = REFLECTION_PRETTY_FUNCTION;
680-
str = str.substr(str.rfind("::") + 2);
681-
str = str.substr(0, str.find('>'));
682-
return str.substr(str.find('<') + 1);
676+
std::string_view str = REFLECTION_PRETTY_FUNCTION;
677+
str = str.substr(str.rfind("::") + 2);
678+
str = str.substr(0, str.find('>'));
679+
return str.substr(str.find('<') + 1);
683680
#else
684-
constexpr auto MarkerStart = std::string_view { "E = " };
685-
std::string_view str = REFLECTION_PRETTY_FUNCTION;
686-
str = str.substr(str.rfind(MarkerStart) + MarkerStart.size());
687-
str = str.substr(0, str.find(']'));
688-
return str;
681+
constexpr auto MarkerStart = std::string_view { "E = " };
682+
std::string_view str = REFLECTION_PRETTY_FUNCTION;
683+
str = str.substr(str.rfind(MarkerStart) + MarkerStart.size());
684+
str = str.substr(0, str.find(']'));
685+
return str;
689686
#endif
690-
}
687+
}
688+
} // namespace detail
689+
690+
/// Gets the name of a member or function pointer
691+
template <auto V>
692+
constexpr std::string_view NameOf = detail::GetName<V>();
691693

692694
/// Calls a callable on members of an object specified with ElementMask sequence with the index of the member as the
693695
/// first argument. and the member's default-constructed value as the second argument.
@@ -730,8 +732,7 @@ template <typename Object, typename Callable>
730732
requires std::same_as<void, std::invoke_result_t<Callable, std::string, MemberTypeOf<0, Object>>>
731733
void CallOnMembers(Object& object, Callable&& callable)
732734
{
733-
EnumerateMembers(object,
734-
[&]<size_t I, typename T>(T&& value) { callable(MemberNameOf<I, Object>, value); });
735+
EnumerateMembers(object, [&]<size_t I, typename T>(T&& value) { callable(MemberNameOf<I, Object>, value); });
735736
}
736737

737738
/// Folds over the members of a type without an object of it.

test-reflection-cpp.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,25 @@ struct SingleValueRecord
3535
int value;
3636
};
3737

38-
TEST_CASE("GetName", "[reflection]")
38+
TEST_CASE("TypeNameOf", "[reflection]")
3939
{
40-
auto const enumValue = Reflection::GetName<Color::Red>();
40+
CHECK(Reflection::TypeNameOf<int> == "int");
41+
CHECK(Reflection::TypeNameOf<Person> == "Person");
42+
CHECK(Reflection::TypeNameOf<std::optional<float>> == "std::optional<float>");
43+
}
44+
45+
TEST_CASE("NameOf", "[reflection]")
46+
{
47+
auto const enumValue = Reflection::NameOf<Color::Red>;
4148
CHECK(enumValue == "Red");
4249

43-
auto const enumValue2 = Reflection::GetName<Color::Green>();
50+
auto const enumValue2 = Reflection::NameOf<Color::Green>;
4451
CHECK(enumValue2 == "Green");
4552

46-
auto const memberName1 = Reflection::GetName<&Person::email>();
53+
auto const memberName1 = Reflection::NameOf<&Person::email>;
4754
CHECK(memberName1 == "email");
4855

49-
auto const singleValueField = Reflection::GetName<&SingleValueRecord::value>();
56+
auto const singleValueField = Reflection::NameOf<&SingleValueRecord::value>;
5057
CHECK(singleValueField == "value");
5158
}
5259

0 commit comments

Comments
 (0)