object.hpp 42 KB

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