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 % 426 426
Test Date: 2026-03-05 09:04:27 Functions: 43.6 % 4594 2001 2593

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

Generated by: LCOV version 2.3