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 % 426 426
Test Date: 2025-12-23 17:20:51 Functions: 43.6 % 4594 2001

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

Generated by: LCOV version 2.1