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