File indexing completed on 2026-05-10 08:45:01
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <cstddef>
0012 #include <string> // string
0013 #include <type_traits> // enable_if_t
0014 #include <utility> // move
0015 #include <vector> // vector
0016
0017 #include <nlohmann/detail/exceptions.hpp>
0018 #include <nlohmann/detail/input/lexer.hpp>
0019 #include <nlohmann/detail/macro_scope.hpp>
0020 #include <nlohmann/detail/string_concat.hpp>
0021 NLOHMANN_JSON_NAMESPACE_BEGIN
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 template<typename BasicJsonType>
0032 struct json_sax
0033 {
0034 using number_integer_t = typename BasicJsonType::number_integer_t;
0035 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
0036 using number_float_t = typename BasicJsonType::number_float_t;
0037 using string_t = typename BasicJsonType::string_t;
0038 using binary_t = typename BasicJsonType::binary_t;
0039
0040
0041
0042
0043
0044 virtual bool null() = 0;
0045
0046
0047
0048
0049
0050
0051 virtual bool boolean(bool val) = 0;
0052
0053
0054
0055
0056
0057
0058 virtual bool number_integer(number_integer_t val) = 0;
0059
0060
0061
0062
0063
0064
0065 virtual bool number_unsigned(number_unsigned_t val) = 0;
0066
0067
0068
0069
0070
0071
0072
0073 virtual bool number_float(number_float_t val, const string_t& s) = 0;
0074
0075
0076
0077
0078
0079
0080
0081 virtual bool string(string_t& val) = 0;
0082
0083
0084
0085
0086
0087
0088
0089 virtual bool binary(binary_t& val) = 0;
0090
0091
0092
0093
0094
0095
0096
0097 virtual bool start_object(std::size_t elements) = 0;
0098
0099
0100
0101
0102
0103
0104
0105 virtual bool key(string_t& val) = 0;
0106
0107
0108
0109
0110
0111 virtual bool end_object() = 0;
0112
0113
0114
0115
0116
0117
0118
0119 virtual bool start_array(std::size_t elements) = 0;
0120
0121
0122
0123
0124
0125 virtual bool end_array() = 0;
0126
0127
0128
0129
0130
0131
0132
0133
0134 virtual bool parse_error(std::size_t position,
0135 const std::string& last_token,
0136 const detail::exception& ex) = 0;
0137
0138 json_sax() = default;
0139 json_sax(const json_sax&) = default;
0140 json_sax(json_sax&&) noexcept = default;
0141 json_sax& operator=(const json_sax&) = default;
0142 json_sax& operator=(json_sax&&) noexcept = default;
0143 virtual ~json_sax() = default;
0144 };
0145
0146 namespace detail
0147 {
0148 constexpr std::size_t unknown_size()
0149 {
0150 return (std::numeric_limits<std::size_t>::max)();
0151 }
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166 template<typename BasicJsonType, typename InputAdapterType>
0167 class json_sax_dom_parser
0168 {
0169 public:
0170 using number_integer_t = typename BasicJsonType::number_integer_t;
0171 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
0172 using number_float_t = typename BasicJsonType::number_float_t;
0173 using string_t = typename BasicJsonType::string_t;
0174 using binary_t = typename BasicJsonType::binary_t;
0175 using lexer_t = lexer<BasicJsonType, InputAdapterType>;
0176
0177
0178
0179
0180
0181
0182 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true, lexer_t* lexer_ = nullptr)
0183 : root(r), allow_exceptions(allow_exceptions_), m_lexer_ref(lexer_)
0184 {}
0185
0186
0187 json_sax_dom_parser(const json_sax_dom_parser&) = delete;
0188 json_sax_dom_parser(json_sax_dom_parser&&) = default;
0189 json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
0190 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
0191 ~json_sax_dom_parser() = default;
0192
0193 bool null()
0194 {
0195 handle_value(nullptr);
0196 return true;
0197 }
0198
0199 bool boolean(bool val)
0200 {
0201 handle_value(val);
0202 return true;
0203 }
0204
0205 bool number_integer(number_integer_t val)
0206 {
0207 handle_value(val);
0208 return true;
0209 }
0210
0211 bool number_unsigned(number_unsigned_t val)
0212 {
0213 handle_value(val);
0214 return true;
0215 }
0216
0217 bool number_float(number_float_t val, const string_t& )
0218 {
0219 handle_value(val);
0220 return true;
0221 }
0222
0223 bool string(string_t& val)
0224 {
0225 handle_value(val);
0226 return true;
0227 }
0228
0229 bool binary(binary_t& val)
0230 {
0231 handle_value(std::move(val));
0232 return true;
0233 }
0234
0235 bool start_object(std::size_t len)
0236 {
0237 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
0238
0239 #if JSON_DIAGNOSTIC_POSITIONS
0240
0241
0242 if (m_lexer_ref)
0243 {
0244
0245
0246 ref_stack.back()->start_position = m_lexer_ref->get_position() - 1;
0247 }
0248 #endif
0249
0250 if (JSON_HEDLEY_UNLIKELY(len != detail::unknown_size() && len > ref_stack.back()->max_size()))
0251 {
0252 JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
0253 }
0254
0255 return true;
0256 }
0257
0258 bool key(string_t& val)
0259 {
0260 JSON_ASSERT(!ref_stack.empty());
0261 JSON_ASSERT(ref_stack.back()->is_object());
0262
0263
0264 object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val));
0265 return true;
0266 }
0267
0268 bool end_object()
0269 {
0270 JSON_ASSERT(!ref_stack.empty());
0271 JSON_ASSERT(ref_stack.back()->is_object());
0272
0273 #if JSON_DIAGNOSTIC_POSITIONS
0274 if (m_lexer_ref)
0275 {
0276
0277 ref_stack.back()->end_position = m_lexer_ref->get_position();
0278 }
0279 #endif
0280
0281 ref_stack.back()->set_parents();
0282 ref_stack.pop_back();
0283 return true;
0284 }
0285
0286 bool start_array(std::size_t len)
0287 {
0288 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
0289
0290 #if JSON_DIAGNOSTIC_POSITIONS
0291
0292
0293 if (m_lexer_ref)
0294 {
0295 ref_stack.back()->start_position = m_lexer_ref->get_position() - 1;
0296 }
0297 #endif
0298
0299 if (JSON_HEDLEY_UNLIKELY(len != detail::unknown_size() && len > ref_stack.back()->max_size()))
0300 {
0301 JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
0302 }
0303
0304 return true;
0305 }
0306
0307 bool end_array()
0308 {
0309 JSON_ASSERT(!ref_stack.empty());
0310 JSON_ASSERT(ref_stack.back()->is_array());
0311
0312 #if JSON_DIAGNOSTIC_POSITIONS
0313 if (m_lexer_ref)
0314 {
0315
0316 ref_stack.back()->end_position = m_lexer_ref->get_position();
0317 }
0318 #endif
0319
0320 ref_stack.back()->set_parents();
0321 ref_stack.pop_back();
0322 return true;
0323 }
0324
0325 template<class Exception>
0326 bool parse_error(std::size_t , const std::string& ,
0327 const Exception& ex)
0328 {
0329 errored = true;
0330 static_cast<void>(ex);
0331 if (allow_exceptions)
0332 {
0333 JSON_THROW(ex);
0334 }
0335 return false;
0336 }
0337
0338 constexpr bool is_errored() const
0339 {
0340 return errored;
0341 }
0342
0343 private:
0344
0345 #if JSON_DIAGNOSTIC_POSITIONS
0346 void handle_diagnostic_positions_for_json_value(BasicJsonType& v)
0347 {
0348 if (m_lexer_ref)
0349 {
0350
0351
0352
0353 v.end_position = m_lexer_ref->get_position();
0354
0355 switch (v.type())
0356 {
0357 case value_t::boolean:
0358 {
0359
0360 v.start_position = v.end_position - (v.m_data.m_value.boolean ? 4 : 5);
0361 break;
0362 }
0363
0364 case value_t::null:
0365 {
0366
0367 v.start_position = v.end_position - 4;
0368 break;
0369 }
0370
0371 case value_t::string:
0372 {
0373
0374 v.start_position = v.end_position - v.m_data.m_value.string->size() - 2;
0375 break;
0376 }
0377
0378
0379
0380
0381
0382
0383 case value_t::discarded:
0384 {
0385 v.end_position = std::string::npos;
0386 v.start_position = v.end_position;
0387 break;
0388 }
0389
0390 case value_t::binary:
0391 case value_t::number_integer:
0392 case value_t::number_unsigned:
0393 case value_t::number_float:
0394 {
0395 v.start_position = v.end_position - m_lexer_ref->get_string().size();
0396 break;
0397 }
0398 case value_t::object:
0399 case value_t::array:
0400 {
0401
0402
0403 break;
0404 }
0405 default:
0406
0407 JSON_ASSERT(false);
0408 }
0409 }
0410 }
0411 #endif
0412
0413
0414
0415
0416
0417
0418
0419 template<typename Value>
0420 JSON_HEDLEY_RETURNS_NON_NULL
0421 BasicJsonType* handle_value(Value&& v)
0422 {
0423 if (ref_stack.empty())
0424 {
0425 root = BasicJsonType(std::forward<Value>(v));
0426
0427 #if JSON_DIAGNOSTIC_POSITIONS
0428 handle_diagnostic_positions_for_json_value(root);
0429 #endif
0430
0431 return &root;
0432 }
0433
0434 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
0435
0436 if (ref_stack.back()->is_array())
0437 {
0438 ref_stack.back()->m_data.m_value.array->emplace_back(std::forward<Value>(v));
0439
0440 #if JSON_DIAGNOSTIC_POSITIONS
0441 handle_diagnostic_positions_for_json_value(ref_stack.back()->m_data.m_value.array->back());
0442 #endif
0443
0444 return &(ref_stack.back()->m_data.m_value.array->back());
0445 }
0446
0447 JSON_ASSERT(ref_stack.back()->is_object());
0448 JSON_ASSERT(object_element);
0449 *object_element = BasicJsonType(std::forward<Value>(v));
0450
0451 #if JSON_DIAGNOSTIC_POSITIONS
0452 handle_diagnostic_positions_for_json_value(*object_element);
0453 #endif
0454
0455 return object_element;
0456 }
0457
0458
0459 BasicJsonType& root;
0460
0461 std::vector<BasicJsonType*> ref_stack {};
0462
0463 BasicJsonType* object_element = nullptr;
0464
0465 bool errored = false;
0466
0467 const bool allow_exceptions = true;
0468
0469 lexer_t* m_lexer_ref = nullptr;
0470 };
0471
0472 template<typename BasicJsonType, typename InputAdapterType>
0473 class json_sax_dom_callback_parser
0474 {
0475 public:
0476 using number_integer_t = typename BasicJsonType::number_integer_t;
0477 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
0478 using number_float_t = typename BasicJsonType::number_float_t;
0479 using string_t = typename BasicJsonType::string_t;
0480 using binary_t = typename BasicJsonType::binary_t;
0481 using parser_callback_t = typename BasicJsonType::parser_callback_t;
0482 using parse_event_t = typename BasicJsonType::parse_event_t;
0483 using lexer_t = lexer<BasicJsonType, InputAdapterType>;
0484
0485 json_sax_dom_callback_parser(BasicJsonType& r,
0486 parser_callback_t cb,
0487 const bool allow_exceptions_ = true,
0488 lexer_t* lexer_ = nullptr)
0489 : root(r), callback(std::move(cb)), allow_exceptions(allow_exceptions_), m_lexer_ref(lexer_)
0490 {
0491 keep_stack.push_back(true);
0492 }
0493
0494
0495 json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
0496 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default;
0497 json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
0498 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default;
0499 ~json_sax_dom_callback_parser() = default;
0500
0501 bool null()
0502 {
0503 handle_value(nullptr);
0504 return true;
0505 }
0506
0507 bool boolean(bool val)
0508 {
0509 handle_value(val);
0510 return true;
0511 }
0512
0513 bool number_integer(number_integer_t val)
0514 {
0515 handle_value(val);
0516 return true;
0517 }
0518
0519 bool number_unsigned(number_unsigned_t val)
0520 {
0521 handle_value(val);
0522 return true;
0523 }
0524
0525 bool number_float(number_float_t val, const string_t& )
0526 {
0527 handle_value(val);
0528 return true;
0529 }
0530
0531 bool string(string_t& val)
0532 {
0533 handle_value(val);
0534 return true;
0535 }
0536
0537 bool binary(binary_t& val)
0538 {
0539 handle_value(std::move(val));
0540 return true;
0541 }
0542
0543 bool start_object(std::size_t len)
0544 {
0545
0546 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
0547 keep_stack.push_back(keep);
0548
0549 auto val = handle_value(BasicJsonType::value_t::object, true);
0550 ref_stack.push_back(val.second);
0551
0552 if (ref_stack.back())
0553 {
0554
0555 #if JSON_DIAGNOSTIC_POSITIONS
0556
0557
0558 if (m_lexer_ref)
0559 {
0560
0561
0562 ref_stack.back()->start_position = m_lexer_ref->get_position() - 1;
0563 }
0564 #endif
0565
0566
0567 if (JSON_HEDLEY_UNLIKELY(len != detail::unknown_size() && len > ref_stack.back()->max_size()))
0568 {
0569 JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
0570 }
0571 }
0572 return true;
0573 }
0574
0575 bool key(string_t& val)
0576 {
0577 BasicJsonType k = BasicJsonType(val);
0578
0579
0580 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
0581 key_keep_stack.push_back(keep);
0582
0583
0584 if (keep && ref_stack.back())
0585 {
0586 object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val) = discarded);
0587 }
0588
0589 return true;
0590 }
0591
0592 bool end_object()
0593 {
0594 if (ref_stack.back())
0595 {
0596 if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
0597 {
0598
0599 *ref_stack.back() = discarded;
0600
0601 #if JSON_DIAGNOSTIC_POSITIONS
0602
0603 handle_diagnostic_positions_for_json_value(*ref_stack.back());
0604 #endif
0605 }
0606 else
0607 {
0608
0609 #if JSON_DIAGNOSTIC_POSITIONS
0610 if (m_lexer_ref)
0611 {
0612
0613 ref_stack.back()->end_position = m_lexer_ref->get_position();
0614 }
0615 #endif
0616
0617 ref_stack.back()->set_parents();
0618 }
0619 }
0620
0621 JSON_ASSERT(!ref_stack.empty());
0622 JSON_ASSERT(!keep_stack.empty());
0623 ref_stack.pop_back();
0624 keep_stack.pop_back();
0625
0626 if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
0627 {
0628
0629 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
0630 {
0631 if (it->is_discarded())
0632 {
0633 ref_stack.back()->erase(it);
0634 break;
0635 }
0636 }
0637 }
0638
0639 return true;
0640 }
0641
0642 bool start_array(std::size_t len)
0643 {
0644 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
0645 keep_stack.push_back(keep);
0646
0647 auto val = handle_value(BasicJsonType::value_t::array, true);
0648 ref_stack.push_back(val.second);
0649
0650 if (ref_stack.back())
0651 {
0652
0653 #if JSON_DIAGNOSTIC_POSITIONS
0654
0655
0656 if (m_lexer_ref)
0657 {
0658
0659
0660 ref_stack.back()->start_position = m_lexer_ref->get_position() - 1;
0661 }
0662 #endif
0663
0664
0665 if (JSON_HEDLEY_UNLIKELY(len != detail::unknown_size() && len > ref_stack.back()->max_size()))
0666 {
0667 JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
0668 }
0669 }
0670
0671 return true;
0672 }
0673
0674 bool end_array()
0675 {
0676 bool keep = true;
0677
0678 if (ref_stack.back())
0679 {
0680 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
0681 if (keep)
0682 {
0683
0684 #if JSON_DIAGNOSTIC_POSITIONS
0685 if (m_lexer_ref)
0686 {
0687
0688 ref_stack.back()->end_position = m_lexer_ref->get_position();
0689 }
0690 #endif
0691
0692 ref_stack.back()->set_parents();
0693 }
0694 else
0695 {
0696
0697 *ref_stack.back() = discarded;
0698
0699 #if JSON_DIAGNOSTIC_POSITIONS
0700
0701 handle_diagnostic_positions_for_json_value(*ref_stack.back());
0702 #endif
0703 }
0704 }
0705
0706 JSON_ASSERT(!ref_stack.empty());
0707 JSON_ASSERT(!keep_stack.empty());
0708 ref_stack.pop_back();
0709 keep_stack.pop_back();
0710
0711
0712 if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
0713 {
0714 ref_stack.back()->m_data.m_value.array->pop_back();
0715 }
0716
0717 return true;
0718 }
0719
0720 template<class Exception>
0721 bool parse_error(std::size_t , const std::string& ,
0722 const Exception& ex)
0723 {
0724 errored = true;
0725 static_cast<void>(ex);
0726 if (allow_exceptions)
0727 {
0728 JSON_THROW(ex);
0729 }
0730 return false;
0731 }
0732
0733 constexpr bool is_errored() const
0734 {
0735 return errored;
0736 }
0737
0738 private:
0739
0740 #if JSON_DIAGNOSTIC_POSITIONS
0741 void handle_diagnostic_positions_for_json_value(BasicJsonType& v)
0742 {
0743 if (m_lexer_ref)
0744 {
0745
0746
0747
0748 v.end_position = m_lexer_ref->get_position();
0749
0750 switch (v.type())
0751 {
0752 case value_t::boolean:
0753 {
0754
0755 v.start_position = v.end_position - (v.m_data.m_value.boolean ? 4 : 5);
0756 break;
0757 }
0758
0759 case value_t::null:
0760 {
0761
0762 v.start_position = v.end_position - 4;
0763 break;
0764 }
0765
0766 case value_t::string:
0767 {
0768
0769 v.start_position = v.end_position - v.m_data.m_value.string->size() - 2;
0770 break;
0771 }
0772
0773 case value_t::discarded:
0774 {
0775 v.end_position = std::string::npos;
0776 v.start_position = v.end_position;
0777 break;
0778 }
0779
0780 case value_t::binary:
0781 case value_t::number_integer:
0782 case value_t::number_unsigned:
0783 case value_t::number_float:
0784 {
0785 v.start_position = v.end_position - m_lexer_ref->get_string().size();
0786 break;
0787 }
0788
0789 case value_t::object:
0790 case value_t::array:
0791 {
0792
0793
0794 break;
0795 }
0796 default:
0797
0798 JSON_ASSERT(false);
0799 }
0800 }
0801 }
0802 #endif
0803
0804
0805
0806
0807
0808
0809
0810
0811
0812
0813
0814
0815
0816
0817
0818
0819 template<typename Value>
0820 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
0821 {
0822 JSON_ASSERT(!keep_stack.empty());
0823
0824
0825
0826 if (!keep_stack.back())
0827 {
0828 return {false, nullptr};
0829 }
0830
0831
0832 auto value = BasicJsonType(std::forward<Value>(v));
0833
0834 #if JSON_DIAGNOSTIC_POSITIONS
0835 handle_diagnostic_positions_for_json_value(value);
0836 #endif
0837
0838
0839 const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
0840
0841
0842 if (!keep)
0843 {
0844 return {false, nullptr};
0845 }
0846
0847 if (ref_stack.empty())
0848 {
0849 root = std::move(value);
0850 return {true, & root};
0851 }
0852
0853
0854
0855 if (!ref_stack.back())
0856 {
0857 return {false, nullptr};
0858 }
0859
0860
0861 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
0862
0863
0864 if (ref_stack.back()->is_array())
0865 {
0866 ref_stack.back()->m_data.m_value.array->emplace_back(std::move(value));
0867 return {true, & (ref_stack.back()->m_data.m_value.array->back())};
0868 }
0869
0870
0871 JSON_ASSERT(ref_stack.back()->is_object());
0872
0873 JSON_ASSERT(!key_keep_stack.empty());
0874 const bool store_element = key_keep_stack.back();
0875 key_keep_stack.pop_back();
0876
0877 if (!store_element)
0878 {
0879 return {false, nullptr};
0880 }
0881
0882 JSON_ASSERT(object_element);
0883 *object_element = std::move(value);
0884 return {true, object_element};
0885 }
0886
0887
0888 BasicJsonType& root;
0889
0890 std::vector<BasicJsonType*> ref_stack {};
0891
0892 std::vector<bool> keep_stack {};
0893
0894 std::vector<bool> key_keep_stack {};
0895
0896 BasicJsonType* object_element = nullptr;
0897
0898 bool errored = false;
0899
0900 const parser_callback_t callback = nullptr;
0901
0902 const bool allow_exceptions = true;
0903
0904 BasicJsonType discarded = BasicJsonType::value_t::discarded;
0905
0906 lexer_t* m_lexer_ref = nullptr;
0907 };
0908
0909 template<typename BasicJsonType>
0910 class json_sax_acceptor
0911 {
0912 public:
0913 using number_integer_t = typename BasicJsonType::number_integer_t;
0914 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
0915 using number_float_t = typename BasicJsonType::number_float_t;
0916 using string_t = typename BasicJsonType::string_t;
0917 using binary_t = typename BasicJsonType::binary_t;
0918
0919 bool null()
0920 {
0921 return true;
0922 }
0923
0924 bool boolean(bool )
0925 {
0926 return true;
0927 }
0928
0929 bool number_integer(number_integer_t )
0930 {
0931 return true;
0932 }
0933
0934 bool number_unsigned(number_unsigned_t )
0935 {
0936 return true;
0937 }
0938
0939 bool number_float(number_float_t , const string_t& )
0940 {
0941 return true;
0942 }
0943
0944 bool string(string_t& )
0945 {
0946 return true;
0947 }
0948
0949 bool binary(binary_t& )
0950 {
0951 return true;
0952 }
0953
0954 bool start_object(std::size_t = detail::unknown_size())
0955 {
0956 return true;
0957 }
0958
0959 bool key(string_t& )
0960 {
0961 return true;
0962 }
0963
0964 bool end_object()
0965 {
0966 return true;
0967 }
0968
0969 bool start_array(std::size_t = detail::unknown_size())
0970 {
0971 return true;
0972 }
0973
0974 bool end_array()
0975 {
0976 return true;
0977 }
0978
0979 bool parse_error(std::size_t , const std::string& , const detail::exception& )
0980 {
0981 return false;
0982 }
0983 };
0984
0985 }
0986 NLOHMANN_JSON_NAMESPACE_END