@@ -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 ) \
@@ -344,60 +310,62 @@ inline constexpr std::size_t count_members
344310namespace cpp_utils ::reflexion
345311{
346312
347- SPLIT_FIELDS_FW_DECL (std::size_t , load_record, );
348-
349-
350- template <typename field_t >
351- struct is_field : std::false_type
313+ struct field_tag_t
352314{
353315};
354316
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)
317+ template <typename composite_t >
318+ consteval auto is_field ()
360319{
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 );
320+ if constexpr (requires { typename composite_t ::field_tag; })
321+ {
322+ return true ;
323+ }
324+ else
325+ {
326+ return false ;
327+ }
364328}
365329
330+ template <typename composite_t >
331+ inline constexpr bool is_field_v = is_field<composite_t >();
366332
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)
333+ template <typename T>
334+ inline constexpr std::size_t count_members = details::MemberCounter<T>();
335+
336+ SPLIT_FIELDS_FW_DECL ([[nodiscard]] constexpr std::size_t , composite_size, const );
337+ template <typename composite_t >
338+ consteval std::size_t composite_size ();
339+
340+ template <typename field_t >
341+ [[nodiscard]] consteval std::size_t field_size ()
369342{
370- return load_field (r, parsing_context, offset, field);
343+ if constexpr (std::is_bounded_array_v<field_t >)
344+ return sizeof (field_t )*std::extent_v<field_t >;
345+ return sizeof (field_t );
371346}
372347
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)
348+ [[nodiscard]] constexpr inline std::size_t fields_size (const auto & , auto & field)
376349{
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);
350+ using Field_t = std::decay_t <decltype (field)>;
351+ if constexpr (std::is_compound_v<Field_t> && ! std::is_bounded_array_v<Field_t> && !is_field_v<Field_t>)
352+ return composite_size<Field_t>();
381353 else
382- return _load_field (r, parsing_context, offset, std::forward<T>(field) );
354+ return field_size<Field_t>( );
383355}
384356
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)
357+ template <typename record_t , typename T, typename ... Ts>
358+ [[nodiscard]] constexpr inline std::size_t fields_size (const record_t & s, T&& field, Ts&&... fields)
388359{
389- offset = load_fields (r, parsing_context, offset, std::forward<T>(field));
390- return load_fields (r, parsing_context, offset, std::forward<Ts>(fields)...);
360+ return fields_size (s, std::forward<T>(field)) + fields_size (s, std::forward<Ts>(fields)...);
391361}
392362
393- SPLIT_FIELDS (std::size_t , load_record, load_fields, );
363+ SPLIT_FIELDS ([[nodiscard]] constexpr std::size_t , composite_size, fields_size, const );
394364
395- template <typename record_t >
396- constexpr record_t load_record ( auto && parsing_context, [[maybe_unused]] std::size_t offset )
365+ template <typename composite_t >
366+ consteval std::size_t composite_size ( )
397367{
398- record_t r;
399- load_record (r, std::forward<decltype (parsing_context)>(parsing_context), offset);
400- return r;
368+ return composite_size (composite_t {});
401369}
402370
403371} // namespace cpp_utils::reflexion
0 commit comments