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