@@ -40,54 +40,20 @@ struct anything
4040 operator T () const ;
4141};
4242
43-
44- template <class T , class Is , class = void >
45- struct _can_construct_with_N : std::false_type
46- {
47- };
48-
49- template <class T , std::size_t ... Is>
50- struct _can_construct_with_N <T, std::index_sequence<Is...>,
51- std::void_t <decltype (T { (void (Is), anything {})... })>> : std::true_type
52- {
53- };
54-
55- template <class T , std::size_t N>
56- using can_construct_with_N = _can_construct_with_N<T, std::make_index_sequence<N>>;
57-
58-
59- template <std::size_t Min, std::size_t Range, template <std::size_t N> class target >
60- struct maximize
61- : std::conditional_t <maximize<Min, Range / 2 , target> {} == (Min + Range / 2 ) - 1 ,
62- maximize<Min + Range / 2 , (Range + 1 ) / 2 , target>, maximize<Min, Range / 2 , target>>
63- {
64- };
65- template <std::size_t Min, template <std::size_t N> class target >
66- struct maximize <Min, 1 , target>
67- : std::conditional_t <target<Min> {}, std::integral_constant<std::size_t , Min>,
68- std::integral_constant<std::size_t , Min - 1 >>
69- {
70- };
71- template <std::size_t Min, template <std::size_t N> class target >
72- struct maximize <Min, 0 , target> : std::integral_constant<std::size_t , Min - 1 >
73- {
74- };
75-
76- template <class T >
77- struct construct_searcher
78- {
79- template <std::size_t N>
80- using result = can_construct_with_N<T, N>;
81- };
82-
83- template <class T , std::size_t Cap = 32 >
84- using construct_airity = details::maximize<0 , Cap, details::construct_searcher<T>::template result>;
43+ template <typename T, typename ... A0>
44+ consteval auto MemberCounter (auto ...c0) {
45+ if constexpr (requires { T{ {A0{}}..., {anything{}}, c0... }; } == false
46+ && requires { T{ {A0{}}..., c0..., anything{}}; } == false )
47+ return sizeof ...(A0) + sizeof ...(c0);
48+ else
49+ if constexpr (requires { T{ {A0{}}..., {anything{}}, c0... }; })
50+ return MemberCounter<T,A0...,anything>(c0...);
51+ else
52+ return MemberCounter<T,A0...>(c0...,anything{});
53+ }
8554
8655}
8756
88- template <typename T>
89- inline constexpr std::size_t count_members
90- = details::construct_airity<std::remove_cv_t <std::remove_reference_t <T>>>::value;
9157
9258#define SPLIT_FIELDS_FW_DECL (return_type, name, const_struct ) \
9359 template <typename T, typename ... Args> \
@@ -99,7 +65,7 @@ inline constexpr std::size_t count_members
9965 template <typename T, typename ... Args> \
10066 constexpr return_type name (const_struct T& structure, Args&&... args) \
10167 { \
102- constexpr std::size_t count = count_members<T>; \
68+ constexpr std::size_t count = cpp_utils::reflexion:: count_members<T>; \
10369 static_assert (count <= 31 ); \
10470 \
10571 if constexpr (count == 1 ) \
@@ -343,61 +309,7 @@ inline constexpr std::size_t count_members
343309
344310namespace cpp_utils ::reflexion
345311{
346-
347- SPLIT_FIELDS_FW_DECL (std::size_t , load_record, );
348-
349-
350- template <typename field_t >
351- struct is_field : std::false_type
352- {
353- };
354-
355- template <typename field_t >
356- inline constexpr bool is_field_v = is_field<field_t >::value;
357-
358-
359- constexpr inline std::size_t _load_field (const auto & , auto & parsing_context, std::size_t offset, types::concepts::fundamental_type auto && field)
360- {
361- using value_t = std::decay_t <decltype (field)>;
362- load_value (parsing_context, offset, std::addressof (field), sizeof (value_t ));
363- return offset + sizeof (value_t );
364- }
365-
366-
367- template <typename record_t , typename parsing_context_t , typename T>
368- constexpr inline std::size_t _load_field (const record_t & r, parsing_context_t & parsing_context, std::size_t offset, T&& field)
369- {
370- return load_field (r, parsing_context, offset, field);
371- }
372-
373- template <typename record_t , typename parsing_context_t , typename T>
374- constexpr inline std::size_t load_fields (const record_t & r, parsing_context_t & parsing_context,
375- [[maybe_unused]] std::size_t offset, T&& field)
376- {
377- using Field_t = std::remove_cv_t <std::remove_reference_t <T>>;
378- constexpr std::size_t count = count_members<Field_t>;
379- if constexpr (std::is_compound_v<Field_t> && (count > 1 ) && (not is_field_v<Field_t>))
380- return load_record (field, parsing_context, offset);
381- else
382- return _load_field (r, parsing_context, offset, std::forward<T>(field));
383- }
384-
385- template <typename record_t , typename parsing_context_t , typename T, typename ... Ts>
386- constexpr inline std::size_t load_fields (const record_t & r, parsing_context_t & parsing_context,
387- [[maybe_unused]] std::size_t offset, T&& field, Ts&&... fields)
388- {
389- offset = load_fields (r, parsing_context, offset, std::forward<T>(field));
390- return load_fields (r, parsing_context, offset, std::forward<Ts>(fields)...);
391- }
392-
393- SPLIT_FIELDS (std::size_t , load_record, load_fields, );
394-
395- template <typename record_t >
396- constexpr record_t load_record (auto && parsing_context, [[maybe_unused]] std::size_t offset)
397- {
398- record_t r;
399- load_record (r, std::forward<decltype (parsing_context)>(parsing_context), offset);
400- return r;
401- }
312+ template <typename T>
313+ inline constexpr std::size_t count_members = details::MemberCounter<T>();
402314
403315} // namespace cpp_utils::reflexion
0 commit comments