From c5424dc35136c00b2d6549704346c872c25d8685 Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Sat, 8 Feb 2025 16:36:11 +0100 Subject: [PATCH] Add MemberClassType

and MemberIndexOf

to get the class type and member-index of P. Signed-off-by: Christian Parpart --- include/reflection-cpp/reflection.hpp | 36 ++++++++++++++++++++++++++- test-reflection-cpp.cpp | 7 ++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/include/reflection-cpp/reflection.hpp b/include/reflection-cpp/reflection.hpp index 00265f2..d529d6d 100644 --- a/include/reflection-cpp/reflection.hpp +++ b/include/reflection-cpp/reflection.hpp @@ -535,6 +535,24 @@ constexpr auto TypeNameOf = [] { #endif }(); +namespace detail +{ + template + struct MemberClassTypeHelper; + + template + struct MemberClassTypeHelper + { + using type = std::remove_cvref_t; + }; +} // namespace detail + +/// Represents the class type of a member pointer +/// +/// @tparam P The member pointer, e.g. &MyClass::member +template +using MemberClassType = typename detail::MemberClassTypeHelper::type; + namespace detail { template @@ -641,7 +659,6 @@ constexpr void template_for(F&& f) namespace detail { - template requires(std::is_member_pointer_v) consteval std::string_view GetName() @@ -691,6 +708,23 @@ namespace detail template constexpr std::string_view NameOf = detail::GetName(); +namespace detail +{ + // private helper for implementing MemberIndexOf

+ template + consteval size_t MemberIndexHelperImpl(std::index_sequence) + { + return (((NameOf

== MemberNames>[I]) ? I : 0) + ...); + } +} // namespace detail + +/// Gets the index of a member pointer in the member list of its class +/// +/// @tparam P The member pointer, e.g. &MyClass::member +template +constexpr size_t MemberIndexOf = + detail::MemberIndexHelperImpl

(std::make_index_sequence>> {}); + /// Calls a callable on members of an object specified with ElementMask sequence with the index of the member as the /// first argument. and the member's default-constructed value as the second argument. template diff --git a/test-reflection-cpp.cpp b/test-reflection-cpp.cpp index 385f64b..4bab11e 100644 --- a/test-reflection-cpp.cpp +++ b/test-reflection-cpp.cpp @@ -35,6 +35,13 @@ struct SingleValueRecord int value; }; +TEST_CASE("MemberIndex", "[reflection]") +{ + static_assert(Reflection::MemberIndexOf<&Person::name> == 0); + static_assert(Reflection::MemberIndexOf<&Person::email> == 1); + static_assert(Reflection::MemberIndexOf<&Person::age> == 2); +} + TEST_CASE("TypeNameOf", "[reflection]") { CHECK(Reflection::TypeNameOf == "int");