@@ -711,16 +711,16 @@ struct handler_tuple;
711711
712712template < class P , template <class ...> class L , class ... V, std::size_t ... I >
713713struct handler_tuple < P, L<V...>, mp11::index_sequence<I...> >
714- : handler_tuple_element< I, get_handler<V, P> >
714+ : handler_tuple_element<I, V >
715715 ...
716716{
717717 handler_tuple ( handler_tuple const & ) = delete ;
718718 handler_tuple& operator =( handler_tuple const & ) = delete ;
719719
720720 template < class Access , class T >
721721 handler_tuple ( Access access, T* pv, P* pp )
722- : handler_tuple_element< I, get_handler<V, P> >(
723- access ( pv, mp11::mp_int <I>() ),
722+ : handler_tuple_element<I, V >(
723+ access ( pv, mp11::mp_size_t <I>() ),
724724 pp )
725725 ...
726726 { }
@@ -803,10 +803,17 @@ class converting_handler<tuple_conversion_tag, T, P>
803803{
804804
805805private:
806+ using ElementTypes = tuple_element_list<T>;
807+
808+ template <class V >
809+ using ElementHandler = get_handler<V, converting_handler>;
810+ using InnerHandlers = mp11::mp_transform<ElementHandler, ElementTypes>;
811+ using HandlerTuple = handler_tuple<converting_handler, InnerHandlers>;
812+
806813 T* value_;
807814 P* parent_;
808815
809- handler_tuple< converting_handler, tuple_element_list<T> > handlers_;
816+ HandlerTuple handlers_;
810817 int inner_active_ = -1 ;
811818
812819public:
@@ -874,7 +881,7 @@ class converting_handler<tuple_conversion_tag, T, P>
874881
875882 struct do_on_array_begin
876883 {
877- handler_tuple< converting_handler, tuple_element_list<T> > & handlers;
884+ HandlerTuple & handlers;
878885 system::error_code& ec;
879886
880887 template < class I >
@@ -905,7 +912,7 @@ class converting_handler<tuple_conversion_tag, T, P>
905912
906913 struct do_on_array_end
907914 {
908- handler_tuple< converting_handler, tuple_element_list<T> > & handlers;
915+ HandlerTuple & handlers;
909916 system::error_code& ec;
910917
911918 template < class I >
@@ -966,6 +973,13 @@ using struct_element_list = mp11::mp_transform_q<
966973
967974struct struct_accessor
968975{
976+ template < class T >
977+ auto operator ()( T*, mp11::mp_size< described_members<T> > ) const
978+ -> void*
979+ {
980+ return nullptr ;
981+ }
982+
969983 template < class T , class I >
970984 auto operator ()( T* t, I ) const
971985 -> described_member_t<T, mp11::mp_at< described_members<T>, I> >*
@@ -976,16 +990,132 @@ struct struct_accessor
976990 }
977991};
978992
979- template < class F >
980993struct struct_key_searcher
981994{
982- F fn;
995+ string_view key;
996+ int & found;
997+ int index = 0 ;
998+
999+ struct_key_searcher (string_view key, int & found) noexcept
1000+ : key(key), found(found)
1001+ {}
9831002
9841003 template < class D >
9851004 void
986- operator ()( D ) const
1005+ operator ()( D )
1006+ {
1007+ if ( key == D::name )
1008+ found = index;
1009+ ++index;
1010+ }
1011+ };
1012+
1013+ template <class P >
1014+ struct ignoring_handler
1015+ {
1016+ P* parent_;
1017+ std::size_t array_depth_ = 0 ;
1018+ std::size_t object_depth_ = 0 ;
1019+
1020+ ignoring_handler (ignoring_handler const &) = delete ;
1021+ ignoring_handler& operator =(ignoring_handler const &) = delete ;
1022+
1023+ ignoring_handler (void *, P* p) noexcept
1024+ : parent_(p)
1025+ {}
1026+
1027+ bool on_object_begin (system::error_code&)
1028+ {
1029+ ++object_depth_;
1030+ return true ;
1031+ }
1032+
1033+ bool on_object_end (system::error_code& ec)
1034+ {
1035+ BOOST_ASSERT ( object_depth_ > 0 );
1036+ --object_depth_;
1037+
1038+ if ( (array_depth_ + object_depth_) == 0 )
1039+ return parent_->signal_value (ec);
1040+ return true ;
1041+ }
1042+
1043+ bool on_array_begin (system::error_code&)
1044+ {
1045+ ++array_depth_;
1046+ return true ;
1047+ }
1048+
1049+ bool on_array_end (system::error_code& ec)
1050+ {
1051+ BOOST_ASSERT ( array_depth_ > 0 );
1052+ --array_depth_;
1053+
1054+ if ( (array_depth_ + object_depth_) == 0 )
1055+ return parent_->signal_end (ec);
1056+ return true ;
1057+ }
1058+
1059+ bool on_key_part (system::error_code&, string_view)
1060+ {
1061+ return true ;
1062+ }
1063+
1064+ bool on_key (system::error_code&, string_view)
1065+ {
1066+ return true ;
1067+ }
1068+
1069+ bool on_string_part (system::error_code&, string_view)
1070+ {
1071+ return true ;
1072+ }
1073+
1074+ bool on_string (system::error_code& ec, string_view)
9871075 {
988- fn ( D::name ) ;
1076+ if ( (array_depth_ + object_depth_) == 0 )
1077+ return parent_->signal_value (ec);
1078+ return true ;
1079+ }
1080+
1081+ bool on_number_part (system::error_code&)
1082+ {
1083+ return true ;
1084+ }
1085+
1086+ bool on_int64 (system::error_code& ec, std::int64_t )
1087+ {
1088+ if ( (array_depth_ + object_depth_) == 0 )
1089+ return parent_->signal_value (ec);
1090+ return true ;
1091+ }
1092+
1093+ bool on_uint64 (system::error_code& ec, std::uint64_t )
1094+ {
1095+ if ( (array_depth_ + object_depth_) == 0 )
1096+ return parent_->signal_value (ec);
1097+ return true ;
1098+ }
1099+
1100+ bool on_double (system::error_code& ec, double )
1101+ {
1102+ if ( (array_depth_ + object_depth_) == 0 )
1103+ return parent_->signal_value (ec);
1104+ return true ;
1105+ }
1106+
1107+ bool on_bool (system::error_code& ec, bool )
1108+ {
1109+ if ( (array_depth_ + object_depth_) == 0 )
1110+ return parent_->signal_value (ec);
1111+ return true ;
1112+ }
1113+
1114+ bool on_null (system::error_code& ec)
1115+ {
1116+ if ( (array_depth_ + object_depth_) == 0 )
1117+ return parent_->signal_value (ec);
1118+ return true ;
9891119 }
9901120};
9911121
@@ -1000,14 +1130,22 @@ class converting_handler<described_class_conversion_tag, V, P>
10001130#else
10011131
10021132private:
1133+ using Dm = described_members<V>;
1134+ using Dt = struct_element_list<V>;
1135+
1136+ template <class T >
1137+ using MemberHandler = get_handler<T, converting_handler>;
1138+ using InnerHandlers = mp11::mp_push_back<
1139+ mp11::mp_transform<MemberHandler, Dt>,
1140+ ignoring_handler<converting_handler> >;
1141+ using InnerCount = mp11::mp_size<InnerHandlers>;
1142+
10031143 V* value_;
10041144 P* parent_;
10051145
10061146 std::string key_;
10071147
1008- using Dm = described_members<V>;
1009-
1010- handler_tuple< converting_handler, struct_element_list<V> > handlers_;
1148+ handler_tuple<converting_handler, InnerHandlers> handlers_;
10111149 int inner_active_ = -1 ;
10121150 std::size_t activated_ = 0 ;
10131151
@@ -1019,23 +1157,27 @@ class converting_handler<described_class_conversion_tag, V, P>
10191157 : value_(v), parent_(p), handlers_(struct_accessor(), v, this)
10201158 {}
10211159
1022- struct is_optional_checker
1160+ struct is_required_checker
10231161 {
1162+ bool operator ()( mp11::mp_size<Dt> ) const noexcept
1163+ {
1164+ return false ;
1165+ }
1166+
10241167 template < class I >
1025- bool operator ()( I ) const noexcept
1168+ auto operator ()( I ) const noexcept
10261169 {
1027- using L = struct_element_list<V>;
1028- using T = mp11::mp_at<L, I>;
1170+ using T = mp11::mp_at<Dt, I>;
10291171 return !is_optional_like<T>::value;
10301172 }
10311173 };
10321174
10331175 bool signal_value (system::error_code&)
10341176 {
10351177 BOOST_ASSERT ( inner_active_ >= 0 );
1036- bool required_member = mp11::mp_with_index< mp11::mp_size<Dm> >(
1178+ bool required_member = mp11::mp_with_index<InnerCount >(
10371179 inner_active_,
1038- is_optional_checker {});
1180+ is_required_checker {});
10391181 if ( required_member )
10401182 ++activated_;
10411183
@@ -1060,7 +1202,7 @@ class converting_handler<described_class_conversion_tag, V, P>
10601202 auto f = [&](auto & handler) { return handler.fn ; }; \
10611203 using F = decltype (f); \
10621204 using H = decltype (handlers_); \
1063- return mp11::mp_with_index< mp11::mp_size<Dm> >( \
1205+ return mp11::mp_with_index<InnerCount >( \
10641206 inner_active_, \
10651207 tuple_handler_op_invoker<H, F>{handlers_, f} );
10661208
@@ -1076,9 +1218,8 @@ class converting_handler<described_class_conversion_tag, V, P>
10761218 {
10771219 if ( inner_active_ < 0 )
10781220 {
1079- using L = struct_element_list<V>;
1080- using C = mp11::mp_count_if<L, is_optional_like>;
1081- constexpr int N = mp11::mp_size<L>::value - C::value;
1221+ using C = mp11::mp_count_if<Dt, is_optional_like>;
1222+ constexpr int N = mp11::mp_size<Dt>::value - C::value;
10821223 if ( activated_ < N )
10831224 {
10841225 BOOST_JSON_FAIL ( ec, error::size_mismatch );
@@ -1129,24 +1270,8 @@ class converting_handler<described_class_conversion_tag, V, P>
11291270 key = key_;
11301271 }
11311272
1132- int i = 0 ;
1133-
1134- auto f = [&](char const * name)
1135- {
1136- if ( key == name )
1137- inner_active_ = i;
1138- ++i;
1139- };
1140-
1141- mp11::mp_for_each<Dm>(
1142- struct_key_searcher<decltype (f)>{f} );
1143-
1144- if ( inner_active_ < 0 )
1145- {
1146- BOOST_JSON_FAIL (ec, error::unknown_name);
1147- return false ;
1148- }
1149-
1273+ inner_active_ = InnerCount::value - 1 ;
1274+ mp11::mp_for_each<Dm>( struct_key_searcher (key, inner_active_) );
11501275 return true ;
11511276 }
11521277
0 commit comments