5#include <reflection-cpp/reflection.hpp>
17 template <
typename MemberPo
inter>
23 template <std::
size_t I, auto Value>
26 static constexpr auto value = Value;
29 template <
typename Sequence,
auto... Values>
32 template <std::size_t... Is,
auto... Values>
33 struct IndexedValues<std::index_sequence<Is...>, Values...>: IndexedValue<Is, Values>...
37 template <std::
size_t I, auto Value>
38 IndexedValue<I, Value> SelectIndexedValue(IndexedValue<I, Value>
const&);
40 template <std::
size_t I,
typename T>
46 template <
typename Sequence,
typename... Types>
49 template <std::size_t... Is,
typename... Types>
50 struct IndexedTypes<std::index_sequence<Is...>, Types...>: IndexedType<Is, Types>...
54 template <std::
size_t I,
typename T>
55 IndexedType<I, T> SelectIndexedType(IndexedType<I, T>
const&);
58 template <std::size_t I,
typename... Types>
59 using NthType =
decltype(SelectIndexedType<I>(
60 std::declval<IndexedTypes<std::make_index_sequence<
sizeof...(Types)>, Types...>>()))::type;
63 template <std::size_t I,
auto... Values>
64 inline constexpr auto NthValue =
65 decltype(SelectIndexedValue<I>(IndexedValues<std::make_index_sequence<
sizeof...(Values)>, Values...> {}))::value;
67 template <
typename Class,
typename Member>
68 struct MemberPointee<Member Class::*>
83template <
auto... MemberPointers>
87 static constexpr std::size_t
Count =
sizeof...(MemberPointers);
94 template <std::
size_t I>
95 using TypeAt = detail::MemberPointee<detail::NthType<I,
decltype(MemberPointers)...>>::type;
101 template <
typename Record,
typename Callable>
104 auto&& visitor = std::forward<Callable>(callable);
110 [&]<std::size_t... I>(std::index_sequence<I...> ) {
111 (visitor.template operator()<I>(MemberAt<I>(record)), ...);
112 }(std::make_index_sequence<Count> {});
116 template <
typename Callable>
119 auto&& visitor = std::forward<Callable>(callable);
120 [&]<std::size_t... I>(std::index_sequence<I...> ) {
121 (visitor.template operator()<I,
TypeAt<I>>(), ...);
122 }(std::make_index_sequence<Count> {});
127 template <
typename ElementMask,
typename Record,
typename Callable>
130 auto&& visitor = std::forward<Callable>(callable);
131 [&]<std::size_t... I>(std::integer_sequence<std::size_t, I...> ) {
132 (visitor.template operator()<I>(MemberAt<I>(record)), ...);
137 template <std::
size_t I,
typename Record>
138 static constexpr decltype(
auto)
MemberAt(Record& record)
140 return (record.*(detail::NthValue<I, MemberPointers...>) );
173template <
typename Record>
178template <
typename Record>
180 { Description<std::remove_cvref_t<Record>>::FieldCount } -> std::convertible_to<std::size_t>;
187 template <std::
size_t I,
typename Record,
bool HasDescriptor>
188 struct RecordMemberTypeOfDispatch
193 template <std::
size_t I,
typename Record>
194 struct RecordMemberTypeOfDispatch<I, Record, false>
196 using type = Reflection::MemberTypeOf<I, Record>;
202template <
typename Record>
205 return Description<std::remove_cvref_t<Record>>::FieldCount;
207 return Reflection::CountMembers<Record>;
212template <std::
size_t I,
typename Record>
217template <std::
size_t I,
typename Record>
221 return Description<std::remove_cvref_t<Record>>::Members::template MemberAt<I>(record);
223 return Reflection::GetMemberAt<I>(std::forward<Record>(record));
231template <
typename Record,
typename Callable>
235 Description<std::remove_cvref_t<Record>>::Members::EnumerateValues(record, std::forward<Callable>(callable));
237 Reflection::EnumerateMembers(record, std::forward<Callable>(callable));
245template <
typename ElementMask,
typename Record,
typename Callable>
249 Description<std::remove_cvref_t<Record>>::Members::template EnumerateMaskedValues<ElementMask>(
250 record, std::forward<Callable>(callable));
252 Reflection::EnumerateMembers<ElementMask>(record, std::forward<Callable>(callable));
259template <
typename Record,
typename Callable>
263 Description<std::remove_cvref_t<Record>>::Members::EnumerateTypes(std::forward<Callable>(callable));
265 Reflection::EnumerateMembers<Record>(std::forward<Callable>(callable));
272template <
typename Record,
typename Callable,
typename ResultType>
275 ResultType result = initialValue;
276 EnumerateRecordMembers<Record>(
277 [&]<std::size_t I,
typename MemberType>() { result = callable.template operator()<I, MemberType>(result); });
Satisfied when a Description specialization exists for the given record type.
constexpr ResultType FoldRecordMembers(ResultType initialValue, Callable const &callable)
Folds over a record's members as result = callable<I, MemberType>(result).
constexpr decltype(auto) GetRecordMemberAt(Record &&record)
Returns a reference to the member at index I — from the descriptor if present, else via reflection.
constexpr std::size_t RecordMemberCount
Number of members in a record — from the descriptor if present, else via reflection.
constexpr void EnumerateRecordMembers(Record &record, Callable &&callable)
Invokes callable as callable<I>(member) for each member of record.
detail::RecordMemberTypeOfDispatch< I, std::remove_cvref_t< Record >, HasDescription< Record > >::type RecordMemberTypeOf
Type of the member at index I — from the descriptor if present, else via reflection.
Customization point providing pre-computed reflection metadata for a record type.
Compile-time list of a record's members, stored as pointers-to-member.
static constexpr std::size_t Count
Number of members in the list.
static constexpr void EnumerateMaskedValues(Record &record, Callable &&callable)
static constexpr void EnumerateTypes(Callable &&callable)
Invokes callable<I, MemberType>() for every member, in order.
detail::MemberPointee< detail::NthType< I, decltype(MemberPointers)... > >::type TypeAt
static constexpr decltype(auto) MemberAt(Record &record)
Returns a reference to the member at index I of record.
static constexpr void EnumerateValues(Record &record, Callable &&callable)