array.hpp 37 KB

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