@@ -36,70 +36,36 @@ namespace details
3636{
3737struct anything
3838{
39- template <class T >
39+ template <class T > requires (!std::is_bounded_array_v<std:: decay_t <T>>)
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> \
94- constexpr return_type name (const_struct T& structure, Args&&... args);
60+ return_type name (const_struct T& structure, Args&&... args);
9561
9662
9763#define SPLIT_FIELDS (return_type, name, function, const_struct ) \
9864 /* this looks quite ugly bit it is worth it!*/ \
9965 template <typename T, typename ... Args> \
100- constexpr return_type name (const_struct T& structure, Args&&... args) \
66+ 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,42 @@ inline constexpr std::size_t count_members
343309
344310namespace cpp_utils ::reflexion
345311{
312+ template <typename T>
313+ inline constexpr std::size_t count_members = details::MemberCounter<T>();
346314
347- SPLIT_FIELDS_FW_DECL (std::size_t , load_record, );
348-
315+ SPLIT_FIELDS_FW_DECL ([[nodiscard]] constexpr std::size_t , composite_size, const );
316+ template <typename composite_t >
317+ consteval std::size_t composite_size ();
349318
350319template <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)
320+ [[nodiscard]] consteval std::size_t field_size ()
369321{
370- return load_field (r, parsing_context, offset, field);
322+ if constexpr (std::is_bounded_array_v<field_t >)
323+ return sizeof (field_t )*std::extent_v<field_t >;
324+ return sizeof (field_t );
371325}
372326
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)
327+ [[nodiscard]] constexpr inline std::size_t fields_size (const auto & , auto & field)
376328{
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);
329+ using Field_t = std::decay_t <decltype (field)>;
330+ if constexpr (std::is_compound_v<Field_t> && ! std::is_bounded_array_v<Field_t>)
331+ return composite_size<Field_t>();
381332 else
382- return _load_field (r, parsing_context, offset, std::forward<T>(field) );
333+ return field_size<Field_t>( );
383334}
384335
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)
336+ template <typename record_t , typename T, typename ... Ts>
337+ [[nodiscard]] constexpr inline std::size_t fields_size (const record_t & s, T&& field, Ts&&... fields)
388338{
389- offset = load_fields (r, parsing_context, offset, std::forward<T>(field));
390- return load_fields (r, parsing_context, offset, std::forward<Ts>(fields)...);
339+ return fields_size (s, std::forward<T>(field)) + fields_size (s, std::forward<Ts>(fields)...);
391340}
392341
393- SPLIT_FIELDS (std::size_t , load_record, load_fields, );
342+ SPLIT_FIELDS ([[nodiscard]] constexpr std::size_t , composite_size, fields_size, const );
394343
395- template <typename record_t >
396- constexpr record_t load_record ( auto && parsing_context, [[maybe_unused]] std::size_t offset )
344+ template <typename composite_t >
345+ consteval std::size_t composite_size ( )
397346{
398- record_t r;
399- load_record (r, std::forward<decltype (parsing_context)>(parsing_context), offset);
400- return r;
347+ return composite_size (composite_t {});
401348}
402349
403350} // namespace cpp_utils::reflexion
0 commit comments