object.hpp 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686
  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_OBJECT_HPP
  10. #define BOOST_JSON_OBJECT_HPP
  11. #include <boost/json/detail/config.hpp>
  12. #include <boost/json/kind.hpp>
  13. #include <boost/json/pilfer.hpp>
  14. #include <boost/json/storage_ptr.hpp>
  15. #include <boost/json/string_view.hpp>
  16. #include <boost/json/detail/object.hpp>
  17. #include <boost/json/detail/value.hpp>
  18. #include <cstdlib>
  19. #include <initializer_list>
  20. #include <iterator>
  21. #include <type_traits>
  22. #include <utility>
  23. namespace boost {
  24. namespace json {
  25. class value;
  26. class value_ref;
  27. class key_value_pair;
  28. /** A dynamically sized associative container of JSON key/value pairs.
  29. This is an associative container whose elements
  30. are key/value pairs with unique keys.
  31. \n
  32. The elements are stored contiguously; iterators are
  33. ordinary pointers, allowing random access pointer
  34. arithmetic for retrieving elements.
  35. In addition, the container maintains an internal
  36. index to speed up find operations, reducing the
  37. average complexity for most lookups and insertions.
  38. \n
  39. Reallocations are usually costly operations in terms of
  40. performance, as elements are copied and the internal
  41. index must be rebuilt. The @ref reserve function can
  42. be used to eliminate reallocations if the number of
  43. elements is known beforehand.
  44. @par Allocators
  45. All elements stored in the container, and their
  46. children if any, will use the same memory resource that
  47. was used to construct the container.
  48. @par Thread Safety
  49. Non-const member functions may not be called
  50. concurrently with any other member functions.
  51. @par Satisfies
  52. <a href="https://en.cppreference.com/w/cpp/named_req/ContiguousContainer"><em>ContiguousContainer</em></a>,
  53. <a href="https://en.cppreference.com/w/cpp/named_req/ReversibleContainer"><em>ReversibleContainer</em></a>, and
  54. <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>.
  55. */
  56. class object
  57. {
  58. struct table;
  59. class revert_construct;
  60. class revert_insert;
  61. friend class value;
  62. friend class object_test;
  63. using access = detail::access;
  64. using index_t = std::uint32_t;
  65. static index_t constexpr null_index_ =
  66. std::uint32_t(-1);
  67. storage_ptr sp_; // must come first
  68. kind k_ = kind::object; // must come second
  69. table* t_;
  70. BOOST_JSON_DECL
  71. static table empty_;
  72. template<class T>
  73. using is_inputit = typename std::enable_if<
  74. std::is_constructible<key_value_pair,
  75. typename std::iterator_traits<T>::reference
  76. >::value>::type;
  77. BOOST_JSON_DECL
  78. explicit
  79. object(detail::unchecked_object&& uo);
  80. public:
  81. /** The type of _Allocator_ returned by @ref get_allocator
  82. This type is a @ref polymorphic_allocator.
  83. */
  84. #ifdef BOOST_JSON_DOCS
  85. // VFALCO doc toolchain renders this incorrectly
  86. using allocator_type = __see_below__;
  87. #else
  88. using allocator_type = polymorphic_allocator<value>;
  89. #endif
  90. /** The type of keys.
  91. The function @ref string::max_size returns the
  92. maximum allowed size of strings used as keys.
  93. */
  94. using key_type = string_view;
  95. /// The type of mapped values
  96. using mapped_type = value;
  97. /// The element type
  98. using value_type = key_value_pair;
  99. /// The type used to represent unsigned integers
  100. using size_type = std::size_t;
  101. /// The type used to represent signed integers
  102. using difference_type = std::ptrdiff_t;
  103. /// A reference to an element
  104. using reference = value_type&;
  105. /// A const reference to an element
  106. using const_reference = value_type const&;
  107. /// A pointer to an element
  108. using pointer = value_type*;
  109. /// A const pointer to an element
  110. using const_pointer = value_type const*;
  111. /// A random access iterator to an element
  112. using iterator = value_type*;
  113. /// A const random access iterator to an element
  114. using const_iterator = value_type const*;
  115. /// A reverse random access iterator to an element
  116. using reverse_iterator =
  117. std::reverse_iterator<iterator>;
  118. /// A const reverse random access iterator to an element
  119. using const_reverse_iterator =
  120. std::reverse_iterator<const_iterator>;
  121. //------------------------------------------------------
  122. /** Destructor.
  123. The destructor for each element is called if needed,
  124. any used memory is deallocated, and shared ownership
  125. of the @ref memory_resource is released.
  126. @par Complexity
  127. Constant, or linear in @ref size().
  128. @par Exception Safety
  129. No-throw guarantee.
  130. */
  131. BOOST_JSON_DECL
  132. ~object() noexcept;
  133. //------------------------------------------------------
  134. /** Default constructor.
  135. The constructed object is empty with zero
  136. capacity, using the [default memory resource].
  137. @par Complexity
  138. Constant.
  139. @par Exception Safety
  140. No-throw guarantee.
  141. [default memory resource]: json/allocators/storage_ptr.html#json.allocators.storage_ptr.default_memory_resource
  142. */
  143. object() noexcept
  144. : t_(&empty_)
  145. {
  146. }
  147. /** Constructor.
  148. The constructed object is empty with zero
  149. capacity, using the specified memory resource.
  150. @par Complexity
  151. Constant.
  152. @par Exception Safety
  153. No-throw guarantee.
  154. @param sp A pointer to the @ref memory_resource
  155. to use. The container will acquire shared
  156. ownership of the memory resource.
  157. */
  158. explicit
  159. object(storage_ptr sp) noexcept
  160. : sp_(std::move(sp))
  161. , t_(&empty_)
  162. {
  163. }
  164. /** Constructor.
  165. The constructed object is empty with capacity
  166. equal to the specified minimum capacity,
  167. using the specified memory resource.
  168. @par Complexity
  169. Constant.
  170. @par Exception Safety
  171. Strong guarantee.
  172. Calls to `memory_resource::allocate` may throw.
  173. @param min_capacity The minimum number
  174. of elements for which capacity is guaranteed
  175. without a subsequent reallocation.
  176. @param sp A pointer to the @ref memory_resource
  177. to use. The container will acquire shared
  178. ownership of the memory resource.
  179. */
  180. BOOST_JSON_DECL
  181. object(
  182. std::size_t min_capacity,
  183. storage_ptr sp = {});
  184. /** Constructor.
  185. The object is constructed with the elements
  186. in the range `{first, last)`, preserving order,
  187. using the specified memory resource.
  188. If there are elements with duplicate keys; that
  189. is, if multiple elements in the range have keys
  190. that compare equal, only the first equivalent
  191. element will be inserted.
  192. @par Constraints
  193. @code
  194. std::is_constructible_v<
  195. key_value_pair,
  196. std::iterator_traits<InputIt>::reference>
  197. @endcode
  198. @par Complexity
  199. Linear in `std::distance(first, last)`.
  200. @par Exception Safety
  201. Strong guarantee.
  202. Calls to `memory_resource::allocate` may throw.
  203. @param first An input iterator pointing to the
  204. first element to insert, or pointing to the end
  205. of the range.
  206. @param last An input iterator pointing to the end
  207. of the range.
  208. @param min_capacity The minimum number
  209. of elements for which capacity is guaranteed
  210. without a subsequent reallocation.
  211. Upon construction, @ref capacity() will be greater
  212. than or equal to this number.
  213. @param sp A pointer to the @ref memory_resource
  214. to use. The container will acquire shared
  215. ownership of the memory resource.
  216. @tparam InputIt a type satisfying the requirements
  217. of __InputIterator__.
  218. */
  219. template<
  220. class InputIt
  221. #ifndef BOOST_JSON_DOCS
  222. ,class = is_inputit<InputIt>
  223. #endif
  224. >
  225. object(
  226. InputIt first,
  227. InputIt last,
  228. std::size_t min_capacity = 0,
  229. storage_ptr sp = {})
  230. : sp_(std::move(sp))
  231. , t_(&empty_)
  232. {
  233. construct(
  234. first, last,
  235. min_capacity,
  236. typename std::iterator_traits<
  237. InputIt>::iterator_category{});
  238. }
  239. /** Move constructor.
  240. The object is constructed by acquiring ownership of
  241. the contents of `other` and shared ownership
  242. of `other`'s memory resource.
  243. @note
  244. After construction, the moved-from object behaves
  245. as if newly constructed with its current memory resource.
  246. @par Complexity
  247. Constant.
  248. @par Exception Safety
  249. No-throw guarantee.
  250. @param other The object to move.
  251. */
  252. BOOST_JSON_DECL
  253. object(object&& other) noexcept;
  254. /** Move constructor.
  255. The object is constructed with the contents of
  256. `other` by move semantics, using the specified
  257. memory resource:
  258. @li If `*other.storage() == *sp`, ownership of
  259. the underlying memory is transferred in constant
  260. time, with no possibility of exceptions.
  261. After construction, the moved-from object behaves
  262. as if newly constructed with its current storage
  263. pointer.
  264. @li If `*other.storage() != *sp`, an
  265. element-wise copy is performed, which may throw.
  266. In this case, the moved-from object is not
  267. changed.
  268. @par Complexity
  269. Constant or linear in `other.size()`.
  270. @par Exception Safety
  271. Strong guarantee.
  272. Calls to `memory_resource::allocate` may throw.
  273. @param other The object to move.
  274. @param sp A pointer to the @ref memory_resource
  275. to use. The container will acquire shared
  276. ownership of the memory resource.
  277. */
  278. BOOST_JSON_DECL
  279. object(
  280. object&& other,
  281. storage_ptr sp);
  282. /** Pilfer constructor.
  283. The object is constructed by acquiring ownership
  284. of the contents of `other` using pilfer semantics.
  285. This is more efficient than move construction, when
  286. it is known that the moved-from object will be
  287. immediately destroyed afterwards.
  288. @par Complexity
  289. Constant.
  290. @par Exception Safety
  291. No-throw guarantee.
  292. @param other The value to pilfer. After pilfer
  293. construction, `other` is not in a usable state
  294. and may only be destroyed.
  295. @see @ref pilfer,
  296. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
  297. Valueless Variants Considered Harmful</a>
  298. */
  299. object(pilfered<object> other) noexcept
  300. : sp_(std::move(other.get().sp_))
  301. , t_(detail::exchange(
  302. other.get().t_, &empty_))
  303. {
  304. }
  305. /** Copy constructor.
  306. The object is constructed with a copy of the
  307. contents of `other`, using `other`'s memory resource.
  308. @par Complexity
  309. Linear in `other.size()`.
  310. @par Exception Safety
  311. Strong guarantee.
  312. Calls to `memory_resource::allocate` may throw.
  313. @param other The object to copy.
  314. */
  315. object(
  316. object const& other)
  317. : object(other, other.sp_)
  318. {
  319. }
  320. /** Copy constructor.
  321. The object is constructed with a copy of the
  322. contents of `other`, using the specified memory resource.
  323. @par Complexity
  324. Linear in `other.size()`.
  325. @par Exception Safety
  326. Strong guarantee.
  327. Calls to `memory_resource::allocate` may throw.
  328. @param other The object to copy.
  329. @param sp A pointer to the @ref memory_resource
  330. to use. The container will acquire shared
  331. ownership of the memory resource.
  332. */
  333. BOOST_JSON_DECL
  334. object(
  335. object const& other,
  336. storage_ptr sp);
  337. /** Construct from initializer-list.
  338. The object is constructed with a copy of the values
  339. in the initializer-list in order, using the
  340. specified memory resource.
  341. If there are elements with duplicate keys; that
  342. is, if multiple elements in the range have keys
  343. that compare equal, only the first equivalent
  344. element will be inserted.
  345. @par Complexity
  346. Linear in `init.size()`.
  347. @par Exception Safety
  348. Strong guarantee.
  349. Calls to `memory_resource::allocate` may throw.
  350. @param init The initializer list to insert.
  351. @param sp A pointer to the @ref memory_resource
  352. to use. The container will acquire shared
  353. ownership of the memory resource.
  354. */
  355. object(
  356. std::initializer_list<
  357. std::pair<string_view, value_ref>> init,
  358. storage_ptr sp = {})
  359. : object(init, 0, std::move(sp))
  360. {
  361. }
  362. /** Construct from initializer-list.
  363. Storage for at least `min_capacity` elements is
  364. reserved, and then
  365. the object is constructed with a copy of the values
  366. in the initializer-list in order, using the
  367. specified memory resource.
  368. If there are elements with duplicate keys; that
  369. is, if multiple elements in the range have keys
  370. that compare equal, only the first equivalent
  371. element will be inserted.
  372. @par Complexity
  373. Linear in `init.size()`.
  374. @par Exception Safety
  375. Strong guarantee.
  376. Calls to `memory_resource::allocate` may throw.
  377. @param init The initializer list to insert.
  378. @param min_capacity The minimum number
  379. of elements for which capacity is guaranteed
  380. without a subsequent reallocation.
  381. Upon construction, @ref capacity() will be greater
  382. than or equal to this number.
  383. @param sp A pointer to the @ref memory_resource
  384. to use. The container will acquire shared
  385. ownership of the memory resource.
  386. */
  387. BOOST_JSON_DECL
  388. object(
  389. std::initializer_list<
  390. std::pair<string_view, value_ref>> init,
  391. std::size_t min_capacity,
  392. storage_ptr sp = {});
  393. //------------------------------------------------------
  394. //
  395. // Assignment
  396. //
  397. //------------------------------------------------------
  398. /** Copy assignment.
  399. The contents of the object are replaced with an
  400. element-wise copy of `other`.
  401. @par Complexity
  402. Linear in @ref size() plus `other.size()`.
  403. @par Exception Safety
  404. Strong guarantee.
  405. Calls to `memory_resource::allocate` may throw.
  406. @param other The object to copy.
  407. */
  408. BOOST_JSON_DECL
  409. object&
  410. operator=(object const& other);
  411. /** Move assignment.
  412. The contents of the object are replaced with the
  413. contents of `other` using move semantics:
  414. @li If `*other.storage() == *sp`, ownership of
  415. the underlying memory is transferred in constant
  416. time, with no possibility of exceptions.
  417. After assignment, the moved-from object behaves
  418. as if newly constructed with its current storage
  419. pointer.
  420. @li If `*other.storage() != *sp`, an
  421. element-wise copy is performed, which may throw.
  422. In this case, the moved-from object is not
  423. changed.
  424. @par Complexity
  425. Constant or linear in @ref size() plus `other.size()`.
  426. @par Exception Safety
  427. Strong guarantee.
  428. Calls to `memory_resource::allocate` may throw.
  429. @param other The object to move.
  430. */
  431. BOOST_JSON_DECL
  432. object&
  433. operator=(object&& other);
  434. /** Assignment.
  435. Replaces the contents with the contents of an
  436. initializer list.
  437. @par Complexity
  438. Linear in @ref size() plus
  439. average case linear in `init.size()`,
  440. worst case quadratic in `init.size()`.
  441. @par Exception Safety
  442. Strong guarantee.
  443. Calls to `memory_resource::allocate` may throw.
  444. @param init The initializer list to copy.
  445. */
  446. BOOST_JSON_DECL
  447. object&
  448. operator=(std::initializer_list<
  449. std::pair<string_view, value_ref>> init);
  450. //------------------------------------------------------
  451. /** Return the associated @ref memory_resource
  452. This returns the @ref memory_resource used by
  453. the container.
  454. @par Complexity
  455. Constant.
  456. @par Exception Safety
  457. No-throw guarantee.
  458. */
  459. storage_ptr const&
  460. storage() const noexcept
  461. {
  462. return sp_;
  463. }
  464. /** Return the associated @ref memory_resource
  465. This function returns an instance of
  466. @ref polymorphic_allocator constructed from the
  467. associated @ref memory_resource.
  468. @par Complexity
  469. Constant.
  470. @par Exception Safety
  471. No-throw guarantee.
  472. */
  473. allocator_type
  474. get_allocator() const noexcept
  475. {
  476. return sp_.get();
  477. }
  478. //------------------------------------------------------
  479. //
  480. // Iterators
  481. //
  482. //------------------------------------------------------
  483. /** Return an iterator to the first element.
  484. If the container is empty, @ref end() is returned.
  485. @par Complexity
  486. Constant.
  487. @par Exception Safety
  488. No-throw guarantee.
  489. */
  490. inline
  491. iterator
  492. begin() noexcept;
  493. /** Return a const iterator to the first element.
  494. If the container is empty, @ref end() is returned.
  495. @par Complexity
  496. Constant.
  497. @par Exception Safety
  498. No-throw guarantee.
  499. */
  500. inline
  501. const_iterator
  502. begin() const noexcept;
  503. /** Return a const iterator to the first element.
  504. If the container is empty, @ref cend() is returned.
  505. @par Complexity
  506. Constant.
  507. @par Exception Safety
  508. No-throw guarantee.
  509. */
  510. inline
  511. const_iterator
  512. cbegin() const noexcept;
  513. /** Return an iterator to the element following the last element.
  514. The element acts as a placeholder; attempting
  515. to access it results in undefined behavior.
  516. @par Complexity
  517. Constant.
  518. @par Exception Safety
  519. No-throw guarantee.
  520. */
  521. inline
  522. iterator
  523. end() noexcept;
  524. /** Return a const iterator to the element following the last element.
  525. The element acts as a placeholder; attempting
  526. to access it results in undefined behavior.
  527. @par Complexity
  528. Constant.
  529. @par Exception Safety
  530. No-throw guarantee.
  531. */
  532. inline
  533. const_iterator
  534. end() const noexcept;
  535. /** Return a const iterator to the element following the last element.
  536. The element acts as a placeholder; attempting
  537. to access it results in undefined behavior.
  538. @par Complexity
  539. Constant.
  540. @par Exception Safety
  541. No-throw guarantee.
  542. */
  543. inline
  544. const_iterator
  545. cend() const noexcept;
  546. /** Return a reverse iterator to the first element of the reversed container.
  547. The pointed-to element corresponds to the
  548. last element of the non-reversed container.
  549. If the container is empty, @ref rend() is returned.
  550. @par Complexity
  551. Constant.
  552. @par Exception Safety
  553. No-throw guarantee.
  554. */
  555. inline
  556. reverse_iterator
  557. rbegin() noexcept;
  558. /** Return a const reverse iterator to the first element of the reversed container.
  559. The pointed-to element corresponds to the
  560. last element of the non-reversed container.
  561. If the container is empty, @ref rend() is returned.
  562. @par Complexity
  563. Constant.
  564. @par Exception Safety
  565. No-throw guarantee.
  566. */
  567. inline
  568. const_reverse_iterator
  569. rbegin() const noexcept;
  570. /** Return a const reverse iterator to the first element of the reversed container.
  571. The pointed-to element corresponds to the
  572. last element of the non-reversed container.
  573. If the container is empty, @ref crend() is returned.
  574. @par Complexity
  575. Constant.
  576. @par Exception Safety
  577. No-throw guarantee.
  578. */
  579. inline
  580. const_reverse_iterator
  581. crbegin() const noexcept;
  582. /** Return a reverse iterator to the element following the last element of the reversed container.
  583. The pointed-to element corresponds to the element
  584. preceding the first element of the non-reversed container.
  585. This element acts as a placeholder, attempting
  586. to access it results in undefined behavior.
  587. @par Complexity
  588. Constant.
  589. @par Exception Safety
  590. No-throw guarantee.
  591. */
  592. inline
  593. reverse_iterator
  594. rend() noexcept;
  595. /** Return a const reverse iterator to the element following the last element of the reversed container.
  596. The pointed-to element corresponds to the element
  597. preceding the first element of the non-reversed container.
  598. This element acts as a placeholder, attempting
  599. to access it results in undefined behavior.
  600. @par Complexity
  601. Constant.
  602. @par Exception Safety
  603. No-throw guarantee.
  604. */
  605. inline
  606. const_reverse_iterator
  607. rend() const noexcept;
  608. /** Return a const reverse iterator to the element following the last element of the reversed container.
  609. The pointed-to element corresponds to the element
  610. preceding the first element of the non-reversed container.
  611. This element acts as a placeholder, attempting
  612. to access it results in undefined behavior.
  613. @par Complexity
  614. Constant.
  615. @par Exception Safety
  616. No-throw guarantee.
  617. */
  618. inline
  619. const_reverse_iterator
  620. crend() const noexcept;
  621. //------------------------------------------------------
  622. //
  623. // Capacity
  624. //
  625. //------------------------------------------------------
  626. /** Return whether there are no elements.
  627. Returns `true` if there are no elements in
  628. the container, i.e. @ref size() returns 0.
  629. @par Complexity
  630. Constant.
  631. @par Exception Safety
  632. No-throw guarantee.
  633. */
  634. inline
  635. bool
  636. empty() const noexcept;
  637. /** Return the number of elements.
  638. This returns the number of elements in the container.
  639. @par Complexity
  640. Constant.
  641. @par Exception Safety
  642. No-throw guarantee.
  643. */
  644. inline
  645. std::size_t
  646. size() const noexcept;
  647. /** Return the maximum number of elements any object can hold
  648. The maximum is an implementation-defined number dependent
  649. on system or library implementation. This value is a
  650. theoretical limit; at runtime, the actual maximum size
  651. may be less due to resource limits.
  652. @par Complexity
  653. Constant.
  654. @par Exception Safety
  655. No-throw guarantee.
  656. */
  657. static
  658. constexpr
  659. std::size_t
  660. max_size() noexcept;
  661. /** Return the number of elements that can be held in currently allocated memory
  662. This number may be larger than the value returned
  663. by @ref size().
  664. @par Complexity
  665. Constant.
  666. @par Exception Safety
  667. No-throw guarantee.
  668. */
  669. inline
  670. std::size_t
  671. capacity() const noexcept;
  672. /** Increase the capacity to at least a certain amount.
  673. This increases the @ref capacity() to a value
  674. that is greater than or equal to `new_capacity`.
  675. If `new_capacity > capacity()`, new memory is
  676. allocated. Otherwise, the call has no effect.
  677. The number of elements and therefore the
  678. @ref size() of the container is not changed.
  679. \n
  680. If new memory is allocated, all iterators
  681. including any past-the-end iterators, and all
  682. references to the elements are invalidated.
  683. Otherwise, no iterators or references are
  684. invalidated.
  685. @par Complexity
  686. Constant or average case linear in
  687. @ref size(), worst case quadratic.
  688. @par Exception Safety
  689. Strong guarantee.
  690. Calls to `memory_resource::allocate` may throw.
  691. @param new_capacity The new minimum capacity.
  692. @throw system_error `new_capacity > max_size()`
  693. */
  694. inline
  695. void
  696. reserve(std::size_t new_capacity);
  697. //------------------------------------------------------
  698. //
  699. // Modifiers
  700. //
  701. //------------------------------------------------------
  702. /** Erase all elements.
  703. Erases all elements from the container without
  704. changing the capacity.
  705. After this call, @ref size() returns zero.
  706. All references, pointers, and iterators are
  707. invalidated.
  708. @par Complexity
  709. Linear in @ref size().
  710. @par Exception Safety
  711. No-throw guarantee.
  712. */
  713. BOOST_JSON_DECL
  714. void
  715. clear() noexcept;
  716. /** Insert elements.
  717. Inserts `p` if `this->contains(value_type(p).key())` is `false`.
  718. @ref value_type must be constructible from `p`.
  719. If the insertion occurs and results in a rehashing
  720. of the container, all iterators and references are invalidated.
  721. Otherwise, they are not affected.
  722. Rehashing occurs only if the new number of elements
  723. is greater than @ref capacity().
  724. @par Constraints
  725. @code
  726. std::is_constructible_v<value_type, P>
  727. @endcode
  728. @par Complexity
  729. Average case amortized constant,
  730. worst case linear in @ref size().
  731. @par Exception Safety
  732. Strong guarantee.
  733. Calls to `memory_resource::allocate` may throw.
  734. @param p The value to insert.
  735. @throw system_error key is too long.
  736. @throw system_error @ref size() >= max_size().
  737. @return A pair where `first` is an iterator
  738. to the existing or inserted element, and `second`
  739. is `true` if the insertion took place or `false` otherwise.
  740. */
  741. template<class P
  742. #ifndef BOOST_JSON_DOCS
  743. ,class = typename std::enable_if<
  744. std::is_constructible<key_value_pair,
  745. P, storage_ptr>::value>::type
  746. #endif
  747. >
  748. std::pair<iterator, bool>
  749. insert(P&& p);
  750. /** Insert elements.
  751. The elements in the range `[first, last)` are inserted one at a time,
  752. in order. Any element with key that is a duplicate of a key already
  753. present in container will be skipped. This also means, that if there
  754. are two keys within the range that are equal to each other, only the
  755. first will be inserted.
  756. Insertion may result in rehashing of the container. In that case all
  757. iterators and references are invalidated. Otherwise, they are not
  758. affected.
  759. @par Precondition
  760. `first` and `last` are not iterators into `*this`.
  761. `first` and `last` form a valid range.
  762. @par Constraints
  763. @code
  764. std::is_constructible_v<value_type, std::iterator_traits<InputIt>::reference>
  765. @endcode
  766. @par Complexity
  767. Linear in `std::distance(first, last)`.
  768. @par Exception Safety
  769. Strong guarantee for forward iterators, basic guarantee for input
  770. iterators.
  771. Calls to `memory_resource::allocate` may throw.
  772. @param first An input iterator pointing to the first
  773. element to insert, or pointing to the end of the range.
  774. @param last An input iterator pointing to the end
  775. of the range.
  776. @tparam InputIt a type satisfying the requirements
  777. of __InputIterator__.
  778. */
  779. template<
  780. class InputIt
  781. #ifndef BOOST_JSON_DOCS
  782. ,class = is_inputit<InputIt>
  783. #endif
  784. >
  785. void
  786. insert(InputIt first, InputIt last)
  787. {
  788. insert(first, last, typename
  789. std::iterator_traits<InputIt
  790. >::iterator_category{});
  791. }
  792. /** Insert elements.
  793. The elements in the initializer list are inserted one at a time, in
  794. order. Any element with key that is a duplicate of a key already
  795. present in container will be skipped. This also means, that if there
  796. are two keys within the initializer list that are equal to each other,
  797. only the first will be inserted.
  798. Insertion may result in rehashing of the container. In that case all
  799. iterators and references are invalidated. Otherwise, they are not
  800. affected.
  801. @par Complexity
  802. Linear in `init.size()`.
  803. @par Exception Safety
  804. Basic guarantee.
  805. Calls to `memory_resource::allocate` may throw.
  806. @param init The initializer list to insert
  807. */
  808. BOOST_JSON_DECL
  809. void
  810. insert(std::initializer_list<
  811. std::pair<string_view, value_ref>> init);
  812. /** Insert an element or assign to the current element if the key already exists.
  813. If the key equivalent to `key` already exists in the
  814. container, assigns `std::forward<M>(m)` to the
  815. `mapped_type` corresponding to the key. Otherwise,
  816. inserts the new value at the end as if by insert,
  817. constructing it from `value_type(key, std::forward<M>(m))`.
  818. If the insertion occurs and results in a rehashing of the container,
  819. all iterators and references are invalidated. Otherwise, they are not
  820. affected. Rehashing occurs only if the new number of elements is
  821. greater than @ref capacity().
  822. @par Complexity
  823. Amortized constant on average, worst case linear in @ref size().
  824. @par Exception Safety
  825. Strong guarantee.
  826. Calls to `memory_resource::allocate` may throw.
  827. @return A `std::pair` where `first` is an iterator
  828. to the existing or inserted element, and `second`
  829. is `true` if the insertion took place or `false` if
  830. the assignment took place.
  831. @param key The key used for lookup and insertion
  832. @param m The value to insert or assign
  833. @throw system_error if key is too long
  834. */
  835. template<class M>
  836. std::pair<iterator, bool>
  837. insert_or_assign(
  838. string_view key, M&& m);
  839. /** Construct an element in-place.
  840. Inserts a new element into the container constructed
  841. in-place with the given argument if there is no
  842. element with the `key` in the container.
  843. If the insertion occurs and results in a rehashing of the container,
  844. all iterators and references are invalidated. Otherwise, they are not
  845. affected. Rehashing occurs only if the new number of elements is
  846. greater than @ref capacity().
  847. @par Complexity
  848. Amortized constant on average, worst case linear in @ref size().
  849. @par Exception Safety
  850. Strong guarantee.
  851. Calls to `memory_resource::allocate` may throw.
  852. @return A `std::pair` where `first` is an iterator
  853. to the existing or inserted element, and `second`
  854. is `true` if the insertion took place or `false` otherwise.
  855. @param key The key used for lookup and insertion
  856. @param arg The argument used to construct the value.
  857. This will be passed as `std::forward<Arg>(arg)` to
  858. the @ref value constructor.
  859. @throw system_error if key is too long
  860. */
  861. template<class Arg>
  862. std::pair<iterator, bool>
  863. emplace(string_view key, Arg&& arg);
  864. /** Erase an element
  865. Remove the element pointed to by `pos`, which must
  866. be valid and dereferenceable.
  867. References and iterators to the erased element are
  868. invalidated. Other iterators and references are not
  869. invalidated.
  870. @note
  871. The @ref end() iterator (which is valid but cannot be
  872. dereferenced) cannot be used as a value for `pos`.
  873. @par Complexity
  874. Constant on average, worst case linear in @ref size().
  875. @par Exception Safety
  876. No-throw guarantee.
  877. @return An iterator following the removed element.
  878. @param pos An iterator pointing to the element to be
  879. removed.
  880. */
  881. BOOST_JSON_DECL
  882. iterator
  883. erase(const_iterator pos) noexcept;
  884. /** Erase an element
  885. Remove the element which matches `key`, if it exists.
  886. References and iterators to the erased element are
  887. invalidated. Other iterators and references are not
  888. invalidated.
  889. @par Complexity
  890. Constant on average, worst case linear in @ref size().
  891. @par Exception Safety
  892. No-throw guarantee.
  893. @return The number of elements removed, which will
  894. be either 0 or 1.
  895. @param key The key to match.
  896. */
  897. BOOST_JSON_DECL
  898. std::size_t
  899. erase(string_view key) noexcept;
  900. /** Erase an element preserving order
  901. Remove the element pointed to by `pos`, which must
  902. be valid and dereferenceable.
  903. References and iterators from `pos` to `end()`, both
  904. included, are invalidated. Other iterators and references
  905. are not invalidated.
  906. The relative order of remaining elements is preserved.
  907. @note
  908. The @ref end() iterator (which is valid but cannot be
  909. dereferenced) cannot be used as a value for `pos`.
  910. @par Complexity
  911. Linear in @ref size().
  912. @par Exception Safety
  913. No-throw guarantee.
  914. @return An iterator following the removed element.
  915. @param pos An iterator pointing to the element to be
  916. removed.
  917. */
  918. BOOST_JSON_DECL
  919. iterator
  920. stable_erase(const_iterator pos) noexcept;
  921. /** Erase an element preserving order
  922. Remove the element which matches `key`, if it exists.
  923. All references and iterators are invalidated.
  924. The relative order of remaining elements is preserved.
  925. @par Complexity
  926. Linear in @ref size().
  927. @par Exception Safety
  928. No-throw guarantee.
  929. @return The number of elements removed, which will
  930. be either 0 or 1.
  931. @param key The key to match.
  932. */
  933. BOOST_JSON_DECL
  934. std::size_t
  935. stable_erase(string_view key) noexcept;
  936. /** Swap two objects.
  937. Exchanges the contents of this object with another
  938. object. Ownership of the respective @ref memory_resource
  939. objects is not transferred.
  940. @li If `*other.storage() == *this->storage()`,
  941. ownership of the underlying memory is swapped in
  942. constant time, with no possibility of exceptions.
  943. All iterators and references remain valid.
  944. @li If `*other.storage() != *this->storage()`,
  945. the contents are logically swapped by making copies,
  946. which can throw. In this case all iterators and
  947. references are invalidated.
  948. @par Complexity
  949. Constant or linear in @ref size() plus `other.size()`.
  950. @par Exception Safety
  951. Strong guarantee.
  952. Calls to `memory_resource::allocate` may throw.
  953. @param other The object to swap with.
  954. If `this == &other`, this function call has no effect.
  955. */
  956. BOOST_JSON_DECL
  957. void
  958. swap(object& other);
  959. /** Swap two objects.
  960. Exchanges the contents of the object `lhs` with
  961. another object `rhs`. Ownership of the respective
  962. @ref memory_resource objects is not transferred.
  963. @li If `*lhs.storage() == *rhs.storage()`,
  964. ownership of the underlying memory is swapped in
  965. constant time, with no possibility of exceptions.
  966. All iterators and references remain valid.
  967. @li If `*lhs.storage() != *rhs.storage()`,
  968. the contents are logically swapped by making a copy,
  969. which can throw. In this case all iterators and
  970. references are invalidated.
  971. @par Effects
  972. @code
  973. lhs.swap( rhs );
  974. @endcode
  975. @par Complexity
  976. Constant or linear in `lhs.size() + rhs.size()`.
  977. @par Exception Safety
  978. Strong guarantee.
  979. Calls to `memory_resource::allocate` may throw.
  980. @param lhs The object to exchange.
  981. @param rhs The object to exchange.
  982. If `&lhs == &rhs`, this function call has no effect.
  983. @see @ref object::swap
  984. */
  985. friend
  986. void
  987. swap(object& lhs, object& rhs)
  988. {
  989. lhs.swap(rhs);
  990. }
  991. //------------------------------------------------------
  992. //
  993. // Lookup
  994. //
  995. //------------------------------------------------------
  996. /** Access the specified element, with bounds checking.
  997. Returns a reference to the mapped value of the element
  998. that matches `key`, otherwise throws.
  999. @par Complexity
  1000. Constant on average, worst case linear in @ref size().
  1001. @par Exception Safety
  1002. Strong guarantee.
  1003. @return A reference to the mapped value.
  1004. @param key The key of the element to find.
  1005. @throw system_error if no such element exists.
  1006. */
  1007. /* @{ */
  1008. inline
  1009. value&
  1010. at(string_view key) &;
  1011. inline
  1012. value&&
  1013. at(string_view key) &&;
  1014. inline
  1015. value const&
  1016. at(string_view key) const&;
  1017. /* @} */
  1018. /** Access or insert the specified element
  1019. Returns a reference to the value that is mapped
  1020. to a key equivalent to key, performing an insertion
  1021. of a null value if such key does not already exist.
  1022. \n
  1023. If an insertion occurs and results in a rehashing of
  1024. the container, all iterators are invalidated. Otherwise
  1025. iterators are not affected. References are not
  1026. invalidated. Rehashing occurs only if the new
  1027. number of elements is greater than @ref capacity().
  1028. @par Complexity
  1029. Constant on average, worst case linear in @ref size().
  1030. @par Exception Safety
  1031. Strong guarantee.
  1032. Calls to `memory_resource::allocate` may throw.
  1033. @return A reference to the mapped value.
  1034. @param key The key of the element to find.
  1035. */
  1036. BOOST_JSON_DECL
  1037. value&
  1038. operator[](string_view key);
  1039. /** Count the number of elements with a specific key
  1040. This function returns the count of the number of
  1041. elements match `key`. The only possible return values
  1042. are 0 and 1.
  1043. @par Complexity
  1044. Constant on average, worst case linear in @ref size().
  1045. @par Exception Safety
  1046. No-throw guarantee.
  1047. @param key The key of the element to find.
  1048. */
  1049. BOOST_JSON_DECL
  1050. std::size_t
  1051. count(string_view key) const noexcept;
  1052. /** Find an element with a specific key
  1053. This function returns an iterator to the element
  1054. matching `key` if it exists, otherwise returns
  1055. @ref end().
  1056. @par Complexity
  1057. Constant on average, worst case linear in @ref size().
  1058. @par Exception Safety
  1059. No-throw guarantee.
  1060. @param key The key of the element to find.
  1061. */
  1062. BOOST_JSON_DECL
  1063. iterator
  1064. find(string_view key) noexcept;
  1065. /** Find an element with a specific key
  1066. This function returns a constant iterator to
  1067. the element matching `key` if it exists,
  1068. otherwise returns @ref end().
  1069. @par Complexity
  1070. Constant on average, worst case linear in @ref size().
  1071. @par Exception Safety
  1072. No-throw guarantee.
  1073. @param key The key of the element to find.
  1074. */
  1075. BOOST_JSON_DECL
  1076. const_iterator
  1077. find(string_view key) const noexcept;
  1078. /** Return `true` if the key is found
  1079. This function returns `true` if a key with the
  1080. specified string is found.
  1081. @par Effects
  1082. @code
  1083. return this->find(key) != this->end();
  1084. @endcode
  1085. @par Complexity
  1086. Constant on average, worst case linear in @ref size().
  1087. @par Exception Safety
  1088. No-throw guarantee.
  1089. @param key The key of the element to find.
  1090. @see @ref find
  1091. */
  1092. BOOST_JSON_DECL
  1093. bool
  1094. contains(string_view key) const noexcept;
  1095. /** Return a pointer to the value if the key is found, or null
  1096. This function searches for a value with the given
  1097. key, and returns a pointer to it if found. Otherwise
  1098. it returns null.
  1099. @par Example
  1100. @code
  1101. if( auto p = obj.if_contains( "key" ) )
  1102. std::cout << *p;
  1103. @endcode
  1104. @par Complexity
  1105. Constant on average, worst case linear in @ref size().
  1106. @par Exception Safety
  1107. No-throw guarantee.
  1108. @param key The key of the element to find.
  1109. @see @ref find
  1110. */
  1111. BOOST_JSON_DECL
  1112. value const*
  1113. if_contains(string_view key) const noexcept;
  1114. /** Return a pointer to the value if the key is found, or null
  1115. This function searches for a value with the given
  1116. key, and returns a pointer to it if found. Otherwise
  1117. it returns null.
  1118. @par Example
  1119. @code
  1120. if( auto p = obj.if_contains( "key" ) )
  1121. std::cout << *p;
  1122. @endcode
  1123. @par Complexity
  1124. Constant on average, worst case linear in @ref size().
  1125. @par Exception Safety
  1126. No-throw guarantee.
  1127. @param key The key of the element to find.
  1128. @see @ref find
  1129. */
  1130. BOOST_JSON_DECL
  1131. value*
  1132. if_contains(string_view key) noexcept;
  1133. /** Return `true` if two objects are equal.
  1134. Objects are equal when their sizes are the same,
  1135. and when for each key in `lhs` there is a matching
  1136. key in `rhs` with the same value.
  1137. @par Complexity
  1138. Constant, or linear (worst case quadratic) in `lhs.size()`.
  1139. @par Exception Safety
  1140. No-throw guarantee.
  1141. */
  1142. // inline friend speeds up overload resolution
  1143. friend
  1144. bool
  1145. operator==(
  1146. object const& lhs,
  1147. object const& rhs) noexcept
  1148. {
  1149. return lhs.equal(rhs);
  1150. }
  1151. /** Return `true` if two objects are not equal.
  1152. Objects are equal when their sizes are the same,
  1153. and when for each key in `lhs` there is a matching
  1154. key in `rhs` with the same value.
  1155. @par Complexity
  1156. Constant, or linear (worst case quadratic) in `lhs.size()`.
  1157. @par Exception Safety
  1158. No-throw guarantee.
  1159. */
  1160. // inline friend speeds up overload resolution
  1161. friend
  1162. bool
  1163. operator!=(
  1164. object const& lhs,
  1165. object const& rhs) noexcept
  1166. {
  1167. return ! (lhs == rhs);
  1168. }
  1169. /** Serialize @ref object to an output stream.
  1170. This function serializes an `object` as JSON into the output stream.
  1171. @return Reference to `os`.
  1172. @par Complexity
  1173. Constant or linear in the size of `obj`.
  1174. @par Exception Safety
  1175. Strong guarantee.
  1176. Calls to `memory_resource::allocate` may throw.
  1177. @param os The output stream to serialize to.
  1178. @param obj The value to serialize.
  1179. */
  1180. BOOST_JSON_DECL
  1181. friend
  1182. std::ostream&
  1183. operator<<(
  1184. std::ostream& os,
  1185. object const& obj);
  1186. private:
  1187. #ifndef BOOST_JSON_DOCS
  1188. // VFALCO friending a detail function makes it public
  1189. template<class CharRange>
  1190. friend
  1191. std::pair<key_value_pair*, std::size_t>
  1192. detail::find_in_object(
  1193. object const& obj,
  1194. CharRange key) noexcept;
  1195. #endif
  1196. template<class InputIt>
  1197. void
  1198. construct(
  1199. InputIt first,
  1200. InputIt last,
  1201. std::size_t min_capacity,
  1202. std::input_iterator_tag);
  1203. template<class InputIt>
  1204. void
  1205. construct(
  1206. InputIt first,
  1207. InputIt last,
  1208. std::size_t min_capacity,
  1209. std::forward_iterator_tag);
  1210. template<class InputIt>
  1211. void
  1212. insert(
  1213. InputIt first,
  1214. InputIt last,
  1215. std::input_iterator_tag);
  1216. template<class InputIt>
  1217. void
  1218. insert(
  1219. InputIt first,
  1220. InputIt last,
  1221. std::forward_iterator_tag);
  1222. template< class... Args >
  1223. std::pair<iterator, bool>
  1224. emplace_impl(string_view key, Args&& ... args );
  1225. BOOST_JSON_DECL
  1226. key_value_pair*
  1227. insert_impl(
  1228. pilfered<key_value_pair> p,
  1229. std::size_t hash);
  1230. BOOST_JSON_DECL
  1231. table*
  1232. reserve_impl(std::size_t new_capacity);
  1233. BOOST_JSON_DECL
  1234. bool
  1235. equal(object const& other) const noexcept;
  1236. inline
  1237. std::size_t
  1238. growth(
  1239. std::size_t new_size) const;
  1240. inline
  1241. void
  1242. remove(
  1243. index_t& head,
  1244. key_value_pair& p) noexcept;
  1245. inline
  1246. void
  1247. destroy() noexcept;
  1248. inline
  1249. void
  1250. destroy(
  1251. key_value_pair* first,
  1252. key_value_pair* last) noexcept;
  1253. template<class FS, class FB>
  1254. auto
  1255. do_erase(
  1256. const_iterator pos,
  1257. FS small_reloc,
  1258. FB big_reloc) noexcept
  1259. -> iterator;
  1260. inline
  1261. void
  1262. reindex_relocate(
  1263. key_value_pair* src,
  1264. key_value_pair* dst) noexcept;
  1265. };
  1266. } // namespace json
  1267. } // namespace boost
  1268. #ifndef BOOST_JSON_DOCS
  1269. // boost::hash trait
  1270. namespace boost
  1271. {
  1272. namespace container_hash
  1273. {
  1274. template< class T > struct is_unordered_range;
  1275. template<>
  1276. struct is_unordered_range< json::object >
  1277. : std::true_type
  1278. {};
  1279. } // namespace container_hash
  1280. } // namespace boost
  1281. // std::hash specialization
  1282. namespace std {
  1283. template <>
  1284. struct hash< ::boost::json::object > {
  1285. BOOST_JSON_DECL
  1286. std::size_t
  1287. operator()(::boost::json::object const& jo) const noexcept;
  1288. };
  1289. } // std
  1290. #endif
  1291. // Must be included here for this file to stand alone
  1292. #include <boost/json/value.hpp>
  1293. // includes are at the bottom of <boost/json/value.hpp>
  1294. #endif