| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975 |
- //
- // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
- // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- //
- // Official repository: https://github.com/boostorg/json
- //
- #ifndef BOOST_JSON_DETAIL_PARSE_INTO_HPP
- #define BOOST_JSON_DETAIL_PARSE_INTO_HPP
- #include <boost/json/detail/config.hpp>
- #include <boost/json/error.hpp>
- #include <boost/json/conversion.hpp>
- #include <boost/describe/enum_from_string.hpp>
- #include <vector>
- /*
- * This file contains the majority of parse_into functionality, specifically
- * the implementation of dedicated handlers for different generic categories of
- * types.
- *
- * At the core of parse_into is the specialisation basic_parser<
- * detail::into_handler<T> >. detail::into_handler<T> is a handler for
- * basic_parser. It directly handles events on_comment_part and on_comment (by
- * ignoring them), on_document_begin (by enabling the nested dedicated
- * handler), and on_document_end (by disabling the nested handler).
- *
- * Every other event is handled by the nested handler, which has the type
- * get_handler< T, into_handler<T> >. The second parameter is the parent
- * handler (in this case, it's the top handler, into_handler<T>). The type is
- * actually an alias to class template converting_handler, which has a separate
- * specialisation for every conversion category from the list of generic
- * conversion categories (e.g. sequence_conversion_tag, tuple_conversion_tag,
- * etc.) Instantiations of the template store a pointer to the parent handler
- * and a pointer to the value T.
- *
- * The nested handler handles specific parser events by setting error_code to
- * an appropriate value, if it receives an event it isn't supposed to handle
- * (e.g. a number handler getting an on_string event), and also updates the
- * value when appropriate. Note that they never need to handle on_comment_part,
- * on_comment, on_document_begin, and on_document_end events, as those are
- * always handled by the top handler into_handler<T>.
- *
- * When the nested handler receives an event that completes the current value,
- * it is supposed to call its parent's signal_value member function. This is
- * necessary for correct handling of composite types (e.g. sequences).
- *
- * Finally, nested handlers should always call parent's signal_end member
- * function if they don't handle on_array_end themselves. This is necessary
- * to correctly handle nested composites (e.g. sequences inside sequences).
- * signal_end can return false and set error state when the containing parser
- * requires more elements.
- *
- * converting_handler instantiations for composite categories of types have
- * their own nested handlers, to which they themselves delegate events. For
- * complex types you will get a tree of handlers with into_handler<T> as the
- * root and handlers for scalars as leaves.
- *
- * To reiterate, only into_handler has to handle on_comment_part, on_comment,
- * on_document_begin, and on_document_end; only handlers for composites and
- * into_handler has to provide signal_value and signal_end; all handlers
- * except for into_handler have to call their parent's signal_end from
- * their on_array_begin, if they don't handle it themselves; once a handler
- * receives an event that finishes its current value, it should call its
- * parent's signal_value.
- */
- namespace boost {
- namespace json {
- namespace detail {
- template< class Impl, class T, class Parent >
- class converting_handler;
- // get_handler
- template< class V, class P >
- using get_handler = converting_handler< generic_conversion_category<V>, V, P >;
- template<error E> class handler_error_base
- {
- public:
- handler_error_base() = default;
- handler_error_base( handler_error_base const& ) = delete;
- handler_error_base& operator=( handler_error_base const& ) = delete;
- public:
- bool on_object_begin( system::error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
- bool on_array_begin( system::error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
- bool on_array_end( system::error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
- bool on_string_part( system::error_code& ec, string_view ) { BOOST_JSON_FAIL( ec, E ); return false; }
- bool on_string( system::error_code& ec, string_view ) { BOOST_JSON_FAIL( ec, E ); return false; }
- bool on_number_part( system::error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
- bool on_int64( system::error_code& ec, std::int64_t ) { BOOST_JSON_FAIL( ec, E ); return false; }
- bool on_uint64( system::error_code& ec, std::uint64_t ) { BOOST_JSON_FAIL( ec, E ); return false; }
- bool on_double( system::error_code& ec, double ) { BOOST_JSON_FAIL( ec, E ); return false; }
- bool on_bool( system::error_code& ec, bool ) { BOOST_JSON_FAIL( ec, E ); return false; }
- bool on_null( system::error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
- // LCOV_EXCL_START
- // parses that can't handle this would fail at on_object_begin
- bool on_object_end( system::error_code& ) { BOOST_ASSERT( false ); return false; }
- bool on_key_part( system::error_code& ec, string_view ) { BOOST_JSON_FAIL( ec, E ); return false; }
- bool on_key( system::error_code& ec, string_view ) { BOOST_JSON_FAIL( ec, E ); return false; }
- // LCOV_EXCL_STOP
- };
- template< class P, error E >
- class scalar_handler
- : public handler_error_base<E>
- {
- protected:
- P* parent_;
- public:
- scalar_handler(scalar_handler const&) = delete;
- scalar_handler& operator=(scalar_handler const&) = delete;
- scalar_handler(P* p): parent_( p )
- {}
- bool on_array_end( system::error_code& ec )
- {
- return parent_->signal_end(ec);
- }
- };
- template< class D, class V, class P, error E >
- class composite_handler
- {
- protected:
- using inner_handler_type = get_handler<V, D>;
- P* parent_;
- #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
- # pragma GCC diagnostic push
- # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
- #endif
- V next_value_ = {};
- inner_handler_type inner_;
- bool inner_active_ = false;
- public:
- composite_handler( composite_handler const& ) = delete;
- composite_handler& operator=( composite_handler const& ) = delete;
- composite_handler( P* p )
- : parent_(p), inner_( &next_value_, static_cast<D*>(this) )
- {}
- #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
- # pragma GCC diagnostic pop
- #endif
- bool signal_end(system::error_code& ec)
- {
- inner_active_ = false;
- return parent_->signal_value(ec);
- }
- #define BOOST_JSON_INVOKE_INNER(f) \
- if( !inner_active_ ) { \
- BOOST_JSON_FAIL(ec, E); \
- return false; \
- } \
- else \
- return inner_.f
- bool on_object_begin( system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
- }
- bool on_object_end( system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
- }
- bool on_array_begin( system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_array_begin(ec) );
- }
- bool on_array_end( system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_array_end(ec) );
- }
- bool on_key_part( system::error_code& ec, string_view sv )
- {
- BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
- }
- bool on_key( system::error_code& ec, string_view sv )
- {
- BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
- }
- bool on_string_part( system::error_code& ec, string_view sv )
- {
- BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
- }
- bool on_string( system::error_code& ec, string_view sv )
- {
- BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
- }
- bool on_number_part( system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
- }
- bool on_int64( system::error_code& ec, std::int64_t v )
- {
- BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
- }
- bool on_uint64( system::error_code& ec, std::uint64_t v )
- {
- BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
- }
- bool on_double( system::error_code& ec, double v )
- {
- BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
- }
- bool on_bool( system::error_code& ec, bool v )
- {
- BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
- }
- bool on_null( system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_null(ec) );
- }
- #undef BOOST_JSON_INVOKE_INNER
- };
- // integral handler
- template<class V,
- typename std::enable_if<std::is_signed<V>::value, int>::type = 0>
- bool integral_in_range( std::int64_t v )
- {
- return v >= (std::numeric_limits<V>::min)() && v <= (std::numeric_limits<V>::max)();
- }
- template<class V,
- typename std::enable_if<!std::is_signed<V>::value, int>::type = 0>
- bool integral_in_range( std::int64_t v )
- {
- return v >= 0 && static_cast<std::uint64_t>( v ) <= (std::numeric_limits<V>::max)();
- }
- template<class V>
- bool integral_in_range( std::uint64_t v )
- {
- return v <= static_cast<typename std::make_unsigned<V>::type>( (std::numeric_limits<V>::max)() );
- }
- template< class V, class P >
- class converting_handler<integral_conversion_tag, V, P>
- : public scalar_handler<P, error::not_integer>
- {
- private:
- V* value_;
- public:
- converting_handler( V* v, P* p )
- : converting_handler::scalar_handler(p)
- , value_(v)
- {}
- bool on_number_part( system::error_code& )
- {
- return true;
- }
- bool on_int64(system::error_code& ec, std::int64_t v)
- {
- if( !integral_in_range<V>( v ) )
- {
- BOOST_JSON_FAIL( ec, error::not_exact );
- return false;
- }
- *value_ = static_cast<V>( v );
- return this->parent_->signal_value(ec);
- }
- bool on_uint64(system::error_code& ec, std::uint64_t v)
- {
- if( !integral_in_range<V>(v) )
- {
- BOOST_JSON_FAIL( ec, error::not_exact );
- return false;
- }
- *value_ = static_cast<V>(v);
- return this->parent_->signal_value(ec);
- }
- };
- // floating point handler
- template< class V, class P>
- class converting_handler<floating_point_conversion_tag, V, P>
- : public scalar_handler<P, error::not_double>
- {
- private:
- V* value_;
- public:
- converting_handler( V* v, P* p )
- : converting_handler::scalar_handler(p)
- , value_(v)
- {}
- bool on_number_part( system::error_code& )
- {
- return true;
- }
- bool on_int64(system::error_code& ec, std::int64_t v)
- {
- *value_ = static_cast<V>(v);
- return this->parent_->signal_value(ec);
- }
- bool on_uint64(system::error_code& ec, std::uint64_t v)
- {
- *value_ = static_cast<V>(v);
- return this->parent_->signal_value(ec);
- }
- bool on_double(system::error_code& ec, double v)
- {
- *value_ = static_cast<V>(v);
- return this->parent_->signal_value(ec);
- }
- };
- // string handler
- template< class V, class P >
- class converting_handler<string_like_conversion_tag, V, P>
- : public scalar_handler<P, error::not_string>
- {
- private:
- V* value_;
- bool cleared_ = false;
- public:
- converting_handler( V* v, P* p )
- : converting_handler::scalar_handler(p)
- , value_(v)
- {}
- bool on_string_part( system::error_code&, string_view sv )
- {
- if( !cleared_ )
- {
- cleared_ = true;
- value_->clear();
- }
- value_->append( sv.begin(), sv.end() );
- return true;
- }
- bool on_string(system::error_code& ec, string_view sv)
- {
- if( !cleared_ )
- value_->clear();
- else
- cleared_ = false;
- value_->append( sv.begin(), sv.end() );
- return this->parent_->signal_value(ec);
- }
- };
- // bool handler
- template< class V, class P >
- class converting_handler<bool_conversion_tag, V, P>
- : public scalar_handler<P, error::not_bool>
- {
- private:
- V* value_;
- public:
- converting_handler( V* v, P* p )
- : converting_handler::scalar_handler(p)
- , value_(v)
- {}
- bool on_bool(system::error_code& ec, bool v)
- {
- *value_ = v;
- return this->parent_->signal_value(ec);
- }
- };
- // null handler
- template< class V, class P >
- class converting_handler<null_like_conversion_tag, V, P>
- : public scalar_handler<P, error::not_null>
- {
- private:
- V* value_;
- public:
- converting_handler( V* v, P* p )
- : converting_handler::scalar_handler(p)
- , value_(v)
- {}
- bool on_null(system::error_code& ec)
- {
- *value_ = {};
- return this->parent_->signal_value(ec);
- }
- };
- // described enum handler
- template< class V, class P >
- class converting_handler<described_enum_conversion_tag, V, P>
- : public scalar_handler<P, error::not_string>
- {
- #ifndef BOOST_DESCRIBE_CXX14
- static_assert(
- sizeof(V) == 0, "Enum support for parse_into requires C++14" );
- #else
- private:
- V* value_;
- std::string name_;
- public:
- converting_handler( V* v, P* p )
- : converting_handler::scalar_handler(p)
- , value_(v)
- {}
- bool on_string_part( system::error_code&, string_view sv )
- {
- name_.append( sv.begin(), sv.end() );
- return true;
- }
- bool on_string(system::error_code& ec, string_view sv)
- {
- string_view name = sv;
- if( !name_.empty() )
- {
- name_.append( sv.begin(), sv.end() );
- name = name_;
- }
- if( !describe::enum_from_string(name, *value_) )
- {
- BOOST_JSON_FAIL(ec, error::unknown_name);
- return false;
- }
- return this->parent_->signal_value(ec);
- }
- #endif // BOOST_DESCRIBE_CXX14
- };
- template< class V, class P >
- class converting_handler<no_conversion_tag, V, P>
- {
- static_assert( sizeof(V) == 0, "This type is not supported" );
- };
- // sequence handler
- template< class It >
- bool cannot_insert(It i, It e)
- {
- return i == e;
- }
- template< class It1, class It2 >
- std::false_type cannot_insert(It1, It2)
- {
- return {};
- }
- template< class It >
- bool needs_more_elements(It i, It e)
- {
- return i != e;
- }
- template< class It1, class It2 >
- std::false_type needs_more_elements(It1, It2)
- {
- return {};
- }
- template<class T>
- void
- clear_container(
- T&,
- mp11::mp_int<2>)
- {
- }
- template<class T>
- void
- clear_container(
- T& target,
- mp11::mp_int<1>)
- {
- target.clear();
- }
- template<class T>
- void
- clear_container(
- T& target,
- mp11::mp_int<0>)
- {
- target.clear();
- }
- template< class V, class P >
- class converting_handler<sequence_conversion_tag, V, P>
- : public composite_handler<
- converting_handler<sequence_conversion_tag, V, P>,
- detail::value_type<V>,
- P,
- error::not_array>
- {
- private:
- V* value_;
- using Inserter = decltype(
- detail::inserter(*value_, inserter_implementation<V>()) );
- Inserter inserter;
- public:
- converting_handler( V* v, P* p )
- : converting_handler::composite_handler(p)
- , value_(v)
- , inserter( detail::inserter(*value_, inserter_implementation<V>()) )
- {}
- bool signal_value(system::error_code& ec)
- {
- if(cannot_insert( inserter, value_->end() ))
- {
- BOOST_JSON_FAIL( ec, error::size_mismatch );
- return false;
- }
- *inserter++ = std::move(this->next_value_);
- #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
- # pragma GCC diagnostic push
- # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
- #endif
- this->next_value_ = {};
- #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
- # pragma GCC diagnostic pop
- #endif
- return true;
- }
- bool signal_end(system::error_code& ec)
- {
- if(needs_more_elements( inserter, value_->end() ))
- {
- BOOST_JSON_FAIL( ec, error::size_mismatch );
- return false;
- }
- inserter = detail::inserter(*value_, inserter_implementation<V>());
- return converting_handler::composite_handler::signal_end(ec);
- }
- bool on_array_begin( system::error_code& ec )
- {
- if( this->inner_active_ )
- return this->inner_.on_array_begin( ec );
- this->inner_active_ = true;
- clear_container( *value_, inserter_implementation<V>() );
- return true;
- }
- bool on_array_end( system::error_code& ec )
- {
- if( this->inner_active_ )
- return this->inner_.on_array_end( ec );
- return this->parent_->signal_end(ec);
- }
- };
- // map handler
- template< class V, class P >
- class converting_handler<map_like_conversion_tag, V, P>
- : public composite_handler<
- converting_handler<map_like_conversion_tag, V, P>,
- detail::mapped_type<V>,
- P,
- error::not_object>
- {
- private:
- V* value_;
- std::string key_;
- public:
- converting_handler( V* v, P* p )
- : converting_handler::composite_handler(p), value_(v)
- {}
- bool signal_value(system::error_code&)
- {
- value_->emplace( std::move(key_), std::move(this->next_value_) );
- key_ = {};
- this->next_value_ = {};
- this->inner_active_ = false;
- return true;
- }
- bool on_object_begin( system::error_code& ec )
- {
- if( this->inner_active_ )
- return this->inner_.on_object_begin(ec);
- clear_container( *value_, inserter_implementation<V>() );
- return true;
- }
- bool on_object_end(system::error_code& ec)
- {
- if( this->inner_active_ )
- return this->inner_.on_object_end(ec);
- return this->parent_->signal_value(ec);
- }
- bool on_array_end( system::error_code& ec )
- {
- if( this->inner_active_ )
- return this->inner_.on_array_end(ec);
- return this->parent_->signal_end(ec);
- }
- bool on_key_part( system::error_code& ec, string_view sv )
- {
- if( this->inner_active_ )
- return this->inner_.on_key_part(ec, sv);
- key_.append( sv.data(), sv.size() );
- return true;
- }
- bool on_key( system::error_code& ec, string_view sv )
- {
- if( this->inner_active_ )
- return this->inner_.on_key(ec, sv);
- key_.append( sv.data(), sv.size() );
- this->inner_active_ = true;
- return true;
- }
- };
- // tuple handler
- template<std::size_t I, class T>
- struct handler_tuple_element
- {
- template< class... Args >
- handler_tuple_element( Args&& ... args )
- : t_( static_cast<Args&&>(args)... )
- {}
- T t_;
- };
- template<std::size_t I, class T>
- T&
- get( handler_tuple_element<I, T>& e )
- {
- return e.t_;
- }
- template<
- class P,
- class LV,
- class S = mp11::make_index_sequence<mp11::mp_size<LV>::value> >
- struct handler_tuple;
- template< class P, template<class...> class L, class... V, std::size_t... I >
- struct handler_tuple< P, L<V...>, mp11::index_sequence<I...> >
- : handler_tuple_element<I, V>
- ...
- {
- handler_tuple( handler_tuple const& ) = delete;
- handler_tuple& operator=( handler_tuple const& ) = delete;
- template< class Access, class T >
- handler_tuple( Access access, T* pv, P* pp )
- : handler_tuple_element<I, V>(
- access( pv, mp11::mp_size_t<I>() ),
- pp )
- ...
- {}
- };
- #if defined(BOOST_MSVC) && BOOST_MSVC < 1910
- template< class T >
- struct tuple_element_list_impl
- {
- template< class I >
- using tuple_element_helper = tuple_element_t<I::value, T>;
- using type = mp11::mp_transform<
- tuple_element_helper,
- mp11::mp_iota< std::tuple_size<T> > >;
- };
- template< class T >
- using tuple_element_list = typename tuple_element_list_impl<T>::type;
- #else
- template< class I, class T >
- using tuple_element_helper = tuple_element_t<I::value, T>;
- template< class T >
- using tuple_element_list = mp11::mp_transform_q<
- mp11::mp_bind_back< tuple_element_helper, T>,
- mp11::mp_iota< std::tuple_size<T> > >;
- #endif
- template< class Op, class... Args>
- struct handler_op_invoker
- {
- public:
- std::tuple<Args&...> args;
- template< class Handler >
- bool
- operator()( Handler& handler ) const
- {
- return (*this)( handler, mp11::index_sequence_for<Args...>() );
- }
- private:
- template< class Handler, std::size_t... I >
- bool
- operator()( Handler& handler, mp11::index_sequence<I...> ) const
- {
- return Op()( handler, std::get<I>(args)... );
- }
- };
- template< class Handlers, class F >
- struct tuple_handler_op_invoker
- {
- Handlers& handlers;
- F fn;
- template< class I >
- bool
- operator()( I ) const
- {
- return fn( get<I::value>(handlers) );
- }
- };
- struct tuple_accessor
- {
- template< class T, class I >
- auto operator()( T* t, I ) const -> tuple_element_t<I::value, T>*
- {
- using std::get;
- return &get<I::value>(*t);
- }
- };
- template< class T, class P >
- class converting_handler<tuple_conversion_tag, T, P>
- {
- private:
- using ElementTypes = tuple_element_list<T>;
- template<class V>
- using ElementHandler = get_handler<V, converting_handler>;
- using InnerHandlers = mp11::mp_transform<ElementHandler, ElementTypes>;
- using HandlerTuple = handler_tuple<converting_handler, InnerHandlers>;
- T* value_;
- P* parent_;
- HandlerTuple handlers_;
- int inner_active_ = -1;
- public:
- converting_handler( converting_handler const& ) = delete;
- converting_handler& operator=( converting_handler const& ) = delete;
- converting_handler( T* v, P* p )
- : value_(v) , parent_(p) , handlers_(tuple_accessor(), v, this)
- {}
- bool signal_value(system::error_code&)
- {
- ++inner_active_;
- return true;
- }
- bool signal_end(system::error_code& ec)
- {
- constexpr int N = std::tuple_size<T>::value;
- if( inner_active_ < N )
- {
- BOOST_JSON_FAIL( ec, error::size_mismatch );
- return false;
- }
- inner_active_ = -1;
- return parent_->signal_value(ec);
- }
- #define BOOST_JSON_HANDLE_EVENT(fn) \
- struct do_ ## fn \
- { \
- template< class H, class... Args > \
- bool operator()( H& h, Args& ... args ) const \
- { \
- return h. fn (args...); \
- } \
- }; \
- \
- template< class... Args > \
- bool fn( system::error_code& ec, Args&& ... args ) \
- { \
- if( inner_active_ < 0 ) \
- { \
- BOOST_JSON_FAIL( ec, error::not_array ); \
- return false; \
- } \
- constexpr int N = std::tuple_size<T>::value; \
- if( inner_active_ >= N ) \
- { \
- BOOST_JSON_FAIL( ec, error::size_mismatch ); \
- return false; \
- } \
- using F = handler_op_invoker< do_ ## fn, system::error_code, Args...>; \
- using H = decltype(handlers_); \
- return mp11::mp_with_index<N>( \
- inner_active_, \
- tuple_handler_op_invoker<H, F>{ \
- handlers_, \
- F{ std::forward_as_tuple(ec, args...) } } ); \
- }
- BOOST_JSON_HANDLE_EVENT( on_object_begin )
- BOOST_JSON_HANDLE_EVENT( on_object_end )
- struct do_on_array_begin
- {
- HandlerTuple& handlers;
- system::error_code& ec;
- template< class I >
- bool operator()( I ) const
- {
- return get<I::value>(handlers).on_array_begin(ec);
- }
- };
- bool on_array_begin( system::error_code& ec )
- {
- if( inner_active_ < 0 )
- {
- inner_active_ = 0;
- return true;
- }
- constexpr int N = std::tuple_size<T>::value;
- if( inner_active_ >= N )
- {
- BOOST_JSON_FAIL( ec, error::size_mismatch );
- return false;
- }
- return mp11::mp_with_index<N>(
- inner_active_, do_on_array_begin{handlers_, ec} );
- }
- struct do_on_array_end
- {
- HandlerTuple& handlers;
- system::error_code& ec;
- template< class I >
- bool operator()( I ) const
- {
- return get<I::value>(handlers).on_array_end(ec);
- }
- };
- bool on_array_end( system::error_code& ec )
- {
- if( inner_active_ < 0 )
- return parent_->signal_end(ec);
- constexpr int N = std::tuple_size<T>::value;
- if( inner_active_ >= N )
- return signal_end(ec);
- return mp11::mp_with_index<N>(
- inner_active_, do_on_array_end{handlers_, ec} );
- }
- BOOST_JSON_HANDLE_EVENT( on_key_part )
- BOOST_JSON_HANDLE_EVENT( on_key )
- BOOST_JSON_HANDLE_EVENT( on_string_part )
- BOOST_JSON_HANDLE_EVENT( on_string )
- BOOST_JSON_HANDLE_EVENT( on_number_part )
- BOOST_JSON_HANDLE_EVENT( on_int64 )
- BOOST_JSON_HANDLE_EVENT( on_uint64 )
- BOOST_JSON_HANDLE_EVENT( on_double )
- BOOST_JSON_HANDLE_EVENT( on_bool )
- BOOST_JSON_HANDLE_EVENT( on_null )
- #undef BOOST_JSON_HANDLE_EVENT
- };
- // described struct handler
- #if defined(BOOST_MSVC) && BOOST_MSVC < 1910
- template< class T >
- struct struct_element_list_impl
- {
- template< class D >
- using helper = described_member_t<T, D>;
- using type = mp11::mp_transform< helper, described_members<T> >;
- };
- template< class T >
- using struct_element_list = typename struct_element_list_impl<T>::type;
- #else
- template< class T >
- using struct_element_list = mp11::mp_transform_q<
- mp11::mp_bind_front< described_member_t, T >, described_members<T> >;
- #endif
- struct struct_accessor
- {
- template< class T >
- auto operator()( T*, mp11::mp_size< described_members<T> > ) const
- -> void*
- {
- return nullptr;
- }
- template< class T, class I >
- auto operator()( T* t, I ) const
- -> described_member_t<T, mp11::mp_at< described_members<T>, I> >*
- {
- using Ds = described_members<T>;
- using D = mp11::mp_at<Ds, I>;
- return &(t->*D::pointer);
- }
- };
- struct struct_key_searcher
- {
- string_view key;
- int& found;
- int index = 0;
- struct_key_searcher(string_view key, int& found) noexcept
- : key(key), found(found)
- {}
- template< class D >
- void
- operator()( D )
- {
- if( key == D::name )
- found = index;
- ++index;
- }
- };
- template<class P>
- struct ignoring_handler
- {
- P* parent_;
- std::size_t array_depth_ = 0;
- std::size_t object_depth_ = 0;
- ignoring_handler(ignoring_handler const&) = delete;
- ignoring_handler& operator=(ignoring_handler const&) = delete;
- ignoring_handler(void*, P* p) noexcept
- : parent_(p)
- {}
- bool on_object_begin(system::error_code&)
- {
- ++object_depth_;
- return true;
- }
- bool on_object_end(system::error_code& ec)
- {
- BOOST_ASSERT( object_depth_ > 0 );
- --object_depth_;
- if( (array_depth_ + object_depth_) == 0 )
- return parent_->signal_value(ec);
- return true;
- }
- bool on_array_begin(system::error_code&)
- {
- ++array_depth_;
- return true;
- }
- bool on_array_end(system::error_code& ec)
- {
- BOOST_ASSERT( array_depth_ > 0 );
- --array_depth_;
- if( (array_depth_ + object_depth_) == 0 )
- return parent_->signal_end(ec);
- return true;
- }
- bool on_key_part(system::error_code&, string_view)
- {
- return true;
- }
- bool on_key(system::error_code&, string_view)
- {
- return true;
- }
- bool on_string_part(system::error_code&, string_view)
- {
- return true;
- }
- bool on_string(system::error_code& ec, string_view)
- {
- if( (array_depth_ + object_depth_) == 0 )
- return parent_->signal_value(ec);
- return true;
- }
- bool on_number_part(system::error_code&)
- {
- return true;
- }
- bool on_int64(system::error_code& ec, std::int64_t)
- {
- if( (array_depth_ + object_depth_) == 0 )
- return parent_->signal_value(ec);
- return true;
- }
- bool on_uint64(system::error_code& ec, std::uint64_t)
- {
- if( (array_depth_ + object_depth_) == 0 )
- return parent_->signal_value(ec);
- return true;
- }
- bool on_double(system::error_code& ec, double)
- {
- if( (array_depth_ + object_depth_) == 0 )
- return parent_->signal_value(ec);
- return true;
- }
- bool on_bool(system::error_code& ec, bool)
- {
- if( (array_depth_ + object_depth_) == 0 )
- return parent_->signal_value(ec);
- return true;
- }
- bool on_null(system::error_code& ec)
- {
- if( (array_depth_ + object_depth_) == 0 )
- return parent_->signal_value(ec);
- return true;
- }
- };
- template<class V, class P>
- class converting_handler<described_class_conversion_tag, V, P>
- {
- #if !defined(BOOST_DESCRIBE_CXX14)
- static_assert(
- sizeof(V) == 0, "Struct support for parse_into requires C++14" );
- #else
- private:
- static_assert(
- uniquely_named_members<V>::value,
- "The type has several described members with the same name.");
- using Dm = described_members<V>;
- using Dt = struct_element_list<V>;
- template<class T>
- using MemberHandler = get_handler<T, converting_handler>;
- using InnerHandlers = mp11::mp_push_back<
- mp11::mp_transform<MemberHandler, Dt>,
- ignoring_handler<converting_handler> >;
- using InnerCount = mp11::mp_size<InnerHandlers>;
- V* value_;
- P* parent_;
- std::string key_;
- handler_tuple<converting_handler, InnerHandlers> handlers_;
- int inner_active_ = -1;
- std::size_t activated_ = 0;
- public:
- converting_handler( converting_handler const& ) = delete;
- converting_handler& operator=( converting_handler const& ) = delete;
- converting_handler( V* v, P* p )
- : value_(v), parent_(p), handlers_(struct_accessor(), v, this)
- {}
- struct is_required_checker
- {
- bool operator()( mp11::mp_size<Dt> ) const noexcept
- {
- return false;
- }
- template< class I >
- auto operator()( I ) const noexcept
- {
- using T = mp11::mp_at<Dt, I>;
- return !is_optional_like<T>::value;
- }
- };
- bool signal_value(system::error_code&)
- {
- BOOST_ASSERT( inner_active_ >= 0 );
- bool required_member = mp11::mp_with_index<InnerCount>(
- inner_active_,
- is_required_checker{});
- if( required_member )
- ++activated_;
- key_ = {};
- inner_active_ = -1;
- return true;
- }
- bool signal_end(system::error_code& ec)
- {
- key_ = {};
- inner_active_ = -1;
- return parent_->signal_value(ec);
- }
- #define BOOST_JSON_INVOKE_INNER(fn) \
- if( inner_active_ < 0 ) \
- { \
- BOOST_JSON_FAIL( ec, error::not_object ); \
- return false; \
- } \
- auto f = [&](auto& handler) { return handler.fn ; }; \
- using F = decltype(f); \
- using H = decltype(handlers_); \
- return mp11::mp_with_index<InnerCount>( \
- inner_active_, \
- tuple_handler_op_invoker<H, F>{handlers_, f} );
- bool on_object_begin( system::error_code& ec )
- {
- if( inner_active_ < 0 )
- return true;
- BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
- }
- bool on_object_end( system::error_code& ec )
- {
- if( inner_active_ < 0 )
- {
- using C = mp11::mp_count_if<Dt, is_optional_like>;
- constexpr int N = mp11::mp_size<Dt>::value - C::value;
- if( activated_ < N )
- {
- BOOST_JSON_FAIL( ec, error::size_mismatch );
- return false;
- }
- return parent_->signal_value(ec);
- }
- BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
- }
- bool on_array_begin( system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_array_begin(ec) );
- }
- bool on_array_end( system::error_code& ec )
- {
- if( inner_active_ < 0 )
- return parent_->signal_end(ec);
- BOOST_JSON_INVOKE_INNER( on_array_end(ec) );
- }
- bool on_key_part( system::error_code& ec, string_view sv )
- {
- if( inner_active_ < 0 )
- {
- key_.append( sv.data(), sv.size() );
- return true;
- }
- BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
- }
- bool on_key( system::error_code& ec, string_view sv )
- {
- if( inner_active_ >= 0 )
- {
- BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
- }
- string_view key = sv;
- if( !key_.empty() )
- {
- key_.append( sv.data(), sv.size() );
- key = key_;
- }
- inner_active_ = InnerCount::value - 1;
- mp11::mp_for_each<Dm>( struct_key_searcher(key, inner_active_) );
- return true;
- }
- bool on_string_part( system::error_code& ec, string_view sv )
- {
- BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
- }
- bool on_string( system::error_code& ec, string_view sv )
- {
- BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
- }
- bool on_number_part( system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
- }
- bool on_int64( system::error_code& ec, std::int64_t v )
- {
- BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
- }
- bool on_uint64( system::error_code& ec, std::uint64_t v )
- {
- BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
- }
- bool on_double( system::error_code& ec, double v )
- {
- BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
- }
- bool on_bool( system::error_code& ec, bool v )
- {
- BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
- }
- bool on_null( system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_null(ec) );
- }
- #undef BOOST_JSON_INVOKE_INNER
- #endif
- };
- // variant handler
- struct object_begin_handler_event
- { };
- struct object_end_handler_event
- { };
- struct array_begin_handler_event
- { };
- struct array_end_handler_event
- { };
- struct key_handler_event
- {
- std::string value;
- };
- struct string_handler_event
- {
- std::string value;
- };
- struct int64_handler_event
- {
- std::int64_t value;
- };
- struct uint64_handler_event
- {
- std::uint64_t value;
- };
- struct double_handler_event
- {
- double value;
- };
- struct bool_handler_event
- {
- bool value;
- };
- struct null_handler_event
- { };
- using parse_event = variant2::variant<
- object_begin_handler_event,
- object_end_handler_event,
- array_begin_handler_event,
- array_end_handler_event,
- key_handler_event,
- string_handler_event,
- int64_handler_event,
- uint64_handler_event,
- double_handler_event,
- bool_handler_event,
- null_handler_event>;
- template< class H >
- struct event_visitor
- {
- H& handler;
- system::error_code& ec;
- bool
- operator()(object_begin_handler_event&) const
- {
- return handler.on_object_begin(ec);
- }
- bool
- operator()(object_end_handler_event&) const
- {
- return handler.on_object_end(ec);
- }
- bool
- operator()(array_begin_handler_event&) const
- {
- return handler.on_array_begin(ec);
- }
- bool
- operator()(array_end_handler_event&) const
- {
- return handler.on_array_end(ec);
- }
- bool
- operator()(key_handler_event& ev) const
- {
- return handler.on_key(ec, ev.value);
- }
- bool
- operator()(string_handler_event& ev) const
- {
- return handler.on_string(ec, ev.value);
- }
- bool
- operator()(int64_handler_event& ev) const
- {
- return handler.on_int64(ec, ev.value);
- }
- bool
- operator()(uint64_handler_event& ev) const
- {
- return handler.on_uint64(ec, ev.value);
- }
- bool
- operator()(double_handler_event& ev) const
- {
- return handler.on_double(ec, ev.value);
- }
- bool
- operator()(bool_handler_event& ev) const
- {
- return handler.on_bool(ec, ev.value);
- }
- bool
- operator()(null_handler_event&) const
- {
- return handler.on_null(ec);
- }
- };
- // L<T...> -> variant< monostate, get_handler<T, P>... >
- template< class P, class L >
- using inner_handler_variant = mp11::mp_push_front<
- mp11::mp_transform_q<
- mp11::mp_bind_back<get_handler, P>,
- mp11::mp_apply<variant2::variant, L>>,
- variant2::monostate>;
- template< class T, class P >
- class converting_handler<variant_conversion_tag, T, P>
- {
- private:
- using variant_size = mp11::mp_size<T>;
- T* value_;
- P* parent_;
- std::string string_;
- std::vector< parse_event > events_;
- inner_handler_variant<converting_handler, T> inner_;
- int inner_active_ = -1;
- public:
- converting_handler( converting_handler const& ) = delete;
- converting_handler& operator=( converting_handler const& ) = delete;
- converting_handler( T* v, P* p )
- : value_( v )
- , parent_( p )
- {}
- bool signal_value(system::error_code& ec)
- {
- inner_.template emplace<0>();
- inner_active_ = -1;
- events_.clear();
- return parent_->signal_value(ec);
- }
- bool signal_end(system::error_code& ec)
- {
- return parent_->signal_end(ec);
- }
- struct alternative_selector
- {
- converting_handler* self;
- template< class I >
- void
- operator()( I ) const
- {
- using V = mp11::mp_at<T, I>;
- auto& v = self->value_->template emplace<I::value>( V{} );
- self->inner_.template emplace<I::value + 1>(&v, self);
- }
- };
- void
- next_alternative()
- {
- if( ++inner_active_ >= static_cast<int>(variant_size::value) )
- return;
- mp11::mp_with_index< variant_size::value >(
- inner_active_, alternative_selector{this} );
- }
- struct event_processor
- {
- converting_handler* self;
- system::error_code& ec;
- parse_event& event;
- template< class I >
- bool operator()( I ) const
- {
- auto& handler = variant2::get<I::value + 1>(self->inner_);
- using Handler = remove_cvref<decltype(handler)>;
- return variant2::visit(
- event_visitor<Handler>{handler, ec}, event );
- }
- };
- bool process_events(system::error_code& ec)
- {
- constexpr std::size_t N = variant_size::value;
- // should be pointers not iterators, otherwise MSVC crashes
- auto const last = events_.data() + events_.size();
- auto first = last - 1;
- bool ok = false;
- if( inner_active_ < 0 )
- next_alternative();
- do
- {
- if( static_cast<std::size_t>(inner_active_) >= N )
- {
- BOOST_JSON_FAIL( ec, error::exhausted_variants );
- return false;
- }
- for ( ; first != last; ++first )
- {
- ok = mp11::mp_with_index< N >(
- inner_active_, event_processor{this, ec, *first} );
- if( !ok )
- {
- first = events_.data();
- next_alternative();
- ec.clear();
- break;
- }
- }
- }
- while( !ok );
- return true;
- }
- #define BOOST_JSON_INVOKE_INNER(ev, ec) \
- events_.emplace_back( ev ); \
- return process_events(ec);
- bool on_object_begin( system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( object_begin_handler_event{}, ec );
- }
- bool on_object_end( system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( object_end_handler_event{}, ec );
- }
- bool on_array_begin( system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( array_begin_handler_event{}, ec );
- }
- bool on_array_end( system::error_code& ec )
- {
- if( !inner_active_ )
- return signal_end(ec);
- BOOST_JSON_INVOKE_INNER( array_end_handler_event{}, ec );
- }
- bool on_key_part( system::error_code&, string_view sv )
- {
- string_.append(sv);
- return true;
- }
- bool on_key( system::error_code& ec, string_view sv )
- {
- string_.append(sv);
- BOOST_JSON_INVOKE_INNER( key_handler_event{ std::move(string_) }, ec );
- }
- bool on_string_part( system::error_code&, string_view sv )
- {
- string_.append(sv);
- return true;
- }
- bool on_string( system::error_code& ec, string_view sv )
- {
- string_.append(sv);
- BOOST_JSON_INVOKE_INNER(
- string_handler_event{ std::move(string_) }, ec );
- }
- bool on_number_part( system::error_code& )
- {
- return true;
- }
- bool on_int64( system::error_code& ec, std::int64_t v )
- {
- BOOST_JSON_INVOKE_INNER( int64_handler_event{v}, ec );
- }
- bool on_uint64( system::error_code& ec, std::uint64_t v )
- {
- BOOST_JSON_INVOKE_INNER( uint64_handler_event{v}, ec );
- }
- bool on_double( system::error_code& ec, double v )
- {
- BOOST_JSON_INVOKE_INNER( double_handler_event{v}, ec );
- }
- bool on_bool( system::error_code& ec, bool v )
- {
- BOOST_JSON_INVOKE_INNER( bool_handler_event{v}, ec );
- }
- bool on_null( system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( null_handler_event{}, ec );
- }
- #undef BOOST_JSON_INVOKE_INNER
- };
- // optional handler
- template<class V, class P>
- class converting_handler<optional_conversion_tag, V, P>
- {
- private:
- using inner_type = value_result_type<V>;
- using inner_handler_type = get_handler<inner_type, converting_handler>;
- V* value_;
- P* parent_;
- inner_type inner_value_ = {};
- inner_handler_type inner_;
- bool inner_active_ = false;
- public:
- converting_handler( converting_handler const& ) = delete;
- converting_handler& operator=( converting_handler const& ) = delete;
- converting_handler( V* v, P* p )
- : value_(v), parent_(p), inner_(&inner_value_, this)
- {}
- bool signal_value(system::error_code& ec)
- {
- *value_ = std::move(inner_value_);
- inner_active_ = false;
- return parent_->signal_value(ec);
- }
- bool signal_end(system::error_code& ec)
- {
- return parent_->signal_end(ec);
- }
- #define BOOST_JSON_INVOKE_INNER(fn) \
- if( !inner_active_ ) \
- inner_active_ = true; \
- return inner_.fn;
- bool on_object_begin( system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
- }
- bool on_object_end( system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
- }
- bool on_array_begin( system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_array_begin(ec) );
- }
- bool on_array_end( system::error_code& ec )
- {
- if( !inner_active_ )
- return signal_end(ec);
- BOOST_JSON_INVOKE_INNER( on_array_end(ec) );
- }
- bool on_key_part( system::error_code& ec, string_view sv )
- {
- BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
- }
- bool on_key( system::error_code& ec, string_view sv )
- {
- BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
- }
- bool on_string_part( system::error_code& ec, string_view sv )
- {
- BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
- }
- bool on_string( system::error_code& ec, string_view sv )
- {
- BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
- }
- bool on_number_part( system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
- }
- bool on_int64( system::error_code& ec, std::int64_t v )
- {
- BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
- }
- bool on_uint64( system::error_code& ec, std::uint64_t v )
- {
- BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
- }
- bool on_double( system::error_code& ec, double v )
- {
- BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
- }
- bool on_bool( system::error_code& ec, bool v )
- {
- BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
- }
- bool on_null(system::error_code& ec)
- {
- if( !inner_active_ )
- {
- *value_ = {};
- return this->parent_->signal_value(ec);
- }
- else
- {
- return inner_.on_null(ec);
- }
- }
- #undef BOOST_JSON_INVOKE_INNER
- };
- // path handler
- template< class V, class P >
- class converting_handler<path_conversion_tag, V, P>
- : public scalar_handler<P, error::not_string>
- {
- private:
- V* value_;
- bool cleared_ = false;
- public:
- converting_handler( V* v, P* p )
- : converting_handler::scalar_handler(p)
- , value_(v)
- {}
- bool on_string_part( system::error_code&, string_view sv )
- {
- if( !cleared_ )
- {
- cleared_ = true;
- value_->clear();
- }
- value_->concat( sv.begin(), sv.end() );
- return true;
- }
- bool on_string(system::error_code& ec, string_view sv)
- {
- if( !cleared_ )
- value_->clear();
- else
- cleared_ = false;
- value_->concat( sv.begin(), sv.end() );
- return this->parent_->signal_value(ec);
- }
- };
- // into_handler
- template< class V >
- class into_handler
- {
- private:
- using inner_handler_type = get_handler<V, into_handler>;
- inner_handler_type inner_;
- bool inner_active_ = true;
- public:
- into_handler( into_handler const& ) = delete;
- into_handler& operator=( into_handler const& ) = delete;
- public:
- static constexpr std::size_t max_object_size = object::max_size();
- static constexpr std::size_t max_array_size = array::max_size();
- static constexpr std::size_t max_key_size = string::max_size();
- static constexpr std::size_t max_string_size = string::max_size();
- public:
- explicit into_handler( V* v ): inner_( v, this )
- {
- }
- bool signal_value(system::error_code&)
- {
- return true;
- }
- bool signal_end(system::error_code&)
- {
- return true;
- }
- bool on_document_begin( system::error_code& )
- {
- return true;
- }
- bool on_document_end( system::error_code& )
- {
- inner_active_ = false;
- return true;
- }
- #define BOOST_JSON_INVOKE_INNER(f) \
- if( !inner_active_ ) \
- { \
- BOOST_JSON_FAIL( ec, error::extra_data ); \
- return false; \
- } \
- else \
- return inner_.f
- bool on_object_begin( system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
- }
- bool on_object_end( std::size_t, system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
- }
- bool on_array_begin( system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_array_begin(ec) );
- }
- bool on_array_end( std::size_t, system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_array_end(ec) );
- }
- bool on_key_part( string_view sv, std::size_t, system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
- }
- bool on_key( string_view sv, std::size_t, system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
- }
- bool on_string_part( string_view sv, std::size_t, system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
- }
- bool on_string( string_view sv, std::size_t, system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
- }
- bool on_number_part( string_view, system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
- }
- bool on_int64( std::int64_t v, string_view, system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
- }
- bool on_uint64( std::uint64_t v, string_view, system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
- }
- bool on_double( double v, string_view, system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
- }
- bool on_bool( bool v, system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
- }
- bool on_null( system::error_code& ec )
- {
- BOOST_JSON_INVOKE_INNER( on_null(ec) );
- }
- bool on_comment_part(string_view, system::error_code&)
- {
- return true;
- }
- bool on_comment(string_view, system::error_code&)
- {
- return true;
- }
- #undef BOOST_JSON_INVOKE_INNER
- };
- } // namespace detail
- } // namespace boost
- } // namespace json
- #endif
|