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