detail/parse_into.hpp

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