@@ -456,17 +456,27 @@ inline constexpr decltype(auto) ToTuple(T&& t) noexcept
456456 // clang-format on
457457}
458458
459+ template <auto I, typename T>
460+ constexpr decltype (auto ) GetMemberAt(T&& t)
461+ {
462+ return std::get<I>(ToTuple (std::forward<T>(t)));
463+ }
464+
465+ // / Represents the type of the member at index I of type Object
466+ template <auto I, typename Object>
467+ using MemberTypeOf = std::remove_cvref_t <decltype (std::get<I>(ToTuple(Object {})))>;
468+
459469template <class T >
460470struct WrappedPointer final
461471{
462- const T* ptr ;
472+ T* pointer ;
463473};
464474
465475template <size_t N, class T >
466476constexpr auto GetElementPtrAt (T&& t) noexcept
467477{
468- auto & p = get <N>(ToTuple (t));
469- return WrappedPointer<std::remove_cvref_t <decltype (p)>> { &p };
478+ auto & p = GetMemberAt <N>(std::forward<T> (t));
479+ return WrappedPointer<std::remove_reference_t <decltype (p)>> { &p };
470480}
471481
472482namespace detail
@@ -673,7 +683,7 @@ consteval auto GetName()
673683 std::string_view str = REFLECTION_PRETTY_FUNCTION;
674684 str = str.substr (str.rfind (" ::" ) + 2 );
675685 str = str.substr (0 , str.find (' >' ));
676- return str.substr (str.find (' <' )+ 1 );
686+ return str.substr (str.find (' <' ) + 1 );
677687#else
678688 constexpr auto MarkerStart = std::string_view { " E = " };
679689 std::string_view str = REFLECTION_PRETTY_FUNCTION;
@@ -683,18 +693,32 @@ consteval auto GetName()
683693#endif
684694}
685695
696+ // / Calls a callable on each member of an object with the index of the member as the first argument.
697+ // / and the member's default-constructed value as the second argument.
698+ template <typename Object, typename Callable>
699+ constexpr void EnumerateMembers (Object& object, Callable&& callable)
700+ {
701+ template_for<0 , CountMembers<Object>>([&]<auto I>() { callable.template operator ()<I>(GetMemberAt<I>(object)); });
702+ }
703+
704+ // / Calls a callable on each member of an object with the index and member's type as template arguments.
686705template <typename Object, typename Callable>
687- void CallOnMembers (Object const & object, Callable&& callable)
706+ constexpr void EnumerateMembers ( Callable&& callable)
688707{
689- template_for<0 , Reflection::CountMembers<Object>>(
690- [&]<auto I>() { callable (Reflection::MemberNameOf<I, Object>, std::get<I>(Reflection::ToTuple (object))); });
708+ // clang-format off
709+ template_for<0 , CountMembers<Object>>(
710+ [&]<auto I>() {
711+ callable.template operator ()<I, MemberTypeOf<I, Object>>();
712+ }
713+ );
714+ // clang-format on
691715}
692716
693717template <typename Object, typename Callable>
694718void CallOnMembers (Object& object, Callable&& callable)
695719{
696- template_for< 0 , Reflection::CountMembers< Object>>(
697- [&]<auto I>( ) { callable (Reflection:: MemberNameOf<I, Object>, std::get<I>( Reflection::ToTuple (object)) ); });
720+ EnumerateMembers< Object>(object,
721+ [&]<size_t I, typename T>(T&& value ) { callable (MemberNameOf<I, Object>, value ); });
698722}
699723
700724// / Folds over the members of a type without an object of it.
@@ -709,11 +733,9 @@ constexpr ResultType FoldMembers(ResultType initialValue, Callable const& callab
709733{
710734 // clang-format off
711735 ResultType result = initialValue;
712- template_for<0 , Reflection::CountMembers<Object>>(
713- [&]<size_t I>() {
714- result = callable (Reflection::MemberNameOf<I, Object>,
715- std::get<I>(Reflection::ToTuple (Object {})),
716- result);
736+ EnumerateMembers<Object>(
737+ [&]<size_t I, typename MemberType>() {
738+ result = callable.template operator ()<I, MemberTypeOf<I, Object>>(result);
717739 }
718740 );
719741 // clang-format on
@@ -729,15 +751,16 @@ constexpr ResultType FoldMembers(ResultType initialValue, Callable const& callab
729751// /
730752// / @return The result of the fold
731753template <typename Object, typename Callable, typename ResultType>
732- constexpr ResultType FoldMembers (Object const & object, ResultType initialValue, Callable const & callable)
754+ constexpr ResultType FoldMembers (Object& object, ResultType initialValue, Callable const & callable)
733755{
734756 // clang-format off
735757 ResultType result = initialValue;
736- template_for<0 , Reflection::CountMembers<Object>>([&]<size_t I>() {
737- result = callable (Reflection::MemberNameOf<I, Object>,
738- std::get<I>(Reflection::ToTuple (object)),
739- result);
740- });
758+ EnumerateMembers<Object>(
759+ object,
760+ [&]<size_t I, typename MemberType>(MemberType&& value) {
761+ result = callable (MemberNameOf<I, Object>, value, result);
762+ }
763+ );
741764 return result;
742765 // clang-format on
743766}
0 commit comments