Skip to content

Commit 835a1ef

Browse files
Add MemberClassType<P> and MemberIndexOf<P> to get the class type and member-index of P.
Signed-off-by: Christian Parpart <[email protected]>
1 parent 6a2567b commit 835a1ef

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

include/reflection-cpp/reflection.hpp

+35-1
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,24 @@ constexpr auto TypeNameOf = [] {
535535
#endif
536536
}();
537537

538+
namespace detail
539+
{
540+
template <typename T>
541+
struct MemberClassTypeHelper;
542+
543+
template <typename M, typename T>
544+
struct MemberClassTypeHelper<M T::*>
545+
{
546+
using type = std::remove_cvref_t<T>;
547+
};
548+
} // namespace detail
549+
550+
/// Represents the class type of a member pointer
551+
///
552+
/// @tparam P The member pointer, e.g. &MyClass::member
553+
template <auto P>
554+
using MemberClassType = typename detail::MemberClassTypeHelper<decltype(P)>::type;
555+
538556
namespace detail
539557
{
540558
template <class T, size_t... I>
@@ -641,7 +659,6 @@ constexpr void template_for(F&& f)
641659

642660
namespace detail
643661
{
644-
645662
template <auto P>
646663
requires(std::is_member_pointer_v<decltype(P)>)
647664
consteval std::string_view GetName()
@@ -691,6 +708,23 @@ namespace detail
691708
template <auto V>
692709
constexpr std::string_view NameOf = detail::GetName<V>();
693710

711+
namespace detail
712+
{
713+
// private helper for implementing MemberIndexOf<P>
714+
template <auto P, size_t... I>
715+
consteval size_t MemberIndexHelperImpl(std::index_sequence<I...>)
716+
{
717+
return (((NameOf<P> == MemberNames<MemberClassType<P>>[I]) ? I : 0) + ...);
718+
}
719+
} // namespace detail
720+
721+
/// Gets the index of a member pointer in the member list of its class
722+
///
723+
/// @tparam P The member pointer, e.g. &MyClass::member
724+
template <auto P>
725+
constexpr size_t MemberIndexOf =
726+
MemberIndexHelperImpl<P>(std::make_index_sequence<CountMembers<MemberClassType<P>>> {});
727+
694728
/// Calls a callable on members of an object specified with ElementMask sequence with the index of the member as the
695729
/// first argument. and the member's default-constructed value as the second argument.
696730
template <typename ElementMask, typename Object, typename Callable>

test-reflection-cpp.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ struct SingleValueRecord
3535
int value;
3636
};
3737

38+
TEST_CASE("MemberIndex", "[reflection]")
39+
{
40+
static_assert(Reflection::MemberIndexOf<&Person::name> == 0);
41+
static_assert(Reflection::MemberIndexOf<&Person::email> == 1);
42+
static_assert(Reflection::MemberIndexOf<&Person::age> == 2);
43+
}
44+
3845
TEST_CASE("TypeNameOf", "[reflection]")
3946
{
4047
CHECK(Reflection::TypeNameOf<int> == "int");

0 commit comments

Comments
 (0)