object.hpp 38 KB

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