LCOV - code coverage report
Current view: top level - json/detail - parse_into.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 400 400
Test Date: 2025-12-23 17:21:58 Functions: 41.5 % 3913 1622

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

Generated by: LCOV version 2.1