Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:59

0001 //
0002 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
0003 // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
0004 //
0005 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0006 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 // Official repository: https://github.com/boostorg/json
0009 //
0010 
0011 #ifndef BOOST_JSON_DETAIL_PARSE_INTO_HPP
0012 #define BOOST_JSON_DETAIL_PARSE_INTO_HPP
0013 
0014 #include <boost/json/detail/config.hpp>
0015 
0016 #include <boost/json/error.hpp>
0017 #include <boost/json/conversion.hpp>
0018 #include <boost/describe/enum_from_string.hpp>
0019 
0020 #include <vector>
0021 
0022 /*
0023  * This file contains the majority of parse_into functionality, specifically
0024  * the implementation of dedicated handlers for different generic categories of
0025  * types.
0026  *
0027  * At the core of parse_into is the specialisation basic_parser<
0028  * detail::into_handler<T> >. detail::into_handler<T> is a handler for
0029  * basic_parser. It directly handles events on_comment_part and on_comment (by
0030  * ignoring them), on_document_begin (by enabling the nested dedicated
0031  * handler), and on_document_end (by disabling the nested handler).
0032  *
0033  * Every other event is handled by the nested handler, which has the type
0034  * get_handler< T, into_handler<T> >. The second parameter is the parent
0035  * handler (in this case, it's the top handler, into_handler<T>). The type is
0036  * actually an alias to class template converting_handler, which has a separate
0037  * specialisation for every conversion category from the list of generic
0038  * conversion categories (e.g. sequence_conversion_tag, tuple_conversion_tag,
0039  * etc.) Instantiations of the template store a pointer to the parent handler
0040  * and a pointer to the value T.
0041  *
0042  * The nested handler handles specific parser events by setting error_code to
0043  * an appropriate value, if it receives an event it isn't supposed to handle
0044  * (e.g. a number handler getting an on_string event), and also updates the
0045  * value when appropriate. Note that they never need to handle on_comment_part,
0046  * on_comment, on_document_begin, and on_document_end events, as those are
0047  * always handled by the top handler into_handler<T>.
0048  *
0049  * When the nested handler receives an event that completes the current value,
0050  * it is supposed to call its parent's signal_value member function. This is
0051  * necessary for correct handling of composite types (e.g. sequences).
0052  *
0053  * Finally, nested handlers should always call parent's signal_end member
0054  * function if they don't handle on_array_end themselves. This is necessary
0055  * to correctly handle nested composites (e.g. sequences inside sequences).
0056  * signal_end can return false and set error state when the containing parser
0057  * requires more elements.
0058  *
0059  * converting_handler instantiations for composite categories of types have
0060  * their own nested handlers, to which they themselves delegate events. For
0061  * complex types you will get a tree of handlers with into_handler<T> as the
0062  * root and handlers for scalars as leaves.
0063  *
0064  * To reiterate, only into_handler has to handle on_comment_part, on_comment,
0065  * on_document_begin, and on_document_end; only handlers for composites and
0066  * into_handler has to provide signal_value and signal_end; all handlers
0067  * except for into_handler have to call their parent's signal_end from
0068  * their on_array_begin, if they don't handle it themselves; once a handler
0069  * receives an event that finishes its current value, it should call its
0070  * parent's signal_value.
0071  */
0072 
0073 namespace boost {
0074 namespace json {
0075 namespace detail {
0076 
0077 template< class Impl, class T, class Parent >
0078 class converting_handler;
0079 
0080 // get_handler
0081 template< class V, class P >
0082 using get_handler = converting_handler< generic_conversion_category<V>, V, P >;
0083 
0084 template<error E> class handler_error_base
0085 {
0086 public:
0087 
0088     handler_error_base() = default;
0089 
0090     handler_error_base( handler_error_base const& ) = delete;
0091     handler_error_base& operator=( handler_error_base const& ) = delete;
0092 
0093 public:
0094 
0095     bool on_object_begin( error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
0096     bool on_array_begin( error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
0097     bool on_array_end( error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
0098     bool on_string_part( error_code& ec, string_view ) { BOOST_JSON_FAIL( ec, E ); return false; }
0099     bool on_string( error_code& ec, string_view ) { BOOST_JSON_FAIL( ec, E ); return false; }
0100     bool on_number_part( error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
0101     bool on_int64( error_code& ec, std::int64_t ) { BOOST_JSON_FAIL( ec, E ); return false; }
0102     bool on_uint64( error_code& ec, std::uint64_t ) { BOOST_JSON_FAIL( ec, E ); return false; }
0103     bool on_double( error_code& ec, double ) { BOOST_JSON_FAIL( ec, E ); return false; }
0104     bool on_bool( error_code& ec, bool ) { BOOST_JSON_FAIL( ec, E ); return false; }
0105     bool on_null( error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
0106 
0107     // LCOV_EXCL_START
0108     // parses that can't handle this would fail at on_object_begin
0109     bool on_object_end( error_code& ) { BOOST_ASSERT( false ); return false; }
0110     bool on_key_part( error_code& ec, string_view ) { BOOST_JSON_FAIL( ec, E ); return false; }
0111     bool on_key( error_code& ec, string_view ) { BOOST_JSON_FAIL( ec, E ); return false; }
0112     // LCOV_EXCL_START
0113 };
0114 
0115 template< class P, error E >
0116 class scalar_handler
0117     : public handler_error_base<E>
0118 {
0119 protected:
0120     P* parent_;
0121 
0122 public:
0123     scalar_handler(scalar_handler const&) = delete;
0124     scalar_handler& operator=(scalar_handler const&) = delete;
0125 
0126     scalar_handler(P* p): parent_( p )
0127     {}
0128 
0129     bool on_array_end( error_code& ec )
0130     {
0131         return parent_->signal_end(ec);
0132     }
0133 };
0134 
0135 template< class D, class V, class P, error E >
0136 class composite_handler
0137 {
0138 protected:
0139     using inner_handler_type = get_handler<V, D>;
0140 
0141     P* parent_;
0142 #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
0143 # pragma GCC diagnostic push
0144 # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
0145 #endif
0146     V next_value_ = {};
0147     inner_handler_type inner_;
0148     bool inner_active_ = false;
0149 
0150 public:
0151     composite_handler( composite_handler const& ) = delete;
0152     composite_handler& operator=( composite_handler const& ) = delete;
0153 
0154     composite_handler( P* p )
0155         : parent_(p), inner_( &next_value_, static_cast<D*>(this) )
0156     {}
0157 #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
0158 # pragma GCC diagnostic pop
0159 #endif
0160 
0161     bool signal_end(error_code&)
0162     {
0163         inner_active_ = false;
0164         parent_->signal_value();
0165         return true;
0166     }
0167 
0168 #define BOOST_JSON_INVOKE_INNER(f) \
0169     if( !inner_active_ ) { \
0170         BOOST_JSON_FAIL(ec, E); \
0171         return false; \
0172     } \
0173     else \
0174         return inner_.f
0175 
0176     bool on_object_begin( error_code& ec )
0177     {
0178         BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
0179     }
0180 
0181     bool on_object_end( error_code& ec )
0182     {
0183         BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
0184     }
0185 
0186     bool on_array_begin( error_code& ec )
0187     {
0188         BOOST_JSON_INVOKE_INNER( on_array_begin(ec) );
0189     }
0190 
0191     bool on_array_end( error_code& ec )
0192     {
0193         BOOST_JSON_INVOKE_INNER( on_array_end(ec) );
0194     }
0195 
0196     bool on_key_part( error_code& ec, string_view sv )
0197     {
0198         BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
0199     }
0200 
0201     bool on_key( error_code& ec, string_view sv )
0202     {
0203         BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
0204     }
0205 
0206     bool on_string_part( error_code& ec, string_view sv )
0207     {
0208         BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
0209     }
0210 
0211     bool on_string( error_code& ec, string_view sv )
0212     {
0213         BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
0214     }
0215 
0216     bool on_number_part( error_code& ec )
0217     {
0218         BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
0219     }
0220 
0221     bool on_int64( error_code& ec, std::int64_t v )
0222     {
0223         BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
0224     }
0225 
0226     bool on_uint64( error_code& ec, std::uint64_t v )
0227     {
0228         BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
0229     }
0230 
0231     bool on_double( error_code& ec, double v )
0232     {
0233         BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
0234     }
0235 
0236     bool on_bool( error_code& ec, bool v )
0237     {
0238         BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
0239     }
0240 
0241     bool on_null( error_code& ec )
0242     {
0243         BOOST_JSON_INVOKE_INNER( on_null(ec) );
0244     }
0245 
0246 #undef BOOST_JSON_INVOKE_INNER
0247 };
0248 
0249 // integral handler
0250 template<class V,
0251 typename std::enable_if<std::is_signed<V>::value, int>::type = 0>
0252 bool integral_in_range( std::int64_t v )
0253 {
0254     return v >= (std::numeric_limits<V>::min)() && v <= (std::numeric_limits<V>::max)();
0255 }
0256 
0257 template<class V,
0258 typename std::enable_if<!std::is_signed<V>::value, int>::type = 0>
0259 bool integral_in_range( std::int64_t v )
0260 {
0261     return v >= 0 && static_cast<std::uint64_t>( v ) <= (std::numeric_limits<V>::max)();
0262 }
0263 
0264 template<class V>
0265 bool integral_in_range( std::uint64_t v )
0266 {
0267     return v <= static_cast<typename std::make_unsigned<V>::type>( (std::numeric_limits<V>::max)() );
0268 }
0269 
0270 template< class V, class P >
0271 class converting_handler<integral_conversion_tag, V, P>
0272     : public scalar_handler<P, error::not_integer>
0273 {
0274 private:
0275     V* value_;
0276 
0277 public:
0278     converting_handler( V* v, P* p )
0279         : converting_handler::scalar_handler(p)
0280         , value_(v)
0281     {}
0282 
0283     bool on_number_part( error_code& )
0284     {
0285         return true;
0286     }
0287 
0288     bool on_int64( error_code& ec, std::int64_t v )
0289     {
0290         if( !integral_in_range<V>( v ) )
0291         {
0292             BOOST_JSON_FAIL( ec, error::not_exact );
0293             return false;
0294         }
0295 
0296         *value_ = static_cast<V>( v );
0297 
0298         this->parent_->signal_value();
0299         return true;
0300     }
0301 
0302     bool on_uint64( error_code& ec, std::uint64_t v )
0303     {
0304         if( !integral_in_range<V>( v ) )
0305         {
0306             BOOST_JSON_FAIL( ec, error::not_exact );
0307             return false;
0308         }
0309 
0310         *value_ = static_cast<V>( v );
0311 
0312         this->parent_->signal_value();
0313         return true;
0314     }
0315 };
0316 
0317 // floating point handler
0318 template< class V, class P>
0319 class converting_handler<floating_point_conversion_tag, V, P>
0320     : public scalar_handler<P, error::not_double>
0321 {
0322 private:
0323     V* value_;
0324 
0325 public:
0326     converting_handler( V* v, P* p )
0327         : converting_handler::scalar_handler(p)
0328         , value_(v)
0329     {}
0330 
0331     bool on_number_part( error_code& )
0332     {
0333         return true;
0334     }
0335 
0336     bool on_int64( error_code&, std::int64_t v )
0337     {
0338         *value_ = static_cast<V>( v );
0339 
0340         this->parent_->signal_value();
0341         return true;
0342     }
0343 
0344     bool on_uint64( error_code&, std::uint64_t v )
0345     {
0346         *value_ = static_cast<V>( v );
0347 
0348         this->parent_->signal_value();
0349         return true;
0350     }
0351 
0352     bool on_double( error_code&, double v )
0353     {
0354         *value_ = static_cast<V>( v );
0355 
0356         this->parent_->signal_value();
0357         return true;
0358     }
0359 };
0360 
0361 // string handler
0362 template< class V, class P >
0363 class converting_handler<string_like_conversion_tag, V, P>
0364     : public scalar_handler<P, error::not_string>
0365 {
0366 private:
0367     V* value_;
0368     bool cleared_ = false;
0369 
0370 public:
0371     converting_handler( V* v, P* p )
0372         : converting_handler::scalar_handler(p)
0373         , value_(v)
0374     {}
0375 
0376     bool on_string_part( error_code&, string_view sv )
0377     {
0378         if( !cleared_ )
0379         {
0380             cleared_ = true;
0381             value_->clear();
0382         }
0383 
0384         value_->append( sv.begin(), sv.end() );
0385         return true;
0386     }
0387 
0388     bool on_string( error_code&, string_view sv )
0389     {
0390         if( !cleared_ )
0391             value_->clear();
0392         else
0393             cleared_ = false;
0394 
0395         value_->append( sv.begin(), sv.end() );
0396 
0397         this->parent_->signal_value();
0398         return true;
0399     }
0400 };
0401 
0402 // bool handler
0403 template< class V, class P >
0404 class converting_handler<bool_conversion_tag, V, P>
0405     : public scalar_handler<P, error::not_bool>
0406 {
0407 private:
0408     V* value_;
0409 
0410 public:
0411     converting_handler( V* v, P* p )
0412         : converting_handler::scalar_handler(p)
0413         , value_(v)
0414     {}
0415 
0416     bool on_bool( error_code&, bool v )
0417     {
0418         *value_ = v;
0419 
0420         this->parent_->signal_value();
0421         return true;
0422     }
0423 };
0424 
0425 // null handler
0426 template< class V, class P >
0427 class converting_handler<null_like_conversion_tag, V, P>
0428     : public scalar_handler<P, error::not_null>
0429 {
0430 private:
0431     V* value_;
0432 
0433 public:
0434     converting_handler( V* v, P* p )
0435         : converting_handler::scalar_handler(p)
0436         , value_(v)
0437     {}
0438 
0439     bool on_null( error_code& )
0440     {
0441         *value_ = {};
0442 
0443         this->parent_->signal_value();
0444         return true;
0445     }
0446 };
0447 
0448 // described enum handler
0449 template< class V, class P >
0450 class converting_handler<described_enum_conversion_tag, V, P>
0451     : public scalar_handler<P, error::not_string>
0452 {
0453 #ifndef BOOST_DESCRIBE_CXX14
0454 
0455     static_assert(
0456         sizeof(V) == 0, "Enum support for parse_into requires C++14" );
0457 
0458 #else
0459 
0460 private:
0461     V* value_;
0462     std::string name_;
0463 
0464 public:
0465     converting_handler( V* v, P* p )
0466         : converting_handler::scalar_handler(p)
0467         , value_(v)
0468     {}
0469 
0470     bool on_string_part( error_code&, string_view sv )
0471     {
0472         name_.append( sv.begin(), sv.end() );
0473         return true;
0474     }
0475 
0476     bool on_string( error_code& ec, string_view sv )
0477     {
0478         string_view name = sv;
0479         if( !name_.empty() )
0480         {
0481             name_.append( sv.begin(), sv.end() );
0482             name = name_;
0483         }
0484 
0485         if( !describe::enum_from_string(name, *value_) )
0486         {
0487             BOOST_JSON_FAIL(ec, error::unknown_name);
0488             return false;
0489         }
0490 
0491         this->parent_->signal_value();
0492         return true;
0493     }
0494 
0495 #endif // BOOST_DESCRIBE_CXX14
0496 };
0497 
0498 template< class V, class P >
0499 class converting_handler<no_conversion_tag, V, P>
0500 {
0501     static_assert( sizeof(V) == 0, "This type is not supported" );
0502 };
0503 
0504 // sequence handler
0505 template< class It >
0506 bool check_inserter( It l, It r )
0507 {
0508     return l == r;
0509 }
0510 
0511 template< class It1, class It2 >
0512 std::true_type check_inserter( It1, It2 )
0513 {
0514     return {};
0515 }
0516 
0517 template<class T>
0518 void
0519 clear_container(
0520     T&,
0521     mp11::mp_int<2>)
0522 {
0523 }
0524 
0525 template<class T>
0526 void
0527 clear_container(
0528     T& target,
0529     mp11::mp_int<1>)
0530 {
0531     target.clear();
0532 }
0533 
0534 template<class T>
0535 void
0536 clear_container(
0537     T& target,
0538     mp11::mp_int<0>)
0539 {
0540     target.clear();
0541 }
0542 
0543 template< class V, class P >
0544 class converting_handler<sequence_conversion_tag, V, P>
0545     : public composite_handler<
0546         converting_handler<sequence_conversion_tag, V, P>,
0547         detail::value_type<V>,
0548         P,
0549         error::not_array>
0550 {
0551 private:
0552     V* value_;
0553 
0554     using Inserter = decltype(
0555         detail::inserter(*value_, inserter_implementation<V>()) );
0556     Inserter inserter;
0557 
0558 public:
0559     converting_handler( V* v, P* p )
0560         : converting_handler::composite_handler(p)
0561         , value_(v)
0562         , inserter( detail::inserter(*value_, inserter_implementation<V>()) )
0563     {}
0564 
0565     void signal_value()
0566     {
0567         *inserter++ = std::move(this->next_value_);
0568 #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
0569 # pragma GCC diagnostic push
0570 # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
0571 #endif
0572         this->next_value_ = {};
0573 #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
0574 # pragma GCC diagnostic pop
0575 #endif
0576     }
0577 
0578     bool signal_end(error_code& ec)
0579     {
0580         if( !check_inserter( inserter, value_->end() ) )
0581         {
0582             BOOST_JSON_FAIL( ec, error::size_mismatch );
0583             return false;
0584         }
0585 
0586         inserter = detail::inserter(*value_, inserter_implementation<V>());
0587 
0588         return converting_handler::composite_handler::signal_end(ec);
0589     }
0590 
0591     bool on_array_begin( error_code& ec )
0592     {
0593         if( this->inner_active_ )
0594             return this->inner_.on_array_begin( ec );
0595 
0596         this->inner_active_ = true;
0597         clear_container( *value_, inserter_implementation<V>() );
0598         return true;
0599     }
0600 
0601     bool on_array_end( error_code& ec )
0602     {
0603         if( this->inner_active_ )
0604             return this->inner_.on_array_end( ec );
0605 
0606         return this->parent_->signal_end(ec);
0607     }
0608 };
0609 
0610 // map handler
0611 template< class V, class P >
0612 class converting_handler<map_like_conversion_tag, V, P>
0613     : public composite_handler<
0614         converting_handler<map_like_conversion_tag, V, P>,
0615         detail::mapped_type<V>,
0616         P,
0617         error::not_object>
0618 {
0619 private:
0620     V* value_;
0621     std::string key_;
0622 
0623 public:
0624     converting_handler( V* v, P* p )
0625         : converting_handler::composite_handler(p), value_(v)
0626     {}
0627 
0628     void signal_value()
0629     {
0630         value_->emplace( std::move(key_), std::move(this->next_value_) );
0631 
0632         key_ = {};
0633         this->next_value_ = {};
0634 
0635         this->inner_active_ = false;
0636     }
0637 
0638     bool on_object_begin( error_code& ec )
0639     {
0640         if( this->inner_active_ )
0641             return this->inner_.on_object_begin(ec);
0642 
0643         clear_container( *value_, inserter_implementation<V>() );
0644         return true;
0645     }
0646 
0647     bool on_object_end( error_code& ec )
0648     {
0649         if( this->inner_active_ )
0650             return this->inner_.on_object_end(ec);
0651 
0652         this->parent_->signal_value();
0653         return true;
0654     }
0655 
0656     bool on_array_end( error_code& ec )
0657     {
0658         if( this->inner_active_ )
0659             return this->inner_.on_array_end(ec);
0660 
0661         return this->parent_->signal_end(ec);
0662     }
0663 
0664     bool on_key_part( error_code& ec, string_view sv )
0665     {
0666         if( this->inner_active_ )
0667             return this->inner_.on_key_part(ec, sv);
0668 
0669         key_.append( sv.data(), sv.size() );
0670         return true;
0671     }
0672 
0673     bool on_key( error_code& ec, string_view sv )
0674     {
0675         if( this->inner_active_ )
0676             return this->inner_.on_key(ec, sv);
0677 
0678         key_.append( sv.data(), sv.size() );
0679 
0680         this->inner_active_ = true;
0681         return true;
0682     }
0683 };
0684 
0685 // tuple handler
0686 template<std::size_t I, class T>
0687 struct handler_tuple_element
0688 {
0689     template< class... Args >
0690     handler_tuple_element( Args&& ... args )
0691         : t_( static_cast<Args&&>(args)... )
0692     {}
0693 
0694     T t_;
0695 };
0696 
0697 template<std::size_t I, class T>
0698 T&
0699 get( handler_tuple_element<I, T>& e )
0700 {
0701     return e.t_;
0702 }
0703 
0704 template<
0705     class P,
0706     class LV,
0707     class S = mp11::make_index_sequence<mp11::mp_size<LV>::value> >
0708 struct handler_tuple;
0709 
0710 template< class P, template<class...> class L, class... V, std::size_t... I >
0711 struct handler_tuple< P, L<V...>, mp11::index_sequence<I...> >
0712     : handler_tuple_element< I, get_handler<V, P> >
0713     ...
0714 {
0715     handler_tuple( handler_tuple const& ) = delete;
0716     handler_tuple& operator=( handler_tuple const& ) = delete;
0717 
0718     template< class Access, class T >
0719     handler_tuple( Access access, T* pv, P* pp )
0720         : handler_tuple_element< I, get_handler<V, P> >(
0721             access( pv, mp11::mp_int<I>() ),
0722             pp )
0723         ...
0724     { }
0725 };
0726 
0727 #if defined(BOOST_MSVC) && BOOST_MSVC < 1910
0728 
0729 template< class T >
0730 struct tuple_element_list_impl
0731 {
0732     template< class I >
0733     using tuple_element_helper = tuple_element_t<I::value, T>;
0734 
0735     using type = mp11::mp_transform<
0736         tuple_element_helper,
0737         mp11::mp_iota< std::tuple_size<T> > >;
0738 };
0739 template< class T >
0740 using tuple_element_list = typename tuple_element_list_impl<T>::type;
0741 
0742 #else
0743 
0744 template< class I, class T >
0745 using tuple_element_helper = tuple_element_t<I::value, T>;
0746 template< class T >
0747 using tuple_element_list = mp11::mp_transform_q<
0748     mp11::mp_bind_back< tuple_element_helper, T>,
0749     mp11::mp_iota< std::tuple_size<T> > >;
0750 
0751 #endif
0752 
0753 template< class Op, class... Args>
0754 struct handler_op_invoker
0755 {
0756 public:
0757     std::tuple<Args&...> args;
0758 
0759     template< class Handler >
0760     bool
0761     operator()( Handler& handler ) const
0762     {
0763         return (*this)( handler, mp11::index_sequence_for<Args...>() );
0764     }
0765 
0766 private:
0767     template< class Handler, std::size_t... I >
0768     bool
0769     operator()( Handler& handler, mp11::index_sequence<I...> ) const
0770     {
0771         return Op()( handler, std::get<I>(args)... );
0772     }
0773 };
0774 
0775 template< class Handlers, class F >
0776 struct tuple_handler_op_invoker
0777 {
0778     Handlers& handlers;
0779     F fn;
0780 
0781     template< class I >
0782     bool
0783     operator()( I ) const
0784     {
0785         return fn( get<I::value>(handlers) );
0786     }
0787 };
0788 
0789 struct tuple_accessor
0790 {
0791     template< class T, class I >
0792     auto operator()( T* t, I ) const -> tuple_element_t<I::value, T>*
0793     {
0794         using std::get;
0795         return &get<I::value>(*t);
0796     }
0797 };
0798 
0799 template< class T, class P >
0800 class converting_handler<tuple_conversion_tag, T, P>
0801 {
0802 
0803 private:
0804     T* value_;
0805     P* parent_;
0806 
0807     handler_tuple< converting_handler, tuple_element_list<T> > handlers_;
0808     int inner_active_ = -1;
0809 
0810 public:
0811     converting_handler( converting_handler const& ) = delete;
0812     converting_handler& operator=( converting_handler const& ) = delete;
0813 
0814     converting_handler( T* v, P* p )
0815         : value_(v) , parent_(p) , handlers_(tuple_accessor(), v, this)
0816     {}
0817 
0818     void signal_value()
0819     {
0820         ++inner_active_;
0821     }
0822 
0823     bool signal_end(error_code& ec)
0824     {
0825         constexpr int N = std::tuple_size<T>::value;
0826         if( inner_active_ < N )
0827         {
0828             BOOST_JSON_FAIL( ec, error::size_mismatch );
0829             return true;
0830         }
0831 
0832         inner_active_ = -1;
0833         parent_->signal_value();
0834         return true;
0835     }
0836 
0837 #define BOOST_JSON_HANDLE_EVENT(fn) \
0838     struct do_ ## fn \
0839     { \
0840         template< class H, class... Args > \
0841         bool operator()( H& h, Args& ... args ) const \
0842         { \
0843             return h. fn (args...); \
0844         } \
0845     }; \
0846        \
0847     template< class... Args > \
0848     bool fn( error_code& ec, Args&& ... args ) \
0849     { \
0850         if( inner_active_ < 0 ) \
0851         { \
0852             BOOST_JSON_FAIL( ec, error::not_array ); \
0853             return false; \
0854         } \
0855         constexpr int N = std::tuple_size<T>::value; \
0856         if( inner_active_ >= N ) \
0857         { \
0858             BOOST_JSON_FAIL( ec, error::size_mismatch ); \
0859             return false; \
0860         } \
0861         using F = handler_op_invoker< do_ ## fn, error_code, Args...>; \
0862         using H = decltype(handlers_); \
0863         return mp11::mp_with_index<N>( \
0864             inner_active_, \
0865             tuple_handler_op_invoker<H, F>{ \
0866                 handlers_, \
0867                 F{ std::forward_as_tuple(ec, args...) } } ); \
0868     }
0869 
0870     BOOST_JSON_HANDLE_EVENT( on_object_begin );
0871     BOOST_JSON_HANDLE_EVENT( on_object_end );
0872 
0873     struct do_on_array_begin
0874     {
0875         handler_tuple< converting_handler, tuple_element_list<T> >& handlers;
0876         error_code& ec;
0877 
0878         template< class I >
0879         bool operator()( I ) const
0880         {
0881             return get<I::value>(handlers).on_array_begin(ec);
0882         };
0883     };
0884     bool on_array_begin( error_code& ec )
0885     {
0886         if( inner_active_ < 0 )
0887         {
0888             inner_active_ = 0;
0889             return true;
0890         }
0891 
0892         constexpr int N = std::tuple_size<T>::value;
0893 
0894         if( inner_active_ >= N )
0895         {
0896             inner_active_ = 0;
0897             return true;
0898         }
0899 
0900         return mp11::mp_with_index<N>(
0901             inner_active_, do_on_array_begin{handlers_, ec} );
0902     }
0903 
0904     struct do_on_array_end
0905     {
0906         handler_tuple< converting_handler, tuple_element_list<T> >& handlers;
0907         error_code& ec;
0908 
0909         template< class I >
0910         bool operator()( I ) const
0911         {
0912             return get<I::value>(handlers).on_array_end(ec);
0913         };
0914     };
0915     bool on_array_end( error_code& ec )
0916     {
0917         if( inner_active_ < 0 )
0918             return parent_->signal_end(ec);
0919 
0920         constexpr int N = std::tuple_size<T>::value;
0921 
0922         if( inner_active_ >= N )
0923             return signal_end(ec);
0924 
0925         return mp11::mp_with_index<N>(
0926             inner_active_, do_on_array_end{handlers_, ec} );
0927     }
0928 
0929     BOOST_JSON_HANDLE_EVENT( on_key_part );
0930     BOOST_JSON_HANDLE_EVENT( on_key );
0931     BOOST_JSON_HANDLE_EVENT( on_string_part );
0932     BOOST_JSON_HANDLE_EVENT( on_string );
0933     BOOST_JSON_HANDLE_EVENT( on_number_part );
0934     BOOST_JSON_HANDLE_EVENT( on_int64 );
0935     BOOST_JSON_HANDLE_EVENT( on_uint64 );
0936     BOOST_JSON_HANDLE_EVENT( on_double );
0937     BOOST_JSON_HANDLE_EVENT( on_bool );
0938     BOOST_JSON_HANDLE_EVENT( on_null );
0939 
0940 #undef BOOST_JSON_HANDLE_EVENT
0941 };
0942 
0943 // described struct handler
0944 #if defined(BOOST_MSVC) && BOOST_MSVC < 1910
0945 
0946 template< class T >
0947 struct struct_element_list_impl
0948 {
0949     template< class D >
0950     using helper = described_member_t<T, D>;
0951 
0952     using type = mp11::mp_transform<
0953         helper,
0954         describe::describe_members<T, describe::mod_public> >;
0955 };
0956 template< class T >
0957 using struct_element_list = typename struct_element_list_impl<T>::type;
0958 
0959 #else
0960 
0961 template< class T >
0962 using struct_element_list = mp11::mp_transform_q<
0963     mp11::mp_bind_front< described_member_t, T >,
0964     describe::describe_members<T, describe::mod_public> >;
0965 
0966 #endif
0967 
0968 struct struct_accessor
0969 {
0970     template< class T, class I >
0971     auto operator()( T* t, I ) const
0972         -> described_member_t<T,
0973              mp11::mp_at<
0974                  describe::describe_members<T, describe::mod_public>, I> >*
0975     {
0976         using Ds = describe::describe_members<T, describe::mod_public>;
0977         using D = mp11::mp_at<Ds, I>;
0978         return &(t->*D::pointer);
0979     }
0980 };
0981 
0982 template< class F >
0983 struct struct_key_searcher
0984 {
0985     F fn;
0986 
0987     template< class D >
0988     void
0989     operator()( D ) const
0990     {
0991         fn( D::name ) ;
0992     }
0993 };
0994 
0995 template<class V, class P>
0996 class converting_handler<described_class_conversion_tag, V, P>
0997 {
0998 #if !defined(BOOST_DESCRIBE_CXX14)
0999 
1000     static_assert(
1001         sizeof(V) == 0, "Struct support for parse_into requires C++14" );
1002 
1003 #else
1004 
1005 private:
1006     V* value_;
1007     P* parent_;
1008 
1009     std::string key_;
1010 
1011     using Dm = describe::describe_members<V, describe::mod_public>;
1012 
1013     handler_tuple< converting_handler, struct_element_list<V> > handlers_;
1014     int inner_active_ = -1;
1015     std::size_t activated_ = 0;
1016 
1017 public:
1018     converting_handler( converting_handler const& ) = delete;
1019     converting_handler& operator=( converting_handler const& ) = delete;
1020 
1021     converting_handler( V* v, P* p )
1022         : value_(v), parent_(p), handlers_(struct_accessor(), v, this)
1023     {}
1024 
1025     struct is_optional_checker
1026     {
1027         template< class I >
1028         bool operator()( I ) const noexcept
1029         {
1030             using L = struct_element_list<V>;
1031             using T = mp11::mp_at<L, I>;
1032             return !is_optional_like<T>::value;
1033         }
1034     };
1035     void signal_value()
1036     {
1037         BOOST_ASSERT( inner_active_ >= 0 );
1038         bool required_member = mp11::mp_with_index< mp11::mp_size<Dm> >(
1039             inner_active_,
1040             is_optional_checker{});
1041         if( required_member )
1042             ++activated_;
1043 
1044         key_ = {};
1045         inner_active_ = -1;
1046     }
1047 
1048     bool signal_end(error_code&)
1049     {
1050         key_ = {};
1051         inner_active_ = -1;
1052         parent_->signal_value();
1053         return true;
1054     }
1055 
1056 #define BOOST_JSON_INVOKE_INNER(fn) \
1057     if( inner_active_ < 0 ) \
1058     { \
1059         BOOST_JSON_FAIL( ec, error::not_object ); \
1060         return false; \
1061     } \
1062     auto f = [&](auto& handler) { return handler.fn ; }; \
1063     using F = decltype(f); \
1064     using H = decltype(handlers_); \
1065     return mp11::mp_with_index< mp11::mp_size<Dm> >( \
1066             inner_active_, \
1067             tuple_handler_op_invoker<H, F>{handlers_, f} );
1068 
1069     bool on_object_begin( error_code& ec )
1070     {
1071         if( inner_active_ < 0 )
1072             return true;
1073 
1074         BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
1075     }
1076 
1077     bool on_object_end( error_code& ec )
1078     {
1079         if( inner_active_ < 0 )
1080         {
1081             using L = struct_element_list<V>;
1082             using C = mp11::mp_count_if<L, is_optional_like>;
1083             constexpr int N = mp11::mp_size<L>::value - C::value;
1084             if( activated_ < N )
1085             {
1086                 BOOST_JSON_FAIL( ec, error::size_mismatch );
1087                 return false;
1088             }
1089 
1090             parent_->signal_value();
1091             return true;
1092         }
1093 
1094         BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
1095     }
1096 
1097     bool on_array_begin( error_code& ec )
1098     {
1099         BOOST_JSON_INVOKE_INNER( on_array_begin(ec) );
1100     }
1101 
1102     bool on_array_end( error_code& ec )
1103     {
1104         if( inner_active_ < 0 )
1105             return parent_->signal_end(ec);
1106 
1107         BOOST_JSON_INVOKE_INNER( on_array_end(ec) );
1108     }
1109 
1110     bool on_key_part( error_code& ec, string_view sv )
1111     {
1112         if( inner_active_ < 0 )
1113         {
1114             key_.append( sv.data(), sv.size() );
1115             return true;
1116         }
1117 
1118         BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
1119     }
1120 
1121     bool on_key( error_code& ec, string_view sv )
1122     {
1123         if( inner_active_ >= 0 )
1124         {
1125             BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
1126         }
1127 
1128         string_view key = sv;
1129         if( !key_.empty() )
1130         {
1131             key_.append( sv.data(), sv.size() );
1132             key = key_;
1133         }
1134 
1135         int i = 0;
1136 
1137         auto f = [&](char const* name)
1138         {
1139             if( key == name )
1140                 inner_active_ = i;
1141             ++i;
1142         };
1143 
1144         mp11::mp_for_each<Dm>(
1145             struct_key_searcher<decltype(f)>{f} );
1146 
1147         if( inner_active_ < 0 )
1148         {
1149             BOOST_JSON_FAIL(ec, error::unknown_name);
1150             return false;
1151         }
1152 
1153         return true;
1154     }
1155 
1156     bool on_string_part( error_code& ec, string_view sv )
1157     {
1158         BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
1159     }
1160 
1161     bool on_string( error_code& ec, string_view sv )
1162     {
1163         BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
1164     }
1165 
1166     bool on_number_part( error_code& ec )
1167     {
1168         BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
1169     }
1170 
1171     bool on_int64( error_code& ec, std::int64_t v )
1172     {
1173         BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
1174     }
1175 
1176     bool on_uint64( error_code& ec, std::uint64_t v )
1177     {
1178         BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
1179     }
1180 
1181     bool on_double( error_code& ec, double v )
1182     {
1183         BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
1184     }
1185 
1186     bool on_bool( error_code& ec, bool v )
1187     {
1188         BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
1189     }
1190 
1191     bool on_null( error_code& ec )
1192     {
1193         BOOST_JSON_INVOKE_INNER( on_null(ec) );
1194     }
1195 
1196 #undef BOOST_JSON_INVOKE_INNER
1197 
1198 #endif
1199 };
1200 
1201 // variant handler
1202 struct object_begin_handler_event
1203 { };
1204 
1205 struct object_end_handler_event
1206 { };
1207 
1208 struct array_begin_handler_event
1209 { };
1210 
1211 struct array_end_handler_event
1212 { };
1213 
1214 struct key_handler_event
1215 {
1216     std::string value;
1217 };
1218 
1219 struct string_handler_event
1220 {
1221     std::string value;
1222 };
1223 
1224 struct int64_handler_event
1225 {
1226     std::int64_t value;
1227 };
1228 
1229 struct uint64_handler_event
1230 {
1231     std::uint64_t value;
1232 };
1233 
1234 struct double_handler_event
1235 {
1236     double value;
1237 };
1238 
1239 struct bool_handler_event
1240 {
1241     bool value;
1242 };
1243 
1244 struct null_handler_event
1245 { };
1246 
1247 using parse_event = variant2::variant<
1248     object_begin_handler_event,
1249     object_end_handler_event,
1250     array_begin_handler_event,
1251     array_end_handler_event,
1252     key_handler_event,
1253     string_handler_event,
1254     int64_handler_event,
1255     uint64_handler_event,
1256     double_handler_event,
1257     bool_handler_event,
1258     null_handler_event>;
1259 
1260 template< class H >
1261 struct event_visitor
1262 {
1263     H& handler;
1264     error_code& ec;
1265 
1266     bool
1267     operator()(object_begin_handler_event&) const
1268     {
1269         return handler.on_object_begin(ec);
1270     }
1271 
1272     bool
1273     operator()(object_end_handler_event&) const
1274     {
1275         return handler.on_object_end(ec);
1276     }
1277 
1278     bool
1279     operator()(array_begin_handler_event&) const
1280     {
1281         return handler.on_array_begin(ec);
1282     }
1283 
1284     bool
1285     operator()(array_end_handler_event&) const
1286     {
1287         return handler.on_array_end(ec);
1288     }
1289 
1290     bool
1291     operator()(key_handler_event& ev) const
1292     {
1293         return handler.on_key(ec, ev.value);
1294     }
1295 
1296     bool
1297     operator()(string_handler_event& ev) const
1298     {
1299         return handler.on_string(ec, ev.value);
1300     }
1301 
1302     bool
1303     operator()(int64_handler_event& ev) const
1304     {
1305         return handler.on_int64(ec, ev.value);
1306     }
1307 
1308     bool
1309     operator()(uint64_handler_event& ev) const
1310     {
1311         return handler.on_uint64(ec, ev.value);
1312     }
1313 
1314     bool
1315     operator()(double_handler_event& ev) const
1316     {
1317         return handler.on_double(ec, ev.value);
1318     }
1319 
1320     bool
1321     operator()(bool_handler_event& ev) const
1322     {
1323         return handler.on_bool(ec, ev.value);
1324     }
1325 
1326     bool
1327     operator()(null_handler_event&) const
1328     {
1329         return handler.on_null(ec);
1330     }
1331 };
1332 
1333 // L<T...> -> variant< monostate, get_handler<T, P>... >
1334 template< class P, class L >
1335 using inner_handler_variant = mp11::mp_push_front<
1336     mp11::mp_transform_q<
1337         mp11::mp_bind_back<get_handler, P>,
1338         mp11::mp_apply<variant2::variant, L>>,
1339     variant2::monostate>;
1340 
1341 template< class T, class P >
1342 class converting_handler<variant_conversion_tag, T, P>
1343 {
1344 private:
1345     using variant_size = mp11::mp_size<T>;
1346 
1347     T* value_;
1348     P* parent_;
1349 
1350     std::string string_;
1351     std::vector< parse_event > events_;
1352     inner_handler_variant<converting_handler, T> inner_;
1353     int inner_active_ = -1;
1354 
1355 public:
1356     converting_handler( converting_handler const& ) = delete;
1357     converting_handler& operator=( converting_handler const& ) = delete;
1358 
1359     converting_handler( T* v, P* p )
1360         : value_( v )
1361         , parent_( p )
1362     {}
1363 
1364     void signal_value()
1365     {
1366         inner_.template emplace<0>();
1367         inner_active_ = -1;
1368         events_.clear();
1369         parent_->signal_value();
1370     }
1371 
1372     bool signal_end(error_code& ec)
1373     {
1374         return parent_->signal_end(ec);
1375     }
1376 
1377     struct alternative_selector
1378     {
1379         converting_handler* self;
1380 
1381         template< class I >
1382         void
1383         operator()( I ) const
1384         {
1385             using V = mp11::mp_at<T, I>;
1386             auto& v = self->value_->template emplace<I::value>( V{} );
1387             self->inner_.template emplace<I::value + 1>(&v, self);
1388         }
1389     };
1390     void
1391     next_alternative()
1392     {
1393         if( ++inner_active_ >= static_cast<int>(variant_size::value) )
1394             return;
1395 
1396         mp11::mp_with_index< variant_size::value >(
1397             inner_active_, alternative_selector{this} );
1398     }
1399 
1400     struct event_processor
1401     {
1402         converting_handler* self;
1403         error_code& ec;
1404         parse_event& event;
1405 
1406         template< class I >
1407         bool operator()( I ) const
1408         {
1409             auto& handler = variant2::get<I::value + 1>(self->inner_);
1410             using Handler = remove_cvref<decltype(handler)>;
1411             return variant2::visit(
1412                 event_visitor<Handler>{handler, ec}, event );
1413         }
1414     };
1415     bool process_events(error_code& ec)
1416     {
1417         constexpr std::size_t N = variant_size::value;
1418 
1419         // should be pointers not iterators, otherwise MSVC crashes
1420         auto const last = events_.data() + events_.size();
1421         auto first = last - 1;
1422         bool ok = false;
1423 
1424         if( inner_active_ < 0 )
1425             next_alternative();
1426         do
1427         {
1428             if( static_cast<std::size_t>(inner_active_) >= N )
1429             {
1430                 BOOST_JSON_FAIL( ec, error::exhausted_variants );
1431                 return false;
1432             }
1433 
1434             for ( ; first != last; ++first )
1435             {
1436                 ok = mp11::mp_with_index< N >(
1437                     inner_active_, event_processor{this, ec, *first} );
1438                 if( !ok )
1439                 {
1440                     first = events_.data();
1441                     next_alternative();
1442                     ec.clear();
1443                     break;
1444                 }
1445             }
1446         }
1447         while( !ok );
1448 
1449         return true;
1450     }
1451 
1452 #define BOOST_JSON_INVOKE_INNER(ev, ec) \
1453     events_.emplace_back( ev ); \
1454     return process_events(ec);
1455 
1456     bool on_object_begin( error_code& ec )
1457     {
1458         BOOST_JSON_INVOKE_INNER( object_begin_handler_event{}, ec );
1459     }
1460 
1461     bool on_object_end( error_code& ec )
1462     {
1463         BOOST_JSON_INVOKE_INNER( object_end_handler_event{}, ec );
1464     }
1465 
1466     bool on_array_begin( error_code& ec )
1467     {
1468         BOOST_JSON_INVOKE_INNER( array_begin_handler_event{}, ec );
1469     }
1470 
1471     bool on_array_end( error_code& ec )
1472     {
1473         if( !inner_active_ )
1474             return signal_end(ec);
1475 
1476         BOOST_JSON_INVOKE_INNER( array_end_handler_event{}, ec );
1477     }
1478 
1479     bool on_key_part( error_code&, string_view sv )
1480     {
1481         string_.append(sv);
1482         return true;
1483     }
1484 
1485     bool on_key( error_code& ec, string_view sv )
1486     {
1487         string_.append(sv);
1488         BOOST_JSON_INVOKE_INNER( key_handler_event{ std::move(string_) }, ec );
1489     }
1490 
1491     bool on_string_part( error_code&, string_view sv )
1492     {
1493         string_.append(sv);
1494         return true;
1495     }
1496 
1497     bool on_string( error_code& ec, string_view sv )
1498     {
1499         string_.append(sv);
1500         BOOST_JSON_INVOKE_INNER(
1501             string_handler_event{ std::move(string_) }, ec );
1502     }
1503 
1504     bool on_number_part( error_code& )
1505     {
1506         return true;
1507     }
1508 
1509     bool on_int64( error_code& ec, std::int64_t v )
1510     {
1511         BOOST_JSON_INVOKE_INNER( int64_handler_event{v}, ec );
1512     }
1513 
1514     bool on_uint64( error_code& ec, std::uint64_t v )
1515     {
1516         BOOST_JSON_INVOKE_INNER( uint64_handler_event{v}, ec );
1517     }
1518 
1519     bool on_double( error_code& ec, double v )
1520     {
1521         BOOST_JSON_INVOKE_INNER( double_handler_event{v}, ec );
1522     }
1523 
1524     bool on_bool( error_code& ec, bool v )
1525     {
1526         BOOST_JSON_INVOKE_INNER( bool_handler_event{v}, ec );
1527     }
1528 
1529     bool on_null( error_code& ec )
1530     {
1531         BOOST_JSON_INVOKE_INNER( null_handler_event{}, ec );
1532     }
1533 
1534 #undef BOOST_JSON_INVOKE_INNER
1535 };
1536 
1537 // optional handler
1538 template<class V, class P>
1539 class converting_handler<optional_conversion_tag, V, P>
1540 {
1541 private:
1542     using inner_type = value_result_type<V>;
1543     using inner_handler_type = get_handler<inner_type, converting_handler>;
1544 
1545     V* value_;
1546     P* parent_;
1547 
1548     inner_type inner_value_ = {};
1549     inner_handler_type inner_;
1550     bool inner_active_ = false;
1551 
1552 public:
1553     converting_handler( converting_handler const& ) = delete;
1554     converting_handler& operator=( converting_handler const& ) = delete;
1555 
1556     converting_handler( V* v, P* p )
1557         : value_(v), parent_(p), inner_(&inner_value_, this)
1558     {}
1559 
1560     void signal_value()
1561     {
1562         *value_ = std::move(inner_value_);
1563 
1564         inner_active_ = false;
1565         parent_->signal_value();
1566     }
1567 
1568     bool signal_end(error_code& ec)
1569     {
1570         return parent_->signal_end(ec);
1571     }
1572 
1573 #define BOOST_JSON_INVOKE_INNER(fn) \
1574     if( !inner_active_ ) \
1575         inner_active_ = true; \
1576     return inner_.fn;
1577 
1578     bool on_object_begin( error_code& ec )
1579     {
1580         BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
1581     }
1582 
1583     bool on_object_end( error_code& ec )
1584     {
1585         BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
1586     }
1587 
1588     bool on_array_begin( error_code& ec )
1589     {
1590         BOOST_JSON_INVOKE_INNER( on_array_begin(ec) );
1591     }
1592 
1593     bool on_array_end( error_code& ec )
1594     {
1595         if( !inner_active_ )
1596             return signal_end(ec);
1597 
1598         BOOST_JSON_INVOKE_INNER( on_array_end(ec) );
1599     }
1600 
1601     bool on_key_part( error_code& ec, string_view sv )
1602     {
1603         BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
1604     }
1605 
1606     bool on_key( error_code& ec, string_view sv )
1607     {
1608         BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
1609     }
1610 
1611     bool on_string_part( error_code& ec, string_view sv )
1612     {
1613         BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
1614     }
1615 
1616     bool on_string( error_code& ec, string_view sv )
1617     {
1618         BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
1619     }
1620 
1621     bool on_number_part( error_code& ec )
1622     {
1623         BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
1624     }
1625 
1626     bool on_int64( error_code& ec, std::int64_t v )
1627     {
1628         BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
1629     }
1630 
1631     bool on_uint64( error_code& ec, std::uint64_t v )
1632     {
1633         BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
1634     }
1635 
1636     bool on_double( error_code& ec, double v )
1637     {
1638         BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
1639     }
1640 
1641     bool on_bool( error_code& ec, bool v )
1642     {
1643         BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
1644     }
1645 
1646     bool on_null( error_code& ec )
1647     {
1648         if( !inner_active_ )
1649         {
1650             *value_ = {};
1651 
1652             this->parent_->signal_value();
1653             return true;
1654         }
1655         else
1656         {
1657             return inner_.on_null(ec);
1658         }
1659     }
1660 
1661 #undef BOOST_JSON_INVOKE_INNER
1662 };
1663 
1664 // into_handler
1665 template< class V >
1666 class into_handler
1667 {
1668 private:
1669 
1670     using inner_handler_type = get_handler<V, into_handler>;
1671 
1672     inner_handler_type inner_;
1673     bool inner_active_ = true;
1674 
1675 public:
1676 
1677     into_handler( into_handler const& ) = delete;
1678     into_handler& operator=( into_handler const& ) = delete;
1679 
1680 public:
1681 
1682     static constexpr std::size_t max_object_size = object::max_size();
1683     static constexpr std::size_t max_array_size = array::max_size();
1684     static constexpr std::size_t max_key_size = string::max_size();
1685     static constexpr std::size_t max_string_size = string::max_size();
1686 
1687 public:
1688 
1689     explicit into_handler( V* v ): inner_( v, this )
1690     {
1691     }
1692 
1693     void signal_value()
1694     {
1695     }
1696 
1697     bool signal_end(error_code&)
1698     {
1699         return true;
1700     }
1701 
1702     bool on_document_begin( error_code& )
1703     {
1704         return true;
1705     }
1706 
1707     bool on_document_end( error_code& )
1708     {
1709         inner_active_ = false;
1710         return true;
1711     }
1712 
1713 #define BOOST_JSON_INVOKE_INNER(f) \
1714     if( !inner_active_ ) \
1715     { \
1716         BOOST_JSON_FAIL( ec, error::extra_data ); \
1717         return false; \
1718     } \
1719     else \
1720         return inner_.f
1721 
1722     bool on_object_begin( error_code& ec )
1723     {
1724         BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
1725     }
1726 
1727     bool on_object_end( std::size_t, error_code& ec )
1728     {
1729         BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
1730     }
1731 
1732     bool on_array_begin( error_code& ec )
1733     {
1734         BOOST_JSON_INVOKE_INNER( on_array_begin(ec) );
1735     }
1736 
1737     bool on_array_end( std::size_t, error_code& ec )
1738     {
1739         BOOST_JSON_INVOKE_INNER( on_array_end(ec) );
1740     }
1741 
1742     bool on_key_part( string_view sv, std::size_t, error_code& ec )
1743     {
1744         BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
1745     }
1746 
1747     bool on_key( string_view sv, std::size_t, error_code& ec )
1748     {
1749         BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
1750     }
1751 
1752     bool on_string_part( string_view sv, std::size_t, error_code& ec )
1753     {
1754         BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
1755     }
1756 
1757     bool on_string( string_view sv, std::size_t, error_code& ec )
1758     {
1759         BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
1760     }
1761 
1762     bool on_number_part( string_view, error_code& ec )
1763     {
1764         BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
1765     }
1766 
1767     bool on_int64( std::int64_t v, string_view, error_code& ec )
1768     {
1769         BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
1770     }
1771 
1772     bool on_uint64( std::uint64_t v, string_view, error_code& ec )
1773     {
1774         BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
1775     }
1776 
1777     bool on_double( double v, string_view, error_code& ec )
1778     {
1779         BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
1780     }
1781 
1782     bool on_bool( bool v, error_code& ec )
1783     {
1784         BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
1785     }
1786 
1787     bool on_null( error_code& ec )
1788     {
1789         BOOST_JSON_INVOKE_INNER( on_null(ec) );
1790     }
1791 
1792     bool on_comment_part(string_view, error_code&)
1793     {
1794         return true;
1795     }
1796 
1797     bool on_comment(string_view, error_code&)
1798     {
1799         return true;
1800     }
1801 
1802 #undef BOOST_JSON_INVOKE_INNER
1803 };
1804 
1805 } // namespace detail
1806 } // namespace boost
1807 } // namespace json
1808 
1809 #endif