LCOV - code coverage report
Current view: top level - json/detail - parse_into.hpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 100.0 % 395 395
Test Date: 2026-07-10 12:38:05 Functions: 41.1 % 4061 1670 2391

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

Generated by: LCOV version 2.3