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