json_basic.hpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855
  1. // Copyright (c) 2018-2020 Jsonxx - Nomango
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in
  11. // all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. // THE SOFTWARE.
  20. #pragma once
  21. #include <map>
  22. #include <string>
  23. #include <array>
  24. #include <vector>
  25. #include <cstdint>
  26. #include <algorithm>
  27. #include "json_value.hpp"
  28. #include "json_parser.hpp"
  29. #include "json_serializer.hpp"
  30. namespace jsonxx {
  31. template<
  32. template<class _Kty, class _Ty, class... _Args> typename _ObjectTy = std::map,
  33. template<class _Kty, class... _Args> typename _ArrayTy = std::vector,
  34. typename _StringTy = std::string,
  35. typename _IntegerTy = std::int32_t,
  36. typename _FloatTy = double,
  37. typename _BooleanTy = bool,
  38. template<class _Ty> typename _Allocator = std::allocator>
  39. class basic_json;
  40. //
  41. // details of basic_json
  42. //
  43. #define DECLARE_BASIC_JSON_TEMPLATE \
  44. template < \
  45. template <class _Kty, class _Ty, class... _Args> typename _ObjectTy, \
  46. template <class _Kty, class... _Args> typename _ArrayTy, \
  47. typename _StringTy, \
  48. typename _IntegerTy, \
  49. typename _FloatTy, \
  50. typename _BooleanTy, \
  51. template <class _Ty> typename _Allocator>
  52. #define DECLARE_BASIC_JSON_TPL_ARGS \
  53. _ObjectTy, _ArrayTy, _StringTy, _IntegerTy, _FloatTy, _BooleanTy, _Allocator
  54. //
  55. // is_basic_json
  56. //
  57. template<typename>
  58. struct is_basic_json
  59. : std::false_type {
  60. };
  61. DECLARE_BASIC_JSON_TEMPLATE
  62. struct is_basic_json<basic_json<DECLARE_BASIC_JSON_TPL_ARGS>>
  63. : std::true_type {
  64. };
  65. //
  66. // basic_json
  67. //
  68. DECLARE_BASIC_JSON_TEMPLATE
  69. class basic_json {
  70. friend struct iterator_impl<basic_json>;
  71. friend struct iterator_impl<const basic_json>;
  72. friend struct json_serializer<basic_json>;
  73. friend struct json_parser<basic_json>;
  74. friend struct json_value_getter<basic_json>;
  75. public:
  76. template<typename _Ty>
  77. using allocator_type = _Allocator<_Ty>;
  78. using size_type = std::size_t;
  79. using difference_type = std::ptrdiff_t;
  80. using string_type = _StringTy;
  81. using char_type = typename _StringTy::value_type;
  82. using integer_type = _IntegerTy;
  83. using float_type = _FloatTy;
  84. using boolean_type = _BooleanTy;
  85. using array_type = _ArrayTy<basic_json, allocator_type<basic_json>>;
  86. using object_type = _ObjectTy<string_type, basic_json, std::less<string_type>, allocator_type<std::pair<const string_type, basic_json>>>;
  87. using initializer_list = std::initializer_list<basic_json>;
  88. using iterator = iterator_impl<basic_json>;
  89. using const_iterator = iterator_impl<const basic_json>;
  90. using reverse_iterator = std::reverse_iterator<iterator>;
  91. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  92. public:
  93. basic_json() {}
  94. basic_json(std::nullptr_t) {}
  95. basic_json(const json_type type) : value_(type) {}
  96. basic_json(basic_json const &other) : value_(other.value_) {}
  97. basic_json(basic_json &&other) : value_(std::move(other.value_)) {
  98. // invalidate payload
  99. other.value_.type = json_type::null;
  100. other.value_.data.object = nullptr;
  101. }
  102. basic_json(string_type const &value) : value_(value) {}
  103. template<
  104. typename _CompatibleTy,
  105. typename std::enable_if<std::is_constructible<string_type, _CompatibleTy>::value, int>::type = 0>
  106. basic_json(const _CompatibleTy &value) {
  107. value_.type = json_type::string;
  108. value_.data.string = value_.template create<string_type>(value);
  109. }
  110. basic_json(array_type const &arr)
  111. : value_(arr) {
  112. }
  113. basic_json(object_type const &object)
  114. : value_(object) {
  115. }
  116. basic_json(integer_type value)
  117. : value_(value) {
  118. }
  119. template<
  120. typename _IntegerUTy,
  121. typename std::enable_if<std::is_integral<_IntegerUTy>::value, int>::type = 0>
  122. basic_json(_IntegerUTy value)
  123. : value_(static_cast<integer_type>(value)) {
  124. }
  125. basic_json(float_type value)
  126. : value_(value) {
  127. }
  128. template<
  129. typename _FloatingTy,
  130. typename std::enable_if<std::is_floating_point<_FloatingTy>::value, int>::type = 0>
  131. basic_json(_FloatingTy value)
  132. : value_(static_cast<float_type>(value)) {
  133. }
  134. basic_json(boolean_type value)
  135. : value_(value) {
  136. }
  137. basic_json(initializer_list const &init_list) {
  138. bool is_an_object = std::all_of(init_list.begin(), init_list.end(), [](const basic_json &json) {
  139. return (json.is_array() && json.size() == 2 && json[0].is_string());
  140. });
  141. if (is_an_object) {
  142. value_ = json_type::object;
  143. std::for_each(init_list.begin(), init_list.end(), [this](const basic_json &json) {
  144. value_.data.object->emplace(
  145. *((*json.value_.data.vector)[0].value_.data.string),
  146. (*json.value_.data.vector)[1]);
  147. });
  148. } else {
  149. value_ = json_type::array;
  150. value_.data.vector->reserve(init_list.size());
  151. value_.data.vector->assign(init_list.begin(), init_list.end());
  152. }
  153. }
  154. static inline basic_json object(initializer_list const &init_list) {
  155. if (init_list.size() != 2 || !(*init_list.begin()).is_string()) {
  156. throw json_type_error("cannot create object from initializer_list");
  157. }
  158. basic_json json;
  159. json.value_ = json_type::object;
  160. json.value_.data.object->emplace(*((*init_list.begin()).value_.data.string), *(init_list.begin() + 1));
  161. return json;
  162. }
  163. static inline basic_json array(initializer_list const &init_list) {
  164. basic_json json;
  165. json.value_ = json_type::array;
  166. if (init_list.size()) {
  167. json.value_.data.vector->reserve(init_list.size());
  168. json.value_.data.vector->assign(init_list.begin(), init_list.end());
  169. }
  170. return json;
  171. }
  172. inline bool is_object() const { return value_.type == json_type::object; }
  173. inline bool is_array() const { return value_.type == json_type::array; }
  174. inline bool is_string() const { return value_.type == json_type::string; }
  175. inline bool is_boolean() const { return value_.type == json_type::boolean; }
  176. inline bool is_integer() const { return value_.type == json_type::number_integer; }
  177. inline bool is_float() const { return value_.type == json_type::number_float; }
  178. inline bool is_number() const { return is_integer() || is_float(); }
  179. inline bool is_null() const { return value_.type == json_type::null; }
  180. inline json_type type() const { return value_.type; }
  181. inline string_type type_name() const {
  182. switch (type()) {
  183. case json_type::object:
  184. return string_type("object");
  185. case json_type::array:
  186. return string_type("array");
  187. case json_type::string:
  188. return string_type("string");
  189. case json_type::number_integer:
  190. return string_type("integer");
  191. case json_type::number_float:
  192. return string_type("float");
  193. case json_type::boolean:
  194. return string_type("boolean");
  195. case json_type::null:
  196. return string_type("null");
  197. }
  198. return string_type();
  199. }
  200. inline void swap(basic_json &rhs) { value_.swap(rhs.value_); }
  201. public:
  202. inline iterator begin() {
  203. iterator iter(this);
  204. iter.set_begin();
  205. return iter;
  206. }
  207. inline const_iterator begin() const { return cbegin(); }
  208. inline const_iterator cbegin() const {
  209. const_iterator iter(this);
  210. iter.set_begin();
  211. return iter;
  212. }
  213. inline iterator end() {
  214. iterator iter(this);
  215. iter.set_end();
  216. return iter;
  217. }
  218. inline const_iterator end() const { return cend(); }
  219. inline const_iterator cend() const {
  220. const_iterator iter(this);
  221. iter.set_end();
  222. return iter;
  223. }
  224. inline reverse_iterator rbegin() { return reverse_iterator(end()); }
  225. inline const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
  226. inline const_reverse_iterator crbegin() const { return rbegin(); }
  227. inline reverse_iterator rend() { return reverse_iterator(begin()); }
  228. inline const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
  229. inline const_reverse_iterator crend() const { return rend(); }
  230. public:
  231. inline size_type size() const {
  232. switch (type()) {
  233. case json_type::null:
  234. return 0;
  235. case json_type::array:
  236. return value_.data.vector->size();
  237. case json_type::object:
  238. return value_.data.object->size();
  239. default:
  240. return 1;
  241. }
  242. }
  243. inline bool empty() const {
  244. if (is_null())
  245. return true;
  246. if (is_object())
  247. return value_.data.object->empty();
  248. if (is_array())
  249. return value_.data.vector->empty();
  250. return false;
  251. }
  252. template<typename _Kty>
  253. inline const_iterator find(_Kty &&key) const {
  254. if (is_object()) {
  255. const_iterator iter;
  256. iter.it_.object_iter = value_.data.object->find(std::forward<_Kty>(key));
  257. return iter;
  258. }
  259. return cend();
  260. }
  261. template<typename _Kty>
  262. inline size_type count(_Kty &&key) const {
  263. return is_object() ? value_.data.object->count(std::forward<_Kty>(key)) : 0;
  264. }
  265. inline size_type erase(const typename object_type::key_type &key) {
  266. if (!is_object()) {
  267. throw json_invalid_key("cannot use erase() with non-object value");
  268. }
  269. return value_.data.object->erase(key);
  270. }
  271. inline void erase(const size_type index) {
  272. if (!is_array()) {
  273. throw json_invalid_key("cannot use erase() with non-array value");
  274. }
  275. value_.data.vector->erase(value_.data.vector->begin() + static_cast<difference_type>(index));
  276. }
  277. template<
  278. class _IteratorTy,
  279. typename std::enable_if<
  280. std::is_same<_IteratorTy, iterator>::value ||
  281. std::is_same<_IteratorTy, const_iterator>::value,
  282. int>::type = 0>
  283. inline _IteratorTy erase(_IteratorTy pos) {
  284. _IteratorTy result = end();
  285. switch (type()) {
  286. case json_type::object: {
  287. result.it_.object_iter = value_.data.object->erase(pos.it_.object_iter);
  288. break;
  289. }
  290. case json_type::array: {
  291. result.it_.array_iter = value_.data.vector->erase(pos.it_.array_iter);
  292. break;
  293. }
  294. default:
  295. throw json_invalid_iterator("cannot use erase() with non-object & non-array value");
  296. }
  297. return result;
  298. }
  299. template<
  300. class _IteratorTy,
  301. typename std::enable_if<
  302. std::is_same<_IteratorTy, iterator>::value ||
  303. std::is_same<_IteratorTy, const_iterator>::value,
  304. int>::type = 0>
  305. inline _IteratorTy erase(_IteratorTy first, _IteratorTy last) {
  306. _IteratorTy result = end();
  307. switch (type()) {
  308. case json_type::object: {
  309. result.it_.object_iter = value_.data.object->erase(first.it_.object_iter, last.it_.object_iter);
  310. break;
  311. }
  312. case json_type::array: {
  313. result.it_.array_iter = value_.data.vector->erase(first.it_.array_iter, last.it_.array_iter);
  314. break;
  315. }
  316. default:
  317. throw json_invalid_iterator("cannot use erase() with non-object & non-array value");
  318. }
  319. return result;
  320. }
  321. inline void push_back(basic_json &&json) {
  322. if (!is_null() && !is_array()) {
  323. throw json_type_error("cannot use push_back() with non-array value");
  324. }
  325. if (is_null()) {
  326. value_ = json_type::array;
  327. }
  328. value_.data.vector->push_back(std::move(json));
  329. }
  330. inline basic_json &operator+=(basic_json &&json) {
  331. push_back(std::move(json));
  332. return (*this);
  333. }
  334. inline void clear() {
  335. switch (type()) {
  336. case json_type::number_integer: {
  337. value_.data.number_integer = 0;
  338. break;
  339. }
  340. case json_type::number_float: {
  341. value_.data.number_float = static_cast<float_type>(0.0);
  342. break;
  343. }
  344. case json_type::boolean: {
  345. value_.data.boolean = false;
  346. break;
  347. }
  348. case json_type::string: {
  349. value_.data.string->clear();
  350. break;
  351. }
  352. case json_type::array: {
  353. value_.data.vector->clear();
  354. break;
  355. }
  356. case json_type::object: {
  357. value_.data.object->clear();
  358. break;
  359. }
  360. default:
  361. break;
  362. }
  363. }
  364. public:
  365. // GET value functions
  366. inline bool get_value(boolean_type &val) const {
  367. if (is_boolean()) {
  368. val = value_.data.boolean;
  369. return true;
  370. }
  371. return false;
  372. }
  373. inline bool get_value(integer_type &val) const {
  374. if (is_integer()) {
  375. val = value_.data.number_integer;
  376. return true;
  377. }
  378. return false;
  379. }
  380. inline bool get_value(float_type &val) const {
  381. if (is_float()) {
  382. val = value_.data.number_float;
  383. return true;
  384. }
  385. return false;
  386. }
  387. template<
  388. typename _IntegerUTy,
  389. typename std::enable_if<std::is_integral<_IntegerUTy>::value, int>::type = 0>
  390. inline bool get_value(_IntegerUTy &val) const {
  391. if (is_integer()) {
  392. val = static_cast<_IntegerUTy>(value_.data.number_integer);
  393. return true;
  394. }
  395. return false;
  396. }
  397. template<
  398. typename _FloatingTy,
  399. typename std::enable_if<std::is_floating_point<_FloatingTy>::value, int>::type = 0>
  400. inline bool get_value(_FloatingTy &val) const {
  401. if (is_float()) {
  402. val = static_cast<_FloatingTy>(value_.data.number_float);
  403. return true;
  404. }
  405. return false;
  406. }
  407. inline bool get_value(array_type &val) const {
  408. if (is_array()) {
  409. val.assign((*value_.data.vector).begin(), (*value_.data.vector).end());
  410. return true;
  411. }
  412. return false;
  413. }
  414. inline bool get_value(string_type &val) const {
  415. if (is_string()) {
  416. val.assign(*value_.data.string);
  417. return true;
  418. }
  419. return false;
  420. }
  421. inline bool get_value(object_type &val) const {
  422. if (is_object()) {
  423. val.assign(*value_.data.object);
  424. return true;
  425. }
  426. return false;
  427. }
  428. boolean_type as_bool() const {
  429. if (!is_boolean())
  430. throw json_type_error("json value must be boolean");
  431. return value_.data.boolean;
  432. }
  433. integer_type as_int() const {
  434. if (!is_integer())
  435. throw json_type_error("json value must be integer");
  436. return value_.data.number_integer;
  437. }
  438. float_type as_float() const {
  439. if (is_float())
  440. throw json_type_error("json value must be float");
  441. return value_.data.number_float;
  442. }
  443. float_type as_float_anynum() const {
  444. if (!is_number())
  445. throw json_type_error("json value must be number");
  446. if (is_integer())
  447. return value_.data.number_integer;
  448. if (is_float())
  449. return value_.data.number_float;
  450. throw json_type_error("json value can not be known");
  451. }
  452. const array_type &as_array() const {
  453. if (!is_array())
  454. throw json_type_error("json value must be array");
  455. return *value_.data.vector;
  456. }
  457. const string_type &as_string() const {
  458. if (!is_string())
  459. throw json_type_error("json value must be string");
  460. return *value_.data.string;
  461. }
  462. const object_type &as_object() const {
  463. if (!is_object())
  464. throw json_type_error("json value must be object");
  465. return *value_.data.object;
  466. }
  467. template<typename _Ty>
  468. _Ty get() const {
  469. _Ty value;
  470. json_value_getter<basic_json>::assign(*this, value);
  471. return value;
  472. }
  473. public:
  474. // operator= functions
  475. inline basic_json &operator=(basic_json const &other) {
  476. value_ = other.value_;
  477. return (*this);
  478. }
  479. inline basic_json &operator=(basic_json &&other) {
  480. value_ = std::move(other.value_);
  481. return (*this);
  482. }
  483. inline basic_json &operator=(std::nullptr_t) {
  484. value_ = nullptr;
  485. return (*this);
  486. }
  487. public:
  488. // operator[] functions
  489. inline basic_json &operator[](size_type index) {
  490. if (is_null()) {
  491. value_ = json_type::array;
  492. }
  493. if (!is_array()) {
  494. throw json_invalid_key("operator[] called on a non-array object");
  495. }
  496. if (index >= value_.data.vector->size()) {
  497. value_.data.vector->insert(value_.data.vector->end(),
  498. index - value_.data.vector->size() + 1,
  499. basic_json());
  500. }
  501. return (*value_.data.vector)[index];
  502. }
  503. inline basic_json &operator[](size_type index) const {
  504. if (!is_array()) {
  505. throw json_invalid_key("operator[] called on a non-array type");
  506. }
  507. if (index >= value_.data.vector->size()) {
  508. throw std::out_of_range("operator[] index out of range");
  509. }
  510. return (*value_.data.vector)[index];
  511. }
  512. inline basic_json &operator[](const typename object_type::key_type &key) {
  513. if (is_null()) {
  514. value_ = json_type::object;
  515. }
  516. if (!is_object()) {
  517. throw json_invalid_key("operator[] called on a non-object type");
  518. }
  519. return (*value_.data.object)[key];
  520. }
  521. inline basic_json &operator[](const typename object_type::key_type &key) const {
  522. if (!is_object()) {
  523. throw json_invalid_key("operator[] called on a non-object object");
  524. }
  525. auto iter = value_.data.object->find(key);
  526. if (iter == value_.data.object->end()) {
  527. throw std::out_of_range("operator[] key out of range");
  528. }
  529. return iter->second;
  530. }
  531. template<typename _CharT>
  532. inline basic_json &operator[](_CharT *key) {
  533. if (is_null()) {
  534. value_ = json_type::object;
  535. }
  536. if (!is_object()) {
  537. throw json_invalid_key("operator[] called on a non-object object");
  538. }
  539. return (*value_.data.object)[key];
  540. }
  541. template<typename _CharT>
  542. inline basic_json &operator[](_CharT *key) const {
  543. if (!is_object()) {
  544. throw json_invalid_key("operator[] called on a non-object object");
  545. }
  546. auto iter = value_.data.object->find(key);
  547. if (iter == value_.data.object->end()) {
  548. throw std::out_of_range("operator[] key out of range");
  549. }
  550. return iter->second;
  551. }
  552. public:
  553. // implicitly convert functions
  554. template<typename _Ty>
  555. inline operator _Ty() const {
  556. return get<_Ty>();
  557. }
  558. public:
  559. // dumps functions
  560. friend std::basic_ostream<char_type> &operator<<(std::basic_ostream<char_type> &out, const basic_json &json) {
  561. using char_type = typename std::basic_ostream<char_type>::char_type;
  562. const bool pretty_print = (out.width() > 0);
  563. const auto indentation = (pretty_print ? out.width() : 0);
  564. out.width(0);
  565. stream_output_adapter<char_type> adapter(out);
  566. json_serializer<basic_json>(&adapter, out.fill()).dump(json, pretty_print,
  567. static_cast<unsigned int>(indentation));
  568. return out;
  569. }
  570. string_type dump(
  571. const int indent = -1,
  572. const char_type indent_char = ' ') const {
  573. string_type result;
  574. string_output_adapter<string_type> adapter(result);
  575. dump(&adapter, indent, indent_char);
  576. return result;
  577. }
  578. void dump(
  579. output_adapter <char_type> *adapter,
  580. const int indent = -1,
  581. const char_type indent_char = ' ') const {
  582. if (indent >= 0) {
  583. json_serializer<basic_json>(adapter, indent_char).dump(*this, true, static_cast<unsigned int>(indent));
  584. } else {
  585. json_serializer<basic_json>(adapter, indent_char).dump(*this, false, 0);
  586. }
  587. }
  588. public:
  589. // parse functions
  590. friend std::basic_istream<char_type> &
  591. operator>>(std::basic_istream<char_type> &in, basic_json &json) {
  592. stream_input_adapter<char_type> adapter(in);
  593. json_parser<basic_json>(&adapter).parse(json);
  594. return in;
  595. }
  596. static inline basic_json parse(const string_type &str) {
  597. string_input_adapter<string_type> adapter(str);
  598. return parse(&adapter);
  599. }
  600. static inline basic_json parse(const char_type *str) {
  601. buffer_input_adapter<char_type> adapter(str);
  602. return parse(&adapter);
  603. }
  604. static inline basic_json parse(std::FILE *file) {
  605. file_input_adapter<char_type> adapter(file);
  606. return parse(&adapter);
  607. }
  608. static inline basic_json parse(input_adapter <char_type> *adapter) {
  609. basic_json result;
  610. json_parser<basic_json>(adapter).parse(result);
  611. return result;
  612. }
  613. public:
  614. // compare functions
  615. friend bool operator==(const basic_json &lhs, const basic_json &rhs) {
  616. const auto lhs_type = lhs.type();
  617. const auto rhs_type = rhs.type();
  618. if (lhs_type == rhs_type) {
  619. switch (lhs_type) {
  620. case json_type::array:
  621. return (*lhs.value_.data.vector == *rhs.value_.data.vector);
  622. case json_type::object:
  623. return (*lhs.value_.data.object == *rhs.value_.data.object);
  624. case json_type::null:
  625. return true;
  626. case json_type::string:
  627. return (*lhs.value_.data.string == *rhs.value_.data.string);
  628. case json_type::boolean:
  629. return (lhs.value_.data.boolean == rhs.value_.data.boolean);
  630. case json_type::number_integer:
  631. return (lhs.value_.data.number_integer == rhs.value_.data.number_integer);
  632. case json_type::number_float:
  633. return (lhs.value_.data.number_float == rhs.value_.data.number_float);
  634. default:
  635. return false;
  636. }
  637. } else if (lhs_type == json_type::number_integer && rhs_type == json_type::number_float) {
  638. return (static_cast<float_type>(lhs.value_.data.number_integer) == rhs.value_.data.number_float);
  639. } else if (lhs_type == json_type::number_float && rhs_type == json_type::number_integer) {
  640. return (lhs.value_.data.number_float == static_cast<float_type>(rhs.value_.data.number_integer));
  641. }
  642. return false;
  643. }
  644. friend bool operator!=(const basic_json &lhs, const basic_json &rhs) {
  645. return !(lhs == rhs);
  646. }
  647. friend bool operator<(const basic_json &lhs, const basic_json &rhs) {
  648. const auto lhs_type = lhs.type();
  649. const auto rhs_type = rhs.type();
  650. if (lhs_type == rhs_type) {
  651. switch (lhs_type) {
  652. case json_type::array:
  653. return (*lhs.value_.data.vector) < (*rhs.value_.data.vector);
  654. case json_type::object:
  655. return (*lhs.value_.data.object) < (*rhs.value_.data.object);
  656. case json_type::null:
  657. return false;
  658. case json_type::string:
  659. return (*lhs.value_.data.string) < (*rhs.value_.data.string);
  660. case json_type::boolean:
  661. return (lhs.value_.data.boolean < rhs.value_.data.boolean);
  662. case json_type::number_integer:
  663. return (lhs.value_.data.number_integer < rhs.value_.data.number_integer);
  664. case json_type::number_float:
  665. return (lhs.value_.data.number_float < rhs.value_.data.number_float);
  666. default:
  667. return false;
  668. }
  669. } else if (lhs_type == json_type::number_integer && rhs_type == json_type::number_float) {
  670. return (static_cast<float_type>(lhs.value_.data.number_integer) < rhs.value_.data.number_float);
  671. } else if (lhs_type == json_type::number_float && rhs_type == json_type::number_integer) {
  672. return (lhs.value_.data.number_float < static_cast<float_type>(rhs.value_.data.number_integer));
  673. }
  674. return false;
  675. }
  676. friend bool operator<=(const basic_json &lhs, const basic_json &rhs) {
  677. return !(rhs < lhs);
  678. }
  679. friend bool operator>(const basic_json &lhs, const basic_json &rhs) {
  680. return rhs < lhs;
  681. }
  682. friend bool operator>=(const basic_json &lhs, const basic_json &rhs) {
  683. return !(lhs < rhs);
  684. }
  685. private:
  686. json_value <basic_json> value_;
  687. };
  688. } // namespace Jsonxx
  689. #undef DECLARE_BASIC_JSON_TEMPLATE
  690. #undef DECLARE_BASIC_JSON_TPL_ARGS