unit-conversions.cpp 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572
  1. // __ _____ _____ _____
  2. // __| | __| | | | JSON for Modern C++ (supporting code)
  3. // | | |__ | | | | | | version 3.11.2
  4. // |_____|_____|_____|_|___| https://github.com/nlohmann/json
  5. //
  6. // Copyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.
  7. // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
  8. // SPDX-License-Identifier: MIT
  9. // cmake/test.cmake selects the C++ standard versions with which to build a
  10. // unit test based on the presence of JSON_HAS_CPP_<VERSION> macros.
  11. // When using macros that are only defined for particular versions of the standard
  12. // (e.g., JSON_HAS_FILESYSTEM for C++17 and up), please mention the corresponding
  13. // version macro in a comment close by, like this:
  14. // JSON_HAS_CPP_<VERSION> (do not remove; see note at top of file)
  15. #include "doctest_compatibility.h"
  16. #define JSON_TESTS_PRIVATE
  17. #include <nlohmann/json.hpp>
  18. using nlohmann::json;
  19. #include <deque>
  20. #include <forward_list>
  21. #include <list>
  22. #include <set>
  23. #include <unordered_map>
  24. #include <unordered_set>
  25. #include <valarray>
  26. // NLOHMANN_JSON_SERIALIZE_ENUM uses a static std::pair
  27. DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
  28. DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors")
  29. TEST_CASE("value conversion")
  30. {
  31. SECTION("get an object (explicit)")
  32. {
  33. const json::object_t o_reference = {{"object", json::object()},
  34. {"array", {1, 2, 3, 4}},
  35. {"number", 42},
  36. {"boolean", false},
  37. {"null", nullptr},
  38. {"string", "Hello world"}
  39. };
  40. json j(o_reference);
  41. SECTION("json::object_t")
  42. {
  43. json::object_t const o = j.get<json::object_t>();
  44. CHECK(json(o) == j);
  45. }
  46. SECTION("std::map<json::string_t, json>")
  47. {
  48. const std::map<json::string_t, json> o =
  49. j.get<std::map<json::string_t, json>>();
  50. CHECK(json(o) == j);
  51. }
  52. SECTION("std::multimap<json::string_t, json>")
  53. {
  54. const std::multimap<json::string_t, json> o =
  55. j.get<std::multimap<json::string_t, json>>();
  56. CHECK(json(o) == j);
  57. }
  58. SECTION("std::unordered_map<json::string_t, json>")
  59. {
  60. const std::unordered_map<json::string_t, json> o =
  61. j.get<std::unordered_map<json::string_t, json>>();
  62. CHECK(json(o) == j);
  63. }
  64. SECTION("std::unordered_multimap<json::string_t, json>")
  65. {
  66. const std::unordered_multimap<json::string_t, json> o =
  67. j.get<std::unordered_multimap<json::string_t, json>>();
  68. CHECK(json(o) == j);
  69. }
  70. SECTION("exception in case of a non-object type")
  71. {
  72. CHECK_THROWS_WITH_AS(
  73. json(json::value_t::null).get<json::object_t>(),
  74. "[json.exception.type_error.302] type must be object, but is null", json::type_error&);
  75. CHECK_THROWS_WITH_AS(
  76. json(json::value_t::array).get<json::object_t>(),
  77. "[json.exception.type_error.302] type must be object, but is array", json::type_error&);
  78. CHECK_THROWS_WITH_AS(
  79. json(json::value_t::string).get<json::object_t>(),
  80. "[json.exception.type_error.302] type must be object, but is string", json::type_error&);
  81. CHECK_THROWS_WITH_AS(json(json::value_t::boolean).get<json::object_t>(),
  82. "[json.exception.type_error.302] type must be object, "
  83. "but is boolean", json::type_error&);
  84. CHECK_THROWS_WITH_AS(
  85. json(json::value_t::number_integer).get<json::object_t>(),
  86. "[json.exception.type_error.302] type must be object, but is number", json::type_error&);
  87. CHECK_THROWS_WITH_AS(
  88. json(json::value_t::number_unsigned).get<json::object_t>(),
  89. "[json.exception.type_error.302] type must be object, but is number", json::type_error&);
  90. CHECK_THROWS_WITH_AS(
  91. json(json::value_t::number_float).get<json::object_t>(),
  92. "[json.exception.type_error.302] type must be object, but is number", json::type_error&);
  93. }
  94. }
  95. SECTION("get an object (explicit, get_to)")
  96. {
  97. const json::object_t o_reference = {{"object", json::object()},
  98. {"array", {1, 2, 3, 4}},
  99. {"number", 42},
  100. {"boolean", false},
  101. {"null", nullptr},
  102. {"string", "Hello world"}
  103. };
  104. json j(o_reference);
  105. SECTION("json::object_t")
  106. {
  107. json::object_t o = {{"previous", "value"}};
  108. j.get_to(o);
  109. CHECK(json(o) == j);
  110. }
  111. SECTION("std::map<json::string_t, json>")
  112. {
  113. std::map<json::string_t, json> o{{"previous", "value"}};
  114. j.get_to(o);
  115. CHECK(json(o) == j);
  116. }
  117. SECTION("std::multimap<json::string_t, json>")
  118. {
  119. std::multimap<json::string_t, json> o{{"previous", "value"}};
  120. j.get_to(o);
  121. CHECK(json(o) == j);
  122. }
  123. SECTION("std::unordered_map<json::string_t, json>")
  124. {
  125. std::unordered_map<json::string_t, json> o{{"previous", "value"}};
  126. j.get_to(o);
  127. CHECK(json(o) == j);
  128. }
  129. SECTION("std::unordered_multimap<json::string_t, json>")
  130. {
  131. std::unordered_multimap<json::string_t, json> o{{"previous", "value"}};
  132. j.get_to(o);
  133. CHECK(json(o) == j);
  134. }
  135. }
  136. #if JSON_USE_IMPLICIT_CONVERSIONS
  137. SECTION("get an object (implicit)")
  138. {
  139. const json::object_t o_reference = {{"object", json::object()},
  140. {"array", {1, 2, 3, 4}},
  141. {"number", 42},
  142. {"boolean", false},
  143. {"null", nullptr},
  144. {"string", "Hello world"}
  145. };
  146. json j(o_reference);
  147. SECTION("json::object_t")
  148. {
  149. const json::object_t o = j;
  150. CHECK(json(o) == j);
  151. }
  152. SECTION("std::map<json::string_t, json>")
  153. {
  154. const std::map<json::string_t, json> o = j;
  155. CHECK(json(o) == j);
  156. }
  157. SECTION("std::multimap<json::string_t, json>")
  158. {
  159. const std::multimap<json::string_t, json> o = j;
  160. CHECK(json(o) == j);
  161. }
  162. SECTION("std::unordered_map<json::string_t, json>")
  163. {
  164. const std::unordered_map<json::string_t, json> o = j;
  165. CHECK(json(o) == j);
  166. }
  167. SECTION("std::unordered_multimap<json::string_t, json>")
  168. {
  169. const std::unordered_multimap<json::string_t, json> o = j;
  170. CHECK(json(o) == j);
  171. }
  172. }
  173. #endif
  174. SECTION("get an array (explicit)")
  175. {
  176. const json::array_t a_reference{json(1), json(1u), json(2.2),
  177. json(false), json("string"), json()};
  178. json j(a_reference);
  179. SECTION("json::array_t")
  180. {
  181. const json::array_t a = j.get<json::array_t>();
  182. CHECK(json(a) == j);
  183. }
  184. SECTION("std::list<json>")
  185. {
  186. const std::list<json> a = j.get<std::list<json>>();
  187. CHECK(json(a) == j);
  188. }
  189. SECTION("std::forward_list<json>")
  190. {
  191. const std::forward_list<json> a = j.get<std::forward_list<json>>();
  192. CHECK(json(a) == j);
  193. CHECK_THROWS_WITH_AS(
  194. json(json::value_t::null).get<std::forward_list<json>>(),
  195. "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
  196. }
  197. SECTION("std::vector<json>")
  198. {
  199. const std::vector<json> a = j.get<std::vector<json>>();
  200. CHECK(json(a) == j);
  201. CHECK_THROWS_WITH_AS(
  202. json(json::value_t::null).get<std::vector<json>>(),
  203. "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
  204. #if !defined(JSON_NOEXCEPTION)
  205. SECTION("reserve is called on containers that supports it")
  206. {
  207. // make sure all values are properly copied
  208. const json j2({1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
  209. auto v2 = j2.get<std::vector<int>>();
  210. CHECK(v2.size() == 10);
  211. }
  212. #endif
  213. }
  214. SECTION("built-in arrays")
  215. {
  216. const char str[] = "a string"; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
  217. const int nbs[] = {0, 1, 2}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
  218. const json j2 = nbs;
  219. const json j3 = str;
  220. auto v = j2.get<std::vector<int>>();
  221. auto s = j3.get<std::string>();
  222. CHECK(std::equal(v.begin(), v.end(), std::begin(nbs)));
  223. CHECK(s == str);
  224. }
  225. SECTION("std::deque<json>")
  226. {
  227. const std::deque<json> a = j.get<std::deque<json>>();
  228. CHECK(json(a) == j);
  229. }
  230. SECTION("exception in case of a non-array type")
  231. {
  232. CHECK_THROWS_WITH_AS(
  233. json(json::value_t::object).get<std::vector<int>>(),
  234. "[json.exception.type_error.302] type must be array, but is object", json::type_error&);
  235. CHECK_THROWS_WITH_AS(
  236. json(json::value_t::null).get<json::array_t>(),
  237. "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
  238. CHECK_THROWS_WITH_AS(
  239. json(json::value_t::object).get<json::array_t>(),
  240. "[json.exception.type_error.302] type must be array, but is object", json::type_error&);
  241. CHECK_THROWS_WITH_AS(
  242. json(json::value_t::string).get<json::array_t>(),
  243. "[json.exception.type_error.302] type must be array, but is string", json::type_error&);
  244. CHECK_THROWS_WITH_AS(
  245. json(json::value_t::boolean).get<json::array_t>(),
  246. "[json.exception.type_error.302] type must be array, but is boolean", json::type_error&);
  247. CHECK_THROWS_WITH_AS(
  248. json(json::value_t::number_integer).get<json::array_t>(),
  249. "[json.exception.type_error.302] type must be array, but is number", json::type_error&);
  250. CHECK_THROWS_WITH_AS(
  251. json(json::value_t::number_unsigned).get<json::array_t>(),
  252. "[json.exception.type_error.302] type must be array, but is number", json::type_error&);
  253. CHECK_THROWS_WITH_AS(
  254. json(json::value_t::number_float).get<json::array_t>(),
  255. "[json.exception.type_error.302] type must be array, but is number", json::type_error&);
  256. }
  257. }
  258. SECTION("get an array (explicit, get_to)")
  259. {
  260. const json::array_t a_reference{json(1), json(1u), json(2.2),
  261. json(false), json("string"), json()};
  262. json j(a_reference);
  263. SECTION("json::array_t")
  264. {
  265. json::array_t a{"previous", "value"};
  266. j.get_to(a);
  267. CHECK(json(a) == j);
  268. }
  269. SECTION("std::valarray<json>")
  270. {
  271. std::valarray<json> a{"previous", "value"};
  272. j.get_to(a);
  273. CHECK(json(a) == j);
  274. }
  275. SECTION("std::list<json>")
  276. {
  277. std::list<json> a{"previous", "value"};
  278. j.get_to(a);
  279. CHECK(json(a) == j);
  280. }
  281. SECTION("std::forward_list<json>")
  282. {
  283. std::forward_list<json> a{"previous", "value"};
  284. j.get_to(a);
  285. CHECK(json(a) == j);
  286. }
  287. SECTION("std::vector<json>")
  288. {
  289. std::vector<json> a{"previous", "value"};
  290. j.get_to(a);
  291. CHECK(json(a) == j);
  292. }
  293. SECTION("built-in arrays")
  294. {
  295. const int nbs[] = {0, 1, 2}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
  296. int nbs2[] = {0, 0, 0}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
  297. const json j2 = nbs;
  298. j2.get_to(nbs2);
  299. CHECK(std::equal(std::begin(nbs), std::end(nbs), std::begin(nbs2)));
  300. }
  301. SECTION("std::deque<json>")
  302. {
  303. std::deque<json> a{"previous", "value"};
  304. j.get_to(a);
  305. CHECK(json(a) == j);
  306. }
  307. }
  308. #if JSON_USE_IMPLICIT_CONVERSIONS
  309. SECTION("get an array (implicit)")
  310. {
  311. const json::array_t a_reference{json(1), json(1u), json(2.2),
  312. json(false), json("string"), json()};
  313. json j(a_reference);
  314. SECTION("json::array_t")
  315. {
  316. const json::array_t a = j;
  317. CHECK(json(a) == j);
  318. }
  319. SECTION("std::list<json>")
  320. {
  321. const std::list<json> a = j;
  322. CHECK(json(a) == j);
  323. }
  324. SECTION("std::forward_list<json>")
  325. {
  326. const std::forward_list<json> a = j;
  327. CHECK(json(a) == j);
  328. }
  329. SECTION("std::vector<json>")
  330. {
  331. const std::vector<json> a = j;
  332. CHECK(json(a) == j);
  333. }
  334. SECTION("std::deque<json>")
  335. {
  336. const std::deque<json> a = j;
  337. CHECK(json(a) == j);
  338. }
  339. }
  340. #endif
  341. SECTION("get a string (explicit)")
  342. {
  343. const json::string_t s_reference{"Hello world"};
  344. json j(s_reference);
  345. SECTION("string_t")
  346. {
  347. const json::string_t s = j.get<json::string_t>();
  348. CHECK(json(s) == j);
  349. }
  350. SECTION("std::string")
  351. {
  352. const std::string s = j.get<std::string>();
  353. CHECK(json(s) == j);
  354. }
  355. #if defined(JSON_HAS_CPP_17)
  356. SECTION("std::string_view")
  357. {
  358. std::string_view const s = j.get<std::string_view>();
  359. CHECK(json(s) == j);
  360. }
  361. #endif
  362. SECTION("exception in case of a non-string type")
  363. {
  364. CHECK_THROWS_WITH_AS(
  365. json(json::value_t::null).get<json::string_t>(),
  366. "[json.exception.type_error.302] type must be string, but is null", json::type_error&);
  367. CHECK_THROWS_WITH_AS(
  368. json(json::value_t::object).get<json::string_t>(),
  369. "[json.exception.type_error.302] type must be string, but is object", json::type_error&);
  370. CHECK_THROWS_WITH_AS(
  371. json(json::value_t::array).get<json::string_t>(),
  372. "[json.exception.type_error.302] type must be string, but is array", json::type_error&);
  373. CHECK_THROWS_WITH_AS(json(json::value_t::boolean).get<json::string_t>(),
  374. "[json.exception.type_error.302] type must be string, "
  375. "but is boolean", json::type_error&);
  376. CHECK_THROWS_WITH_AS(
  377. json(json::value_t::number_integer).get<json::string_t>(),
  378. "[json.exception.type_error.302] type must be string, but is number", json::type_error&);
  379. CHECK_THROWS_WITH_AS(
  380. json(json::value_t::number_unsigned).get<json::string_t>(),
  381. "[json.exception.type_error.302] type must be string, but is number", json::type_error&);
  382. CHECK_THROWS_WITH_AS(
  383. json(json::value_t::number_float).get<json::string_t>(),
  384. "[json.exception.type_error.302] type must be string, but is number", json::type_error&);
  385. }
  386. #if defined(JSON_HAS_CPP_17)
  387. SECTION("exception in case of a non-string type using string_view")
  388. {
  389. CHECK_THROWS_WITH_AS(json(json::value_t::null).get<std::string_view>(),
  390. "[json.exception.type_error.302] type must be string, but is null", json::type_error&);
  391. CHECK_THROWS_WITH_AS(json(json::value_t::object).get<std::string_view>(),
  392. "[json.exception.type_error.302] type must be string, but is object", json::type_error&);
  393. CHECK_THROWS_WITH_AS(json(json::value_t::array).get<std::string_view>(),
  394. "[json.exception.type_error.302] type must be string, but is array", json::type_error&);
  395. CHECK_THROWS_WITH_AS(json(json::value_t::boolean).get<std::string_view>(),
  396. "[json.exception.type_error.302] type must be string, but is boolean", json::type_error&);
  397. CHECK_THROWS_WITH_AS(json(json::value_t::number_integer).get<std::string_view>(),
  398. "[json.exception.type_error.302] type must be string, but is number", json::type_error&);
  399. CHECK_THROWS_WITH_AS(json(json::value_t::number_unsigned).get<std::string_view>(),
  400. "[json.exception.type_error.302] type must be string, but is number", json::type_error&);
  401. CHECK_THROWS_WITH_AS(json(json::value_t::number_float).get<std::string_view>(),
  402. "[json.exception.type_error.302] type must be string, but is number", json::type_error&);
  403. }
  404. #endif
  405. }
  406. SECTION("get a string (explicit, get_to)")
  407. {
  408. const json::string_t s_reference{"Hello world"};
  409. json j(s_reference);
  410. SECTION("string_t")
  411. {
  412. json::string_t s = "previous value";
  413. j.get_to(s);
  414. CHECK(json(s) == j);
  415. }
  416. SECTION("std::string")
  417. {
  418. std::string s = "previous value";
  419. j.get_to(s);
  420. CHECK(json(s) == j);
  421. }
  422. #if defined(JSON_HAS_CPP_17)
  423. SECTION("std::string_view")
  424. {
  425. std::string const s = "previous value";
  426. std::string_view sv = s;
  427. j.get_to(sv);
  428. CHECK(json(sv) == j);
  429. }
  430. #endif
  431. }
  432. SECTION("get null (explicit)")
  433. {
  434. std::nullptr_t n = nullptr;
  435. const json j(n);
  436. auto n2 = j.get<std::nullptr_t>();
  437. CHECK(n2 == n);
  438. CHECK_THROWS_WITH_AS(json(json::value_t::string).get<std::nullptr_t>(),
  439. "[json.exception.type_error.302] type must be null, but is string", json::type_error&);
  440. CHECK_THROWS_WITH_AS(json(json::value_t::object).get<std::nullptr_t>(),
  441. "[json.exception.type_error.302] type must be null, but is object", json::type_error&);
  442. CHECK_THROWS_WITH_AS(json(json::value_t::array).get<std::nullptr_t>(),
  443. "[json.exception.type_error.302] type must be null, but is array", json::type_error&);
  444. CHECK_THROWS_WITH_AS(json(json::value_t::boolean).get<std::nullptr_t>(),
  445. "[json.exception.type_error.302] type must be null, but is boolean", json::type_error&);
  446. CHECK_THROWS_WITH_AS(json(json::value_t::number_integer).get<std::nullptr_t>(),
  447. "[json.exception.type_error.302] type must be null, but is number", json::type_error&);
  448. CHECK_THROWS_WITH_AS(json(json::value_t::number_unsigned).get<std::nullptr_t>(),
  449. "[json.exception.type_error.302] type must be null, but is number", json::type_error&);
  450. CHECK_THROWS_WITH_AS(json(json::value_t::number_float).get<std::nullptr_t>(),
  451. "[json.exception.type_error.302] type must be null, but is number", json::type_error&);
  452. }
  453. #if JSON_USE_IMPLICIT_CONVERSIONS
  454. SECTION("get a string (implicit)")
  455. {
  456. const json::string_t s_reference{"Hello world"};
  457. json j(s_reference);
  458. SECTION("string_t")
  459. {
  460. const json::string_t s = j;
  461. CHECK(json(s) == j);
  462. }
  463. #if defined(JSON_HAS_CPP_17)
  464. SECTION("std::string_view")
  465. {
  466. std::string_view const s = j.get<std::string_view>();
  467. CHECK(json(s) == j);
  468. }
  469. #endif
  470. SECTION("std::string")
  471. {
  472. const std::string s = j;
  473. CHECK(json(s) == j);
  474. }
  475. }
  476. #endif
  477. SECTION("get a boolean (explicit)")
  478. {
  479. const json::boolean_t b_reference{true};
  480. json j(b_reference);
  481. SECTION("boolean_t")
  482. {
  483. auto b = j.get<json::boolean_t>();
  484. CHECK(json(b) == j);
  485. }
  486. SECTION("uint8_t")
  487. {
  488. auto n = j.get<uint8_t>();
  489. CHECK(n == 1);
  490. }
  491. SECTION("bool")
  492. {
  493. const bool b = j.get<bool>();
  494. CHECK(json(b) == j);
  495. }
  496. SECTION("exception in case of a non-number type")
  497. {
  498. CHECK_THROWS_AS(json(json::value_t::string).get<uint8_t>(),
  499. json::type_error&);
  500. CHECK_THROWS_WITH_AS(
  501. json(json::value_t::null).get<json::boolean_t>(),
  502. "[json.exception.type_error.302] type must be boolean, but is null", json::type_error&);
  503. CHECK_THROWS_WITH_AS(json(json::value_t::object).get<json::boolean_t>(),
  504. "[json.exception.type_error.302] type must be boolean, "
  505. "but is object", json::type_error&);
  506. CHECK_THROWS_WITH_AS(
  507. json(json::value_t::array).get<json::boolean_t>(),
  508. "[json.exception.type_error.302] type must be boolean, but is array", json::type_error&);
  509. CHECK_THROWS_WITH_AS(json(json::value_t::string).get<json::boolean_t>(),
  510. "[json.exception.type_error.302] type must be boolean, "
  511. "but is string", json::type_error&);
  512. CHECK_THROWS_WITH_AS(
  513. json(json::value_t::number_integer).get<json::boolean_t>(),
  514. "[json.exception.type_error.302] type must be boolean, but is "
  515. "number", json::type_error&);
  516. CHECK_THROWS_WITH_AS(
  517. json(json::value_t::number_unsigned).get<json::boolean_t>(),
  518. "[json.exception.type_error.302] type must be boolean, but is "
  519. "number", json::type_error&);
  520. CHECK_THROWS_WITH_AS(
  521. json(json::value_t::number_float).get<json::boolean_t>(),
  522. "[json.exception.type_error.302] type must be boolean, but is "
  523. "number", json::type_error&);
  524. }
  525. }
  526. #if JSON_USE_IMPLICIT_CONVERSIONS
  527. SECTION("get a boolean (implicit)")
  528. {
  529. const json::boolean_t b_reference{true};
  530. json j(b_reference);
  531. SECTION("boolean_t")
  532. {
  533. const json::boolean_t b = j;
  534. CHECK(json(b) == j);
  535. }
  536. SECTION("bool")
  537. {
  538. const bool b = j;
  539. CHECK(json(b) == j);
  540. }
  541. }
  542. #endif
  543. SECTION("get an integer number (explicit)")
  544. {
  545. const json::number_integer_t n_reference{42};
  546. json j(n_reference);
  547. const json::number_unsigned_t n_unsigned_reference{42u};
  548. json j_unsigned(n_unsigned_reference);
  549. SECTION("number_integer_t")
  550. {
  551. auto n = j.get<json::number_integer_t>();
  552. CHECK(json(n) == j);
  553. }
  554. SECTION("number_unsigned_t")
  555. {
  556. auto n = j_unsigned.get<json::number_unsigned_t>();
  557. CHECK(json(n) == j_unsigned);
  558. }
  559. SECTION("short")
  560. {
  561. auto n = j.get<short>();
  562. CHECK(json(n) == j);
  563. }
  564. SECTION("unsigned short")
  565. {
  566. auto n = j.get<unsigned short>();
  567. CHECK(json(n) == j);
  568. }
  569. SECTION("int")
  570. {
  571. const int n = j.get<int>();
  572. CHECK(json(n) == j);
  573. }
  574. SECTION("unsigned int")
  575. {
  576. auto n = j.get<unsigned int>();
  577. CHECK(json(n) == j);
  578. }
  579. SECTION("long")
  580. {
  581. const long n = j.get<long>();
  582. CHECK(json(n) == j);
  583. }
  584. SECTION("unsigned long")
  585. {
  586. auto n = j.get<unsigned long>();
  587. CHECK(json(n) == j);
  588. }
  589. SECTION("long long")
  590. {
  591. auto n = j.get<long long>();
  592. CHECK(json(n) == j);
  593. }
  594. SECTION("unsigned long long")
  595. {
  596. auto n = j.get<unsigned long long>();
  597. CHECK(json(n) == j);
  598. }
  599. SECTION("int8_t")
  600. {
  601. auto n = j.get<int8_t>();
  602. CHECK(json(n) == j);
  603. }
  604. SECTION("int16_t")
  605. {
  606. auto n = j.get<int16_t>();
  607. CHECK(json(n) == j);
  608. }
  609. SECTION("int32_t")
  610. {
  611. auto n = j.get<int32_t>();
  612. CHECK(json(n) == j);
  613. }
  614. SECTION("int64_t")
  615. {
  616. auto n = j.get<int64_t>();
  617. CHECK(json(n) == j);
  618. }
  619. SECTION("int8_fast_t")
  620. {
  621. auto n = j.get<int_fast8_t>();
  622. CHECK(json(n) == j);
  623. }
  624. SECTION("int16_fast_t")
  625. {
  626. auto n = j.get<int_fast16_t>();
  627. CHECK(json(n) == j);
  628. }
  629. SECTION("int32_fast_t")
  630. {
  631. auto n = j.get<int_fast32_t>();
  632. CHECK(json(n) == j);
  633. }
  634. SECTION("int64_fast_t")
  635. {
  636. auto n = j.get<int_fast64_t>();
  637. CHECK(json(n) == j);
  638. }
  639. SECTION("int8_least_t")
  640. {
  641. auto n = j.get<int_least8_t>();
  642. CHECK(json(n) == j);
  643. }
  644. SECTION("int16_least_t")
  645. {
  646. auto n = j.get<int_least16_t>();
  647. CHECK(json(n) == j);
  648. }
  649. SECTION("int32_least_t")
  650. {
  651. auto n = j.get<int_least32_t>();
  652. CHECK(json(n) == j);
  653. }
  654. SECTION("int64_least_t")
  655. {
  656. auto n = j.get<int_least64_t>();
  657. CHECK(json(n) == j);
  658. }
  659. SECTION("uint8_t")
  660. {
  661. auto n = j.get<uint8_t>();
  662. CHECK(json(n) == j);
  663. }
  664. SECTION("uint16_t")
  665. {
  666. auto n = j.get<uint16_t>();
  667. CHECK(json(n) == j);
  668. }
  669. SECTION("uint32_t")
  670. {
  671. auto n = j.get<uint32_t>();
  672. CHECK(json(n) == j);
  673. }
  674. SECTION("uint64_t")
  675. {
  676. auto n = j.get<uint64_t>();
  677. CHECK(json(n) == j);
  678. }
  679. SECTION("uint8_fast_t")
  680. {
  681. auto n = j.get<uint_fast8_t>();
  682. CHECK(json(n) == j);
  683. }
  684. SECTION("uint16_fast_t")
  685. {
  686. auto n = j.get<uint_fast16_t>();
  687. CHECK(json(n) == j);
  688. }
  689. SECTION("uint32_fast_t")
  690. {
  691. auto n = j.get<uint_fast32_t>();
  692. CHECK(json(n) == j);
  693. }
  694. SECTION("uint64_fast_t")
  695. {
  696. auto n = j.get<uint_fast64_t>();
  697. CHECK(json(n) == j);
  698. }
  699. SECTION("uint8_least_t")
  700. {
  701. auto n = j.get<uint_least8_t>();
  702. CHECK(json(n) == j);
  703. }
  704. SECTION("uint16_least_t")
  705. {
  706. auto n = j.get<uint_least16_t>();
  707. CHECK(json(n) == j);
  708. }
  709. SECTION("uint32_least_t")
  710. {
  711. auto n = j.get<uint_least32_t>();
  712. CHECK(json(n) == j);
  713. }
  714. SECTION("uint64_least_t")
  715. {
  716. auto n = j.get<uint_least64_t>();
  717. CHECK(json(n) == j);
  718. }
  719. SECTION("exception in case of a non-number type")
  720. {
  721. CHECK_THROWS_WITH_AS(
  722. json(json::value_t::null).get<json::number_integer_t>(),
  723. "[json.exception.type_error.302] type must be number, but is null", json::type_error&);
  724. CHECK_THROWS_WITH_AS(
  725. json(json::value_t::object).get<json::number_integer_t>(),
  726. "[json.exception.type_error.302] type must be number, but is object", json::type_error&);
  727. CHECK_THROWS_WITH_AS(
  728. json(json::value_t::array).get<json::number_integer_t>(),
  729. "[json.exception.type_error.302] type must be number, but is array", json::type_error&);
  730. CHECK_THROWS_WITH_AS(
  731. json(json::value_t::string).get<json::number_integer_t>(),
  732. "[json.exception.type_error.302] type must be number, but is string", json::type_error&);
  733. CHECK_THROWS_WITH_AS(
  734. json(json::value_t::boolean).get<json::number_integer_t>(),
  735. "[json.exception.type_error.302] type must be number, but is "
  736. "boolean", json::type_error&);
  737. CHECK_NOTHROW(
  738. json(json::value_t::number_float).get<json::number_integer_t>());
  739. CHECK_NOTHROW(
  740. json(json::value_t::number_float).get<json::number_unsigned_t>());
  741. }
  742. }
  743. #if JSON_USE_IMPLICIT_CONVERSIONS
  744. SECTION("get an integer number (implicit)")
  745. {
  746. json::number_integer_t const n_reference{42};
  747. json j(n_reference);
  748. json::number_unsigned_t const n_unsigned_reference{42u};
  749. json j_unsigned(n_unsigned_reference);
  750. SECTION("number_integer_t")
  751. {
  752. auto n = j.get<json::number_integer_t>();
  753. CHECK(json(n) == j);
  754. }
  755. SECTION("number_unsigned_t")
  756. {
  757. auto n = j_unsigned.get<json::number_unsigned_t>();
  758. CHECK(json(n) == j_unsigned);
  759. }
  760. SECTION("short")
  761. {
  762. short const n = j;
  763. CHECK(json(n) == j);
  764. }
  765. SECTION("unsigned short")
  766. {
  767. unsigned short const n = j_unsigned;
  768. CHECK(json(n) == j_unsigned);
  769. }
  770. SECTION("int")
  771. {
  772. int const n = j;
  773. CHECK(json(n) == j);
  774. }
  775. SECTION("unsigned int")
  776. {
  777. unsigned int const n = j_unsigned;
  778. CHECK(json(n) == j_unsigned);
  779. }
  780. SECTION("long")
  781. {
  782. long const n = j;
  783. CHECK(json(n) == j);
  784. }
  785. SECTION("unsigned long")
  786. {
  787. unsigned long const n = j_unsigned;
  788. CHECK(json(n) == j_unsigned);
  789. }
  790. SECTION("long long")
  791. {
  792. long long const n = j;
  793. CHECK(json(n) == j);
  794. }
  795. SECTION("unsigned long long")
  796. {
  797. unsigned long long const n = j_unsigned;
  798. CHECK(json(n) == j_unsigned);
  799. }
  800. SECTION("int8_t")
  801. {
  802. int8_t const n = j;
  803. CHECK(json(n) == j);
  804. }
  805. SECTION("int16_t")
  806. {
  807. int16_t const n = j;
  808. CHECK(json(n) == j);
  809. }
  810. SECTION("int32_t")
  811. {
  812. int32_t const n = j;
  813. CHECK(json(n) == j);
  814. }
  815. SECTION("int64_t")
  816. {
  817. int64_t const n = j;
  818. CHECK(json(n) == j);
  819. }
  820. SECTION("int8_fast_t")
  821. {
  822. int_fast8_t const n = j;
  823. CHECK(json(n) == j);
  824. }
  825. SECTION("int16_fast_t")
  826. {
  827. int_fast16_t const n = j;
  828. CHECK(json(n) == j);
  829. }
  830. SECTION("int32_fast_t")
  831. {
  832. int_fast32_t const n = j;
  833. CHECK(json(n) == j);
  834. }
  835. SECTION("int64_fast_t")
  836. {
  837. int_fast64_t const n = j;
  838. CHECK(json(n) == j);
  839. }
  840. SECTION("int8_least_t")
  841. {
  842. int_least8_t const n = j;
  843. CHECK(json(n) == j);
  844. }
  845. SECTION("int16_least_t")
  846. {
  847. int_least16_t const n = j;
  848. CHECK(json(n) == j);
  849. }
  850. SECTION("int32_least_t")
  851. {
  852. int_least32_t const n = j;
  853. CHECK(json(n) == j);
  854. }
  855. SECTION("int64_least_t")
  856. {
  857. int_least64_t const n = j;
  858. CHECK(json(n) == j);
  859. }
  860. SECTION("uint8_t")
  861. {
  862. uint8_t const n = j_unsigned;
  863. CHECK(json(n) == j_unsigned);
  864. }
  865. SECTION("uint16_t")
  866. {
  867. uint16_t const n = j_unsigned;
  868. CHECK(json(n) == j_unsigned);
  869. }
  870. SECTION("uint32_t")
  871. {
  872. uint32_t const n = j_unsigned;
  873. CHECK(json(n) == j_unsigned);
  874. }
  875. SECTION("uint64_t")
  876. {
  877. uint64_t const n = j_unsigned;
  878. CHECK(json(n) == j_unsigned);
  879. }
  880. SECTION("uint8_fast_t")
  881. {
  882. uint_fast8_t const n = j_unsigned;
  883. CHECK(json(n) == j_unsigned);
  884. }
  885. SECTION("uint16_fast_t")
  886. {
  887. uint_fast16_t const n = j_unsigned;
  888. CHECK(json(n) == j_unsigned);
  889. }
  890. SECTION("uint32_fast_t")
  891. {
  892. uint_fast32_t const n = j_unsigned;
  893. CHECK(json(n) == j_unsigned);
  894. }
  895. SECTION("uint64_fast_t")
  896. {
  897. uint_fast64_t const n = j_unsigned;
  898. CHECK(json(n) == j_unsigned);
  899. }
  900. SECTION("uint8_least_t")
  901. {
  902. uint_least8_t const n = j_unsigned;
  903. CHECK(json(n) == j_unsigned);
  904. }
  905. SECTION("uint16_least_t")
  906. {
  907. uint_least16_t const n = j_unsigned;
  908. CHECK(json(n) == j_unsigned);
  909. }
  910. SECTION("uint32_least_t")
  911. {
  912. uint_least32_t const n = j_unsigned;
  913. CHECK(json(n) == j_unsigned);
  914. }
  915. SECTION("uint64_least_t")
  916. {
  917. uint_least64_t const n = j_unsigned;
  918. CHECK(json(n) == j_unsigned);
  919. }
  920. }
  921. #endif
  922. SECTION("get a floating-point number (explicit)")
  923. {
  924. json::number_float_t const n_reference{42.23};
  925. json const j(n_reference);
  926. SECTION("number_float_t")
  927. {
  928. auto n = j.get<json::number_float_t>();
  929. CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
  930. }
  931. SECTION("float")
  932. {
  933. auto n = j.get<float>();
  934. CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
  935. }
  936. SECTION("double")
  937. {
  938. auto n = j.get<double>();
  939. CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
  940. }
  941. SECTION("exception in case of a non-string type")
  942. {
  943. CHECK_THROWS_WITH_AS(
  944. json(json::value_t::null).get<json::number_float_t>(),
  945. "[json.exception.type_error.302] type must be number, but is null", json::type_error&);
  946. CHECK_THROWS_WITH_AS(
  947. json(json::value_t::object).get<json::number_float_t>(),
  948. "[json.exception.type_error.302] type must be number, but is object", json::type_error&);
  949. CHECK_THROWS_WITH_AS(
  950. json(json::value_t::array).get<json::number_float_t>(),
  951. "[json.exception.type_error.302] type must be number, but is array", json::type_error&);
  952. CHECK_THROWS_WITH_AS(
  953. json(json::value_t::string).get<json::number_float_t>(),
  954. "[json.exception.type_error.302] type must be number, but is string", json::type_error&);
  955. CHECK_THROWS_WITH_AS(
  956. json(json::value_t::boolean).get<json::number_float_t>(),
  957. "[json.exception.type_error.302] type must be number, but is "
  958. "boolean", json::type_error&);
  959. CHECK_NOTHROW(
  960. json(json::value_t::number_integer).get<json::number_float_t>());
  961. CHECK_NOTHROW(
  962. json(json::value_t::number_unsigned).get<json::number_float_t>());
  963. }
  964. }
  965. #if JSON_USE_IMPLICIT_CONVERSIONS
  966. SECTION("get a floating-point number (implicit)")
  967. {
  968. json::number_float_t const n_reference{42.23};
  969. json const j(n_reference);
  970. SECTION("number_float_t")
  971. {
  972. json::number_float_t const n = j;
  973. CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
  974. }
  975. SECTION("float")
  976. {
  977. float const n = j;
  978. CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
  979. }
  980. SECTION("double")
  981. {
  982. double const n = j;
  983. CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float));
  984. }
  985. }
  986. #endif
  987. SECTION("get a binary value (explicit)")
  988. {
  989. json::binary_t const n_reference{{1, 2, 3}};
  990. json j(n_reference);
  991. SECTION("binary_t")
  992. {
  993. json::binary_t const b = j.get<json::binary_t>();
  994. CHECK(*json(b).m_value.binary == *j.m_value.binary);
  995. }
  996. SECTION("get_binary()")
  997. {
  998. SECTION("non-const")
  999. {
  1000. auto& b = j.get_binary();
  1001. CHECK(*json(b).m_value.binary == *j.m_value.binary);
  1002. }
  1003. SECTION("non-const")
  1004. {
  1005. const json j_const = j;
  1006. const auto& b = j_const.get_binary();
  1007. CHECK(*json(b).m_value.binary == *j.m_value.binary);
  1008. }
  1009. }
  1010. SECTION("exception in case of a non-string type")
  1011. {
  1012. json j_null(json::value_t::null);
  1013. json j_object(json::value_t::object);
  1014. json j_array(json::value_t::array);
  1015. json j_string(json::value_t::string);
  1016. json j_boolean(json::value_t::boolean);
  1017. const json j_null_const(json::value_t::null);
  1018. const json j_object_const(json::value_t::object);
  1019. const json j_array_const(json::value_t::array);
  1020. const json j_string_const(json::value_t::string);
  1021. const json j_boolean_const(json::value_t::boolean);
  1022. CHECK_THROWS_WITH_AS(j_null.get<json::binary_t>(),
  1023. "[json.exception.type_error.302] type must be binary, but is null",
  1024. json::type_error&);
  1025. CHECK_THROWS_WITH_AS(j_object.get<json::binary_t>(),
  1026. "[json.exception.type_error.302] type must be binary, but is object",
  1027. json::type_error&);
  1028. CHECK_THROWS_WITH_AS(j_array.get<json::binary_t>(),
  1029. "[json.exception.type_error.302] type must be binary, but is array",
  1030. json::type_error&);
  1031. CHECK_THROWS_WITH_AS(j_string.get<json::binary_t>(),
  1032. "[json.exception.type_error.302] type must be binary, but is string",
  1033. json::type_error&);
  1034. CHECK_THROWS_WITH_AS(j_boolean.get<json::binary_t>(),
  1035. "[json.exception.type_error.302] type must be binary, but is boolean",
  1036. json::type_error&);
  1037. CHECK_THROWS_WITH_AS(j_null_const.get<json::binary_t>(),
  1038. "[json.exception.type_error.302] type must be binary, but is null",
  1039. json::type_error&);
  1040. CHECK_THROWS_WITH_AS(j_object_const.get<json::binary_t>(),
  1041. "[json.exception.type_error.302] type must be binary, but is object",
  1042. json::type_error&);
  1043. CHECK_THROWS_WITH_AS(j_array_const.get<json::binary_t>(),
  1044. "[json.exception.type_error.302] type must be binary, but is array",
  1045. json::type_error&);
  1046. CHECK_THROWS_WITH_AS(j_string_const.get<json::binary_t>(),
  1047. "[json.exception.type_error.302] type must be binary, but is string",
  1048. json::type_error&);
  1049. CHECK_THROWS_WITH_AS(j_boolean_const.get<json::binary_t>(),
  1050. "[json.exception.type_error.302] type must be binary, but is boolean",
  1051. json::type_error&);
  1052. CHECK_THROWS_WITH_AS(j_null.get_binary(),
  1053. "[json.exception.type_error.302] type must be binary, but is null",
  1054. json::type_error&);
  1055. CHECK_THROWS_WITH_AS(j_object.get_binary(),
  1056. "[json.exception.type_error.302] type must be binary, but is object",
  1057. json::type_error&);
  1058. CHECK_THROWS_WITH_AS(j_array.get_binary(),
  1059. "[json.exception.type_error.302] type must be binary, but is array",
  1060. json::type_error&);
  1061. CHECK_THROWS_WITH_AS(j_string.get_binary(),
  1062. "[json.exception.type_error.302] type must be binary, but is string",
  1063. json::type_error&);
  1064. CHECK_THROWS_WITH_AS(j_boolean.get_binary(),
  1065. "[json.exception.type_error.302] type must be binary, but is boolean",
  1066. json::type_error&);
  1067. CHECK_THROWS_WITH_AS(j_null_const.get_binary(),
  1068. "[json.exception.type_error.302] type must be binary, but is null",
  1069. json::type_error&);
  1070. CHECK_THROWS_WITH_AS(j_object_const.get_binary(),
  1071. "[json.exception.type_error.302] type must be binary, but is object",
  1072. json::type_error&);
  1073. CHECK_THROWS_WITH_AS(j_array_const.get_binary(),
  1074. "[json.exception.type_error.302] type must be binary, but is array",
  1075. json::type_error&);
  1076. CHECK_THROWS_WITH_AS(j_string_const.get_binary(),
  1077. "[json.exception.type_error.302] type must be binary, but is string",
  1078. json::type_error&);
  1079. CHECK_THROWS_WITH_AS(j_boolean_const.get_binary(),
  1080. "[json.exception.type_error.302] type must be binary, but is boolean",
  1081. json::type_error&);
  1082. }
  1083. }
  1084. #if JSON_USE_IMPLICIT_CONVERSIONS
  1085. SECTION("get a binary value (implicit)")
  1086. {
  1087. json::binary_t const n_reference{{1, 2, 3}};
  1088. json const j(n_reference);
  1089. SECTION("binary_t")
  1090. {
  1091. json::binary_t const b = j;
  1092. CHECK(*json(b).m_value.binary == *j.m_value.binary);
  1093. }
  1094. }
  1095. #endif
  1096. SECTION("get an enum")
  1097. {
  1098. enum c_enum { value_1, value_2 };
  1099. enum class cpp_enum { value_1, value_2 };
  1100. CHECK(json(value_1).get<c_enum>() == value_1);
  1101. CHECK(json(cpp_enum::value_1).get<cpp_enum>() == cpp_enum::value_1);
  1102. }
  1103. SECTION("more involved conversions")
  1104. {
  1105. SECTION("object-like STL containers")
  1106. {
  1107. json const j1 = {{"one", 1}, {"two", 2}, {"three", 3}};
  1108. json const j2 = {{"one", 1u}, {"two", 2u}, {"three", 3u}};
  1109. json const j3 = {{"one", 1.1}, {"two", 2.2}, {"three", 3.3}};
  1110. json const j4 = {{"one", true}, {"two", false}, {"three", true}};
  1111. json const j5 = {{"one", "eins"}, {"two", "zwei"}, {"three", "drei"}};
  1112. SECTION("std::map")
  1113. {
  1114. j1.get<std::map<std::string, int>>();
  1115. j2.get<std::map<std::string, unsigned int>>();
  1116. j3.get<std::map<std::string, double>>();
  1117. j4.get<std::map<std::string, bool>>();
  1118. j5.get<std::map<std::string, std::string>>();
  1119. }
  1120. SECTION("std::unordered_map")
  1121. {
  1122. j1.get<std::unordered_map<std::string, int>>();
  1123. j2.get<std::unordered_map<std::string, unsigned int>>();
  1124. j3.get<std::unordered_map<std::string, double>>();
  1125. j4.get<std::unordered_map<std::string, bool>>();
  1126. j5.get<std::unordered_map<std::string, std::string>>();
  1127. // CHECK(m5["one"] == "eins");
  1128. }
  1129. SECTION("std::multimap")
  1130. {
  1131. j1.get<std::multimap<std::string, int>>();
  1132. j2.get<std::multimap<std::string, unsigned int>>();
  1133. j3.get<std::multimap<std::string, double>>();
  1134. j4.get<std::multimap<std::string, bool>>();
  1135. j5.get<std::multimap<std::string, std::string>>();
  1136. // CHECK(m5["one"] == "eins");
  1137. }
  1138. SECTION("std::unordered_multimap")
  1139. {
  1140. j1.get<std::unordered_multimap<std::string, int>>();
  1141. j2.get<std::unordered_multimap<std::string, unsigned int>>();
  1142. j3.get<std::unordered_multimap<std::string, double>>();
  1143. j4.get<std::unordered_multimap<std::string, bool>>();
  1144. j5.get<std::unordered_multimap<std::string, std::string>>();
  1145. // CHECK(m5["one"] == "eins");
  1146. }
  1147. SECTION("exception in case of a non-object type")
  1148. {
  1149. CHECK_THROWS_WITH_AS(
  1150. (json().get<std::map<std::string, int>>()),
  1151. "[json.exception.type_error.302] type must be object, but is null", json::type_error&);
  1152. }
  1153. }
  1154. SECTION("array-like STL containers")
  1155. {
  1156. json const j1 = {1, 2, 3, 4};
  1157. json const j2 = {1u, 2u, 3u, 4u};
  1158. json const j3 = {1.2, 2.3, 3.4, 4.5};
  1159. json const j4 = {true, false, true};
  1160. json const j5 = {"one", "two", "three"};
  1161. SECTION("std::list")
  1162. {
  1163. j1.get<std::list<int>>();
  1164. j2.get<std::list<unsigned int>>();
  1165. j3.get<std::list<double>>();
  1166. j4.get<std::list<bool>>();
  1167. j5.get<std::list<std::string>>();
  1168. }
  1169. SECTION("std::forward_list")
  1170. {
  1171. j1.get<std::forward_list<int>>();
  1172. j2.get<std::forward_list<unsigned int>>();
  1173. j3.get<std::forward_list<double>>();
  1174. j4.get<std::forward_list<bool>>();
  1175. j5.get<std::forward_list<std::string>>();
  1176. }
  1177. SECTION("std::array")
  1178. {
  1179. j1.get<std::array<int, 4>>();
  1180. j2.get<std::array<unsigned int, 3>>();
  1181. j3.get<std::array<double, 4>>();
  1182. j4.get<std::array<bool, 3>>();
  1183. j5.get<std::array<std::string, 3>>();
  1184. SECTION("std::array is larger than JSON")
  1185. {
  1186. std::array<int, 6> arr6 = {{1, 2, 3, 4, 5, 6}};
  1187. CHECK_THROWS_WITH_AS(j1.get_to(arr6), "[json.exception.out_of_range.401] "
  1188. "array index 4 is out of range", json::out_of_range&);
  1189. }
  1190. SECTION("std::array is smaller than JSON")
  1191. {
  1192. std::array<int, 2> arr2 = {{8, 9}};
  1193. j1.get_to(arr2);
  1194. CHECK(arr2[0] == 1);
  1195. CHECK(arr2[1] == 2);
  1196. }
  1197. }
  1198. SECTION("std::valarray")
  1199. {
  1200. j1.get<std::valarray<int>>();
  1201. j2.get<std::valarray<unsigned int>>();
  1202. j3.get<std::valarray<double>>();
  1203. j4.get<std::valarray<bool>>();
  1204. j5.get<std::valarray<std::string>>();
  1205. }
  1206. SECTION("std::vector")
  1207. {
  1208. j1.get<std::vector<int>>();
  1209. j2.get<std::vector<unsigned int>>();
  1210. j3.get<std::vector<double>>();
  1211. j4.get<std::vector<bool>>();
  1212. j5.get<std::vector<std::string>>();
  1213. }
  1214. SECTION("std::deque")
  1215. {
  1216. j1.get<std::deque<int>>();
  1217. j2.get<std::deque<unsigned int>>();
  1218. j2.get<std::deque<double>>();
  1219. j4.get<std::deque<bool>>();
  1220. j5.get<std::deque<std::string>>();
  1221. }
  1222. SECTION("std::set")
  1223. {
  1224. j1.get<std::set<int>>();
  1225. j2.get<std::set<unsigned int>>();
  1226. j3.get<std::set<double>>();
  1227. j4.get<std::set<bool>>();
  1228. j5.get<std::set<std::string>>();
  1229. }
  1230. SECTION("std::unordered_set")
  1231. {
  1232. j1.get<std::unordered_set<int>>();
  1233. j2.get<std::unordered_set<unsigned int>>();
  1234. j3.get<std::unordered_set<double>>();
  1235. j4.get<std::unordered_set<bool>>();
  1236. j5.get<std::unordered_set<std::string>>();
  1237. }
  1238. SECTION("std::map (array of pairs)")
  1239. {
  1240. std::map<int, int> m{{0, 1}, {1, 2}, {2, 3}};
  1241. json const j6 = m;
  1242. auto m2 = j6.get<std::map<int, int>>();
  1243. CHECK(m == m2);
  1244. json const j7 = {0, 1, 2, 3};
  1245. json const j8 = 2;
  1246. CHECK_THROWS_WITH_AS((j7.get<std::map<int, int>>()),
  1247. "[json.exception.type_error.302] type must be array, "
  1248. "but is number", json::type_error&);
  1249. CHECK_THROWS_WITH_AS((j8.get<std::map<int, int>>()),
  1250. "[json.exception.type_error.302] type must be array, "
  1251. "but is number", json::type_error&);
  1252. SECTION("superfluous entries")
  1253. {
  1254. json const j9 = {{0, 1, 2}, {1, 2, 3}, {2, 3, 4}};
  1255. m2 = j9.get<std::map<int, int>>();
  1256. CHECK(m == m2);
  1257. }
  1258. }
  1259. SECTION("std::unordered_map (array of pairs)")
  1260. {
  1261. std::unordered_map<int, int> m{{0, 1}, {1, 2}, {2, 3}};
  1262. json const j6 = m;
  1263. auto m2 = j6.get<std::unordered_map<int, int>>();
  1264. CHECK(m == m2);
  1265. json const j7 = {0, 1, 2, 3};
  1266. json const j8 = 2;
  1267. CHECK_THROWS_WITH_AS((j7.get<std::unordered_map<int, int>>()),
  1268. "[json.exception.type_error.302] type must be array, "
  1269. "but is number", json::type_error&);
  1270. CHECK_THROWS_WITH_AS((j8.get<std::unordered_map<int, int>>()),
  1271. "[json.exception.type_error.302] type must be array, "
  1272. "but is number", json::type_error&);
  1273. SECTION("superfluous entries")
  1274. {
  1275. json const j9{{0, 1, 2}, {1, 2, 3}, {2, 3, 4}};
  1276. m2 = j9.get<std::unordered_map<int, int>>();
  1277. CHECK(m == m2);
  1278. }
  1279. }
  1280. SECTION("exception in case of a non-object type")
  1281. {
  1282. // does type really must be an array? or it rather must not be null?
  1283. // that's what I thought when other test like this one broke
  1284. CHECK_THROWS_WITH_AS(
  1285. (json().get<std::list<int>>()),
  1286. "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
  1287. CHECK_THROWS_WITH_AS(
  1288. (json().get<std::vector<int>>()),
  1289. "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
  1290. CHECK_THROWS_WITH_AS(
  1291. (json().get<std::vector<json>>()),
  1292. "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
  1293. CHECK_THROWS_WITH_AS(
  1294. (json().get<std::list<json>>()),
  1295. "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
  1296. CHECK_THROWS_WITH_AS(
  1297. (json().get<std::valarray<int>>()),
  1298. "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
  1299. CHECK_THROWS_WITH_AS(
  1300. (json().get<std::map<int, int>>()),
  1301. "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
  1302. }
  1303. }
  1304. }
  1305. }
  1306. enum class cards {kreuz, pik, herz, karo};
  1307. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
  1308. NLOHMANN_JSON_SERIALIZE_ENUM(cards,
  1309. {
  1310. {cards::kreuz, "kreuz"},
  1311. {cards::pik, "pik"},
  1312. {cards::pik, "puk"}, // second entry for cards::puk; will not be used
  1313. {cards::herz, "herz"},
  1314. {cards::karo, "karo"}
  1315. })
  1316. enum TaskState
  1317. {
  1318. TS_STOPPED,
  1319. TS_RUNNING,
  1320. TS_COMPLETED,
  1321. TS_INVALID = -1,
  1322. };
  1323. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive
  1324. NLOHMANN_JSON_SERIALIZE_ENUM(TaskState,
  1325. {
  1326. {TS_INVALID, nullptr},
  1327. {TS_STOPPED, "stopped"},
  1328. {TS_RUNNING, "running"},
  1329. {TS_COMPLETED, "completed"},
  1330. })
  1331. TEST_CASE("JSON to enum mapping")
  1332. {
  1333. SECTION("enum class")
  1334. {
  1335. // enum -> json
  1336. CHECK(json(cards::kreuz) == "kreuz");
  1337. CHECK(json(cards::pik) == "pik");
  1338. CHECK(json(cards::herz) == "herz");
  1339. CHECK(json(cards::karo) == "karo");
  1340. // json -> enum
  1341. CHECK(cards::kreuz == json("kreuz"));
  1342. CHECK(cards::pik == json("pik"));
  1343. CHECK(cards::herz == json("herz"));
  1344. CHECK(cards::karo == json("karo"));
  1345. // invalid json -> first enum
  1346. CHECK(cards::kreuz == json("what?").get<cards>());
  1347. }
  1348. SECTION("traditional enum")
  1349. {
  1350. // enum -> json
  1351. CHECK(json(TS_STOPPED) == "stopped");
  1352. CHECK(json(TS_RUNNING) == "running");
  1353. CHECK(json(TS_COMPLETED) == "completed");
  1354. CHECK(json(TS_INVALID) == json());
  1355. // json -> enum
  1356. CHECK(TS_STOPPED == json("stopped"));
  1357. CHECK(TS_RUNNING == json("running"));
  1358. CHECK(TS_COMPLETED == json("completed"));
  1359. CHECK(TS_INVALID == json());
  1360. // invalid json -> first enum
  1361. CHECK(TS_INVALID == json("what?").get<TaskState>());
  1362. }
  1363. }
  1364. DOCTEST_CLANG_SUPPRESS_WARNING_POP