object.hpp 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684
  1. //
  2. // Copyright (c) 2019 Vinnie Falco ([email protected])
  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. /** Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
  82. This type is a `boost::container::pmr::polymorphic_allocator`.
  83. */
  84. #ifdef BOOST_JSON_DOCS
  85. using allocator_type = __see_below__;
  86. #else
  87. // VFALCO doc toolchain renders this incorrectly
  88. using allocator_type = container::pmr::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, any used memory is
  124. deallocated, and shared ownership of the
  125. `boost::container::pmr::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 `boost::container::pmr::memory_resource` to
  155. use. The container will acquire shared ownership of the memory
  156. 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 `boost::container::pmr::memory_resource` to
  177. use. The container will acquire shared ownership of the memory
  178. 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 `boost::container::pmr::memory_resource` to
  214. use. The container will acquire shared ownership of the memory
  215. 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 `boost::container::pmr::memory_resource` to
  275. use. The container will acquire shared ownership of the memory
  276. 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 `boost::container::pmr::memory_resource` to
  330. use. The container will acquire shared ownership of the memory
  331. 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 `boost::container::pmr::memory_resource` to
  352. use. The container will acquire shared ownership of the memory
  353. 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 `boost::container::pmr::memory_resource` to
  384. use. The container will acquire shared ownership of the memory
  385. 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 memory resource.
  452. This function returns the `boost::container::pmr::memory_resource` used
  453. by 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 allocator.
  465. This function returns an instance of @ref allocator_type constructed
  466. from the associated `boost::container::pmr::memory_resource`.
  467. @par Complexity
  468. Constant.
  469. @par Exception Safety
  470. No-throw guarantee.
  471. */
  472. allocator_type
  473. get_allocator() const noexcept
  474. {
  475. return sp_.get();
  476. }
  477. //------------------------------------------------------
  478. //
  479. // Iterators
  480. //
  481. //------------------------------------------------------
  482. /** Return an iterator to the first element.
  483. If the container is empty, @ref end() is returned.
  484. @par Complexity
  485. Constant.
  486. @par Exception Safety
  487. No-throw guarantee.
  488. */
  489. inline
  490. iterator
  491. begin() noexcept;
  492. /** Return a const iterator to the first element.
  493. If the container is empty, @ref end() is returned.
  494. @par Complexity
  495. Constant.
  496. @par Exception Safety
  497. No-throw guarantee.
  498. */
  499. inline
  500. const_iterator
  501. begin() const noexcept;
  502. /** Return a const iterator to the first element.
  503. If the container is empty, @ref cend() is returned.
  504. @par Complexity
  505. Constant.
  506. @par Exception Safety
  507. No-throw guarantee.
  508. */
  509. inline
  510. const_iterator
  511. cbegin() const noexcept;
  512. /** Return an iterator to the element following the last element.
  513. The element acts as a placeholder; attempting
  514. to access it results in undefined behavior.
  515. @par Complexity
  516. Constant.
  517. @par Exception Safety
  518. No-throw guarantee.
  519. */
  520. inline
  521. iterator
  522. end() noexcept;
  523. /** Return a const iterator to the element following the last element.
  524. The element acts as a placeholder; attempting
  525. to access it results in undefined behavior.
  526. @par Complexity
  527. Constant.
  528. @par Exception Safety
  529. No-throw guarantee.
  530. */
  531. inline
  532. const_iterator
  533. end() const noexcept;
  534. /** Return a const iterator to the element following the last element.
  535. The element acts as a placeholder; attempting
  536. to access it results in undefined behavior.
  537. @par Complexity
  538. Constant.
  539. @par Exception Safety
  540. No-throw guarantee.
  541. */
  542. inline
  543. const_iterator
  544. cend() const noexcept;
  545. /** Return a reverse iterator to the first element of the reversed container.
  546. The pointed-to element corresponds to the
  547. last element of the non-reversed container.
  548. If the container is empty, @ref rend() is returned.
  549. @par Complexity
  550. Constant.
  551. @par Exception Safety
  552. No-throw guarantee.
  553. */
  554. inline
  555. reverse_iterator
  556. rbegin() noexcept;
  557. /** Return a const reverse iterator to the first element of the reversed container.
  558. The pointed-to element corresponds to the
  559. last element of the non-reversed container.
  560. If the container is empty, @ref rend() is returned.
  561. @par Complexity
  562. Constant.
  563. @par Exception Safety
  564. No-throw guarantee.
  565. */
  566. inline
  567. const_reverse_iterator
  568. rbegin() const noexcept;
  569. /** Return a const reverse iterator to the first element of the reversed container.
  570. The pointed-to element corresponds to the
  571. last element of the non-reversed container.
  572. If the container is empty, @ref crend() is returned.
  573. @par Complexity
  574. Constant.
  575. @par Exception Safety
  576. No-throw guarantee.
  577. */
  578. inline
  579. const_reverse_iterator
  580. crbegin() const noexcept;
  581. /** Return a reverse iterator to the element following the last element of the reversed container.
  582. The pointed-to element corresponds to the element
  583. preceding the first element of the non-reversed container.
  584. This element acts as a placeholder, attempting
  585. to access it results in undefined behavior.
  586. @par Complexity
  587. Constant.
  588. @par Exception Safety
  589. No-throw guarantee.
  590. */
  591. inline
  592. reverse_iterator
  593. rend() noexcept;
  594. /** Return a const reverse iterator to the element following the last element of the reversed container.
  595. The pointed-to element corresponds to the element
  596. preceding the first element of the non-reversed container.
  597. This element acts as a placeholder, attempting
  598. to access it results in undefined behavior.
  599. @par Complexity
  600. Constant.
  601. @par Exception Safety
  602. No-throw guarantee.
  603. */
  604. inline
  605. const_reverse_iterator
  606. rend() const noexcept;
  607. /** Return a const reverse iterator to the element following the last element of the reversed container.
  608. The pointed-to element corresponds to the element
  609. preceding the first element of the non-reversed container.
  610. This element acts as a placeholder, attempting
  611. to access it results in undefined behavior.
  612. @par Complexity
  613. Constant.
  614. @par Exception Safety
  615. No-throw guarantee.
  616. */
  617. inline
  618. const_reverse_iterator
  619. crend() const noexcept;
  620. //------------------------------------------------------
  621. //
  622. // Capacity
  623. //
  624. //------------------------------------------------------
  625. /** Return whether there are no elements.
  626. Returns `true` if there are no elements in
  627. the container, i.e. @ref size() returns 0.
  628. @par Complexity
  629. Constant.
  630. @par Exception Safety
  631. No-throw guarantee.
  632. */
  633. inline
  634. bool
  635. empty() const noexcept;
  636. /** Return the number of elements.
  637. This returns the number of elements in the container.
  638. @par Complexity
  639. Constant.
  640. @par Exception Safety
  641. No-throw guarantee.
  642. */
  643. inline
  644. std::size_t
  645. size() const noexcept;
  646. /** Return the maximum number of elements any object can hold
  647. The maximum is an implementation-defined number dependent
  648. on system or library implementation. This value is a
  649. theoretical limit; at runtime, the actual maximum size
  650. may be less due to resource limits.
  651. @par Complexity
  652. Constant.
  653. @par Exception Safety
  654. No-throw guarantee.
  655. */
  656. static
  657. constexpr
  658. std::size_t
  659. max_size() noexcept;
  660. /** Return the number of elements that can be held in currently allocated memory
  661. This number may be larger than the value returned
  662. by @ref size().
  663. @par Complexity
  664. Constant.
  665. @par Exception Safety
  666. No-throw guarantee.
  667. */
  668. inline
  669. std::size_t
  670. capacity() const noexcept;
  671. /** Increase the capacity to at least a certain amount.
  672. This increases the @ref capacity() to a value
  673. that is greater than or equal to `new_capacity`.
  674. If `new_capacity > capacity()`, new memory is
  675. allocated. Otherwise, the call has no effect.
  676. The number of elements and therefore the
  677. @ref size() of the container is not changed.
  678. \n
  679. If new memory is allocated, all iterators
  680. including any past-the-end iterators, and all
  681. references to the elements are invalidated.
  682. Otherwise, no iterators or references are
  683. invalidated.
  684. @par Complexity
  685. Constant or average case linear in
  686. @ref size(), worst case quadratic.
  687. @par Exception Safety
  688. Strong guarantee.
  689. Calls to `memory_resource::allocate` may throw.
  690. @param new_capacity The new minimum capacity.
  691. @throw `boost::system::system_error` `new_capacity > max_size()`.
  692. */
  693. inline
  694. void
  695. reserve(std::size_t new_capacity);
  696. //------------------------------------------------------
  697. //
  698. // Modifiers
  699. //
  700. //------------------------------------------------------
  701. /** Erase all elements.
  702. Erases all elements from the container without
  703. changing the capacity.
  704. After this call, @ref size() returns zero.
  705. All references, pointers, and iterators are
  706. invalidated.
  707. @par Complexity
  708. Linear in @ref size().
  709. @par Exception Safety
  710. No-throw guarantee.
  711. */
  712. BOOST_JSON_DECL
  713. void
  714. clear() noexcept;
  715. /** Insert elements.
  716. Inserts `p` if `this->contains(value_type(p).key())` is `false`.
  717. @ref value_type must be constructible from `p`.
  718. If the insertion occurs and results in a rehashing
  719. of the container, all iterators and references are invalidated.
  720. Otherwise, they are not affected.
  721. Rehashing occurs only if the new number of elements
  722. is greater than @ref capacity().
  723. @par Constraints
  724. @code
  725. std::is_constructible_v<value_type, P>
  726. @endcode
  727. @par Complexity
  728. Average case amortized constant,
  729. worst case linear in @ref size().
  730. @par Exception Safety
  731. Strong guarantee.
  732. Calls to `memory_resource::allocate` may throw.
  733. @param p The value to insert.
  734. @throw `boost::system::system_error` key is too long.
  735. @throw `boost::system::system_error` @ref size() >= max_size().
  736. @return A pair where `first` is an iterator
  737. to the existing or inserted element, and `second`
  738. is `true` if the insertion took place or `false` otherwise.
  739. */
  740. template<class P
  741. #ifndef BOOST_JSON_DOCS
  742. ,class = typename std::enable_if<
  743. std::is_constructible<key_value_pair,
  744. P, storage_ptr>::value>::type
  745. #endif
  746. >
  747. std::pair<iterator, bool>
  748. insert(P&& p);
  749. /** Insert elements.
  750. The elements in the range `[first, last)` are inserted one at a time,
  751. in order. Any element with key that is a duplicate of a key already
  752. present in container will be skipped. This also means, that if there
  753. are two keys within the range that are equal to each other, only the
  754. first will be inserted.
  755. Insertion may result in rehashing of the container. In that case all
  756. iterators and references are invalidated. Otherwise, they are not
  757. affected.
  758. @par Precondition
  759. `first` and `last` are not iterators into `*this`.
  760. `first` and `last` form a valid range.
  761. @par Constraints
  762. @code
  763. std::is_constructible_v<value_type, std::iterator_traits<InputIt>::reference>
  764. @endcode
  765. @par Complexity
  766. Linear in `std::distance(first, last)`.
  767. @par Exception Safety
  768. Strong guarantee for forward iterators, basic guarantee for input
  769. iterators.
  770. Calls to `memory_resource::allocate` may throw.
  771. @param first An input iterator pointing to the first
  772. element to insert, or pointing to the end of the range.
  773. @param last An input iterator pointing to the end
  774. of the range.
  775. @tparam InputIt a type satisfying the requirements
  776. of __InputIterator__.
  777. */
  778. template<
  779. class InputIt
  780. #ifndef BOOST_JSON_DOCS
  781. ,class = is_inputit<InputIt>
  782. #endif
  783. >
  784. void
  785. insert(InputIt first, InputIt last)
  786. {
  787. insert(first, last, typename
  788. std::iterator_traits<InputIt
  789. >::iterator_category{});
  790. }
  791. /** Insert elements.
  792. The elements in the initializer list are inserted one at a time, in
  793. order. Any element with key that is a duplicate of a key already
  794. present in container will be skipped. This also means, that if there
  795. are two keys within the initializer list that are equal to each other,
  796. only the first will be inserted.
  797. Insertion may result in rehashing of the container. In that case all
  798. iterators and references are invalidated. Otherwise, they are not
  799. affected.
  800. @par Complexity
  801. Linear in `init.size()`.
  802. @par Exception Safety
  803. Basic guarantee.
  804. Calls to `memory_resource::allocate` may throw.
  805. @param init The initializer list to insert
  806. */
  807. BOOST_JSON_DECL
  808. void
  809. insert(std::initializer_list<
  810. std::pair<string_view, value_ref>> init);
  811. /** Insert an element or assign to the current element if the key already exists.
  812. If the key equivalent to `key` already exists in the
  813. container, assigns `std::forward<M>(m)` to the
  814. `mapped_type` corresponding to the key. Otherwise,
  815. inserts the new value at the end as if by insert,
  816. constructing it from `value_type(key, std::forward<M>(m))`.
  817. If the insertion occurs and results in a rehashing of the container,
  818. all iterators and references are invalidated. Otherwise, they are not
  819. affected. Rehashing occurs only if the new number of elements is
  820. greater than @ref capacity().
  821. @par Complexity
  822. Amortized constant on average, worst case linear in @ref size().
  823. @par Exception Safety
  824. Strong guarantee.
  825. Calls to `memory_resource::allocate` may throw.
  826. @return A `std::pair` where `first` is an iterator
  827. to the existing or inserted element, and `second`
  828. is `true` if the insertion took place or `false` if
  829. the assignment took place.
  830. @param key The key used for lookup and insertion
  831. @param m The value to insert or assign
  832. @throw `boost::system::system_error` if key is too long.
  833. */
  834. template<class M>
  835. std::pair<iterator, bool>
  836. insert_or_assign(
  837. string_view key, M&& m);
  838. /** Construct an element in-place.
  839. Inserts a new element into the container constructed
  840. in-place with the given argument if there is no
  841. element with the `key` in the container.
  842. If the insertion occurs and results in a rehashing of the container,
  843. all iterators and references are invalidated. Otherwise, they are not
  844. affected. Rehashing occurs only if the new number of elements is
  845. greater than @ref capacity().
  846. @par Complexity
  847. Amortized constant on average, worst case linear in @ref size().
  848. @par Exception Safety
  849. Strong guarantee.
  850. Calls to `memory_resource::allocate` may throw.
  851. @return A `std::pair` where `first` is an iterator
  852. to the existing or inserted element, and `second`
  853. is `true` if the insertion took place or `false` otherwise.
  854. @param key The key used for lookup and insertion
  855. @param arg The argument used to construct the value.
  856. This will be passed as `std::forward<Arg>(arg)` to
  857. the @ref value constructor.
  858. @throw `boost::system::system_error` if key is too long.
  859. */
  860. template<class Arg>
  861. std::pair<iterator, bool>
  862. emplace(string_view key, Arg&& arg);
  863. /** Erase an element
  864. Remove the element pointed to by `pos`, which must
  865. be valid and dereferenceable.
  866. References and iterators to the erased element are
  867. invalidated. Other iterators and references are not
  868. invalidated.
  869. @note
  870. The @ref end() iterator (which is valid but cannot be
  871. dereferenced) cannot be used as a value for `pos`.
  872. @par Complexity
  873. Constant on average, worst case linear in @ref size().
  874. @par Exception Safety
  875. No-throw guarantee.
  876. @return An iterator following the removed element.
  877. @param pos An iterator pointing to the element to be
  878. removed.
  879. */
  880. BOOST_JSON_DECL
  881. iterator
  882. erase(const_iterator pos) noexcept;
  883. /** Erase an element
  884. Remove the element which matches `key`, if it exists.
  885. References and iterators to the erased element are
  886. invalidated. Other iterators and references are not
  887. invalidated.
  888. @par Complexity
  889. Constant on average, worst case linear in @ref size().
  890. @par Exception Safety
  891. No-throw guarantee.
  892. @return The number of elements removed, which will
  893. be either 0 or 1.
  894. @param key The key to match.
  895. */
  896. BOOST_JSON_DECL
  897. std::size_t
  898. erase(string_view key) noexcept;
  899. /** Erase an element preserving order
  900. Remove the element pointed to by `pos`, which must
  901. be valid and dereferenceable.
  902. References and iterators from `pos` to `end()`, both
  903. included, are invalidated. Other iterators and references
  904. are not invalidated.
  905. The relative order of remaining elements is preserved.
  906. @note
  907. The @ref end() iterator (which is valid but cannot be
  908. dereferenced) cannot be used as a value for `pos`.
  909. @par Complexity
  910. Linear in @ref size().
  911. @par Exception Safety
  912. No-throw guarantee.
  913. @return An iterator following the removed element.
  914. @param pos An iterator pointing to the element to be
  915. removed.
  916. */
  917. BOOST_JSON_DECL
  918. iterator
  919. stable_erase(const_iterator pos) noexcept;
  920. /** Erase an element preserving order
  921. Remove the element which matches `key`, if it exists.
  922. All references and iterators are invalidated.
  923. The relative order of remaining elements is preserved.
  924. @par Complexity
  925. Linear in @ref size().
  926. @par Exception Safety
  927. No-throw guarantee.
  928. @return The number of elements removed, which will
  929. be either 0 or 1.
  930. @param key The key to match.
  931. */
  932. BOOST_JSON_DECL
  933. std::size_t
  934. stable_erase(string_view key) noexcept;
  935. /** Swap two objects.
  936. Exchanges the contents of this object with another object. Ownership of
  937. the respective `boost::container::pmr::memory_resource` objects is not
  938. transferred.
  939. @li If `*other.storage() == *this->storage()`,
  940. ownership of the underlying memory is swapped in
  941. constant time, with no possibility of exceptions.
  942. All iterators and references remain valid.
  943. @li If `*other.storage() != *this->storage()`,
  944. the contents are logically swapped by making copies,
  945. which can throw. In this case all iterators and
  946. references are invalidated.
  947. @par Complexity
  948. Constant or linear in @ref size() plus `other.size()`.
  949. @par Exception Safety
  950. Strong guarantee.
  951. Calls to `memory_resource::allocate` may throw.
  952. @param other The object to swap with.
  953. If `this == &other`, this function call has no effect.
  954. */
  955. BOOST_JSON_DECL
  956. void
  957. swap(object& other);
  958. /** Swap two objects.
  959. Exchanges the contents of the object `lhs` with another object `rhs`.
  960. Ownership of the respective `boost::container::pmr::memory_resource`
  961. objects is not transferred.
  962. @li If `*lhs.storage() == *rhs.storage()`,
  963. ownership of the underlying memory is swapped in
  964. constant time, with no possibility of exceptions.
  965. All iterators and references remain valid.
  966. @li If `*lhs.storage() != *rhs.storage()`,
  967. the contents are logically swapped by making a copy,
  968. which can throw. In this case all iterators and
  969. references are invalidated.
  970. @par Effects
  971. @code
  972. lhs.swap( rhs );
  973. @endcode
  974. @par Complexity
  975. Constant or linear in `lhs.size() + rhs.size()`.
  976. @par Exception Safety
  977. Strong guarantee.
  978. Calls to `memory_resource::allocate` may throw.
  979. @param lhs The object to exchange.
  980. @param rhs The object to exchange.
  981. If `&lhs == &rhs`, this function call has no effect.
  982. @see @ref object::swap
  983. */
  984. friend
  985. void
  986. swap(object& lhs, object& rhs)
  987. {
  988. lhs.swap(rhs);
  989. }
  990. //------------------------------------------------------
  991. //
  992. // Lookup
  993. //
  994. //------------------------------------------------------
  995. /** Access the specified element, with bounds checking.
  996. Returns a reference to the mapped value of the element
  997. that matches `key`, otherwise throws.
  998. @par Complexity
  999. Constant on average, worst case linear in @ref size().
  1000. @par Exception Safety
  1001. Strong guarantee.
  1002. @return A reference to the mapped value.
  1003. @param key The key of the element to find.
  1004. @throw `boost::system::system_error` if no such element exists.
  1005. */
  1006. /* @{ */
  1007. inline
  1008. value&
  1009. at(string_view key) &;
  1010. inline
  1011. value&&
  1012. at(string_view key) &&;
  1013. inline
  1014. value const&
  1015. at(string_view key) const&;
  1016. /* @} */
  1017. /** Access or insert the specified element
  1018. Returns a reference to the value that is mapped
  1019. to a key equivalent to key, performing an insertion
  1020. of a null value if such key does not already exist.
  1021. \n
  1022. If an insertion occurs and results in a rehashing of
  1023. the container, all iterators are invalidated. Otherwise
  1024. iterators are not affected. References are not
  1025. invalidated. Rehashing occurs only if the new
  1026. number of elements is greater than @ref capacity().
  1027. @par Complexity
  1028. Constant on average, worst case linear in @ref size().
  1029. @par Exception Safety
  1030. Strong guarantee.
  1031. Calls to `memory_resource::allocate` may throw.
  1032. @return A reference to the mapped value.
  1033. @param key The key of the element to find.
  1034. */
  1035. BOOST_JSON_DECL
  1036. value&
  1037. operator[](string_view key);
  1038. /** Count the number of elements with a specific key
  1039. This function returns the count of the number of
  1040. elements match `key`. The only possible return values
  1041. are 0 and 1.
  1042. @par Complexity
  1043. Constant on average, worst case linear in @ref size().
  1044. @par Exception Safety
  1045. No-throw guarantee.
  1046. @param key The key of the element to find.
  1047. */
  1048. BOOST_JSON_DECL
  1049. std::size_t
  1050. count(string_view key) const noexcept;
  1051. /** Find an element with a specific key
  1052. This function returns an iterator to the element
  1053. matching `key` if it exists, otherwise returns
  1054. @ref end().
  1055. @par Complexity
  1056. Constant on average, worst case linear in @ref size().
  1057. @par Exception Safety
  1058. No-throw guarantee.
  1059. @param key The key of the element to find.
  1060. */
  1061. BOOST_JSON_DECL
  1062. iterator
  1063. find(string_view key) noexcept;
  1064. /** Find an element with a specific key
  1065. This function returns a constant iterator to
  1066. the element matching `key` if it exists,
  1067. otherwise returns @ref end().
  1068. @par Complexity
  1069. Constant on average, worst case linear in @ref size().
  1070. @par Exception Safety
  1071. No-throw guarantee.
  1072. @param key The key of the element to find.
  1073. */
  1074. BOOST_JSON_DECL
  1075. const_iterator
  1076. find(string_view key) const noexcept;
  1077. /** Return `true` if the key is found
  1078. This function returns `true` if a key with the
  1079. specified string is found.
  1080. @par Effects
  1081. @code
  1082. return this->find(key) != this->end();
  1083. @endcode
  1084. @par Complexity
  1085. Constant on average, worst case linear in @ref size().
  1086. @par Exception Safety
  1087. No-throw guarantee.
  1088. @param key The key of the element to find.
  1089. @see @ref find
  1090. */
  1091. BOOST_JSON_DECL
  1092. bool
  1093. contains(string_view key) const noexcept;
  1094. /** Return a pointer to the value if the key is found, or null
  1095. This function searches for a value with the given
  1096. key, and returns a pointer to it if found. Otherwise
  1097. it returns null.
  1098. @par Example
  1099. @code
  1100. if( auto p = obj.if_contains( "key" ) )
  1101. std::cout << *p;
  1102. @endcode
  1103. @par Complexity
  1104. Constant on average, worst case linear in @ref size().
  1105. @par Exception Safety
  1106. No-throw guarantee.
  1107. @param key The key of the element to find.
  1108. @see @ref find
  1109. */
  1110. BOOST_JSON_DECL
  1111. value const*
  1112. if_contains(string_view key) const noexcept;
  1113. /** Return a pointer to the value if the key is found, or null
  1114. This function searches for a value with the given
  1115. key, and returns a pointer to it if found. Otherwise
  1116. it returns null.
  1117. @par Example
  1118. @code
  1119. if( auto p = obj.if_contains( "key" ) )
  1120. std::cout << *p;
  1121. @endcode
  1122. @par Complexity
  1123. Constant on average, worst case linear in @ref size().
  1124. @par Exception Safety
  1125. No-throw guarantee.
  1126. @param key The key of the element to find.
  1127. @see @ref find
  1128. */
  1129. BOOST_JSON_DECL
  1130. value*
  1131. if_contains(string_view key) noexcept;
  1132. /** Return `true` if two objects are equal.
  1133. Objects are equal when their sizes are the same,
  1134. and when for each key in `lhs` there is a matching
  1135. key in `rhs` with the same value.
  1136. @par Complexity
  1137. Constant, or linear (worst case quadratic) in `lhs.size()`.
  1138. @par Exception Safety
  1139. No-throw guarantee.
  1140. */
  1141. // inline friend speeds up overload resolution
  1142. friend
  1143. bool
  1144. operator==(
  1145. object const& lhs,
  1146. object const& rhs) noexcept
  1147. {
  1148. return lhs.equal(rhs);
  1149. }
  1150. /** Return `true` if two objects are not equal.
  1151. Objects are equal when their sizes are the same,
  1152. and when for each key in `lhs` there is a matching
  1153. key in `rhs` with the same value.
  1154. @par Complexity
  1155. Constant, or linear (worst case quadratic) in `lhs.size()`.
  1156. @par Exception Safety
  1157. No-throw guarantee.
  1158. */
  1159. // inline friend speeds up overload resolution
  1160. friend
  1161. bool
  1162. operator!=(
  1163. object const& lhs,
  1164. object const& rhs) noexcept
  1165. {
  1166. return ! (lhs == rhs);
  1167. }
  1168. /** Serialize @ref object to an output stream.
  1169. This function serializes an `object` as JSON into the output stream.
  1170. @return Reference to `os`.
  1171. @par Complexity
  1172. Constant or linear in the size of `obj`.
  1173. @par Exception Safety
  1174. Strong guarantee.
  1175. Calls to `memory_resource::allocate` may throw.
  1176. @param os The output stream to serialize to.
  1177. @param obj The value to serialize.
  1178. */
  1179. BOOST_JSON_DECL
  1180. friend
  1181. std::ostream&
  1182. operator<<(
  1183. std::ostream& os,
  1184. object const& obj);
  1185. private:
  1186. #ifndef BOOST_JSON_DOCS
  1187. // VFALCO friending a detail function makes it public
  1188. template<class CharRange>
  1189. friend
  1190. std::pair<key_value_pair*, std::size_t>
  1191. detail::find_in_object(
  1192. object const& obj,
  1193. CharRange key) noexcept;
  1194. #endif
  1195. template<class InputIt>
  1196. void
  1197. construct(
  1198. InputIt first,
  1199. InputIt last,
  1200. std::size_t min_capacity,
  1201. std::input_iterator_tag);
  1202. template<class InputIt>
  1203. void
  1204. construct(
  1205. InputIt first,
  1206. InputIt last,
  1207. std::size_t min_capacity,
  1208. std::forward_iterator_tag);
  1209. template<class InputIt>
  1210. void
  1211. insert(
  1212. InputIt first,
  1213. InputIt last,
  1214. std::input_iterator_tag);
  1215. template<class InputIt>
  1216. void
  1217. insert(
  1218. InputIt first,
  1219. InputIt last,
  1220. std::forward_iterator_tag);
  1221. template< class... Args >
  1222. std::pair<iterator, bool>
  1223. emplace_impl(string_view key, Args&& ... args );
  1224. BOOST_JSON_DECL
  1225. key_value_pair*
  1226. insert_impl(
  1227. pilfered<key_value_pair> p,
  1228. std::size_t hash);
  1229. BOOST_JSON_DECL
  1230. table*
  1231. reserve_impl(std::size_t new_capacity);
  1232. BOOST_JSON_DECL
  1233. bool
  1234. equal(object const& other) const noexcept;
  1235. inline
  1236. std::size_t
  1237. growth(
  1238. std::size_t new_size) const;
  1239. inline
  1240. void
  1241. remove(
  1242. index_t& head,
  1243. key_value_pair& p) noexcept;
  1244. inline
  1245. void
  1246. destroy() noexcept;
  1247. inline
  1248. void
  1249. destroy(
  1250. key_value_pair* first,
  1251. key_value_pair* last) noexcept;
  1252. template<class FS, class FB>
  1253. auto
  1254. do_erase(
  1255. const_iterator pos,
  1256. FS small_reloc,
  1257. FB big_reloc) noexcept
  1258. -> iterator;
  1259. inline
  1260. void
  1261. reindex_relocate(
  1262. key_value_pair* src,
  1263. key_value_pair* dst) noexcept;
  1264. };
  1265. } // namespace json
  1266. } // namespace boost
  1267. #ifndef BOOST_JSON_DOCS
  1268. // boost::hash trait
  1269. namespace boost
  1270. {
  1271. namespace container_hash
  1272. {
  1273. template< class T > struct is_unordered_range;
  1274. template<>
  1275. struct is_unordered_range< json::object >
  1276. : std::true_type
  1277. {};
  1278. } // namespace container_hash
  1279. } // namespace boost
  1280. // std::hash specialization
  1281. namespace std {
  1282. template <>
  1283. struct hash< ::boost::json::object > {
  1284. BOOST_JSON_DECL
  1285. std::size_t
  1286. operator()(::boost::json::object const& jo) const noexcept;
  1287. };
  1288. } // std
  1289. #endif
  1290. // Must be included here for this file to stand alone
  1291. #include <boost/json/value.hpp>
  1292. // includes are at the bottom of <boost/json/value.hpp>
  1293. #endif