value.ipp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. //
  2. // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Official repository: https://github.com/boostorg/json
  8. //
  9. #ifndef BOOST_JSON_IMPL_VALUE_IPP
  10. #define BOOST_JSON_IMPL_VALUE_IPP
  11. #include <boost/json/value.hpp>
  12. #include <cstring>
  13. #include <limits>
  14. #include <new>
  15. #include <utility>
  16. BOOST_JSON_NS_BEGIN
  17. value::
  18. ~value()
  19. {
  20. switch(kind())
  21. {
  22. case json::kind::null:
  23. case json::kind::bool_:
  24. case json::kind::int64:
  25. case json::kind::uint64:
  26. case json::kind::double_:
  27. sca_.~scalar();
  28. break;
  29. case json::kind::string:
  30. str_.~string();
  31. break;
  32. case json::kind::array:
  33. arr_.~array();
  34. break;
  35. case json::kind::object:
  36. obj_.~object();
  37. break;
  38. }
  39. }
  40. value::
  41. value(
  42. value const& other,
  43. storage_ptr sp)
  44. {
  45. switch(other.kind())
  46. {
  47. case json::kind::null:
  48. ::new(&sca_) scalar(
  49. std::move(sp));
  50. break;
  51. case json::kind::bool_:
  52. ::new(&sca_) scalar(
  53. other.sca_.b,
  54. std::move(sp));
  55. break;
  56. case json::kind::int64:
  57. ::new(&sca_) scalar(
  58. other.sca_.i,
  59. std::move(sp));
  60. break;
  61. case json::kind::uint64:
  62. ::new(&sca_) scalar(
  63. other.sca_.u,
  64. std::move(sp));
  65. break;
  66. case json::kind::double_:
  67. ::new(&sca_) scalar(
  68. other.sca_.d,
  69. std::move(sp));
  70. break;
  71. case json::kind::string:
  72. ::new(&str_) string(
  73. other.str_,
  74. std::move(sp));
  75. break;
  76. case json::kind::array:
  77. ::new(&arr_) array(
  78. other.arr_,
  79. std::move(sp));
  80. break;
  81. case json::kind::object:
  82. ::new(&obj_) object(
  83. other.obj_,
  84. std::move(sp));
  85. break;
  86. }
  87. }
  88. value::
  89. value(value&& other) noexcept
  90. {
  91. relocate(this, other);
  92. ::new(&other.sca_) scalar(sp_);
  93. }
  94. value::
  95. value(
  96. value&& other,
  97. storage_ptr sp)
  98. {
  99. switch(other.kind())
  100. {
  101. case json::kind::null:
  102. ::new(&sca_) scalar(
  103. std::move(sp));
  104. break;
  105. case json::kind::bool_:
  106. ::new(&sca_) scalar(
  107. other.sca_.b, std::move(sp));
  108. break;
  109. case json::kind::int64:
  110. ::new(&sca_) scalar(
  111. other.sca_.i, std::move(sp));
  112. break;
  113. case json::kind::uint64:
  114. ::new(&sca_) scalar(
  115. other.sca_.u, std::move(sp));
  116. break;
  117. case json::kind::double_:
  118. ::new(&sca_) scalar(
  119. other.sca_.d, std::move(sp));
  120. break;
  121. case json::kind::string:
  122. ::new(&str_) string(
  123. std::move(other.str_),
  124. std::move(sp));
  125. break;
  126. case json::kind::array:
  127. ::new(&arr_) array(
  128. std::move(other.arr_),
  129. std::move(sp));
  130. break;
  131. case json::kind::object:
  132. ::new(&obj_) object(
  133. std::move(other.obj_),
  134. std::move(sp));
  135. break;
  136. }
  137. }
  138. //----------------------------------------------------------
  139. //
  140. // Conversion
  141. //
  142. //----------------------------------------------------------
  143. value::
  144. value(
  145. std::initializer_list<value_ref> init,
  146. storage_ptr sp)
  147. {
  148. if(value_ref::maybe_object(init))
  149. ::new(&obj_) object(
  150. value_ref::make_object(
  151. init, std::move(sp)));
  152. else
  153. ::new(&arr_) array(
  154. value_ref::make_array(
  155. init, std::move(sp)));
  156. }
  157. //----------------------------------------------------------
  158. //
  159. // Assignment
  160. //
  161. //----------------------------------------------------------
  162. value&
  163. value::
  164. operator=(value const& other)
  165. {
  166. value(other,
  167. storage()).swap(*this);
  168. return *this;
  169. }
  170. value&
  171. value::
  172. operator=(value&& other)
  173. {
  174. value(std::move(other),
  175. storage()).swap(*this);
  176. return *this;
  177. }
  178. value&
  179. value::
  180. operator=(
  181. std::initializer_list<value_ref> init)
  182. {
  183. value(init,
  184. storage()).swap(*this);
  185. return *this;
  186. }
  187. value&
  188. value::
  189. operator=(string_view s)
  190. {
  191. value(s, storage()).swap(*this);
  192. return *this;
  193. }
  194. value&
  195. value::
  196. operator=(char const* s)
  197. {
  198. value(s, storage()).swap(*this);
  199. return *this;
  200. }
  201. value&
  202. value::
  203. operator=(string const& str)
  204. {
  205. value(str, storage()).swap(*this);
  206. return *this;
  207. }
  208. value&
  209. value::
  210. operator=(string&& str)
  211. {
  212. value(std::move(str),
  213. storage()).swap(*this);
  214. return *this;
  215. }
  216. value&
  217. value::
  218. operator=(array const& arr)
  219. {
  220. value(arr, storage()).swap(*this);
  221. return *this;
  222. }
  223. value&
  224. value::
  225. operator=(array&& arr)
  226. {
  227. value(std::move(arr),
  228. storage()).swap(*this);
  229. return *this;
  230. }
  231. value&
  232. value::
  233. operator=(object const& obj)
  234. {
  235. value(obj, storage()).swap(*this);
  236. return *this;
  237. }
  238. value&
  239. value::
  240. operator=(object&& obj)
  241. {
  242. value(std::move(obj),
  243. storage()).swap(*this);
  244. return *this;
  245. }
  246. //----------------------------------------------------------
  247. //
  248. // Modifiers
  249. //
  250. //----------------------------------------------------------
  251. string&
  252. value::
  253. emplace_string() noexcept
  254. {
  255. return *::new(&str_) string(destroy());
  256. }
  257. array&
  258. value::
  259. emplace_array() noexcept
  260. {
  261. return *::new(&arr_) array(destroy());
  262. }
  263. object&
  264. value::
  265. emplace_object() noexcept
  266. {
  267. return *::new(&obj_) object(destroy());
  268. }
  269. void
  270. value::
  271. swap(value& other)
  272. {
  273. if(*storage() == *other.storage())
  274. {
  275. // fast path
  276. union U
  277. {
  278. value tmp;
  279. U(){}
  280. ~U(){}
  281. };
  282. U u;
  283. relocate(&u.tmp, *this);
  284. relocate(this, other);
  285. relocate(&other, u.tmp);
  286. return;
  287. }
  288. // copy
  289. value temp1(
  290. std::move(*this),
  291. other.storage());
  292. value temp2(
  293. std::move(other),
  294. this->storage());
  295. other.~value();
  296. ::new(&other) value(pilfer(temp1));
  297. this->~value();
  298. ::new(this) value(pilfer(temp2));
  299. }
  300. //----------------------------------------------------------
  301. //
  302. // private
  303. //
  304. //----------------------------------------------------------
  305. storage_ptr
  306. value::
  307. destroy() noexcept
  308. {
  309. switch(kind())
  310. {
  311. case json::kind::null:
  312. case json::kind::bool_:
  313. case json::kind::int64:
  314. case json::kind::uint64:
  315. case json::kind::double_:
  316. break;
  317. case json::kind::string:
  318. {
  319. auto sp = str_.storage();
  320. str_.~string();
  321. return sp;
  322. }
  323. case json::kind::array:
  324. {
  325. auto sp = arr_.storage();
  326. arr_.~array();
  327. return sp;
  328. }
  329. case json::kind::object:
  330. {
  331. auto sp = obj_.storage();
  332. obj_.~object();
  333. return sp;
  334. }
  335. }
  336. return std::move(sp_);
  337. }
  338. bool
  339. value::
  340. equal(value const& other) const noexcept
  341. {
  342. switch(kind())
  343. {
  344. default: // unreachable()?
  345. case json::kind::null:
  346. return other.kind() == json::kind::null;
  347. case json::kind::bool_:
  348. return
  349. other.kind() == json::kind::bool_ &&
  350. get_bool() == other.get_bool();
  351. case json::kind::int64:
  352. switch(other.kind())
  353. {
  354. case json::kind::int64:
  355. return get_int64() == other.get_int64();
  356. case json::kind::uint64:
  357. if(get_int64() < 0)
  358. return false;
  359. return static_cast<std::uint64_t>(
  360. get_int64()) == other.get_uint64();
  361. default:
  362. return false;
  363. }
  364. case json::kind::uint64:
  365. switch(other.kind())
  366. {
  367. case json::kind::uint64:
  368. return get_uint64() == other.get_uint64();
  369. case json::kind::int64:
  370. if(other.get_int64() < 0)
  371. return false;
  372. return static_cast<std::uint64_t>(
  373. other.get_int64()) == get_uint64();
  374. default:
  375. return false;
  376. }
  377. case json::kind::double_:
  378. return
  379. other.kind() == json::kind::double_ &&
  380. get_double() == other.get_double();
  381. case json::kind::string:
  382. return
  383. other.kind() == json::kind::string &&
  384. get_string() == other.get_string();
  385. case json::kind::array:
  386. return
  387. other.kind() == json::kind::array &&
  388. get_array() == other.get_array();
  389. case json::kind::object:
  390. return
  391. other.kind() == json::kind::object &&
  392. get_object() == other.get_object();
  393. }
  394. }
  395. //----------------------------------------------------------
  396. //
  397. // key_value_pair
  398. //
  399. //----------------------------------------------------------
  400. // empty keys point here
  401. BOOST_JSON_REQUIRE_CONST_INIT
  402. char const
  403. key_value_pair::empty_[1] = { 0 };
  404. key_value_pair::
  405. key_value_pair(
  406. pilfered<json::value> key,
  407. pilfered<json::value> value) noexcept
  408. : value_(value)
  409. {
  410. std::size_t len;
  411. key_ = access::release_key(key.get(), len);
  412. len_ = static_cast<std::uint32_t>(len);
  413. }
  414. key_value_pair::
  415. key_value_pair(
  416. key_value_pair const& other,
  417. storage_ptr sp)
  418. : value_(other.value_, std::move(sp))
  419. {
  420. auto p = reinterpret_cast<
  421. char*>(value_.storage()->
  422. allocate(other.len_ + 1,
  423. alignof(char)));
  424. std::memcpy(
  425. p, other.key_, other.len_);
  426. len_ = other.len_;
  427. p[len_] = 0;
  428. key_ = p;
  429. }
  430. //----------------------------------------------------------
  431. BOOST_JSON_NS_END
  432. #endif