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