GCC Code Coverage Report


Directory: libs/json/include/boost/json/
File: detail/parse_into.hpp
Date: 2025-12-23 17:22:01
Exec Total Coverage
Lines: 400 400 100.0%
Functions: 1579 3864 40.9%
Branches: 158 208 76.0%

Line Branch Exec Source
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 2 bool on_object_begin( system::error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
96 14 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 2 bool on_string_part( system::error_code& ec, string_view ) { BOOST_JSON_FAIL( ec, E ); return false; }
99 108 bool on_string( system::error_code& ec, string_view ) { BOOST_JSON_FAIL( ec, E ); return false; }
100 4 bool on_number_part( system::error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
101 14 bool on_int64( system::error_code& ec, std::int64_t ) { BOOST_JSON_FAIL( ec, E ); return false; }
102 14 bool on_uint64( system::error_code& ec, std::uint64_t ) { BOOST_JSON_FAIL( ec, E ); return false; }
103 14 bool on_double( system::error_code& ec, double ) { BOOST_JSON_FAIL( ec, E ); return false; }
104 2 bool on_bool( system::error_code& ec, bool ) { BOOST_JSON_FAIL( ec, E ); return false; }
105 6 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 1565 scalar_handler(P* p): parent_( p )
127 1565 {}
128
129 348 bool on_array_end( system::error_code& ec )
130 {
131 348 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 800 composite_handler( P* p )
155
1/1
✓ Branch 2 taken 108 times.
800 : parent_(p), inner_( &next_value_, static_cast<D*>(this) )
156 800 {}
157 #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
158 # pragma GCC diagnostic pop
159 #endif
160
161 542 bool signal_end(system::error_code&)
162 {
163 542 inner_active_ = false;
164 542 parent_->signal_value();
165 542 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 42 bool on_object_begin( system::error_code& ec )
177 {
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
42 BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
179 }
180
181 42 bool on_object_end( system::error_code& ec )
182 {
183
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
42 BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
184 }
185
186 106 bool on_array_begin( system::error_code& ec )
187 {
188
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 52 times.
106 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 6 bool on_key_part( system::error_code& ec, string_view sv )
197 {
198
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
6 BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
199 }
200
201 42 bool on_key( system::error_code& ec, string_view sv )
202 {
203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
42 BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
204 }
205
206 48 bool on_string_part( system::error_code& ec, string_view sv )
207 {
208
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 23 times.
48 BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
209 }
210
211 98 bool on_string( system::error_code& ec, string_view sv )
212 {
213
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
98 BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
214 }
215
216 448 bool on_number_part( system::error_code& ec )
217 {
218
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 222 times.
448 BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
219 }
220
221 1752 bool on_int64( system::error_code& ec, std::int64_t v )
222 {
223
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 876 times.
1752 BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
224 }
225
226 14 bool on_uint64( system::error_code& ec, std::uint64_t v )
227 {
228
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
14 BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
229 }
230
231 84 bool on_double( system::error_code& ec, double v )
232 {
233
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
84 BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
234 }
235
236 42 bool on_bool( system::error_code& ec, bool v )
237 {
238
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
42 BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
239 }
240
241 28 bool on_null( system::error_code& ec )
242 {
243
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
28 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 1314 bool integral_in_range( std::int64_t v )
253 {
254
3/4
✓ Branch 1 taken 659 times.
✓ Branch 2 taken 1 times.
✓ Branch 4 taken 659 times.
✗ Branch 5 not taken.
1314 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 70 bool integral_in_range( std::int64_t v )
260 {
261
2/4
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 35 times.
✗ Branch 4 not taken.
70 return v >= 0 && static_cast<std::uint64_t>( v ) <= (std::numeric_limits<V>::max)();
262 }
263
264 template<class V>
265 72 bool integral_in_range( std::uint64_t v )
266 {
267 72 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 1053 converting_handler( V* v, P* p )
279 : converting_handler::scalar_handler(p)
280 1053 , value_(v)
281 1053 {}
282
283 628 bool on_number_part( system::error_code& )
284 {
285 628 return true;
286 }
287
288 1384 bool on_int64( system::error_code& ec, std::int64_t v )
289 {
290
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 694 times.
1384 if( !integral_in_range<V>( v ) )
291 {
292 2 BOOST_JSON_FAIL( ec, error::not_exact );
293 2 return false;
294 }
295
296 1382 *value_ = static_cast<V>( v );
297
298 1382 this->parent_->signal_value();
299 1382 return true;
300 }
301
302 72 bool on_uint64( system::error_code& ec, std::uint64_t v )
303 {
304
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 35 times.
72 if( !integral_in_range<V>( v ) )
305 {
306 2 BOOST_JSON_FAIL( ec, error::not_exact );
307 2 return false;
308 }
309
310 70 *value_ = static_cast<V>( v );
311
312 70 this->parent_->signal_value();
313 70 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 104 converting_handler( V* v, P* p )
327 : converting_handler::scalar_handler(p)
328 104 , value_(v)
329 104 {}
330
331 198 bool on_number_part( system::error_code& )
332 {
333 198 return true;
334 }
335
336 2 bool on_int64( system::error_code&, std::int64_t v )
337 {
338 2 *value_ = static_cast<V>( v );
339
340 2 this->parent_->signal_value();
341 2 return true;
342 }
343
344 2 bool on_uint64( system::error_code&, std::uint64_t v )
345 {
346 2 *value_ = static_cast<V>( v );
347
348 2 this->parent_->signal_value();
349 2 return true;
350 }
351
352 126 bool on_double( system::error_code&, double v )
353 {
354 126 *value_ = static_cast<V>( v );
355
356 126 this->parent_->signal_value();
357 126 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 188 converting_handler( V* v, P* p )
372 : converting_handler::scalar_handler(p)
373 188 , value_(v)
374 188 {}
375
376 42 bool on_string_part( system::error_code&, string_view sv )
377 {
378
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 16 times.
42 if( !cleared_ )
379 {
380 10 cleared_ = true;
381 10 value_->clear();
382 }
383
384 42 value_->append( sv.begin(), sv.end() );
385 42 return true;
386 }
387
388 200 bool on_string( system::error_code&, string_view sv )
389 {
390
2/2
✓ Branch 0 taken 95 times.
✓ Branch 1 taken 5 times.
200 if( !cleared_ )
391 190 value_->clear();
392 else
393 10 cleared_ = false;
394
395 200 value_->append( sv.begin(), sv.end() );
396
397 200 this->parent_->signal_value();
398 200 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 116 converting_handler( V* v, P* p )
412 : converting_handler::scalar_handler(p)
413 116 , value_(v)
414 116 {}
415
416 84 bool on_bool( system::error_code&, bool v )
417 {
418 84 *value_ = v;
419
420 84 this->parent_->signal_value();
421 84 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 104 converting_handler( V* v, P* p )
435 : converting_handler::scalar_handler(p)
436 104 , value_(v)
437 104 {}
438
439 70 bool on_null( system::error_code& )
440 {
441 70 *value_ = {};
442
443 70 this->parent_->signal_value();
444 70 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 484 std::true_type check_inserter( It1, It2 )
513 {
514 484 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 514 clear_container(
528 T& target,
529 mp11::mp_int<1>)
530 {
531 514 target.clear();
532 514 }
533
534 template<class T>
535 void
536 289 clear_container(
537 T& target,
538 mp11::mp_int<0>)
539 {
540 289 target.clear();
541 289 }
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 535 converting_handler( V* v, P* p )
560 : converting_handler::composite_handler(p)
561 535 , value_(v)
562
1/1
✓ Branch 2 taken 64 times.
535 , inserter( detail::inserter(*value_, inserter_implementation<V>()) )
563 535 {}
564
565 1234 void signal_value()
566 {
567
1/1
✓ Branch 4 taken 505 times.
1234 *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 1234 this->next_value_ = {};
573 #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
574 # pragma GCC diagnostic pop
575 #endif
576 1234 }
577
578 542 bool signal_end(system::error_code& ec)
579 {
580
3/4
✗ Branch 3 not taken.
✓ Branch 4 taken 243 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 28 times.
542 if( !check_inserter( inserter, value_->end() ) )
581 {
582 2 BOOST_JSON_FAIL( ec, error::size_mismatch );
583 2 return false;
584 }
585
586 540 inserter = detail::inserter(*value_, inserter_implementation<V>());
587
588 540 return converting_handler::composite_handler::signal_end(ec);
589 }
590
591 936 bool on_array_begin( system::error_code& ec )
592 {
593
2/2
✓ Branch 0 taken 182 times.
✓ Branch 1 taken 287 times.
936 if( this->inner_active_ )
594 364 return this->inner_.on_array_begin( ec );
595
596 572 this->inner_active_ = true;
597 572 clear_container( *value_, inserter_implementation<V>() );
598 572 return true;
599 }
600
601 990 bool on_array_end( system::error_code& ec )
602 {
603
2/2
✓ Branch 0 taken 454 times.
✓ Branch 1 taken 42 times.
990 if( this->inner_active_ )
604 906 return this->inner_.on_array_end( ec );
605
606 84 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 263 converting_handler( V* v, P* p )
625 263 : converting_handler::composite_handler(p), value_(v)
626 263 {}
627
628 266 void signal_value()
629 {
630 266 value_->emplace( std::move(key_), std::move(this->next_value_) );
631
632 266 key_ = {};
633 266 this->next_value_ = {};
634
635 266 this->inner_active_ = false;
636 266 }
637
638 319 bool on_object_begin( system::error_code& ec )
639 {
640
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 145 times.
319 if( this->inner_active_ )
641 30 return this->inner_.on_object_begin(ec);
642
643 289 clear_container( *value_, inserter_implementation<V>() );
644 289 return true;
645 }
646
647 303 bool on_object_end( system::error_code& ec )
648 {
649
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 137 times.
303 if( this->inner_active_ )
650 30 return this->inner_.on_object_end(ec);
651
652 273 this->parent_->signal_value();
653 273 return true;
654 }
655
656 114 bool on_array_end( system::error_code& ec )
657 {
658
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 7 times.
114 if( this->inner_active_ )
659 100 return this->inner_.on_array_end(ec);
660
661 14 return this->parent_->signal_end(ec);
662 }
663
664 84 bool on_key_part( system::error_code& ec, string_view sv )
665 {
666
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 40 times.
84 if( this->inner_active_ )
667 4 return this->inner_.on_key_part(ec, sv);
668
669 80 key_.append( sv.data(), sv.size() );
670 80 return true;
671 }
672
673 310 bool on_key( system::error_code& ec, string_view sv )
674 {
675
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 142 times.
310 if( this->inner_active_ )
676 28 return this->inner_.on_key(ec, sv);
677
678 282 key_.append( sv.data(), sv.size() );
679
680 282 this->inner_active_ = true;
681 282 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 548 handler_tuple_element( Args&& ... args )
691 548 : t_( static_cast<Args&&>(args)... )
692 548 {}
693
694 T t_;
695 };
696
697 template<std::size_t I, class T>
698 T&
699 1010 get( handler_tuple_element<I, T>& e )
700 {
701 1010 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 246 handler_tuple( Access access, T* pv, P* pp )
720 : handler_tuple_element< I, get_handler<V, P> >(
721 6 access( pv, mp11::mp_int<I>() ),
722 pp )
723
3/3
✓ Branch 2 taken 123 times.
✓ Branch 6 taken 122 times.
✓ Branch 10 taken 29 times.
246 ...
724 246 { }
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 920 operator()( Handler& handler ) const
762 {
763 920 return (*this)( handler, mp11::index_sequence_for<Args...>() );
764 }
765
766 private:
767 template< class Handler, std::size_t... I >
768 bool
769 920 operator()( Handler& handler, mp11::index_sequence<I...> ) const
770 {
771
1/1
✓ Branch 2 taken 131 times.
920 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 920 operator()( I ) const
784 {
785 920 return fn( get<I::value>(handlers) );
786 }
787 };
788
789 struct tuple_accessor
790 {
791 template< class T, class I >
792 548 auto operator()( T* t, I ) const -> tuple_element_t<I::value, T>*
793 {
794 using std::get;
795 548 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 246 converting_handler( T* v, P* p )
815 246 : value_(v) , parent_(p) , handlers_(tuple_accessor(), v, this)
816 246 {}
817
818 556 void signal_value()
819 {
820 556 ++inner_active_;
821 556 }
822
823 240 bool signal_end(system::error_code& ec)
824 {
825 240 constexpr int N = std::tuple_size<T>::value;
826
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 119 times.
240 if( inner_active_ < N )
827 {
828 2 BOOST_JSON_FAIL( ec, error::size_mismatch );
829 2 return true;
830 }
831
832 238 inner_active_ = -1;
833 238 parent_->signal_value();
834 238 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
3/5
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 28 times.
✓ Branch 10 taken 28 times.
112 BOOST_JSON_HANDLE_EVENT( on_object_begin )
871
3/5
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 21 times.
✓ Branch 10 taken 21 times.
84 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 44 bool operator()( I ) const
880 {
881 44 return get<I::value>(handlers).on_array_begin(ec);
882 }
883 };
884 304 bool on_array_begin( system::error_code& ec )
885 {
886
2/2
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 23 times.
304 if( inner_active_ < 0 )
887 {
888 258 inner_active_ = 0;
889 258 return true;
890 }
891
892 46 constexpr int N = std::tuple_size<T>::value;
893
894
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 22 times.
46 if( inner_active_ >= N )
895 {
896 2 BOOST_JSON_FAIL( ec, error::size_mismatch );
897 2 return false;
898 }
899
900 44 return mp11::mp_with_index<N>(
901
1/1
✓ Branch 1 taken 22 times.
44 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 46 bool operator()( I ) const
911 {
912 46 return get<I::value>(handlers).on_array_end(ec);
913 }
914 };
915 382 bool on_array_end( system::error_code& ec )
916 {
917
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 142 times.
382 if( inner_active_ < 0 )
918 98 return parent_->signal_end(ec);
919
920 284 constexpr int N = std::tuple_size<T>::value;
921
922
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 23 times.
284 if( inner_active_ >= N )
923 238 return signal_end(ec);
924
925 46 return mp11::mp_with_index<N>(
926
1/1
✓ Branch 1 taken 23 times.
46 inner_active_, do_on_array_end{handlers_, ec} );
927 }
928
929
3/5
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✓ Branch 10 taken 3 times.
12 BOOST_JSON_HANDLE_EVENT( on_key_part )
930
4/6
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 28 times.
✓ Branch 10 taken 28 times.
✓ Branch 2 taken 21 times.
112 BOOST_JSON_HANDLE_EVENT( on_key )
931
3/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 5 times.
✓ Branch 10 taken 5 times.
20 BOOST_JSON_HANDLE_EVENT( on_string_part )
932
4/6
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 28 times.
✓ Branch 10 taken 28 times.
✓ Branch 2 taken 14 times.
112 BOOST_JSON_HANDLE_EVENT( on_string )
933
5/5
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 76 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 75 times.
✓ Branch 10 taken 75 times.
304 BOOST_JSON_HANDLE_EVENT( on_number_part )
934
3/5
✗ Branch 0 not taken.
✓ Branch 1 taken 209 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 209 times.
✓ Branch 10 taken 209 times.
836 BOOST_JSON_HANDLE_EVENT( on_int64 )
935
3/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 7 times.
✓ Branch 10 taken 7 times.
28 BOOST_JSON_HANDLE_EVENT( on_uint64 )
936
3/5
✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 35 times.
✓ Branch 10 taken 35 times.
140 BOOST_JSON_HANDLE_EVENT( on_double )
937
3/5
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 14 times.
✓ Branch 10 taken 14 times.
56 BOOST_JSON_HANDLE_EVENT( on_bool )
938
3/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 7 times.
✓ Branch 10 taken 7 times.
28 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 28 operator()(object_begin_handler_event&) const
1263 {
1264 28 return handler.on_object_begin(ec);
1265 }
1266
1267 bool
1268 14 operator()(object_end_handler_event&) const
1269 {
1270 14 return handler.on_object_end(ec);
1271 }
1272
1273 bool
1274 84 operator()(array_begin_handler_event&) const
1275 {
1276 84 return handler.on_array_begin(ec);
1277 }
1278
1279 bool
1280 42 operator()(array_end_handler_event&) const
1281 {
1282 42 return handler.on_array_end(ec);
1283 }
1284
1285 bool
1286 42 operator()(key_handler_event& ev) const
1287 {
1288 42 return handler.on_key(ec, ev.value);
1289 }
1290
1291 bool
1292 206 operator()(string_handler_event& ev) const
1293 {
1294
1/1
✓ Branch 2 taken 35 times.
206 return handler.on_string(ec, ev.value);
1295 }
1296
1297 bool
1298 308 operator()(int64_handler_event& ev) const
1299 {
1300 308 return handler.on_int64(ec, ev.value);
1301 }
1302
1303 bool
1304 28 operator()(uint64_handler_event& ev) const
1305 {
1306 28 return handler.on_uint64(ec, ev.value);
1307 }
1308
1309 bool
1310 42 operator()(double_handler_event& ev) const
1311 {
1312 42 return handler.on_double(ec, ev.value);
1313 }
1314
1315 bool
1316 14 operator()(bool_handler_event& ev) const
1317 {
1318 14 return handler.on_bool(ec, ev.value);
1319 }
1320
1321 bool
1322 14 operator()(null_handler_event&) const
1323 {
1324 14 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 174 converting_handler( T* v, P* p )
1355 174 : value_( v )
1356 174 , parent_( p )
1357 174 {}
1358
1359 252 void signal_value()
1360 {
1361 252 inner_.template emplace<0>();
1362 252 inner_active_ = -1;
1363 252 events_.clear();
1364 252 parent_->signal_value();
1365 252 }
1366
1367 28 bool signal_end(system::error_code& ec)
1368 {
1369 28 return parent_->signal_end(ec);
1370 }
1371
1372 struct alternative_selector
1373 {
1374 converting_handler* self;
1375
1376 template< class I >
1377 void
1378 444 operator()( I ) const
1379 {
1380 using V = mp11::mp_at<T, I>;
1381
1/1
✓ Branch 1 taken 152 times.
444 auto& v = self->value_->template emplace<I::value>( V{} );
1382
1/1
✓ Branch 1 taken 222 times.
444 self->inner_.template emplace<I::value + 1>(&v, self);
1383 444 }
1384 };
1385 void
1386 450 next_alternative()
1387 {
1388
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 222 times.
450 if( ++inner_active_ >= static_cast<int>(variant_size::value) )
1389 6 return;
1390
1391 444 mp11::mp_with_index< variant_size::value >(
1392
1/1
✓ Branch 1 taken 222 times.
444 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 822 bool operator()( I ) const
1403 {
1404 822 auto& handler = variant2::get<I::value + 1>(self->inner_);
1405 using Handler = remove_cvref<decltype(handler)>;
1406 822 return variant2::visit(
1407
1/1
✓ Branch 1 taken 411 times.
1644 event_visitor<Handler>{handler, ec}, event );
1408 }
1409 };
1410 566 bool process_events(system::error_code& ec)
1411 {
1412 566 constexpr std::size_t N = variant_size::value;
1413
1414 // should be pointers not iterators, otherwise MSVC crashes
1415 566 auto const last = events_.data() + events_.size();
1416 566 auto first = last - 1;
1417 566 bool ok = false;
1418
1419
2/2
✓ Branch 0 taken 143 times.
✓ Branch 1 taken 140 times.
566 if( inner_active_ < 0 )
1420 286 next_alternative();
1421 do
1422 {
1423
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 362 times.
730 if( static_cast<std::size_t>(inner_active_) >= N )
1424 {
1425 6 BOOST_JSON_FAIL( ec, error::exhausted_variants );
1426 6 return false;
1427 }
1428
1429
2/2
✓ Branch 0 taken 411 times.
✓ Branch 1 taken 280 times.
1382 for ( ; first != last; ++first )
1430 {
1431 1644 ok = mp11::mp_with_index< N >(
1432
1/1
✓ Branch 1 taken 411 times.
822 inner_active_, event_processor{this, ec, *first} );
1433
2/2
✓ Branch 0 taken 82 times.
✓ Branch 1 taken 329 times.
822 if( !ok )
1434 {
1435 164 first = events_.data();
1436 164 next_alternative();
1437 164 ec.clear();
1438 164 break;
1439 }
1440 }
1441 }
1442
2/2
✓ Branch 0 taken 82 times.
✓ Branch 1 taken 280 times.
724 while( !ok );
1443
1444 560 return true;
1445 }
1446
1447 #define BOOST_JSON_INVOKE_INNER(ev, ec) \
1448 events_.emplace_back( ev ); \
1449 return process_events(ec);
1450
1451 14 bool on_object_begin( system::error_code& ec )
1452 {
1453
1/1
✓ Branch 1 taken 7 times.
14 BOOST_JSON_INVOKE_INNER( object_begin_handler_event{}, ec );
1454 }
1455
1456 14 bool on_object_end( system::error_code& ec )
1457 {
1458
1/1
✓ Branch 1 taken 7 times.
14 BOOST_JSON_INVOKE_INNER( object_end_handler_event{}, ec );
1459 }
1460
1461 42 bool on_array_begin( system::error_code& ec )
1462 {
1463
1/1
✓ Branch 1 taken 21 times.
42 BOOST_JSON_INVOKE_INNER( array_begin_handler_event{}, ec );
1464 }
1465
1466 56 bool on_array_end( system::error_code& ec )
1467 {
1468
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 21 times.
56 if( !inner_active_ )
1469 14 return signal_end(ec);
1470
1471
1/1
✓ Branch 1 taken 21 times.
42 BOOST_JSON_INVOKE_INNER( array_end_handler_event{}, ec );
1472 }
1473
1474 10 bool on_key_part( system::error_code&, string_view sv )
1475 {
1476
2/2
✓ Branch 1 taken 5 times.
✓ Branch 4 taken 5 times.
10 string_.append(sv);
1477 10 return true;
1478 }
1479
1480 28 bool on_key( system::error_code& ec, string_view sv )
1481 {
1482
2/2
✓ Branch 1 taken 14 times.
✓ Branch 4 taken 14 times.
28 string_.append(sv);
1483
1/1
✓ Branch 2 taken 14 times.
56 BOOST_JSON_INVOKE_INNER( key_handler_event{ std::move(string_) }, ec );
1484 28 }
1485
1486 62 bool on_string_part( system::error_code&, string_view sv )
1487 {
1488
2/2
✓ Branch 1 taken 31 times.
✓ Branch 4 taken 31 times.
62 string_.append(sv);
1489 62 return true;
1490 }
1491
1492 90 bool on_string( system::error_code& ec, string_view sv )
1493 {
1494
2/2
✓ Branch 1 taken 45 times.
✓ Branch 4 taken 45 times.
90 string_.append(sv);
1495
1/1
✓ Branch 2 taken 45 times.
180 BOOST_JSON_INVOKE_INNER(
1496 string_handler_event{ std::move(string_) }, ec );
1497 90 }
1498
1499 120 bool on_number_part( system::error_code& )
1500 {
1501 120 return true;
1502 }
1503
1504 266 bool on_int64( system::error_code& ec, std::int64_t v )
1505 {
1506
1/1
✓ Branch 1 taken 133 times.
266 BOOST_JSON_INVOKE_INNER( int64_handler_event{v}, ec );
1507 }
1508
1509 14 bool on_uint64( system::error_code& ec, std::uint64_t v )
1510 {
1511
1/1
✓ Branch 1 taken 7 times.
14 BOOST_JSON_INVOKE_INNER( uint64_handler_event{v}, ec );
1512 }
1513
1514 28 bool on_double( system::error_code& ec, double v )
1515 {
1516
1/1
✓ Branch 1 taken 14 times.
28 BOOST_JSON_INVOKE_INNER( double_handler_event{v}, ec );
1517 }
1518
1519 14 bool on_bool( system::error_code& ec, bool v )
1520 {
1521
1/1
✓ Branch 1 taken 7 times.
14 BOOST_JSON_INVOKE_INNER( bool_handler_event{v}, ec );
1522 }
1523
1524 14 bool on_null( system::error_code& ec )
1525 {
1526
1/1
✓ Branch 1 taken 7 times.
14 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 993 explicit into_handler( V* v ): inner_( v, this )
1726 {
1727 993 }
1728
1729 931 void signal_value()
1730 {
1731 931 }
1732
1733 14 bool signal_end(system::error_code&)
1734 {
1735 14 return true;
1736 }
1737
1738 991 bool on_document_begin( system::error_code& )
1739 {
1740 991 return true;
1741 }
1742
1743 945 bool on_document_end( system::error_code& )
1744 {
1745 945 inner_active_ = false;
1746 945 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 277 bool on_object_begin( system::error_code& ec )
1759 {
1760
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 139 times.
277 BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
1761 }
1762
1763 273 bool on_object_end( std::size_t, system::error_code& ec )
1764 {
1765
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 137 times.
273 BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
1766 }
1767
1768 808 bool on_array_begin( system::error_code& ec )
1769 {
1770
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 405 times.
808 BOOST_JSON_INVOKE_INNER( on_array_begin(ec) );
1771 }
1772
1773 796 bool on_array_end( std::size_t, system::error_code& ec )
1774 {
1775
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 399 times.
796 BOOST_JSON_INVOKE_INNER( on_array_end(ec) );
1776 }
1777
1778 90 bool on_key_part( string_view sv, std::size_t, system::error_code& ec )
1779 {
1780
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
90 BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
1781 }
1782
1783 268 bool on_key( string_view sv, std::size_t, system::error_code& ec )
1784 {
1785
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 135 times.
268 BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
1786 }
1787
1788 108 bool on_string_part( string_view sv, std::size_t, system::error_code& ec )
1789 {
1790
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
108 BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
1791 }
1792
1793 192 bool on_string( string_view sv, std::size_t, system::error_code& ec )
1794 {
1795
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
192 BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
1796 }
1797
1798 958 bool on_number_part( string_view, system::error_code& ec )
1799 {
1800
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 479 times.
958 BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
1801 }
1802
1803 1358 bool on_int64( std::int64_t v, string_view, system::error_code& ec )
1804 {
1805
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 682 times.
1358 BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
1806 }
1807
1808 74 bool on_uint64( std::uint64_t v, string_view, system::error_code& ec )
1809 {
1810
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
74 BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
1811 }
1812
1813 126 bool on_double( double v, string_view, system::error_code& ec )
1814 {
1815
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
126 BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
1816 }
1817
1818 86 bool on_bool( bool v, system::error_code& ec )
1819 {
1820
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
86 BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
1821 }
1822
1823 76 bool on_null( system::error_code& ec )
1824 {
1825
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
76 BOOST_JSON_INVOKE_INNER( on_null(ec) );
1826 }
1827
1828 2508 bool on_comment_part(string_view, system::error_code&)
1829 {
1830 2508 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
1846