LCOV - code coverage report
Current view: top level - json/detail - parse_into.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 395 395
Test Date: 2025-12-23 17:35:04 Functions: 41.1 % 4061 1670

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
       3              : // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
       4              : //
       5              : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       6              : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       7              : //
       8              : // Official repository: https://github.com/boostorg/json
       9              : //
      10              : 
      11              : #ifndef BOOST_JSON_DETAIL_PARSE_INTO_HPP
      12              : #define BOOST_JSON_DETAIL_PARSE_INTO_HPP
      13              : 
      14              : #include <boost/json/detail/config.hpp>
      15              : 
      16              : #include <boost/json/error.hpp>
      17              : #include <boost/json/conversion.hpp>
      18              : #include <boost/describe/enum_from_string.hpp>
      19              : 
      20              : #include <vector>
      21              : 
      22              : /*
      23              :  * This file contains the majority of parse_into functionality, specifically
      24              :  * the implementation of dedicated handlers for different generic categories of
      25              :  * types.
      26              :  *
      27              :  * At the core of parse_into is the specialisation basic_parser<
      28              :  * detail::into_handler<T> >. detail::into_handler<T> is a handler for
      29              :  * basic_parser. It directly handles events on_comment_part and on_comment (by
      30              :  * ignoring them), on_document_begin (by enabling the nested dedicated
      31              :  * handler), and on_document_end (by disabling the nested handler).
      32              :  *
      33              :  * Every other event is handled by the nested handler, which has the type
      34              :  * get_handler< T, into_handler<T> >. The second parameter is the parent
      35              :  * handler (in this case, it's the top handler, into_handler<T>). The type is
      36              :  * actually an alias to class template converting_handler, which has a separate
      37              :  * specialisation for every conversion category from the list of generic
      38              :  * conversion categories (e.g. sequence_conversion_tag, tuple_conversion_tag,
      39              :  * etc.) Instantiations of the template store a pointer to the parent handler
      40              :  * and a pointer to the value T.
      41              :  *
      42              :  * The nested handler handles specific parser events by setting error_code to
      43              :  * an appropriate value, if it receives an event it isn't supposed to handle
      44              :  * (e.g. a number handler getting an on_string event), and also updates the
      45              :  * value when appropriate. Note that they never need to handle on_comment_part,
      46              :  * on_comment, on_document_begin, and on_document_end events, as those are
      47              :  * always handled by the top handler into_handler<T>.
      48              :  *
      49              :  * When the nested handler receives an event that completes the current value,
      50              :  * it is supposed to call its parent's signal_value member function. This is
      51              :  * necessary for correct handling of composite types (e.g. sequences).
      52              :  *
      53              :  * Finally, nested handlers should always call parent's signal_end member
      54              :  * function if they don't handle on_array_end themselves. This is necessary
      55              :  * to correctly handle nested composites (e.g. sequences inside sequences).
      56              :  * signal_end can return false and set error state when the containing parser
      57              :  * requires more elements.
      58              :  *
      59              :  * converting_handler instantiations for composite categories of types have
      60              :  * their own nested handlers, to which they themselves delegate events. For
      61              :  * complex types you will get a tree of handlers with into_handler<T> as the
      62              :  * root and handlers for scalars as leaves.
      63              :  *
      64              :  * To reiterate, only into_handler has to handle on_comment_part, on_comment,
      65              :  * on_document_begin, and on_document_end; only handlers for composites and
      66              :  * into_handler has to provide signal_value and signal_end; all handlers
      67              :  * except for into_handler have to call their parent's signal_end from
      68              :  * their on_array_begin, if they don't handle it themselves; once a handler
      69              :  * receives an event that finishes its current value, it should call its
      70              :  * parent's signal_value.
      71              :  */
      72              : 
      73              : namespace boost {
      74              : namespace json {
      75              : namespace detail {
      76              : 
      77              : template< class Impl, class T, class Parent >
      78              : class converting_handler;
      79              : 
      80              : // get_handler
      81              : template< class V, class P >
      82              : using get_handler = converting_handler< generic_conversion_category<V>, V, P >;
      83              : 
      84              : template<error E> class handler_error_base
      85              : {
      86              : public:
      87              : 
      88              :     handler_error_base() = default;
      89              : 
      90              :     handler_error_base( handler_error_base const& ) = delete;
      91              :     handler_error_base& operator=( handler_error_base const& ) = delete;
      92              : 
      93              : public:
      94              : 
      95            2 :     bool on_object_begin( system::error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
      96            7 :     bool on_array_begin( system::error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
      97              :     bool on_array_end( system::error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
      98            1 :     bool on_string_part( system::error_code& ec, string_view ) { BOOST_JSON_FAIL( ec, E ); return false; }
      99           60 :     bool on_string( system::error_code& ec, string_view ) { BOOST_JSON_FAIL( ec, E ); return false; }
     100            2 :     bool on_number_part( system::error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
     101            8 :     bool on_int64( system::error_code& ec, std::int64_t ) { BOOST_JSON_FAIL( ec, E ); return false; }
     102            8 :     bool on_uint64( system::error_code& ec, std::uint64_t ) { BOOST_JSON_FAIL( ec, E ); return false; }
     103            7 :     bool on_double( system::error_code& ec, double ) { BOOST_JSON_FAIL( ec, E ); return false; }
     104            2 :     bool on_bool( system::error_code& ec, bool ) { BOOST_JSON_FAIL( ec, E ); return false; }
     105            4 :     bool on_null( system::error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
     106              : 
     107              :     // LCOV_EXCL_START
     108              :     // parses that can't handle this would fail at on_object_begin
     109              :     bool on_object_end( system::error_code& ) { BOOST_ASSERT( false ); return false; }
     110              :     bool on_key_part( system::error_code& ec, string_view ) { BOOST_JSON_FAIL( ec, E ); return false; }
     111              :     bool on_key( system::error_code& ec, string_view ) { BOOST_JSON_FAIL( ec, E ); return false; }
     112              :     // LCOV_EXCL_STOP
     113              : };
     114              : 
     115              : template< class P, error E >
     116              : class scalar_handler
     117              :     : public handler_error_base<E>
     118              : {
     119              : protected:
     120              :     P* parent_;
     121              : 
     122              : public:
     123              :     scalar_handler(scalar_handler const&) = delete;
     124              :     scalar_handler& operator=(scalar_handler const&) = delete;
     125              : 
     126          816 :     scalar_handler(P* p): parent_( p )
     127          816 :     {}
     128              : 
     129          180 :     bool on_array_end( system::error_code& ec )
     130              :     {
     131          180 :         return parent_->signal_end(ec);
     132              :     }
     133              : };
     134              : 
     135              : template< class D, class V, class P, error E >
     136              : class composite_handler
     137              : {
     138              : protected:
     139              :     using inner_handler_type = get_handler<V, D>;
     140              : 
     141              :     P* parent_;
     142              : #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
     143              : # pragma GCC diagnostic push
     144              : # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
     145              : #endif
     146              :     V next_value_ = {};
     147              :     inner_handler_type inner_;
     148              :     bool inner_active_ = false;
     149              : 
     150              : public:
     151              :     composite_handler( composite_handler const& ) = delete;
     152              :     composite_handler& operator=( composite_handler const& ) = delete;
     153              : 
     154          413 :     composite_handler( P* p )
     155          413 :         : parent_(p), inner_( &next_value_, static_cast<D*>(this) )
     156          413 :     {}
     157              : #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
     158              : # pragma GCC diagnostic pop
     159              : #endif
     160              : 
     161          272 :     bool signal_end(system::error_code& ec)
     162              :     {
     163          272 :         inner_active_ = false;
     164          272 :         return parent_->signal_value(ec);
     165              :     }
     166              : 
     167              : #define BOOST_JSON_INVOKE_INNER(f) \
     168              :     if( !inner_active_ ) { \
     169              :         BOOST_JSON_FAIL(ec, E); \
     170              :         return false; \
     171              :     } \
     172              :     else \
     173              :         return inner_.f
     174              : 
     175           21 :     bool on_object_begin( system::error_code& ec )
     176              :     {
     177           21 :         BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
     178              :     }
     179              : 
     180           21 :     bool on_object_end( system::error_code& ec )
     181              :     {
     182           21 :         BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
     183              :     }
     184              : 
     185           59 :     bool on_array_begin( system::error_code& ec )
     186              :     {
     187           59 :         BOOST_JSON_INVOKE_INNER( on_array_begin(ec) );
     188              :     }
     189              : 
     190              :     bool on_array_end( system::error_code& ec )
     191              :     {
     192              :         BOOST_JSON_INVOKE_INNER( on_array_end(ec) );
     193              :     }
     194              : 
     195            3 :     bool on_key_part( system::error_code& ec, string_view sv )
     196              :     {
     197            3 :         BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
     198              :     }
     199              : 
     200           21 :     bool on_key( system::error_code& ec, string_view sv )
     201              :     {
     202           21 :         BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
     203              :     }
     204              : 
     205           24 :     bool on_string_part( system::error_code& ec, string_view sv )
     206              :     {
     207           24 :         BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
     208              :     }
     209              : 
     210           50 :     bool on_string( system::error_code& ec, string_view sv )
     211              :     {
     212           50 :         BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
     213              :     }
     214              : 
     215          229 :     bool on_number_part( system::error_code& ec )
     216              :     {
     217          229 :         BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
     218              :     }
     219              : 
     220          894 :     bool on_int64( system::error_code& ec, std::int64_t v )
     221              :     {
     222          894 :         BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
     223              :     }
     224              : 
     225            7 :     bool on_uint64( system::error_code& ec, std::uint64_t v )
     226              :     {
     227            7 :         BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
     228              :     }
     229              : 
     230           42 :     bool on_double( system::error_code& ec, double v )
     231              :     {
     232           42 :         BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
     233              :     }
     234              : 
     235           21 :     bool on_bool( system::error_code& ec, bool v )
     236              :     {
     237           21 :         BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
     238              :     }
     239              : 
     240           14 :     bool on_null( system::error_code& ec )
     241              :     {
     242           14 :         BOOST_JSON_INVOKE_INNER( on_null(ec) );
     243              :     }
     244              : 
     245              : #undef BOOST_JSON_INVOKE_INNER
     246              : };
     247              : 
     248              : // integral handler
     249              : template<class V,
     250              : typename std::enable_if<std::is_signed<V>::value, int>::type = 0>
     251          680 : bool integral_in_range( std::int64_t v )
     252              : {
     253          680 :     return v >= (std::numeric_limits<V>::min)() && v <= (std::numeric_limits<V>::max)();
     254              : }
     255              : 
     256              : template<class V,
     257              : typename std::enable_if<!std::is_signed<V>::value, int>::type = 0>
     258           35 : bool integral_in_range( std::int64_t v )
     259              : {
     260           35 :     return v >= 0 && static_cast<std::uint64_t>( v ) <= (std::numeric_limits<V>::max)();
     261              : }
     262              : 
     263              : template<class V>
     264           37 : bool integral_in_range( std::uint64_t v )
     265              : {
     266           37 :     return v <= static_cast<typename std::make_unsigned<V>::type>( (std::numeric_limits<V>::max)() );
     267              : }
     268              : 
     269              : template< class V, class P >
     270              : class converting_handler<integral_conversion_tag, V, P>
     271              :     : public scalar_handler<P, error::not_integer>
     272              : {
     273              : private:
     274              :     V* value_;
     275              : 
     276              : public:
     277          553 :     converting_handler( V* v, P* p )
     278              :         : converting_handler::scalar_handler(p)
     279          553 :         , value_(v)
     280          553 :     {}
     281              : 
     282          319 :     bool on_number_part( system::error_code& )
     283              :     {
     284          319 :         return true;
     285              :     }
     286              : 
     287          715 :     bool on_int64(system::error_code& ec, std::int64_t v)
     288              :     {
     289          715 :         if( !integral_in_range<V>( v ) )
     290              :         {
     291            2 :             BOOST_JSON_FAIL( ec, error::not_exact );
     292            2 :             return false;
     293              :         }
     294              : 
     295          713 :         *value_ = static_cast<V>( v );
     296          713 :         return this->parent_->signal_value(ec);
     297              :     }
     298              : 
     299           37 :     bool on_uint64(system::error_code& ec, std::uint64_t v)
     300              :     {
     301           37 :         if( !integral_in_range<V>(v) )
     302              :         {
     303            2 :             BOOST_JSON_FAIL( ec, error::not_exact );
     304            2 :             return false;
     305              :         }
     306              : 
     307           35 :         *value_ = static_cast<V>(v);
     308           35 :         return this->parent_->signal_value(ec);
     309              :     }
     310              : };
     311              : 
     312              : // floating point handler
     313              : template< class V, class P>
     314              : class converting_handler<floating_point_conversion_tag, V, P>
     315              :     : public scalar_handler<P, error::not_double>
     316              : {
     317              : private:
     318              :     V* value_;
     319              : 
     320              : public:
     321           53 :     converting_handler( V* v, P* p )
     322              :         : converting_handler::scalar_handler(p)
     323           53 :         , value_(v)
     324           53 :     {}
     325              : 
     326           99 :     bool on_number_part( system::error_code& )
     327              :     {
     328           99 :         return true;
     329              :     }
     330              : 
     331            1 :     bool on_int64(system::error_code& ec, std::int64_t v)
     332              :     {
     333            1 :         *value_ = static_cast<V>(v);
     334            1 :         return this->parent_->signal_value(ec);
     335              :     }
     336              : 
     337            1 :     bool on_uint64(system::error_code& ec, std::uint64_t v)
     338              :     {
     339            1 :         *value_ = static_cast<V>(v);
     340            1 :         return this->parent_->signal_value(ec);
     341              :     }
     342              : 
     343           63 :     bool on_double(system::error_code& ec, double v)
     344              :     {
     345           63 :         *value_ = static_cast<V>(v);
     346           63 :         return this->parent_->signal_value(ec);
     347              :     }
     348              : };
     349              : 
     350              : // string handler
     351              : template< class V, class P >
     352              : class converting_handler<string_like_conversion_tag, V, P>
     353              :     : public scalar_handler<P, error::not_string>
     354              : {
     355              : private:
     356              :     V* value_;
     357              :     bool cleared_ = false;
     358              : 
     359              : public:
     360           95 :     converting_handler( V* v, P* p )
     361              :         : converting_handler::scalar_handler(p)
     362           95 :         , value_(v)
     363           95 :     {}
     364              : 
     365           21 :     bool on_string_part( system::error_code&, string_view sv )
     366              :     {
     367           21 :         if( !cleared_ )
     368              :         {
     369            5 :             cleared_ = true;
     370            5 :             value_->clear();
     371              :         }
     372              : 
     373           21 :         value_->append( sv.begin(), sv.end() );
     374           21 :         return true;
     375              :     }
     376              : 
     377          100 :     bool on_string(system::error_code& ec, string_view sv)
     378              :     {
     379          100 :         if( !cleared_ )
     380           95 :             value_->clear();
     381              :         else
     382            5 :             cleared_ = false;
     383              : 
     384          100 :         value_->append( sv.begin(), sv.end() );
     385          100 :         return this->parent_->signal_value(ec);
     386              :     }
     387              : };
     388              : 
     389              : // bool handler
     390              : template< class V, class P >
     391              : class converting_handler<bool_conversion_tag, V, P>
     392              :     : public scalar_handler<P, error::not_bool>
     393              : {
     394              : private:
     395              :     V* value_;
     396              : 
     397              : public:
     398           60 :     converting_handler( V* v, P* p )
     399              :         : converting_handler::scalar_handler(p)
     400           60 :         , value_(v)
     401           60 :     {}
     402              : 
     403           42 :     bool on_bool(system::error_code& ec, bool v)
     404              :     {
     405           42 :         *value_ = v;
     406           42 :         return this->parent_->signal_value(ec);
     407              :     }
     408              : };
     409              : 
     410              : // null handler
     411              : template< class V, class P >
     412              : class converting_handler<null_like_conversion_tag, V, P>
     413              :     : public scalar_handler<P, error::not_null>
     414              : {
     415              : private:
     416              :     V* value_;
     417              : 
     418              : public:
     419           55 :     converting_handler( V* v, P* p )
     420              :         : converting_handler::scalar_handler(p)
     421           55 :         , value_(v)
     422           55 :     {}
     423              : 
     424           35 :     bool on_null(system::error_code& ec)
     425              :     {
     426           35 :         *value_ = {};
     427           35 :         return this->parent_->signal_value(ec);
     428              :     }
     429              : };
     430              : 
     431              : // described enum handler
     432              : template< class V, class P >
     433              : class converting_handler<described_enum_conversion_tag, V, P>
     434              :     : public scalar_handler<P, error::not_string>
     435              : {
     436              : #ifndef BOOST_DESCRIBE_CXX14
     437              : 
     438              :     static_assert(
     439              :         sizeof(V) == 0, "Enum support for parse_into requires C++14" );
     440              : 
     441              : #else
     442              : 
     443              : private:
     444              :     V* value_;
     445              :     std::string name_;
     446              : 
     447              : public:
     448              :     converting_handler( V* v, P* p )
     449              :         : converting_handler::scalar_handler(p)
     450              :         , value_(v)
     451              :     {}
     452              : 
     453              :     bool on_string_part( system::error_code&, string_view sv )
     454              :     {
     455              :         name_.append( sv.begin(), sv.end() );
     456              :         return true;
     457              :     }
     458              : 
     459              :     bool on_string(system::error_code& ec, string_view sv)
     460              :     {
     461              :         string_view name = sv;
     462              :         if( !name_.empty() )
     463              :         {
     464              :             name_.append( sv.begin(), sv.end() );
     465              :             name = name_;
     466              :         }
     467              : 
     468              :         if( !describe::enum_from_string(name, *value_) )
     469              :         {
     470              :             BOOST_JSON_FAIL(ec, error::unknown_name);
     471              :             return false;
     472              :         }
     473              : 
     474              :         return this->parent_->signal_value(ec);
     475              :     }
     476              : 
     477              : #endif // BOOST_DESCRIBE_CXX14
     478              : };
     479              : 
     480              : template< class V, class P >
     481              : class converting_handler<no_conversion_tag, V, P>
     482              : {
     483              :     static_assert( sizeof(V) == 0, "This type is not supported" );
     484              : };
     485              : 
     486              : // sequence handler
     487              : template< class It >
     488          128 : bool cannot_insert(It i, It e)
     489              : {
     490          128 :     return i == e;
     491              : }
     492              : 
     493              : template< class It1, class It2 >
     494          507 : std::false_type cannot_insert(It1, It2)
     495              : {
     496          507 :     return {};
     497              : }
     498              : 
     499              : template< class It >
     500           30 : bool needs_more_elements(It i, It e)
     501              : {
     502           30 :     return i != e;
     503              : }
     504              : 
     505              : template< class It1, class It2 >
     506          244 : std::false_type needs_more_elements(It1, It2)
     507              : {
     508          244 :     return {};
     509              : }
     510              : 
     511              : template<class T>
     512              : void
     513           32 : clear_container(
     514              :     T&,
     515              :     mp11::mp_int<2>)
     516              : {
     517           32 : }
     518              : 
     519              : template<class T>
     520              : void
     521          260 : clear_container(
     522              :     T& target,
     523              :     mp11::mp_int<1>)
     524              : {
     525          260 :     target.clear();
     526          260 : }
     527              : 
     528              : template<class T>
     529              : void
     530          149 : clear_container(
     531              :     T& target,
     532              :     mp11::mp_int<0>)
     533              : {
     534          149 :     target.clear();
     535          149 : }
     536              : 
     537              : template< class V, class P >
     538              : class converting_handler<sequence_conversion_tag, V, P>
     539              :     : public composite_handler<
     540              :         converting_handler<sequence_conversion_tag, V, P>,
     541              :         detail::value_type<V>,
     542              :         P,
     543              :         error::not_array>
     544              : {
     545              : private:
     546              :     V* value_;
     547              : 
     548              :     using Inserter = decltype(
     549              :         detail::inserter(*value_, inserter_implementation<V>()) );
     550              :     Inserter inserter;
     551              : 
     552              : public:
     553          276 :     converting_handler( V* v, P* p )
     554              :         : converting_handler::composite_handler(p)
     555          276 :         , value_(v)
     556          276 :         , inserter( detail::inserter(*value_, inserter_implementation<V>()) )
     557          276 :     {}
     558              : 
     559          635 :     bool signal_value(system::error_code& ec)
     560              :     {
     561          635 :         if(cannot_insert( inserter, value_->end() ))
     562              :         {
     563            2 :             BOOST_JSON_FAIL( ec, error::size_mismatch );
     564            2 :             return false;
     565              :         }
     566              : 
     567          633 :         *inserter++ = std::move(this->next_value_);
     568              : #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
     569              : # pragma GCC diagnostic push
     570              : # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
     571              : #endif
     572          633 :         this->next_value_ = {};
     573              : #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
     574              : # pragma GCC diagnostic pop
     575              : #endif
     576          633 :         return true;
     577              :     }
     578              : 
     579          274 :     bool signal_end(system::error_code& ec)
     580              :     {
     581          274 :         if(needs_more_elements( inserter, value_->end() ))
     582              :         {
     583            2 :             BOOST_JSON_FAIL( ec, error::size_mismatch );
     584            2 :             return false;
     585              :         }
     586              : 
     587          272 :         inserter = detail::inserter(*value_, inserter_implementation<V>());
     588              : 
     589          272 :         return converting_handler::composite_handler::signal_end(ec);
     590              :     }
     591              : 
     592          474 :     bool on_array_begin( system::error_code& ec )
     593              :     {
     594          474 :         if( this->inner_active_ )
     595          182 :             return this->inner_.on_array_begin( ec );
     596              : 
     597          292 :         this->inner_active_ = true;
     598          292 :         clear_container( *value_, inserter_implementation<V>() );
     599          292 :         return true;
     600              :     }
     601              : 
     602          498 :     bool on_array_end( system::error_code& ec )
     603              :     {
     604          498 :         if( this->inner_active_ )
     605          456 :             return this->inner_.on_array_end( ec );
     606              : 
     607           42 :         return this->parent_->signal_end(ec);
     608              :     }
     609              : };
     610              : 
     611              : // map handler
     612              : template< class V, class P >
     613              : class converting_handler<map_like_conversion_tag, V, P>
     614              :     : public composite_handler<
     615              :         converting_handler<map_like_conversion_tag, V, P>,
     616              :         detail::mapped_type<V>,
     617              :         P,
     618              :         error::not_object>
     619              : {
     620              : private:
     621              :     V* value_;
     622              :     std::string key_;
     623              : 
     624              : public:
     625          137 :     converting_handler( V* v, P* p )
     626          137 :         : converting_handler::composite_handler(p), value_(v)
     627          137 :     {}
     628              : 
     629          135 :     bool signal_value(system::error_code&)
     630              :     {
     631          135 :         value_->emplace( std::move(key_), std::move(this->next_value_) );
     632              : 
     633          135 :         key_ = {};
     634          135 :         this->next_value_ = {};
     635              : 
     636          135 :         this->inner_active_ = false;
     637              : 
     638          135 :         return true;
     639              :     }
     640              : 
     641          165 :     bool on_object_begin( system::error_code& ec )
     642              :     {
     643          165 :         if( this->inner_active_ )
     644           16 :             return this->inner_.on_object_begin(ec);
     645              : 
     646          149 :         clear_container( *value_, inserter_implementation<V>() );
     647          149 :         return true;
     648              :     }
     649              : 
     650          154 :     bool on_object_end(system::error_code& ec)
     651              :     {
     652          154 :         if( this->inner_active_ )
     653           16 :             return this->inner_.on_object_end(ec);
     654              : 
     655          138 :         return this->parent_->signal_value(ec);
     656              :     }
     657              : 
     658           60 :     bool on_array_end( system::error_code& ec )
     659              :     {
     660           60 :         if( this->inner_active_ )
     661           53 :             return this->inner_.on_array_end(ec);
     662              : 
     663            7 :         return this->parent_->signal_end(ec);
     664              :     }
     665              : 
     666           45 :     bool on_key_part( system::error_code& ec, string_view sv )
     667              :     {
     668           45 :         if( this->inner_active_ )
     669            2 :             return this->inner_.on_key_part(ec, sv);
     670              : 
     671           43 :         key_.append( sv.data(), sv.size() );
     672           43 :         return true;
     673              :     }
     674              : 
     675          160 :     bool on_key( system::error_code& ec, string_view sv )
     676              :     {
     677          160 :         if( this->inner_active_ )
     678           14 :             return this->inner_.on_key(ec, sv);
     679              : 
     680          146 :         key_.append( sv.data(), sv.size() );
     681              : 
     682          146 :         this->inner_active_ = true;
     683          146 :         return true;
     684              :     }
     685              : };
     686              : 
     687              : // tuple handler
     688              : template<std::size_t I, class T>
     689              : struct handler_tuple_element
     690              : {
     691              :     template< class... Args >
     692          286 :     handler_tuple_element( Args&& ... args )
     693          286 :         : t_( static_cast<Args&&>(args)... )
     694          286 :     {}
     695              : 
     696              :     T t_;
     697              : };
     698              : 
     699              : template<std::size_t I, class T>
     700              : T&
     701          516 : get( handler_tuple_element<I, T>& e )
     702              : {
     703          516 :     return e.t_;
     704              : }
     705              : 
     706              : template<
     707              :     class P,
     708              :     class LV,
     709              :     class S = mp11::make_index_sequence<mp11::mp_size<LV>::value> >
     710              : struct handler_tuple;
     711              : 
     712              : template< class P, template<class...> class L, class... V, std::size_t... I >
     713              : struct handler_tuple< P, L<V...>, mp11::index_sequence<I...> >
     714              :     : handler_tuple_element<I, V>
     715              :     ...
     716              : {
     717              :     handler_tuple( handler_tuple const& ) = delete;
     718              :     handler_tuple& operator=( handler_tuple const& ) = delete;
     719              : 
     720              :     template< class Access, class T >
     721          129 :     handler_tuple( Access access, T* pv, P* pp )
     722              :         : handler_tuple_element<I, V>(
     723            6 :             access( pv, mp11::mp_size_t<I>() ),
     724              :             pp )
     725          129 :         ...
     726          129 :     {}
     727              : };
     728              : 
     729              : #if defined(BOOST_MSVC) && BOOST_MSVC < 1910
     730              : 
     731              : template< class T >
     732              : struct tuple_element_list_impl
     733              : {
     734              :     template< class I >
     735              :     using tuple_element_helper = tuple_element_t<I::value, T>;
     736              : 
     737              :     using type = mp11::mp_transform<
     738              :         tuple_element_helper,
     739              :         mp11::mp_iota< std::tuple_size<T> > >;
     740              : };
     741              : template< class T >
     742              : using tuple_element_list = typename tuple_element_list_impl<T>::type;
     743              : 
     744              : #else
     745              : 
     746              : template< class I, class T >
     747              : using tuple_element_helper = tuple_element_t<I::value, T>;
     748              : template< class T >
     749              : using tuple_element_list = mp11::mp_transform_q<
     750              :     mp11::mp_bind_back< tuple_element_helper, T>,
     751              :     mp11::mp_iota< std::tuple_size<T> > >;
     752              : 
     753              : #endif
     754              : 
     755              : template< class Op, class... Args>
     756              : struct handler_op_invoker
     757              : {
     758              : public:
     759              :     std::tuple<Args&...> args;
     760              : 
     761              :     template< class Handler >
     762              :     bool
     763          466 :     operator()( Handler& handler ) const
     764              :     {
     765          466 :         return (*this)( handler, mp11::index_sequence_for<Args...>() );
     766              :     }
     767              : 
     768              : private:
     769              :     template< class Handler, std::size_t... I >
     770              :     bool
     771          466 :     operator()( Handler& handler, mp11::index_sequence<I...> ) const
     772              :     {
     773          466 :         return Op()( handler, std::get<I>(args)... );
     774              :     }
     775              : };
     776              : 
     777              : template< class Handlers, class F >
     778              : struct tuple_handler_op_invoker
     779              : {
     780              :     Handlers& handlers;
     781              :     F fn;
     782              : 
     783              :     template< class I >
     784              :     bool
     785          466 :     operator()( I ) const
     786              :     {
     787          466 :         return fn( get<I::value>(handlers) );
     788              :     }
     789              : };
     790              : 
     791              : struct tuple_accessor
     792              : {
     793              :     template< class T, class I >
     794          286 :     auto operator()( T* t, I ) const -> tuple_element_t<I::value, T>*
     795              :     {
     796              :         using std::get;
     797          286 :         return &get<I::value>(*t);
     798              :     }
     799              : };
     800              : 
     801              : template< class T, class P >
     802              : class converting_handler<tuple_conversion_tag, T, P>
     803              : {
     804              : 
     805              : private:
     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              : 
     813              :     T* value_;
     814              :     P* parent_;
     815              : 
     816              :     HandlerTuple handlers_;
     817              :     int inner_active_ = -1;
     818              : 
     819              : public:
     820              :     converting_handler( converting_handler const& ) = delete;
     821              :     converting_handler& operator=( converting_handler const& ) = delete;
     822              : 
     823          129 :     converting_handler( T* v, P* p )
     824          129 :         : value_(v) , parent_(p) , handlers_(tuple_accessor(), v, this)
     825          129 :     {}
     826              : 
     827          283 :     bool signal_value(system::error_code&)
     828              :     {
     829          283 :         ++inner_active_;
     830          283 :         return true;
     831              :     }
     832              : 
     833          123 :     bool signal_end(system::error_code& ec)
     834              :     {
     835          123 :         constexpr int N = std::tuple_size<T>::value;
     836          123 :         if( inner_active_ < N )
     837              :         {
     838            4 :             BOOST_JSON_FAIL( ec, error::size_mismatch );
     839            4 :             return false;
     840              :         }
     841              : 
     842          119 :         inner_active_ = -1;
     843          119 :         return parent_->signal_value(ec);
     844              :     }
     845              : 
     846              : #define BOOST_JSON_HANDLE_EVENT(fn) \
     847              :     struct do_ ## fn \
     848              :     { \
     849              :         template< class H, class... Args > \
     850              :         bool operator()( H& h, Args& ... args ) const \
     851              :         { \
     852              :             return h. fn (args...); \
     853              :         } \
     854              :     }; \
     855              :        \
     856              :     template< class... Args > \
     857              :     bool fn( system::error_code& ec, Args&& ... args ) \
     858              :     { \
     859              :         if( inner_active_ < 0 ) \
     860              :         { \
     861              :             BOOST_JSON_FAIL( ec, error::not_array ); \
     862              :             return false; \
     863              :         } \
     864              :         constexpr int N = std::tuple_size<T>::value; \
     865              :         if( inner_active_ >= N ) \
     866              :         { \
     867              :             BOOST_JSON_FAIL( ec, error::size_mismatch ); \
     868              :             return false; \
     869              :         } \
     870              :         using F = handler_op_invoker< do_ ## fn, system::error_code, Args...>; \
     871              :         using H = decltype(handlers_); \
     872              :         return mp11::mp_with_index<N>( \
     873              :             inner_active_, \
     874              :             tuple_handler_op_invoker<H, F>{ \
     875              :                 handlers_, \
     876              :                 F{ std::forward_as_tuple(ec, args...) } } ); \
     877              :     }
     878              : 
     879           56 :     BOOST_JSON_HANDLE_EVENT( on_object_begin )
     880           42 :     BOOST_JSON_HANDLE_EVENT( on_object_end )
     881              : 
     882              :     struct do_on_array_begin
     883              :     {
     884              :         HandlerTuple& handlers;
     885              :         system::error_code& ec;
     886              : 
     887              :         template< class I >
     888           23 :         bool operator()( I ) const
     889              :         {
     890           23 :             return get<I::value>(handlers).on_array_begin(ec);
     891              :         }
     892              :     };
     893          159 :     bool on_array_begin( system::error_code& ec )
     894              :     {
     895          159 :         if( inner_active_ < 0 )
     896              :         {
     897          134 :             inner_active_ = 0;
     898          134 :             return true;
     899              :         }
     900              : 
     901           25 :         constexpr int N = std::tuple_size<T>::value;
     902              : 
     903           25 :         if( inner_active_ >= N )
     904              :         {
     905            2 :             BOOST_JSON_FAIL( ec, error::size_mismatch );
     906            2 :             return false;
     907              :         }
     908              : 
     909           23 :         return mp11::mp_with_index<N>(
     910           23 :             inner_active_, do_on_array_begin{handlers_, ec} );
     911              :     }
     912              : 
     913              :     struct do_on_array_end
     914              :     {
     915              :         HandlerTuple& handlers;
     916              :         system::error_code& ec;
     917              : 
     918              :         template< class I >
     919           27 :         bool operator()( I ) const
     920              :         {
     921           27 :             return get<I::value>(handlers).on_array_end(ec);
     922              :         }
     923              :     };
     924          195 :     bool on_array_end( system::error_code& ec )
     925              :     {
     926          195 :         if( inner_active_ < 0 )
     927           49 :             return parent_->signal_end(ec);
     928              : 
     929          146 :         constexpr int N = std::tuple_size<T>::value;
     930              : 
     931          146 :         if( inner_active_ >= N )
     932          119 :             return signal_end(ec);
     933              : 
     934           27 :         return mp11::mp_with_index<N>(
     935           27 :             inner_active_, do_on_array_end{handlers_, ec} );
     936              :     }
     937              : 
     938            6 :     BOOST_JSON_HANDLE_EVENT( on_key_part )
     939           56 :     BOOST_JSON_HANDLE_EVENT( on_key )
     940           10 :     BOOST_JSON_HANDLE_EVENT( on_string_part )
     941           56 :     BOOST_JSON_HANDLE_EVENT( on_string )
     942          152 :     BOOST_JSON_HANDLE_EVENT( on_number_part )
     943          432 :     BOOST_JSON_HANDLE_EVENT( on_int64 )
     944           14 :     BOOST_JSON_HANDLE_EVENT( on_uint64 )
     945           70 :     BOOST_JSON_HANDLE_EVENT( on_double )
     946           28 :     BOOST_JSON_HANDLE_EVENT( on_bool )
     947           14 :     BOOST_JSON_HANDLE_EVENT( on_null )
     948              : 
     949              : #undef BOOST_JSON_HANDLE_EVENT
     950              : };
     951              : 
     952              : // described struct handler
     953              : #if defined(BOOST_MSVC) && BOOST_MSVC < 1910
     954              : 
     955              : template< class T >
     956              : struct struct_element_list_impl
     957              : {
     958              :     template< class D >
     959              :     using helper = described_member_t<T, D>;
     960              : 
     961              :     using type = mp11::mp_transform< helper, described_members<T> >;
     962              : };
     963              : template< class T >
     964              : using struct_element_list = typename struct_element_list_impl<T>::type;
     965              : 
     966              : #else
     967              : 
     968              : template< class T >
     969              : using struct_element_list = mp11::mp_transform_q<
     970              :     mp11::mp_bind_front< described_member_t, T >, described_members<T> >;
     971              : 
     972              : #endif
     973              : 
     974              : struct struct_accessor
     975              : {
     976              :     template< class T >
     977              :     auto operator()( T*, mp11::mp_size< described_members<T> > ) const
     978              :         -> void*
     979              :     {
     980              :         return nullptr;
     981              :     }
     982              : 
     983              :     template< class T, class I >
     984              :     auto operator()( T* t, I ) const
     985              :         -> described_member_t<T, mp11::mp_at< described_members<T>, I> >*
     986              :     {
     987              :         using Ds = described_members<T>;
     988              :         using D = mp11::mp_at<Ds, I>;
     989              :         return &(t->*D::pointer);
     990              :     }
     991              : };
     992              : 
     993              : struct struct_key_searcher
     994              : {
     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              :     {}
    1002              : 
    1003              :     template< class D >
    1004              :     void
    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)
    1075              :     {
    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;
    1119              :     }
    1120              : };
    1121              : 
    1122              : template<class V, class P>
    1123              : class converting_handler<described_class_conversion_tag, V, P>
    1124              : {
    1125              : #if !defined(BOOST_DESCRIBE_CXX14)
    1126              : 
    1127              :     static_assert(
    1128              :         sizeof(V) == 0, "Struct support for parse_into requires C++14" );
    1129              : 
    1130              : #else
    1131              : 
    1132              : private:
    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              : 
    1143              :     V* value_;
    1144              :     P* parent_;
    1145              : 
    1146              :     std::string key_;
    1147              : 
    1148              :     handler_tuple<converting_handler, InnerHandlers> handlers_;
    1149              :     int inner_active_ = -1;
    1150              :     std::size_t activated_ = 0;
    1151              : 
    1152              : public:
    1153              :     converting_handler( converting_handler const& ) = delete;
    1154              :     converting_handler& operator=( converting_handler const& ) = delete;
    1155              : 
    1156              :     converting_handler( V* v, P* p )
    1157              :         : value_(v), parent_(p), handlers_(struct_accessor(), v, this)
    1158              :     {}
    1159              : 
    1160              :     struct is_required_checker
    1161              :     {
    1162              :         bool operator()( mp11::mp_size<Dt> ) const noexcept
    1163              :         {
    1164              :             return false;
    1165              :         }
    1166              : 
    1167              :         template< class I >
    1168              :         auto operator()( I ) const noexcept
    1169              :         {
    1170              :             using T = mp11::mp_at<Dt, I>;
    1171              :             return !is_optional_like<T>::value;
    1172              :         }
    1173              :     };
    1174              : 
    1175              :     bool signal_value(system::error_code&)
    1176              :     {
    1177              :         BOOST_ASSERT( inner_active_ >= 0 );
    1178              :         bool required_member = mp11::mp_with_index<InnerCount>(
    1179              :             inner_active_,
    1180              :             is_required_checker{});
    1181              :         if( required_member )
    1182              :             ++activated_;
    1183              : 
    1184              :         key_ = {};
    1185              :         inner_active_ = -1;
    1186              :         return true;
    1187              :     }
    1188              : 
    1189              :     bool signal_end(system::error_code& ec)
    1190              :     {
    1191              :         key_ = {};
    1192              :         inner_active_ = -1;
    1193              :         return parent_->signal_value(ec);
    1194              :     }
    1195              : 
    1196              : #define BOOST_JSON_INVOKE_INNER(fn) \
    1197              :     if( inner_active_ < 0 ) \
    1198              :     { \
    1199              :         BOOST_JSON_FAIL( ec, error::not_object ); \
    1200              :         return false; \
    1201              :     } \
    1202              :     auto f = [&](auto& handler) { return handler.fn ; }; \
    1203              :     using F = decltype(f); \
    1204              :     using H = decltype(handlers_); \
    1205              :     return mp11::mp_with_index<InnerCount>( \
    1206              :             inner_active_, \
    1207              :             tuple_handler_op_invoker<H, F>{handlers_, f} );
    1208              : 
    1209              :     bool on_object_begin( system::error_code& ec )
    1210              :     {
    1211              :         if( inner_active_ < 0 )
    1212              :             return true;
    1213              : 
    1214              :         BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
    1215              :     }
    1216              : 
    1217              :     bool on_object_end( system::error_code& ec )
    1218              :     {
    1219              :         if( inner_active_ < 0 )
    1220              :         {
    1221              :             using C = mp11::mp_count_if<Dt, is_optional_like>;
    1222              :             constexpr int N = mp11::mp_size<Dt>::value - C::value;
    1223              :             if( activated_ < N )
    1224              :             {
    1225              :                 BOOST_JSON_FAIL( ec, error::size_mismatch );
    1226              :                 return false;
    1227              :             }
    1228              : 
    1229              :             return parent_->signal_value(ec);
    1230              :         }
    1231              : 
    1232              :         BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
    1233              :     }
    1234              : 
    1235              :     bool on_array_begin( system::error_code& ec )
    1236              :     {
    1237              :         BOOST_JSON_INVOKE_INNER( on_array_begin(ec) );
    1238              :     }
    1239              : 
    1240              :     bool on_array_end( system::error_code& ec )
    1241              :     {
    1242              :         if( inner_active_ < 0 )
    1243              :             return parent_->signal_end(ec);
    1244              : 
    1245              :         BOOST_JSON_INVOKE_INNER( on_array_end(ec) );
    1246              :     }
    1247              : 
    1248              :     bool on_key_part( system::error_code& ec, string_view sv )
    1249              :     {
    1250              :         if( inner_active_ < 0 )
    1251              :         {
    1252              :             key_.append( sv.data(), sv.size() );
    1253              :             return true;
    1254              :         }
    1255              : 
    1256              :         BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
    1257              :     }
    1258              : 
    1259              :     bool on_key( system::error_code& ec, string_view sv )
    1260              :     {
    1261              :         if( inner_active_ >= 0 )
    1262              :         {
    1263              :             BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
    1264              :         }
    1265              : 
    1266              :         string_view key = sv;
    1267              :         if( !key_.empty() )
    1268              :         {
    1269              :             key_.append( sv.data(), sv.size() );
    1270              :             key = key_;
    1271              :         }
    1272              : 
    1273              :         inner_active_ = InnerCount::value - 1;
    1274              :         mp11::mp_for_each<Dm>( struct_key_searcher(key, inner_active_) );
    1275              :         return true;
    1276              :     }
    1277              : 
    1278              :     bool on_string_part( system::error_code& ec, string_view sv )
    1279              :     {
    1280              :         BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
    1281              :     }
    1282              : 
    1283              :     bool on_string( system::error_code& ec, string_view sv )
    1284              :     {
    1285              :         BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
    1286              :     }
    1287              : 
    1288              :     bool on_number_part( system::error_code& ec )
    1289              :     {
    1290              :         BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
    1291              :     }
    1292              : 
    1293              :     bool on_int64( system::error_code& ec, std::int64_t v )
    1294              :     {
    1295              :         BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
    1296              :     }
    1297              : 
    1298              :     bool on_uint64( system::error_code& ec, std::uint64_t v )
    1299              :     {
    1300              :         BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
    1301              :     }
    1302              : 
    1303              :     bool on_double( system::error_code& ec, double v )
    1304              :     {
    1305              :         BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
    1306              :     }
    1307              : 
    1308              :     bool on_bool( system::error_code& ec, bool v )
    1309              :     {
    1310              :         BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
    1311              :     }
    1312              : 
    1313              :     bool on_null( system::error_code& ec )
    1314              :     {
    1315              :         BOOST_JSON_INVOKE_INNER( on_null(ec) );
    1316              :     }
    1317              : 
    1318              : #undef BOOST_JSON_INVOKE_INNER
    1319              : 
    1320              : #endif
    1321              : };
    1322              : 
    1323              : // variant handler
    1324              : struct object_begin_handler_event
    1325              : { };
    1326              : 
    1327              : struct object_end_handler_event
    1328              : { };
    1329              : 
    1330              : struct array_begin_handler_event
    1331              : { };
    1332              : 
    1333              : struct array_end_handler_event
    1334              : { };
    1335              : 
    1336              : struct key_handler_event
    1337              : {
    1338              :     std::string value;
    1339              : };
    1340              : 
    1341              : struct string_handler_event
    1342              : {
    1343              :     std::string value;
    1344              : };
    1345              : 
    1346              : struct int64_handler_event
    1347              : {
    1348              :     std::int64_t value;
    1349              : };
    1350              : 
    1351              : struct uint64_handler_event
    1352              : {
    1353              :     std::uint64_t value;
    1354              : };
    1355              : 
    1356              : struct double_handler_event
    1357              : {
    1358              :     double value;
    1359              : };
    1360              : 
    1361              : struct bool_handler_event
    1362              : {
    1363              :     bool value;
    1364              : };
    1365              : 
    1366              : struct null_handler_event
    1367              : { };
    1368              : 
    1369              : using parse_event = variant2::variant<
    1370              :     object_begin_handler_event,
    1371              :     object_end_handler_event,
    1372              :     array_begin_handler_event,
    1373              :     array_end_handler_event,
    1374              :     key_handler_event,
    1375              :     string_handler_event,
    1376              :     int64_handler_event,
    1377              :     uint64_handler_event,
    1378              :     double_handler_event,
    1379              :     bool_handler_event,
    1380              :     null_handler_event>;
    1381              : 
    1382              : template< class H >
    1383              : struct event_visitor
    1384              : {
    1385              :     H& handler;
    1386              :     system::error_code& ec;
    1387              : 
    1388              :     bool
    1389           14 :     operator()(object_begin_handler_event&) const
    1390              :     {
    1391           14 :         return handler.on_object_begin(ec);
    1392              :     }
    1393              : 
    1394              :     bool
    1395            7 :     operator()(object_end_handler_event&) const
    1396              :     {
    1397            7 :         return handler.on_object_end(ec);
    1398              :     }
    1399              : 
    1400              :     bool
    1401           42 :     operator()(array_begin_handler_event&) const
    1402              :     {
    1403           42 :         return handler.on_array_begin(ec);
    1404              :     }
    1405              : 
    1406              :     bool
    1407           21 :     operator()(array_end_handler_event&) const
    1408              :     {
    1409           21 :         return handler.on_array_end(ec);
    1410              :     }
    1411              : 
    1412              :     bool
    1413           21 :     operator()(key_handler_event& ev) const
    1414              :     {
    1415           21 :         return handler.on_key(ec, ev.value);
    1416              :     }
    1417              : 
    1418              :     bool
    1419          108 :     operator()(string_handler_event& ev) const
    1420              :     {
    1421          108 :         return handler.on_string(ec, ev.value);
    1422              :     }
    1423              : 
    1424              :     bool
    1425          154 :     operator()(int64_handler_event& ev) const
    1426              :     {
    1427          154 :         return handler.on_int64(ec, ev.value);
    1428              :     }
    1429              : 
    1430              :     bool
    1431           14 :     operator()(uint64_handler_event& ev) const
    1432              :     {
    1433           14 :         return handler.on_uint64(ec, ev.value);
    1434              :     }
    1435              : 
    1436              :     bool
    1437           21 :     operator()(double_handler_event& ev) const
    1438              :     {
    1439           21 :         return handler.on_double(ec, ev.value);
    1440              :     }
    1441              : 
    1442              :     bool
    1443            7 :     operator()(bool_handler_event& ev) const
    1444              :     {
    1445            7 :         return handler.on_bool(ec, ev.value);
    1446              :     }
    1447              : 
    1448              :     bool
    1449            7 :     operator()(null_handler_event&) const
    1450              :     {
    1451            7 :         return handler.on_null(ec);
    1452              :     }
    1453              : };
    1454              : 
    1455              : // L<T...> -> variant< monostate, get_handler<T, P>... >
    1456              : template< class P, class L >
    1457              : using inner_handler_variant = mp11::mp_push_front<
    1458              :     mp11::mp_transform_q<
    1459              :         mp11::mp_bind_back<get_handler, P>,
    1460              :         mp11::mp_apply<variant2::variant, L>>,
    1461              :     variant2::monostate>;
    1462              : 
    1463              : template< class T, class P >
    1464              : class converting_handler<variant_conversion_tag, T, P>
    1465              : {
    1466              : private:
    1467              :     using variant_size = mp11::mp_size<T>;
    1468              : 
    1469              :     T* value_;
    1470              :     P* parent_;
    1471              : 
    1472              :     std::string string_;
    1473              :     std::vector< parse_event > events_;
    1474              :     inner_handler_variant<converting_handler, T> inner_;
    1475              :     int inner_active_ = -1;
    1476              : 
    1477              : public:
    1478              :     converting_handler( converting_handler const& ) = delete;
    1479              :     converting_handler& operator=( converting_handler const& ) = delete;
    1480              : 
    1481           90 :     converting_handler( T* v, P* p )
    1482           90 :         : value_( v )
    1483           90 :         , parent_( p )
    1484           90 :     {}
    1485              : 
    1486          126 :     bool signal_value(system::error_code& ec)
    1487              :     {
    1488          126 :         inner_.template emplace<0>();
    1489          126 :         inner_active_ = -1;
    1490          126 :         events_.clear();
    1491          126 :         return parent_->signal_value(ec);
    1492              :     }
    1493              : 
    1494           14 :     bool signal_end(system::error_code& ec)
    1495              :     {
    1496           14 :         return parent_->signal_end(ec);
    1497              :     }
    1498              : 
    1499              :     struct alternative_selector
    1500              :     {
    1501              :         converting_handler* self;
    1502              : 
    1503              :         template< class I >
    1504              :         void
    1505          227 :         operator()( I ) const
    1506              :         {
    1507              :             using V = mp11::mp_at<T, I>;
    1508          227 :             auto& v = self->value_->template emplace<I::value>( V{} );
    1509          227 :             self->inner_.template emplace<I::value + 1>(&v, self);
    1510          227 :         }
    1511              :     };
    1512              :     void
    1513          233 :     next_alternative()
    1514              :     {
    1515          233 :         if( ++inner_active_ >= static_cast<int>(variant_size::value) )
    1516            6 :             return;
    1517              : 
    1518          227 :         mp11::mp_with_index< variant_size::value >(
    1519          227 :             inner_active_, alternative_selector{this} );
    1520              :     }
    1521              : 
    1522              :     struct event_processor
    1523              :     {
    1524              :         converting_handler* self;
    1525              :         system::error_code& ec;
    1526              :         parse_event& event;
    1527              : 
    1528              :         template< class I >
    1529          416 :         bool operator()( I ) const
    1530              :         {
    1531          416 :             auto& handler = variant2::get<I::value + 1>(self->inner_);
    1532              :             using Handler = remove_cvref<decltype(handler)>;
    1533          416 :             return variant2::visit(
    1534          832 :                 event_visitor<Handler>{handler, ec}, event );
    1535              :         }
    1536              :     };
    1537          286 :     bool process_events(system::error_code& ec)
    1538              :     {
    1539          286 :         constexpr std::size_t N = variant_size::value;
    1540              : 
    1541              :         // should be pointers not iterators, otherwise MSVC crashes
    1542          286 :         auto const last = events_.data() + events_.size();
    1543          286 :         auto first = last - 1;
    1544          286 :         bool ok = false;
    1545              : 
    1546          286 :         if( inner_active_ < 0 )
    1547          146 :             next_alternative();
    1548              :         do
    1549              :         {
    1550          373 :             if( static_cast<std::size_t>(inner_active_) >= N )
    1551              :             {
    1552            6 :                 BOOST_JSON_FAIL( ec, error::exhausted_variants );
    1553            6 :                 return false;
    1554              :             }
    1555              : 
    1556          696 :             for ( ; first != last; ++first )
    1557              :             {
    1558          832 :                 ok = mp11::mp_with_index< N >(
    1559          416 :                     inner_active_, event_processor{this, ec, *first} );
    1560          416 :                 if( !ok )
    1561              :                 {
    1562           87 :                     first = events_.data();
    1563           87 :                     next_alternative();
    1564           87 :                     ec.clear();
    1565           87 :                     break;
    1566              :                 }
    1567              :             }
    1568              :         }
    1569          367 :         while( !ok );
    1570              : 
    1571          280 :         return true;
    1572              :     }
    1573              : 
    1574              : #define BOOST_JSON_INVOKE_INNER(ev, ec) \
    1575              :     events_.emplace_back( ev ); \
    1576              :     return process_events(ec);
    1577              : 
    1578            7 :     bool on_object_begin( system::error_code& ec )
    1579              :     {
    1580            7 :         BOOST_JSON_INVOKE_INNER( object_begin_handler_event{}, ec );
    1581              :     }
    1582              : 
    1583            7 :     bool on_object_end( system::error_code& ec )
    1584              :     {
    1585            7 :         BOOST_JSON_INVOKE_INNER( object_end_handler_event{}, ec );
    1586              :     }
    1587              : 
    1588           21 :     bool on_array_begin( system::error_code& ec )
    1589              :     {
    1590           21 :         BOOST_JSON_INVOKE_INNER( array_begin_handler_event{}, ec );
    1591              :     }
    1592              : 
    1593           28 :     bool on_array_end( system::error_code& ec )
    1594              :     {
    1595           28 :         if( !inner_active_ )
    1596            7 :             return signal_end(ec);
    1597              : 
    1598           21 :         BOOST_JSON_INVOKE_INNER( array_end_handler_event{}, ec );
    1599              :     }
    1600              : 
    1601            5 :     bool on_key_part( system::error_code&, string_view sv )
    1602              :     {
    1603            5 :         string_.append(sv);
    1604            5 :         return true;
    1605              :     }
    1606              : 
    1607           14 :     bool on_key( system::error_code& ec, string_view sv )
    1608              :     {
    1609           14 :         string_.append(sv);
    1610           28 :         BOOST_JSON_INVOKE_INNER( key_handler_event{ std::move(string_) }, ec );
    1611           14 :     }
    1612              : 
    1613           31 :     bool on_string_part( system::error_code&, string_view sv )
    1614              :     {
    1615           31 :         string_.append(sv);
    1616           31 :         return true;
    1617              :     }
    1618              : 
    1619           48 :     bool on_string( system::error_code& ec, string_view sv )
    1620              :     {
    1621           48 :         string_.append(sv);
    1622           96 :         BOOST_JSON_INVOKE_INNER(
    1623              :             string_handler_event{ std::move(string_) }, ec );
    1624           48 :     }
    1625              : 
    1626           60 :     bool on_number_part( system::error_code& )
    1627              :     {
    1628           60 :         return true;
    1629              :     }
    1630              : 
    1631          133 :     bool on_int64( system::error_code& ec, std::int64_t v )
    1632              :     {
    1633          133 :         BOOST_JSON_INVOKE_INNER( int64_handler_event{v}, ec );
    1634              :     }
    1635              : 
    1636            7 :     bool on_uint64( system::error_code& ec, std::uint64_t v )
    1637              :     {
    1638            7 :         BOOST_JSON_INVOKE_INNER( uint64_handler_event{v}, ec );
    1639              :     }
    1640              : 
    1641           14 :     bool on_double( system::error_code& ec, double v )
    1642              :     {
    1643           14 :         BOOST_JSON_INVOKE_INNER( double_handler_event{v}, ec );
    1644              :     }
    1645              : 
    1646            7 :     bool on_bool( system::error_code& ec, bool v )
    1647              :     {
    1648            7 :         BOOST_JSON_INVOKE_INNER( bool_handler_event{v}, ec );
    1649              :     }
    1650              : 
    1651            7 :     bool on_null( system::error_code& ec )
    1652              :     {
    1653            7 :         BOOST_JSON_INVOKE_INNER( null_handler_event{}, ec );
    1654              :     }
    1655              : 
    1656              : #undef BOOST_JSON_INVOKE_INNER
    1657              : };
    1658              : 
    1659              : // optional handler
    1660              : template<class V, class P>
    1661              : class converting_handler<optional_conversion_tag, V, P>
    1662              : {
    1663              : private:
    1664              :     using inner_type = value_result_type<V>;
    1665              :     using inner_handler_type = get_handler<inner_type, converting_handler>;
    1666              : 
    1667              :     V* value_;
    1668              :     P* parent_;
    1669              : 
    1670              :     inner_type inner_value_ = {};
    1671              :     inner_handler_type inner_;
    1672              :     bool inner_active_ = false;
    1673              : 
    1674              : public:
    1675              :     converting_handler( converting_handler const& ) = delete;
    1676              :     converting_handler& operator=( converting_handler const& ) = delete;
    1677              : 
    1678              :     converting_handler( V* v, P* p )
    1679              :         : value_(v), parent_(p), inner_(&inner_value_, this)
    1680              :     {}
    1681              : 
    1682              :     bool signal_value(system::error_code& ec)
    1683              :     {
    1684              :         *value_ = std::move(inner_value_);
    1685              : 
    1686              :         inner_active_ = false;
    1687              :         return parent_->signal_value(ec);
    1688              :     }
    1689              : 
    1690              :     bool signal_end(system::error_code& ec)
    1691              :     {
    1692              :         return parent_->signal_end(ec);
    1693              :     }
    1694              : 
    1695              : #define BOOST_JSON_INVOKE_INNER(fn) \
    1696              :     if( !inner_active_ ) \
    1697              :         inner_active_ = true; \
    1698              :     return inner_.fn;
    1699              : 
    1700              :     bool on_object_begin( system::error_code& ec )
    1701              :     {
    1702              :         BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
    1703              :     }
    1704              : 
    1705              :     bool on_object_end( system::error_code& ec )
    1706              :     {
    1707              :         BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
    1708              :     }
    1709              : 
    1710              :     bool on_array_begin( system::error_code& ec )
    1711              :     {
    1712              :         BOOST_JSON_INVOKE_INNER( on_array_begin(ec) );
    1713              :     }
    1714              : 
    1715              :     bool on_array_end( system::error_code& ec )
    1716              :     {
    1717              :         if( !inner_active_ )
    1718              :             return signal_end(ec);
    1719              : 
    1720              :         BOOST_JSON_INVOKE_INNER( on_array_end(ec) );
    1721              :     }
    1722              : 
    1723              :     bool on_key_part( system::error_code& ec, string_view sv )
    1724              :     {
    1725              :         BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
    1726              :     }
    1727              : 
    1728              :     bool on_key( system::error_code& ec, string_view sv )
    1729              :     {
    1730              :         BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
    1731              :     }
    1732              : 
    1733              :     bool on_string_part( system::error_code& ec, string_view sv )
    1734              :     {
    1735              :         BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
    1736              :     }
    1737              : 
    1738              :     bool on_string( system::error_code& ec, string_view sv )
    1739              :     {
    1740              :         BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
    1741              :     }
    1742              : 
    1743              :     bool on_number_part( system::error_code& ec )
    1744              :     {
    1745              :         BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
    1746              :     }
    1747              : 
    1748              :     bool on_int64( system::error_code& ec, std::int64_t v )
    1749              :     {
    1750              :         BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
    1751              :     }
    1752              : 
    1753              :     bool on_uint64( system::error_code& ec, std::uint64_t v )
    1754              :     {
    1755              :         BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
    1756              :     }
    1757              : 
    1758              :     bool on_double( system::error_code& ec, double v )
    1759              :     {
    1760              :         BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
    1761              :     }
    1762              : 
    1763              :     bool on_bool( system::error_code& ec, bool v )
    1764              :     {
    1765              :         BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
    1766              :     }
    1767              : 
    1768              :     bool on_null(system::error_code& ec)
    1769              :     {
    1770              :         if( !inner_active_ )
    1771              :         {
    1772              :             *value_ = {};
    1773              :             return this->parent_->signal_value(ec);
    1774              :         }
    1775              :         else
    1776              :         {
    1777              :             return inner_.on_null(ec);
    1778              :         }
    1779              :     }
    1780              : 
    1781              : #undef BOOST_JSON_INVOKE_INNER
    1782              : };
    1783              : 
    1784              : // path handler
    1785              : template< class V, class P >
    1786              : class converting_handler<path_conversion_tag, V, P>
    1787              :     : public scalar_handler<P, error::not_string>
    1788              : {
    1789              : private:
    1790              :     V* value_;
    1791              :     bool cleared_ = false;
    1792              : 
    1793              : public:
    1794              :     converting_handler( V* v, P* p )
    1795              :         : converting_handler::scalar_handler(p)
    1796              :         , value_(v)
    1797              :     {}
    1798              : 
    1799              :     bool on_string_part( system::error_code&, string_view sv )
    1800              :     {
    1801              :         if( !cleared_ )
    1802              :         {
    1803              :             cleared_ = true;
    1804              :             value_->clear();
    1805              :         }
    1806              : 
    1807              :         value_->concat( sv.begin(), sv.end() );
    1808              :         return true;
    1809              :     }
    1810              : 
    1811              :     bool on_string(system::error_code& ec, string_view sv)
    1812              :     {
    1813              :         if( !cleared_ )
    1814              :             value_->clear();
    1815              :         else
    1816              :             cleared_ = false;
    1817              : 
    1818              :         value_->concat( sv.begin(), sv.end() );
    1819              : 
    1820              :         return this->parent_->signal_value(ec);
    1821              :     }
    1822              : };
    1823              : 
    1824              : // into_handler
    1825              : template< class V >
    1826              : class into_handler
    1827              : {
    1828              : private:
    1829              : 
    1830              :     using inner_handler_type = get_handler<V, into_handler>;
    1831              : 
    1832              :     inner_handler_type inner_;
    1833              :     bool inner_active_ = true;
    1834              : 
    1835              : public:
    1836              : 
    1837              :     into_handler( into_handler const& ) = delete;
    1838              :     into_handler& operator=( into_handler const& ) = delete;
    1839              : 
    1840              : public:
    1841              : 
    1842              :     static constexpr std::size_t max_object_size = object::max_size();
    1843              :     static constexpr std::size_t max_array_size = array::max_size();
    1844              :     static constexpr std::size_t max_key_size = string::max_size();
    1845              :     static constexpr std::size_t max_string_size = string::max_size();
    1846              : 
    1847              : public:
    1848              : 
    1849          522 :     explicit into_handler( V* v ): inner_( v, this )
    1850              :     {
    1851          522 :     }
    1852              : 
    1853          466 :     bool signal_value(system::error_code&)
    1854              :     {
    1855          466 :         return true;
    1856              :     }
    1857              : 
    1858            7 :     bool signal_end(system::error_code&)
    1859              :     {
    1860            7 :         return true;
    1861              :     }
    1862              : 
    1863          521 :     bool on_document_begin( system::error_code& )
    1864              :     {
    1865          521 :         return true;
    1866              :     }
    1867              : 
    1868          473 :     bool on_document_end( system::error_code& )
    1869              :     {
    1870          473 :         inner_active_ = false;
    1871          473 :         return true;
    1872              :     }
    1873              : 
    1874              : #define BOOST_JSON_INVOKE_INNER(f) \
    1875              :     if( !inner_active_ ) \
    1876              :     { \
    1877              :         BOOST_JSON_FAIL( ec, error::extra_data ); \
    1878              :         return false; \
    1879              :     } \
    1880              :     else \
    1881              :         return inner_.f
    1882              : 
    1883          144 :     bool on_object_begin( system::error_code& ec )
    1884              :     {
    1885          144 :         BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
    1886              :     }
    1887              : 
    1888          138 :     bool on_object_end( std::size_t, system::error_code& ec )
    1889              :     {
    1890          138 :         BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
    1891              :     }
    1892              : 
    1893          418 :     bool on_array_begin( system::error_code& ec )
    1894              :     {
    1895          418 :         BOOST_JSON_INVOKE_INNER( on_array_begin(ec) );
    1896              :     }
    1897              : 
    1898          404 :     bool on_array_end( std::size_t, system::error_code& ec )
    1899              :     {
    1900          404 :         BOOST_JSON_INVOKE_INNER( on_array_end(ec) );
    1901              :     }
    1902              : 
    1903           48 :     bool on_key_part( string_view sv, std::size_t, system::error_code& ec )
    1904              :     {
    1905           48 :         BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
    1906              :     }
    1907              : 
    1908          139 :     bool on_key( string_view sv, std::size_t, system::error_code& ec )
    1909              :     {
    1910          139 :         BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
    1911              :     }
    1912              : 
    1913           54 :     bool on_string_part( string_view sv, std::size_t, system::error_code& ec )
    1914              :     {
    1915           54 :         BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
    1916              :     }
    1917              : 
    1918          101 :     bool on_string( string_view sv, std::size_t, system::error_code& ec )
    1919              :     {
    1920          101 :         BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
    1921              :     }
    1922              : 
    1923          484 :     bool on_number_part( string_view, system::error_code& ec )
    1924              :     {
    1925          484 :         BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
    1926              :     }
    1927              : 
    1928          707 :     bool on_int64( std::int64_t v, string_view, system::error_code& ec )
    1929              :     {
    1930          707 :         BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
    1931              :     }
    1932              : 
    1933           39 :     bool on_uint64( std::uint64_t v, string_view, system::error_code& ec )
    1934              :     {
    1935           39 :         BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
    1936              :     }
    1937              : 
    1938           63 :     bool on_double( double v, string_view, system::error_code& ec )
    1939              :     {
    1940           63 :         BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
    1941              :     }
    1942              : 
    1943           44 :     bool on_bool( bool v, system::error_code& ec )
    1944              :     {
    1945           44 :         BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
    1946              :     }
    1947              : 
    1948           39 :     bool on_null( system::error_code& ec )
    1949              :     {
    1950           39 :         BOOST_JSON_INVOKE_INNER( on_null(ec) );
    1951              :     }
    1952              : 
    1953         1254 :     bool on_comment_part(string_view, system::error_code&)
    1954              :     {
    1955         1254 :         return true;
    1956              :     }
    1957              : 
    1958           66 :     bool on_comment(string_view, system::error_code&)
    1959              :     {
    1960           66 :         return true;
    1961              :     }
    1962              : 
    1963              : #undef BOOST_JSON_INVOKE_INNER
    1964              : };
    1965              : 
    1966              : } // namespace detail
    1967              : } // namespace boost
    1968              : } // namespace json
    1969              : 
    1970              : #endif
        

Generated by: LCOV version 2.1