unit-comparison.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. // __ _____ _____ _____
  2. // __| | __| | | | JSON for Modern C++ (supporting code)
  3. // | | |__ | | | | | | version 3.11.2
  4. // |_____|_____|_____|_|___| https://github.com/nlohmann/json
  5. //
  6. // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
  7. // SPDX-License-Identifier: MIT
  8. // cmake/test.cmake selects the C++ standard versions with which to build a
  9. // unit test based on the presence of JSON_HAS_CPP_<VERSION> macros.
  10. // When using macros that are only defined for particular versions of the standard
  11. // (e.g., JSON_HAS_FILESYSTEM for C++17 and up), please mention the corresponding
  12. // version macro in a comment close by, like this:
  13. // JSON_HAS_CPP_<VERSION> (do not remove; see note at top of file)
  14. #include "doctest_compatibility.h"
  15. #define JSON_TESTS_PRIVATE
  16. #include <nlohmann/json.hpp>
  17. using nlohmann::json;
  18. #if JSON_HAS_THREE_WAY_COMPARISON
  19. // this can be replaced with the doctest stl extension header in version 2.5
  20. namespace doctest
  21. {
  22. template<> struct StringMaker<std::partial_ordering>
  23. {
  24. static String convert(const std::partial_ordering& order)
  25. {
  26. if (order == std::partial_ordering::less)
  27. {
  28. return "std::partial_ordering::less";
  29. }
  30. if (order == std::partial_ordering::equivalent)
  31. {
  32. return "std::partial_ordering::equivalent";
  33. }
  34. if (order == std::partial_ordering::greater)
  35. {
  36. return "std::partial_ordering::greater";
  37. }
  38. if (order == std::partial_ordering::unordered)
  39. {
  40. return "std::partial_ordering::unordered";
  41. }
  42. return "{?}";
  43. }
  44. };
  45. } // namespace doctest
  46. #endif
  47. namespace
  48. {
  49. // helper function to check std::less<json::value_t>
  50. // see https://en.cppreference.com/w/cpp/utility/functional/less
  51. template <typename A, typename B, typename U = std::less<json::value_t>>
  52. bool f(A a, B b, U u = U())
  53. {
  54. return u(a, b);
  55. }
  56. } // namespace
  57. TEST_CASE("lexicographical comparison operators")
  58. {
  59. constexpr auto f_ = false;
  60. constexpr auto _t = true;
  61. constexpr auto nan = std::numeric_limits<json::number_float_t>::quiet_NaN();
  62. #if JSON_HAS_THREE_WAY_COMPARISON
  63. constexpr auto lt = std::partial_ordering::less;
  64. constexpr auto gt = std::partial_ordering::greater;
  65. constexpr auto eq = std::partial_ordering::equivalent;
  66. constexpr auto un = std::partial_ordering::unordered;
  67. #endif
  68. #if JSON_HAS_THREE_WAY_COMPARISON
  69. INFO("using 3-way comparison");
  70. #endif
  71. #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
  72. INFO("using legacy comparison");
  73. #endif
  74. //REQUIRE(std::numeric_limits<json::number_float_t>::has_quiet_NaN);
  75. REQUIRE(std::isnan(nan));
  76. SECTION("types")
  77. {
  78. std::vector<json::value_t> j_types =
  79. {
  80. json::value_t::null,
  81. json::value_t::boolean,
  82. json::value_t::number_integer,
  83. json::value_t::number_unsigned,
  84. json::value_t::number_float,
  85. json::value_t::object,
  86. json::value_t::array,
  87. json::value_t::string,
  88. json::value_t::binary,
  89. json::value_t::discarded
  90. };
  91. std::vector<std::vector<bool>> expected_lt =
  92. {
  93. //0 1 2 3 4 5 6 7 8 9
  94. {f_, _t, _t, _t, _t, _t, _t, _t, _t, f_}, // 0
  95. {f_, f_, _t, _t, _t, _t, _t, _t, _t, f_}, // 1
  96. {f_, f_, f_, f_, f_, _t, _t, _t, _t, f_}, // 2
  97. {f_, f_, f_, f_, f_, _t, _t, _t, _t, f_}, // 3
  98. {f_, f_, f_, f_, f_, _t, _t, _t, _t, f_}, // 4
  99. {f_, f_, f_, f_, f_, f_, _t, _t, _t, f_}, // 5
  100. {f_, f_, f_, f_, f_, f_, f_, _t, _t, f_}, // 6
  101. {f_, f_, f_, f_, f_, f_, f_, f_, _t, f_}, // 7
  102. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 8
  103. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 9
  104. };
  105. SECTION("comparison: less")
  106. {
  107. REQUIRE(expected_lt.size() == j_types.size());
  108. for (size_t i = 0; i < j_types.size(); ++i)
  109. {
  110. REQUIRE(expected_lt[i].size() == j_types.size());
  111. for (size_t j = 0; j < j_types.size(); ++j)
  112. {
  113. CAPTURE(i)
  114. CAPTURE(j)
  115. // check precomputed values
  116. #if JSON_HAS_THREE_WAY_COMPARISON
  117. // JSON_HAS_CPP_20 (do not remove; see note at top of file)
  118. CHECK((j_types[i] < j_types[j]) == expected_lt[i][j]);
  119. #else
  120. CHECK(operator<(j_types[i], j_types[j]) == expected_lt[i][j]);
  121. #endif
  122. CHECK(f(j_types[i], j_types[j]) == expected_lt[i][j]);
  123. }
  124. }
  125. }
  126. #if JSON_HAS_THREE_WAY_COMPARISON
  127. // JSON_HAS_CPP_20 (do not remove; see note at top of file)
  128. SECTION("comparison: 3-way")
  129. {
  130. std::vector<std::vector<std::partial_ordering>> expected =
  131. {
  132. //0 1 2 3 4 5 6 7 8 9
  133. {eq, lt, lt, lt, lt, lt, lt, lt, lt, un}, // 0
  134. {gt, eq, lt, lt, lt, lt, lt, lt, lt, un}, // 1
  135. {gt, gt, eq, eq, eq, lt, lt, lt, lt, un}, // 2
  136. {gt, gt, eq, eq, eq, lt, lt, lt, lt, un}, // 3
  137. {gt, gt, eq, eq, eq, lt, lt, lt, lt, un}, // 4
  138. {gt, gt, gt, gt, gt, eq, lt, lt, lt, un}, // 5
  139. {gt, gt, gt, gt, gt, gt, eq, lt, lt, un}, // 6
  140. {gt, gt, gt, gt, gt, gt, gt, eq, lt, un}, // 7
  141. {gt, gt, gt, gt, gt, gt, gt, gt, eq, un}, // 8
  142. {un, un, un, un, un, un, un, un, un, un}, // 9
  143. };
  144. // check expected partial_ordering against expected boolean
  145. REQUIRE(expected.size() == expected_lt.size());
  146. for (size_t i = 0; i < expected.size(); ++i)
  147. {
  148. REQUIRE(expected[i].size() == expected_lt[i].size());
  149. for (size_t j = 0; j < expected[i].size(); ++j)
  150. {
  151. CAPTURE(i)
  152. CAPTURE(j)
  153. CHECK(std::is_lt(expected[i][j]) == expected_lt[i][j]);
  154. }
  155. }
  156. // check 3-way comparison against expected partial_ordering
  157. REQUIRE(expected.size() == j_types.size());
  158. for (size_t i = 0; i < j_types.size(); ++i)
  159. {
  160. REQUIRE(expected[i].size() == j_types.size());
  161. for (size_t j = 0; j < j_types.size(); ++j)
  162. {
  163. CAPTURE(i)
  164. CAPTURE(j)
  165. CHECK((j_types[i] <=> j_types[j]) == expected[i][j]); // *NOPAD*
  166. }
  167. }
  168. }
  169. #endif
  170. }
  171. SECTION("values")
  172. {
  173. json j_values =
  174. {
  175. nullptr, nullptr, // 0 1
  176. -17, 42, // 2 3
  177. 8u, 13u, // 4 5
  178. 3.14159, 23.42, // 6 7
  179. nan, nan, // 8 9
  180. "foo", "bar", // 10 11
  181. true, false, // 12 13
  182. {1, 2, 3}, {"one", "two", "three"}, // 14 15
  183. {{"first", 1}, {"second", 2}}, {{"a", "A"}, {"b", {"B"}}}, // 16 17
  184. json::binary({1, 2, 3}), json::binary({1, 2, 4}), // 18 19
  185. json(json::value_t::discarded), json(json::value_t::discarded) // 20 21
  186. };
  187. std::vector<std::vector<bool>> expected_eq =
  188. {
  189. //0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
  190. {_t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 0
  191. {_t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 1
  192. {f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 2
  193. {f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 3
  194. {f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 4
  195. {f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 5
  196. {f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 6
  197. {f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 7
  198. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 8
  199. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 9
  200. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 10
  201. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 11
  202. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 12
  203. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, f_}, // 13
  204. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_}, // 14
  205. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_}, // 15
  206. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_}, // 16
  207. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_}, // 17
  208. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_}, // 18
  209. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_}, // 19
  210. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 20
  211. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 21
  212. };
  213. std::vector<std::vector<bool>> expected_lt =
  214. {
  215. //0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
  216. {f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_}, // 0
  217. {f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_}, // 1
  218. {f_, f_, f_, _t, _t, _t, _t, _t, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 2
  219. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 3
  220. {f_, f_, f_, _t, f_, _t, f_, _t, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 4
  221. {f_, f_, f_, _t, f_, f_, f_, _t, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 5
  222. {f_, f_, f_, _t, _t, _t, f_, _t, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 6
  223. {f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 7
  224. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 8
  225. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 9
  226. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_}, // 10
  227. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_}, // 11
  228. {f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 12
  229. {f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, f_, _t, _t, _t, _t, _t, _t, f_, f_}, // 13
  230. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, _t, f_, f_, _t, _t, f_, f_}, // 14
  231. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_}, // 15
  232. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, _t, _t, f_, f_, _t, _t, f_, f_}, // 16
  233. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, _t, _t, _t, f_, _t, _t, f_, f_}, // 17
  234. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, f_, f_}, // 18
  235. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 19
  236. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 20
  237. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 21
  238. };
  239. SECTION("compares unordered")
  240. {
  241. std::vector<std::vector<bool>> expected =
  242. {
  243. //0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
  244. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 0
  245. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 1
  246. {f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 2
  247. {f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 3
  248. {f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 4
  249. {f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 5
  250. {f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 6
  251. {f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 7
  252. {f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 8
  253. {f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 9
  254. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 10
  255. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 11
  256. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 12
  257. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 13
  258. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 14
  259. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 15
  260. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 16
  261. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 17
  262. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 18
  263. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, _t, _t}, // 19
  264. {_t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t}, // 20
  265. {_t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t, _t}, // 21
  266. };
  267. // check if two values compare unordered as expected
  268. REQUIRE(expected.size() == j_values.size());
  269. for (size_t i = 0; i < j_values.size(); ++i)
  270. {
  271. REQUIRE(expected[i].size() == j_values.size());
  272. for (size_t j = 0; j < j_values.size(); ++j)
  273. {
  274. CAPTURE(i)
  275. CAPTURE(j)
  276. CHECK(json::compares_unordered(j_values[i], j_values[j]) == expected[i][j]);
  277. }
  278. }
  279. }
  280. #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
  281. SECTION("compares unordered (inverse)")
  282. {
  283. std::vector<std::vector<bool>> expected =
  284. {
  285. //0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
  286. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 0
  287. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 1
  288. {f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 2
  289. {f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 3
  290. {f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 4
  291. {f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 5
  292. {f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 6
  293. {f_, f_, f_, f_, f_, f_, f_, f_, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 7
  294. {f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 8
  295. {f_, f_, _t, _t, _t, _t, _t, _t, _t, _t, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 9
  296. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 10
  297. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 11
  298. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 12
  299. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 13
  300. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 14
  301. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 15
  302. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 16
  303. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 17
  304. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 18
  305. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 19
  306. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 20
  307. {f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_, f_}, // 21
  308. };
  309. // check that two values compare unordered as expected (with legacy-mode enabled)
  310. REQUIRE(expected.size() == j_values.size());
  311. for (size_t i = 0; i < j_values.size(); ++i)
  312. {
  313. REQUIRE(expected[i].size() == j_values.size());
  314. for (size_t j = 0; j < j_values.size(); ++j)
  315. {
  316. CAPTURE(i)
  317. CAPTURE(j)
  318. CAPTURE(j_values[i])
  319. CAPTURE(j_values[j])
  320. CHECK(json::compares_unordered(j_values[i], j_values[j], true) == expected[i][j]);
  321. }
  322. }
  323. }
  324. #endif
  325. SECTION("comparison: equal")
  326. {
  327. // check that two values compare equal
  328. REQUIRE(expected_eq.size() == j_values.size());
  329. for (size_t i = 0; i < j_values.size(); ++i)
  330. {
  331. REQUIRE(expected_eq[i].size() == j_values.size());
  332. for (size_t j = 0; j < j_values.size(); ++j)
  333. {
  334. CAPTURE(i)
  335. CAPTURE(j)
  336. CHECK((j_values[i] == j_values[j]) == expected_eq[i][j]);
  337. }
  338. }
  339. // compare with null pointer
  340. json j_null;
  341. CHECK(j_null == nullptr);
  342. CHECK(nullptr == j_null);
  343. }
  344. SECTION("comparison: not equal")
  345. {
  346. // check that two values compare unequal as expected
  347. for (size_t i = 0; i < j_values.size(); ++i)
  348. {
  349. for (size_t j = 0; j < j_values.size(); ++j)
  350. {
  351. CAPTURE(i)
  352. CAPTURE(j)
  353. if (json::compares_unordered(j_values[i], j_values[j], true))
  354. {
  355. // if two values compare unordered,
  356. // check that the boolean comparison result is always false
  357. CHECK_FALSE(j_values[i] != j_values[j]);
  358. }
  359. else
  360. {
  361. // otherwise, check that they compare according to their definition
  362. // as the inverse of equal
  363. CHECK((j_values[i] != j_values[j]) == !(j_values[i] == j_values[j]));
  364. }
  365. }
  366. }
  367. // compare with null pointer
  368. const json j_null;
  369. CHECK((j_null != nullptr) == false);
  370. CHECK((nullptr != j_null) == false);
  371. CHECK((j_null != nullptr) == !(j_null == nullptr));
  372. CHECK((nullptr != j_null) == !(nullptr == j_null));
  373. }
  374. SECTION("comparison: less")
  375. {
  376. // check that two values compare less than as expected
  377. REQUIRE(expected_lt.size() == j_values.size());
  378. for (size_t i = 0; i < j_values.size(); ++i)
  379. {
  380. REQUIRE(expected_lt[i].size() == j_values.size());
  381. for (size_t j = 0; j < j_values.size(); ++j)
  382. {
  383. CAPTURE(i)
  384. CAPTURE(j)
  385. CHECK((j_values[i] < j_values[j]) == expected_lt[i][j]);
  386. }
  387. }
  388. }
  389. SECTION("comparison: less than or equal equal")
  390. {
  391. // check that two values compare less than or equal as expected
  392. for (size_t i = 0; i < j_values.size(); ++i)
  393. {
  394. for (size_t j = 0; j < j_values.size(); ++j)
  395. {
  396. CAPTURE(i)
  397. CAPTURE(j)
  398. if (json::compares_unordered(j_values[i], j_values[j], true))
  399. {
  400. // if two values compare unordered,
  401. // check that the boolean comparison result is always false
  402. CHECK_FALSE(j_values[i] <= j_values[j]);
  403. }
  404. else
  405. {
  406. // otherwise, check that they compare according to their definition
  407. // as the inverse of less than with the operand order reversed
  408. CHECK((j_values[i] <= j_values[j]) == !(j_values[j] < j_values[i]));
  409. }
  410. }
  411. }
  412. }
  413. SECTION("comparison: greater than")
  414. {
  415. // check that two values compare greater than as expected
  416. for (size_t i = 0; i < j_values.size(); ++i)
  417. {
  418. for (size_t j = 0; j < j_values.size(); ++j)
  419. {
  420. CAPTURE(i)
  421. CAPTURE(j)
  422. if (json::compares_unordered(j_values[i], j_values[j]))
  423. {
  424. // if two values compare unordered,
  425. // check that the boolean comparison result is always false
  426. CHECK_FALSE(j_values[i] > j_values[j]);
  427. }
  428. else
  429. {
  430. // otherwise, check that they compare according to their definition
  431. // as the inverse of less than or equal which is defined as
  432. // the inverse of less than with the operand order reversed
  433. CHECK((j_values[i] > j_values[j]) == !(j_values[i] <= j_values[j]));
  434. CHECK((j_values[i] > j_values[j]) == !!(j_values[j] < j_values[i]));
  435. }
  436. }
  437. }
  438. }
  439. SECTION("comparison: greater than or equal")
  440. {
  441. // check that two values compare greater than or equal as expected
  442. for (size_t i = 0; i < j_values.size(); ++i)
  443. {
  444. for (size_t j = 0; j < j_values.size(); ++j)
  445. {
  446. CAPTURE(i)
  447. CAPTURE(j)
  448. if (json::compares_unordered(j_values[i], j_values[j], true))
  449. {
  450. // if two values compare unordered,
  451. // check that the boolean result is always false
  452. CHECK_FALSE(j_values[i] >= j_values[j]);
  453. }
  454. else
  455. {
  456. // otherwise, check that they compare according to their definition
  457. // as the inverse of less than
  458. CHECK((j_values[i] >= j_values[j]) == !(j_values[i] < j_values[j]));
  459. }
  460. }
  461. }
  462. }
  463. #if JSON_HAS_THREE_WAY_COMPARISON
  464. // JSON_HAS_CPP_20 (do not remove; see note at top of file)
  465. SECTION("comparison: 3-way")
  466. {
  467. std::vector<std::vector<std::partial_ordering>> expected =
  468. {
  469. //0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
  470. {eq, eq, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, un, un}, // 0
  471. {eq, eq, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, un, un}, // 1
  472. {gt, gt, eq, lt, lt, lt, lt, lt, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 2
  473. {gt, gt, gt, eq, gt, gt, gt, gt, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 3
  474. {gt, gt, gt, lt, eq, lt, gt, lt, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 4
  475. {gt, gt, gt, lt, gt, eq, gt, lt, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 5
  476. {gt, gt, gt, lt, lt, lt, eq, lt, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 6
  477. {gt, gt, gt, lt, gt, gt, gt, eq, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 7
  478. {gt, gt, un, un, un, un, un, un, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 8
  479. {gt, gt, un, un, un, un, un, un, un, un, lt, lt, gt, gt, lt, lt, lt, lt, lt, lt, un, un}, // 9
  480. {gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, eq, gt, gt, gt, gt, gt, gt, gt, lt, lt, un, un}, // 10
  481. {gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, lt, eq, gt, gt, gt, gt, gt, gt, lt, lt, un, un}, // 11
  482. {gt, gt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, eq, gt, lt, lt, lt, lt, lt, lt, un, un}, // 12
  483. {gt, gt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, lt, eq, lt, lt, lt, lt, lt, lt, un, un}, // 13
  484. {gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, lt, lt, gt, gt, eq, lt, gt, gt, lt, lt, un, un}, // 14
  485. {gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, lt, lt, gt, gt, gt, eq, gt, gt, lt, lt, un, un}, // 15
  486. {gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, lt, lt, gt, gt, lt, lt, eq, gt, lt, lt, un, un}, // 16
  487. {gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, lt, lt, gt, gt, lt, lt, lt, eq, lt, lt, un, un}, // 17
  488. {gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, eq, lt, un, un}, // 18
  489. {gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, gt, eq, un, un}, // 19
  490. {un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un}, // 20
  491. {un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un, un}, // 21
  492. };
  493. // check expected partial_ordering against expected booleans
  494. REQUIRE(expected.size() == expected_eq.size());
  495. REQUIRE(expected.size() == expected_lt.size());
  496. for (size_t i = 0; i < expected.size(); ++i)
  497. {
  498. REQUIRE(expected[i].size() == expected_eq[i].size());
  499. REQUIRE(expected[i].size() == expected_lt[i].size());
  500. for (size_t j = 0; j < expected[i].size(); ++j)
  501. {
  502. CAPTURE(i)
  503. CAPTURE(j)
  504. CHECK(std::is_eq(expected[i][j]) == expected_eq[i][j]);
  505. CHECK(std::is_lt(expected[i][j]) == expected_lt[i][j]);
  506. if (std::is_gt(expected[i][j]))
  507. {
  508. CHECK((!expected_eq[i][j] && !expected_lt[i][j]));
  509. }
  510. }
  511. }
  512. // check that two values compare according to their expected ordering
  513. REQUIRE(expected.size() == j_values.size());
  514. for (size_t i = 0; i < j_values.size(); ++i)
  515. {
  516. REQUIRE(expected[i].size() == j_values.size());
  517. for (size_t j = 0; j < j_values.size(); ++j)
  518. {
  519. CAPTURE(i)
  520. CAPTURE(j)
  521. CHECK((j_values[i] <=> j_values[j]) == expected[i][j]); // *NOPAD*
  522. }
  523. }
  524. }
  525. #endif
  526. }
  527. #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
  528. SECTION("parser callback regression")
  529. {
  530. SECTION("filter specific element")
  531. {
  532. const auto* s_object = R"(
  533. {
  534. "foo": 2,
  535. "bar": {
  536. "baz": 1
  537. }
  538. }
  539. )";
  540. const auto* s_array = R"(
  541. [1,2,[3,4,5],4,5]
  542. )";
  543. json j_object = json::parse(s_object, [](int /*unused*/, json::parse_event_t /*unused*/, const json & j) noexcept
  544. {
  545. // filter all number(2) elements
  546. return j != json(2);
  547. });
  548. CHECK (j_object == json({{"bar", {{"baz", 1}}}}));
  549. json j_array = json::parse(s_array, [](int /*unused*/, json::parse_event_t /*unused*/, const json & j) noexcept
  550. {
  551. return j != json(2);
  552. });
  553. CHECK (j_array == json({1, {3, 4, 5}, 4, 5}));
  554. }
  555. }
  556. #endif
  557. }