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