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:38:56 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              :     static_assert(
    1134              :         uniquely_named_members<V>::value,
    1135              :         "The type has several described members with the same name.");
    1136              : 
    1137              :     using Dm = described_members<V>;
    1138              :     using Dt = struct_element_list<V>;
    1139              : 
    1140              :     template<class T>
    1141              :     using MemberHandler = get_handler<T, converting_handler>;
    1142              :     using InnerHandlers = mp11::mp_push_back<
    1143              :         mp11::mp_transform<MemberHandler, Dt>,
    1144              :         ignoring_handler<converting_handler> >;
    1145              :     using InnerCount = mp11::mp_size<InnerHandlers>;
    1146              : 
    1147              :     V* value_;
    1148              :     P* parent_;
    1149              : 
    1150              :     std::string key_;
    1151              : 
    1152              :     handler_tuple<converting_handler, InnerHandlers> handlers_;
    1153              :     int inner_active_ = -1;
    1154              :     std::size_t activated_ = 0;
    1155              : 
    1156              : public:
    1157              :     converting_handler( converting_handler const& ) = delete;
    1158              :     converting_handler& operator=( converting_handler const& ) = delete;
    1159              : 
    1160              :     converting_handler( V* v, P* p )
    1161              :         : value_(v), parent_(p), handlers_(struct_accessor(), v, this)
    1162              :     {}
    1163              : 
    1164              :     struct is_required_checker
    1165              :     {
    1166              :         bool operator()( mp11::mp_size<Dt> ) const noexcept
    1167              :         {
    1168              :             return false;
    1169              :         }
    1170              : 
    1171              :         template< class I >
    1172              :         auto operator()( I ) const noexcept
    1173              :         {
    1174              :             using T = mp11::mp_at<Dt, I>;
    1175              :             return !is_optional_like<T>::value;
    1176              :         }
    1177              :     };
    1178              : 
    1179              :     bool signal_value(system::error_code&)
    1180              :     {
    1181              :         BOOST_ASSERT( inner_active_ >= 0 );
    1182              :         bool required_member = mp11::mp_with_index<InnerCount>(
    1183              :             inner_active_,
    1184              :             is_required_checker{});
    1185              :         if( required_member )
    1186              :             ++activated_;
    1187              : 
    1188              :         key_ = {};
    1189              :         inner_active_ = -1;
    1190              :         return true;
    1191              :     }
    1192              : 
    1193              :     bool signal_end(system::error_code& ec)
    1194              :     {
    1195              :         key_ = {};
    1196              :         inner_active_ = -1;
    1197              :         return parent_->signal_value(ec);
    1198              :     }
    1199              : 
    1200              : #define BOOST_JSON_INVOKE_INNER(fn) \
    1201              :     if( inner_active_ < 0 ) \
    1202              :     { \
    1203              :         BOOST_JSON_FAIL( ec, error::not_object ); \
    1204              :         return false; \
    1205              :     } \
    1206              :     auto f = [&](auto& handler) { return handler.fn ; }; \
    1207              :     using F = decltype(f); \
    1208              :     using H = decltype(handlers_); \
    1209              :     return mp11::mp_with_index<InnerCount>( \
    1210              :             inner_active_, \
    1211              :             tuple_handler_op_invoker<H, F>{handlers_, f} );
    1212              : 
    1213              :     bool on_object_begin( system::error_code& ec )
    1214              :     {
    1215              :         if( inner_active_ < 0 )
    1216              :             return true;
    1217              : 
    1218              :         BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
    1219              :     }
    1220              : 
    1221              :     bool on_object_end( system::error_code& ec )
    1222              :     {
    1223              :         if( inner_active_ < 0 )
    1224              :         {
    1225              :             using C = mp11::mp_count_if<Dt, is_optional_like>;
    1226              :             constexpr int N = mp11::mp_size<Dt>::value - C::value;
    1227              :             if( activated_ < N )
    1228              :             {
    1229              :                 BOOST_JSON_FAIL( ec, error::size_mismatch );
    1230              :                 return false;
    1231              :             }
    1232              : 
    1233              :             return parent_->signal_value(ec);
    1234              :         }
    1235              : 
    1236              :         BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
    1237              :     }
    1238              : 
    1239              :     bool on_array_begin( system::error_code& ec )
    1240              :     {
    1241              :         BOOST_JSON_INVOKE_INNER( on_array_begin(ec) );
    1242              :     }
    1243              : 
    1244              :     bool on_array_end( system::error_code& ec )
    1245              :     {
    1246              :         if( inner_active_ < 0 )
    1247              :             return parent_->signal_end(ec);
    1248              : 
    1249              :         BOOST_JSON_INVOKE_INNER( on_array_end(ec) );
    1250              :     }
    1251              : 
    1252              :     bool on_key_part( system::error_code& ec, string_view sv )
    1253              :     {
    1254              :         if( inner_active_ < 0 )
    1255              :         {
    1256              :             key_.append( sv.data(), sv.size() );
    1257              :             return true;
    1258              :         }
    1259              : 
    1260              :         BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
    1261              :     }
    1262              : 
    1263              :     bool on_key( system::error_code& ec, string_view sv )
    1264              :     {
    1265              :         if( inner_active_ >= 0 )
    1266              :         {
    1267              :             BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
    1268              :         }
    1269              : 
    1270              :         string_view key = sv;
    1271              :         if( !key_.empty() )
    1272              :         {
    1273              :             key_.append( sv.data(), sv.size() );
    1274              :             key = key_;
    1275              :         }
    1276              : 
    1277              :         inner_active_ = InnerCount::value - 1;
    1278              :         mp11::mp_for_each<Dm>( struct_key_searcher(key, inner_active_) );
    1279              :         return true;
    1280              :     }
    1281              : 
    1282              :     bool on_string_part( system::error_code& ec, string_view sv )
    1283              :     {
    1284              :         BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
    1285              :     }
    1286              : 
    1287              :     bool on_string( system::error_code& ec, string_view sv )
    1288              :     {
    1289              :         BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
    1290              :     }
    1291              : 
    1292              :     bool on_number_part( system::error_code& ec )
    1293              :     {
    1294              :         BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
    1295              :     }
    1296              : 
    1297              :     bool on_int64( system::error_code& ec, std::int64_t v )
    1298              :     {
    1299              :         BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
    1300              :     }
    1301              : 
    1302              :     bool on_uint64( system::error_code& ec, std::uint64_t v )
    1303              :     {
    1304              :         BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
    1305              :     }
    1306              : 
    1307              :     bool on_double( system::error_code& ec, double v )
    1308              :     {
    1309              :         BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
    1310              :     }
    1311              : 
    1312              :     bool on_bool( system::error_code& ec, bool v )
    1313              :     {
    1314              :         BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
    1315              :     }
    1316              : 
    1317              :     bool on_null( system::error_code& ec )
    1318              :     {
    1319              :         BOOST_JSON_INVOKE_INNER( on_null(ec) );
    1320              :     }
    1321              : 
    1322              : #undef BOOST_JSON_INVOKE_INNER
    1323              : 
    1324              : #endif
    1325              : };
    1326              : 
    1327              : // variant handler
    1328              : struct object_begin_handler_event
    1329              : { };
    1330              : 
    1331              : struct object_end_handler_event
    1332              : { };
    1333              : 
    1334              : struct array_begin_handler_event
    1335              : { };
    1336              : 
    1337              : struct array_end_handler_event
    1338              : { };
    1339              : 
    1340              : struct key_handler_event
    1341              : {
    1342              :     std::string value;
    1343              : };
    1344              : 
    1345              : struct string_handler_event
    1346              : {
    1347              :     std::string value;
    1348              : };
    1349              : 
    1350              : struct int64_handler_event
    1351              : {
    1352              :     std::int64_t value;
    1353              : };
    1354              : 
    1355              : struct uint64_handler_event
    1356              : {
    1357              :     std::uint64_t value;
    1358              : };
    1359              : 
    1360              : struct double_handler_event
    1361              : {
    1362              :     double value;
    1363              : };
    1364              : 
    1365              : struct bool_handler_event
    1366              : {
    1367              :     bool value;
    1368              : };
    1369              : 
    1370              : struct null_handler_event
    1371              : { };
    1372              : 
    1373              : using parse_event = variant2::variant<
    1374              :     object_begin_handler_event,
    1375              :     object_end_handler_event,
    1376              :     array_begin_handler_event,
    1377              :     array_end_handler_event,
    1378              :     key_handler_event,
    1379              :     string_handler_event,
    1380              :     int64_handler_event,
    1381              :     uint64_handler_event,
    1382              :     double_handler_event,
    1383              :     bool_handler_event,
    1384              :     null_handler_event>;
    1385              : 
    1386              : template< class H >
    1387              : struct event_visitor
    1388              : {
    1389              :     H& handler;
    1390              :     system::error_code& ec;
    1391              : 
    1392              :     bool
    1393           14 :     operator()(object_begin_handler_event&) const
    1394              :     {
    1395           14 :         return handler.on_object_begin(ec);
    1396              :     }
    1397              : 
    1398              :     bool
    1399            7 :     operator()(object_end_handler_event&) const
    1400              :     {
    1401            7 :         return handler.on_object_end(ec);
    1402              :     }
    1403              : 
    1404              :     bool
    1405           42 :     operator()(array_begin_handler_event&) const
    1406              :     {
    1407           42 :         return handler.on_array_begin(ec);
    1408              :     }
    1409              : 
    1410              :     bool
    1411           21 :     operator()(array_end_handler_event&) const
    1412              :     {
    1413           21 :         return handler.on_array_end(ec);
    1414              :     }
    1415              : 
    1416              :     bool
    1417           21 :     operator()(key_handler_event& ev) const
    1418              :     {
    1419           21 :         return handler.on_key(ec, ev.value);
    1420              :     }
    1421              : 
    1422              :     bool
    1423          108 :     operator()(string_handler_event& ev) const
    1424              :     {
    1425          108 :         return handler.on_string(ec, ev.value);
    1426              :     }
    1427              : 
    1428              :     bool
    1429          154 :     operator()(int64_handler_event& ev) const
    1430              :     {
    1431          154 :         return handler.on_int64(ec, ev.value);
    1432              :     }
    1433              : 
    1434              :     bool
    1435           14 :     operator()(uint64_handler_event& ev) const
    1436              :     {
    1437           14 :         return handler.on_uint64(ec, ev.value);
    1438              :     }
    1439              : 
    1440              :     bool
    1441           21 :     operator()(double_handler_event& ev) const
    1442              :     {
    1443           21 :         return handler.on_double(ec, ev.value);
    1444              :     }
    1445              : 
    1446              :     bool
    1447            7 :     operator()(bool_handler_event& ev) const
    1448              :     {
    1449            7 :         return handler.on_bool(ec, ev.value);
    1450              :     }
    1451              : 
    1452              :     bool
    1453            7 :     operator()(null_handler_event&) const
    1454              :     {
    1455            7 :         return handler.on_null(ec);
    1456              :     }
    1457              : };
    1458              : 
    1459              : // L<T...> -> variant< monostate, get_handler<T, P>... >
    1460              : template< class P, class L >
    1461              : using inner_handler_variant = mp11::mp_push_front<
    1462              :     mp11::mp_transform_q<
    1463              :         mp11::mp_bind_back<get_handler, P>,
    1464              :         mp11::mp_apply<variant2::variant, L>>,
    1465              :     variant2::monostate>;
    1466              : 
    1467              : template< class T, class P >
    1468              : class converting_handler<variant_conversion_tag, T, P>
    1469              : {
    1470              : private:
    1471              :     using variant_size = mp11::mp_size<T>;
    1472              : 
    1473              :     T* value_;
    1474              :     P* parent_;
    1475              : 
    1476              :     std::string string_;
    1477              :     std::vector< parse_event > events_;
    1478              :     inner_handler_variant<converting_handler, T> inner_;
    1479              :     int inner_active_ = -1;
    1480              : 
    1481              : public:
    1482              :     converting_handler( converting_handler const& ) = delete;
    1483              :     converting_handler& operator=( converting_handler const& ) = delete;
    1484              : 
    1485           90 :     converting_handler( T* v, P* p )
    1486           90 :         : value_( v )
    1487           90 :         , parent_( p )
    1488           90 :     {}
    1489              : 
    1490          126 :     bool signal_value(system::error_code& ec)
    1491              :     {
    1492          126 :         inner_.template emplace<0>();
    1493          126 :         inner_active_ = -1;
    1494          126 :         events_.clear();
    1495          126 :         return parent_->signal_value(ec);
    1496              :     }
    1497              : 
    1498           14 :     bool signal_end(system::error_code& ec)
    1499              :     {
    1500           14 :         return parent_->signal_end(ec);
    1501              :     }
    1502              : 
    1503              :     struct alternative_selector
    1504              :     {
    1505              :         converting_handler* self;
    1506              : 
    1507              :         template< class I >
    1508              :         void
    1509          227 :         operator()( I ) const
    1510              :         {
    1511              :             using V = mp11::mp_at<T, I>;
    1512          227 :             auto& v = self->value_->template emplace<I::value>( V{} );
    1513          227 :             self->inner_.template emplace<I::value + 1>(&v, self);
    1514          227 :         }
    1515              :     };
    1516              :     void
    1517          233 :     next_alternative()
    1518              :     {
    1519          233 :         if( ++inner_active_ >= static_cast<int>(variant_size::value) )
    1520            6 :             return;
    1521              : 
    1522          227 :         mp11::mp_with_index< variant_size::value >(
    1523          227 :             inner_active_, alternative_selector{this} );
    1524              :     }
    1525              : 
    1526              :     struct event_processor
    1527              :     {
    1528              :         converting_handler* self;
    1529              :         system::error_code& ec;
    1530              :         parse_event& event;
    1531              : 
    1532              :         template< class I >
    1533          416 :         bool operator()( I ) const
    1534              :         {
    1535          416 :             auto& handler = variant2::get<I::value + 1>(self->inner_);
    1536              :             using Handler = remove_cvref<decltype(handler)>;
    1537          416 :             return variant2::visit(
    1538          832 :                 event_visitor<Handler>{handler, ec}, event );
    1539              :         }
    1540              :     };
    1541          286 :     bool process_events(system::error_code& ec)
    1542              :     {
    1543          286 :         constexpr std::size_t N = variant_size::value;
    1544              : 
    1545              :         // should be pointers not iterators, otherwise MSVC crashes
    1546          286 :         auto const last = events_.data() + events_.size();
    1547          286 :         auto first = last - 1;
    1548          286 :         bool ok = false;
    1549              : 
    1550          286 :         if( inner_active_ < 0 )
    1551          146 :             next_alternative();
    1552              :         do
    1553              :         {
    1554          373 :             if( static_cast<std::size_t>(inner_active_) >= N )
    1555              :             {
    1556            6 :                 BOOST_JSON_FAIL( ec, error::exhausted_variants );
    1557            6 :                 return false;
    1558              :             }
    1559              : 
    1560          696 :             for ( ; first != last; ++first )
    1561              :             {
    1562          832 :                 ok = mp11::mp_with_index< N >(
    1563          416 :                     inner_active_, event_processor{this, ec, *first} );
    1564          416 :                 if( !ok )
    1565              :                 {
    1566           87 :                     first = events_.data();
    1567           87 :                     next_alternative();
    1568           87 :                     ec.clear();
    1569           87 :                     break;
    1570              :                 }
    1571              :             }
    1572              :         }
    1573          367 :         while( !ok );
    1574              : 
    1575          280 :         return true;
    1576              :     }
    1577              : 
    1578              : #define BOOST_JSON_INVOKE_INNER(ev, ec) \
    1579              :     events_.emplace_back( ev ); \
    1580              :     return process_events(ec);
    1581              : 
    1582            7 :     bool on_object_begin( system::error_code& ec )
    1583              :     {
    1584            7 :         BOOST_JSON_INVOKE_INNER( object_begin_handler_event{}, ec );
    1585              :     }
    1586              : 
    1587            7 :     bool on_object_end( system::error_code& ec )
    1588              :     {
    1589            7 :         BOOST_JSON_INVOKE_INNER( object_end_handler_event{}, ec );
    1590              :     }
    1591              : 
    1592           21 :     bool on_array_begin( system::error_code& ec )
    1593              :     {
    1594           21 :         BOOST_JSON_INVOKE_INNER( array_begin_handler_event{}, ec );
    1595              :     }
    1596              : 
    1597           28 :     bool on_array_end( system::error_code& ec )
    1598              :     {
    1599           28 :         if( !inner_active_ )
    1600            7 :             return signal_end(ec);
    1601              : 
    1602           21 :         BOOST_JSON_INVOKE_INNER( array_end_handler_event{}, ec );
    1603              :     }
    1604              : 
    1605            5 :     bool on_key_part( system::error_code&, string_view sv )
    1606              :     {
    1607            5 :         string_.append(sv);
    1608            5 :         return true;
    1609              :     }
    1610              : 
    1611           14 :     bool on_key( system::error_code& ec, string_view sv )
    1612              :     {
    1613           14 :         string_.append(sv);
    1614           28 :         BOOST_JSON_INVOKE_INNER( key_handler_event{ std::move(string_) }, ec );
    1615           14 :     }
    1616              : 
    1617           31 :     bool on_string_part( system::error_code&, string_view sv )
    1618              :     {
    1619           31 :         string_.append(sv);
    1620           31 :         return true;
    1621              :     }
    1622              : 
    1623           48 :     bool on_string( system::error_code& ec, string_view sv )
    1624              :     {
    1625           48 :         string_.append(sv);
    1626           96 :         BOOST_JSON_INVOKE_INNER(
    1627              :             string_handler_event{ std::move(string_) }, ec );
    1628           48 :     }
    1629              : 
    1630           60 :     bool on_number_part( system::error_code& )
    1631              :     {
    1632           60 :         return true;
    1633              :     }
    1634              : 
    1635          133 :     bool on_int64( system::error_code& ec, std::int64_t v )
    1636              :     {
    1637          133 :         BOOST_JSON_INVOKE_INNER( int64_handler_event{v}, ec );
    1638              :     }
    1639              : 
    1640            7 :     bool on_uint64( system::error_code& ec, std::uint64_t v )
    1641              :     {
    1642            7 :         BOOST_JSON_INVOKE_INNER( uint64_handler_event{v}, ec );
    1643              :     }
    1644              : 
    1645           14 :     bool on_double( system::error_code& ec, double v )
    1646              :     {
    1647           14 :         BOOST_JSON_INVOKE_INNER( double_handler_event{v}, ec );
    1648              :     }
    1649              : 
    1650            7 :     bool on_bool( system::error_code& ec, bool v )
    1651              :     {
    1652            7 :         BOOST_JSON_INVOKE_INNER( bool_handler_event{v}, ec );
    1653              :     }
    1654              : 
    1655            7 :     bool on_null( system::error_code& ec )
    1656              :     {
    1657            7 :         BOOST_JSON_INVOKE_INNER( null_handler_event{}, ec );
    1658              :     }
    1659              : 
    1660              : #undef BOOST_JSON_INVOKE_INNER
    1661              : };
    1662              : 
    1663              : // optional handler
    1664              : template<class V, class P>
    1665              : class converting_handler<optional_conversion_tag, V, P>
    1666              : {
    1667              : private:
    1668              :     using inner_type = value_result_type<V>;
    1669              :     using inner_handler_type = get_handler<inner_type, converting_handler>;
    1670              : 
    1671              :     V* value_;
    1672              :     P* parent_;
    1673              : 
    1674              :     inner_type inner_value_ = {};
    1675              :     inner_handler_type inner_;
    1676              :     bool inner_active_ = false;
    1677              : 
    1678              : public:
    1679              :     converting_handler( converting_handler const& ) = delete;
    1680              :     converting_handler& operator=( converting_handler const& ) = delete;
    1681              : 
    1682              :     converting_handler( V* v, P* p )
    1683              :         : value_(v), parent_(p), inner_(&inner_value_, this)
    1684              :     {}
    1685              : 
    1686              :     bool signal_value(system::error_code& ec)
    1687              :     {
    1688              :         *value_ = std::move(inner_value_);
    1689              : 
    1690              :         inner_active_ = false;
    1691              :         return parent_->signal_value(ec);
    1692              :     }
    1693              : 
    1694              :     bool signal_end(system::error_code& ec)
    1695              :     {
    1696              :         return parent_->signal_end(ec);
    1697              :     }
    1698              : 
    1699              : #define BOOST_JSON_INVOKE_INNER(fn) \
    1700              :     if( !inner_active_ ) \
    1701              :         inner_active_ = true; \
    1702              :     return inner_.fn;
    1703              : 
    1704              :     bool on_object_begin( system::error_code& ec )
    1705              :     {
    1706              :         BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
    1707              :     }
    1708              : 
    1709              :     bool on_object_end( system::error_code& ec )
    1710              :     {
    1711              :         BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
    1712              :     }
    1713              : 
    1714              :     bool on_array_begin( system::error_code& ec )
    1715              :     {
    1716              :         BOOST_JSON_INVOKE_INNER( on_array_begin(ec) );
    1717              :     }
    1718              : 
    1719              :     bool on_array_end( system::error_code& ec )
    1720              :     {
    1721              :         if( !inner_active_ )
    1722              :             return signal_end(ec);
    1723              : 
    1724              :         BOOST_JSON_INVOKE_INNER( on_array_end(ec) );
    1725              :     }
    1726              : 
    1727              :     bool on_key_part( system::error_code& ec, string_view sv )
    1728              :     {
    1729              :         BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
    1730              :     }
    1731              : 
    1732              :     bool on_key( system::error_code& ec, string_view sv )
    1733              :     {
    1734              :         BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
    1735              :     }
    1736              : 
    1737              :     bool on_string_part( system::error_code& ec, string_view sv )
    1738              :     {
    1739              :         BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
    1740              :     }
    1741              : 
    1742              :     bool on_string( system::error_code& ec, string_view sv )
    1743              :     {
    1744              :         BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
    1745              :     }
    1746              : 
    1747              :     bool on_number_part( system::error_code& ec )
    1748              :     {
    1749              :         BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
    1750              :     }
    1751              : 
    1752              :     bool on_int64( system::error_code& ec, std::int64_t v )
    1753              :     {
    1754              :         BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
    1755              :     }
    1756              : 
    1757              :     bool on_uint64( system::error_code& ec, std::uint64_t v )
    1758              :     {
    1759              :         BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
    1760              :     }
    1761              : 
    1762              :     bool on_double( system::error_code& ec, double v )
    1763              :     {
    1764              :         BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
    1765              :     }
    1766              : 
    1767              :     bool on_bool( system::error_code& ec, bool v )
    1768              :     {
    1769              :         BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
    1770              :     }
    1771              : 
    1772              :     bool on_null(system::error_code& ec)
    1773              :     {
    1774              :         if( !inner_active_ )
    1775              :         {
    1776              :             *value_ = {};
    1777              :             return this->parent_->signal_value(ec);
    1778              :         }
    1779              :         else
    1780              :         {
    1781              :             return inner_.on_null(ec);
    1782              :         }
    1783              :     }
    1784              : 
    1785              : #undef BOOST_JSON_INVOKE_INNER
    1786              : };
    1787              : 
    1788              : // path handler
    1789              : template< class V, class P >
    1790              : class converting_handler<path_conversion_tag, V, P>
    1791              :     : public scalar_handler<P, error::not_string>
    1792              : {
    1793              : private:
    1794              :     V* value_;
    1795              :     bool cleared_ = false;
    1796              : 
    1797              : public:
    1798              :     converting_handler( V* v, P* p )
    1799              :         : converting_handler::scalar_handler(p)
    1800              :         , value_(v)
    1801              :     {}
    1802              : 
    1803              :     bool on_string_part( system::error_code&, string_view sv )
    1804              :     {
    1805              :         if( !cleared_ )
    1806              :         {
    1807              :             cleared_ = true;
    1808              :             value_->clear();
    1809              :         }
    1810              : 
    1811              :         value_->concat( sv.begin(), sv.end() );
    1812              :         return true;
    1813              :     }
    1814              : 
    1815              :     bool on_string(system::error_code& ec, string_view sv)
    1816              :     {
    1817              :         if( !cleared_ )
    1818              :             value_->clear();
    1819              :         else
    1820              :             cleared_ = false;
    1821              : 
    1822              :         value_->concat( sv.begin(), sv.end() );
    1823              : 
    1824              :         return this->parent_->signal_value(ec);
    1825              :     }
    1826              : };
    1827              : 
    1828              : // into_handler
    1829              : template< class V >
    1830              : class into_handler
    1831              : {
    1832              : private:
    1833              : 
    1834              :     using inner_handler_type = get_handler<V, into_handler>;
    1835              : 
    1836              :     inner_handler_type inner_;
    1837              :     bool inner_active_ = true;
    1838              : 
    1839              : public:
    1840              : 
    1841              :     into_handler( into_handler const& ) = delete;
    1842              :     into_handler& operator=( into_handler const& ) = delete;
    1843              : 
    1844              : public:
    1845              : 
    1846              :     static constexpr std::size_t max_object_size = object::max_size();
    1847              :     static constexpr std::size_t max_array_size = array::max_size();
    1848              :     static constexpr std::size_t max_key_size = string::max_size();
    1849              :     static constexpr std::size_t max_string_size = string::max_size();
    1850              : 
    1851              : public:
    1852              : 
    1853          522 :     explicit into_handler( V* v ): inner_( v, this )
    1854              :     {
    1855          522 :     }
    1856              : 
    1857          466 :     bool signal_value(system::error_code&)
    1858              :     {
    1859          466 :         return true;
    1860              :     }
    1861              : 
    1862            7 :     bool signal_end(system::error_code&)
    1863              :     {
    1864            7 :         return true;
    1865              :     }
    1866              : 
    1867          521 :     bool on_document_begin( system::error_code& )
    1868              :     {
    1869          521 :         return true;
    1870              :     }
    1871              : 
    1872          473 :     bool on_document_end( system::error_code& )
    1873              :     {
    1874          473 :         inner_active_ = false;
    1875          473 :         return true;
    1876              :     }
    1877              : 
    1878              : #define BOOST_JSON_INVOKE_INNER(f) \
    1879              :     if( !inner_active_ ) \
    1880              :     { \
    1881              :         BOOST_JSON_FAIL( ec, error::extra_data ); \
    1882              :         return false; \
    1883              :     } \
    1884              :     else \
    1885              :         return inner_.f
    1886              : 
    1887          144 :     bool on_object_begin( system::error_code& ec )
    1888              :     {
    1889          144 :         BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
    1890              :     }
    1891              : 
    1892          138 :     bool on_object_end( std::size_t, system::error_code& ec )
    1893              :     {
    1894          138 :         BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
    1895              :     }
    1896              : 
    1897          418 :     bool on_array_begin( system::error_code& ec )
    1898              :     {
    1899          418 :         BOOST_JSON_INVOKE_INNER( on_array_begin(ec) );
    1900              :     }
    1901              : 
    1902          404 :     bool on_array_end( std::size_t, system::error_code& ec )
    1903              :     {
    1904          404 :         BOOST_JSON_INVOKE_INNER( on_array_end(ec) );
    1905              :     }
    1906              : 
    1907           48 :     bool on_key_part( string_view sv, std::size_t, system::error_code& ec )
    1908              :     {
    1909           48 :         BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
    1910              :     }
    1911              : 
    1912          139 :     bool on_key( string_view sv, std::size_t, system::error_code& ec )
    1913              :     {
    1914          139 :         BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
    1915              :     }
    1916              : 
    1917           54 :     bool on_string_part( string_view sv, std::size_t, system::error_code& ec )
    1918              :     {
    1919           54 :         BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
    1920              :     }
    1921              : 
    1922          101 :     bool on_string( string_view sv, std::size_t, system::error_code& ec )
    1923              :     {
    1924          101 :         BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
    1925              :     }
    1926              : 
    1927          484 :     bool on_number_part( string_view, system::error_code& ec )
    1928              :     {
    1929          484 :         BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
    1930              :     }
    1931              : 
    1932          707 :     bool on_int64( std::int64_t v, string_view, system::error_code& ec )
    1933              :     {
    1934          707 :         BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
    1935              :     }
    1936              : 
    1937           39 :     bool on_uint64( std::uint64_t v, string_view, system::error_code& ec )
    1938              :     {
    1939           39 :         BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
    1940              :     }
    1941              : 
    1942           63 :     bool on_double( double v, string_view, system::error_code& ec )
    1943              :     {
    1944           63 :         BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
    1945              :     }
    1946              : 
    1947           44 :     bool on_bool( bool v, system::error_code& ec )
    1948              :     {
    1949           44 :         BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
    1950              :     }
    1951              : 
    1952           39 :     bool on_null( system::error_code& ec )
    1953              :     {
    1954           39 :         BOOST_JSON_INVOKE_INNER( on_null(ec) );
    1955              :     }
    1956              : 
    1957         1254 :     bool on_comment_part(string_view, system::error_code&)
    1958              :     {
    1959         1254 :         return true;
    1960              :     }
    1961              : 
    1962           66 :     bool on_comment(string_view, system::error_code&)
    1963              :     {
    1964           66 :         return true;
    1965              :     }
    1966              : 
    1967              : #undef BOOST_JSON_INVOKE_INNER
    1968              : };
    1969              : 
    1970              : } // namespace detail
    1971              : } // namespace boost
    1972              : } // namespace json
    1973              : 
    1974              : #endif
        

Generated by: LCOV version 2.1