varray.hpp 76 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196
  1. // Boost.Container varray
  2. //
  3. // Copyright (c) 2011-2013 Andrew Hundt.
  4. // Copyright (c) 2012-2015 Adam Wulkiewicz, Lodz, Poland.
  5. //
  6. // This file was modified by Oracle on 2020.
  7. // Modifications copyright (c) 2020, Oracle and/or its affiliates.
  8. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  9. //
  10. // Use, modification and distribution is subject to the Boost Software License,
  11. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  12. // http://www.boost.org/LICENSE_1_0.txt)
  13. #ifndef BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_HPP
  14. #define BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_HPP
  15. // TODO - REMOVE/CHANGE
  16. #include <boost/container/detail/config_begin.hpp>
  17. #include <boost/container/detail/workaround.hpp>
  18. #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  19. #include <boost/move/detail/fwd_macros.hpp>
  20. #endif
  21. #include <boost/concept_check.hpp>
  22. #include <boost/config.hpp>
  23. #include <boost/core/ignore_unused.hpp>
  24. #include <boost/swap.hpp>
  25. #include <boost/integer.hpp>
  26. // TODO - use std::reverse_iterator and std::iterator_traits
  27. // instead Boost.Iterator to remove dependency?
  28. // or boost/detail/iterator.hpp ?
  29. #include <boost/iterator/reverse_iterator.hpp>
  30. #include <boost/iterator/iterator_concepts.hpp>
  31. #include <boost/type_traits/alignment_of.hpp>
  32. #include <boost/type_traits/aligned_storage.hpp>
  33. #include <boost/geometry/core/static_assert.hpp>
  34. #include <boost/geometry/index/detail/assert.hpp>
  35. #include <boost/geometry/index/detail/exception.hpp>
  36. #include <boost/geometry/index/detail/varray_detail.hpp>
  37. /*!
  38. \defgroup varray_non_member varray non-member functions
  39. */
  40. namespace boost { namespace geometry { namespace index { namespace detail {
  41. namespace varray_detail {
  42. template <typename Value, std::size_t Capacity>
  43. struct varray_traits
  44. {
  45. typedef Value value_type;
  46. typedef std::size_t size_type;
  47. typedef std::ptrdiff_t difference_type;
  48. typedef Value * pointer;
  49. typedef const Value * const_pointer;
  50. typedef Value & reference;
  51. typedef const Value & const_reference;
  52. typedef std::false_type use_memop_in_swap_and_move;
  53. typedef std::false_type use_optimized_swap;
  54. typedef std::false_type disable_trivial_init;
  55. };
  56. template <typename Varray>
  57. struct checker
  58. {
  59. typedef typename Varray::size_type size_type;
  60. typedef typename Varray::const_iterator const_iterator;
  61. static inline void check_capacity(Varray const& v, size_type s)
  62. {
  63. BOOST_GEOMETRY_INDEX_ASSERT(s <= v.capacity(), "size too big");
  64. ::boost::ignore_unused(v, s);
  65. }
  66. static inline void throw_out_of_bounds(Varray const& v, size_type i)
  67. {
  68. if ( v.size() <= i )
  69. throw_out_of_range("index out of bounds");
  70. ::boost::ignore_unused(v, i);
  71. }
  72. static inline void check_index(Varray const& v, size_type i)
  73. {
  74. BOOST_GEOMETRY_INDEX_ASSERT(i < v.size(), "index out of bounds");
  75. ::boost::ignore_unused(v, i);
  76. }
  77. static inline void check_not_empty(Varray const& v)
  78. {
  79. BOOST_GEOMETRY_INDEX_ASSERT(!v.empty(), "the container is empty");
  80. ::boost::ignore_unused(v);
  81. }
  82. static inline void check_iterator_end_neq(Varray const& v, const_iterator position)
  83. {
  84. BOOST_GEOMETRY_INDEX_ASSERT(v.begin() <= position && position < v.end(), "iterator out of bounds");
  85. ::boost::ignore_unused(v, position);
  86. }
  87. static inline void check_iterator_end_eq(Varray const& v, const_iterator position)
  88. {
  89. BOOST_GEOMETRY_INDEX_ASSERT(v.begin() <= position && position <= v.end(), "iterator out of bounds");
  90. ::boost::ignore_unused(v, position);
  91. }
  92. };
  93. } // namespace varray_detail
  94. /*!
  95. \brief A variable-size array container with fixed capacity.
  96. varray is a sequence container like boost::container::vector with contiguous storage that can
  97. change in size, along with the static allocation, low overhead, and fixed capacity of boost::array.
  98. A varray is a sequence that supports random access to elements, constant time insertion and
  99. removal of elements at the end, and linear time insertion and removal of elements at the beginning or
  100. in the middle. The number of elements in a varray may vary dynamically up to a fixed capacity
  101. because elements are stored within the object itself similarly to an array. However, objects are
  102. initialized as they are inserted into varray unlike C arrays or std::array which must construct
  103. all elements on instantiation. The behavior of varray enables the use of statically allocated
  104. elements in cases with complex object lifetime requirements that would otherwise not be trivially
  105. possible.
  106. \par Error Handling
  107. Insertion beyond the capacity and out of bounds errors result in undefined behavior unless
  108. otherwise specified. In this respect if size() == capacity(), then varray::push_back()
  109. behaves like std::vector pop_front() if size() == empty(). The reason for this difference
  110. is because unlike vectors, varray does not perform allocation.
  111. \par Advanced Usage
  112. Error handling behavior can be modified to more closely match std::vector exception behavior
  113. when exceeding bounds by providing an alternate Strategy and varray_traits instantiation.
  114. \tparam Value The type of element that will be stored.
  115. \tparam Capacity The maximum number of elements varray can store, fixed at compile time.
  116. \tparam Strategy Defines the public typedefs and error handlers,
  117. implements StaticVectorStrategy and has some similarities
  118. to an Allocator.
  119. */
  120. template <typename Value, std::size_t Capacity>
  121. class varray
  122. {
  123. typedef varray_detail::varray_traits<Value, Capacity> vt;
  124. typedef varray_detail::checker<varray> errh;
  125. BOOST_GEOMETRY_STATIC_ASSERT(
  126. ( std::is_unsigned<typename vt::size_type>::value &&
  127. sizeof(typename boost::uint_value_t<Capacity>::least) <= sizeof(typename vt::size_type) ),
  128. "Size type is too small for specified capacity.",
  129. typename vt::size_type, std::integral_constant<std::size_t, Capacity>
  130. );
  131. typedef boost::aligned_storage<
  132. sizeof(Value[Capacity]),
  133. boost::alignment_of<Value[Capacity]>::value
  134. > aligned_storage_type;
  135. template <typename V, std::size_t C>
  136. friend class varray;
  137. BOOST_COPYABLE_AND_MOVABLE(varray)
  138. #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
  139. public:
  140. template <std::size_t C>
  141. varray & operator=(varray<Value, C> & sv)
  142. {
  143. typedef varray<Value, C> other;
  144. this->operator=(static_cast<const ::boost::rv<other> &>(const_cast<const other &>(sv)));
  145. return *this;
  146. }
  147. #endif
  148. public:
  149. //! @brief The type of elements stored in the container.
  150. typedef typename vt::value_type value_type;
  151. //! @brief The unsigned integral type used by the container.
  152. typedef typename vt::size_type size_type;
  153. //! @brief The pointers difference type.
  154. typedef typename vt::difference_type difference_type;
  155. //! @brief The pointer type.
  156. typedef typename vt::pointer pointer;
  157. //! @brief The const pointer type.
  158. typedef typename vt::const_pointer const_pointer;
  159. //! @brief The value reference type.
  160. typedef typename vt::reference reference;
  161. //! @brief The value const reference type.
  162. typedef typename vt::const_reference const_reference;
  163. //! @brief The iterator type.
  164. typedef pointer iterator;
  165. //! @brief The const iterator type.
  166. typedef const_pointer const_iterator;
  167. //! @brief The reverse iterator type.
  168. typedef boost::reverse_iterator<iterator> reverse_iterator;
  169. //! @brief The const reverse iterator.
  170. typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
  171. //! @brief Constructs an empty varray.
  172. //!
  173. //! @par Throws
  174. //! Nothing.
  175. //!
  176. //! @par Complexity
  177. //! Constant O(1).
  178. varray()
  179. : m_size(0)
  180. {}
  181. //! @pre <tt>count <= capacity()</tt>
  182. //!
  183. //! @brief Constructs a varray containing count default constructed Values.
  184. //!
  185. //! @param count The number of values which will be contained in the container.
  186. //!
  187. //! @par Throws
  188. //! If Value's default constructor throws.
  189. //! @internal
  190. //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
  191. //! @endinternal
  192. //!
  193. //! @par Complexity
  194. //! Linear O(N).
  195. explicit varray(size_type count)
  196. : m_size(0)
  197. {
  198. this->resize(count); // may throw
  199. }
  200. //! @pre <tt>count <= capacity()</tt>
  201. //!
  202. //! @brief Constructs a varray containing count copies of value.
  203. //!
  204. //! @param count The number of copies of a values that will be contained in the container.
  205. //! @param value The value which will be used to copy construct values.
  206. //!
  207. //! @par Throws
  208. //! If Value's copy constructor throws.
  209. //! @internal
  210. //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
  211. //! @endinternal
  212. //!
  213. //! @par Complexity
  214. //! Linear O(N).
  215. varray(size_type count, value_type const& value)
  216. : m_size(0)
  217. {
  218. this->resize(count, value); // may throw
  219. }
  220. //! @pre
  221. //! @li <tt>distance(first, last) <= capacity()</tt>
  222. //! @li Iterator must meet the \c ForwardTraversalIterator concept.
  223. //!
  224. //! @brief Constructs a varray containing copy of a range <tt>[first, last)</tt>.
  225. //!
  226. //! @param first The iterator to the first element in range.
  227. //! @param last The iterator to the one after the last element in range.
  228. //!
  229. //! @par Throws
  230. //! If Value's constructor taking a dereferenced Iterator throws.
  231. //! @internal
  232. //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
  233. //! @endinternal
  234. //!
  235. //! @par Complexity
  236. //! Linear O(N).
  237. template <typename Iterator>
  238. varray(Iterator first, Iterator last)
  239. : m_size(0)
  240. {
  241. BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<Iterator>)); // Make sure you passed a ForwardIterator
  242. this->assign(first, last); // may throw
  243. }
  244. //! @brief Constructs a copy of other varray.
  245. //!
  246. //! @param other The varray which content will be copied to this one.
  247. //!
  248. //! @par Throws
  249. //! If Value's copy constructor throws.
  250. //!
  251. //! @par Complexity
  252. //! Linear O(N).
  253. varray(varray const& other)
  254. : m_size(other.size())
  255. {
  256. namespace sv = varray_detail;
  257. sv::uninitialized_copy(other.begin(), other.end(), this->begin()); // may throw
  258. }
  259. //! @pre <tt>other.size() <= capacity()</tt>.
  260. //!
  261. //! @brief Constructs a copy of other varray.
  262. //!
  263. //! @param other The varray which content will be copied to this one.
  264. //!
  265. //! @par Throws
  266. //! If Value's copy constructor throws.
  267. //! @internal
  268. //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
  269. //! @endinternal
  270. //!
  271. //! @par Complexity
  272. //! Linear O(N).
  273. template <std::size_t C>
  274. varray(varray<value_type, C> const& other)
  275. : m_size(other.size())
  276. {
  277. errh::check_capacity(*this, other.size()); // may throw
  278. namespace sv = varray_detail;
  279. sv::uninitialized_copy(other.begin(), other.end(), this->begin()); // may throw
  280. }
  281. //! @brief Copy assigns Values stored in the other varray to this one.
  282. //!
  283. //! @param other The varray which content will be copied to this one.
  284. //!
  285. //! @par Throws
  286. //! If Value's copy constructor or copy assignment throws.
  287. //!
  288. //! @par Complexity
  289. //! Linear O(N).
  290. varray & operator=(BOOST_COPY_ASSIGN_REF(varray) other)
  291. {
  292. this->assign(other.begin(), other.end()); // may throw
  293. return *this;
  294. }
  295. //! @pre <tt>other.size() <= capacity()</tt>
  296. //!
  297. //! @brief Copy assigns Values stored in the other varray to this one.
  298. //!
  299. //! @param other The varray which content will be copied to this one.
  300. //!
  301. //! @par Throws
  302. //! If Value's copy constructor or copy assignment throws.
  303. //! @internal
  304. //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
  305. //! @endinternal
  306. //!
  307. //! @par Complexity
  308. //! Linear O(N).
  309. template <std::size_t C>
  310. varray & operator=(BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(varray, value_type, C) other)
  311. {
  312. this->assign(other.begin(), other.end()); // may throw
  313. return *this;
  314. }
  315. //! @brief Move constructor. Moves Values stored in the other varray to this one.
  316. //!
  317. //! @param other The varray which content will be moved to this one.
  318. //!
  319. //! @par Throws
  320. //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
  321. //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
  322. //! @internal
  323. //! @li It throws only if \c use_memop_in_swap_and_move is \c false_type - default.
  324. //! @endinternal
  325. //!
  326. //! @par Complexity
  327. //! Linear O(N).
  328. varray(BOOST_RV_REF(varray) other)
  329. {
  330. typedef typename
  331. vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
  332. this->move_ctor_dispatch(other, use_memop_in_swap_and_move());
  333. }
  334. //! @pre <tt>other.size() <= capacity()</tt>
  335. //!
  336. //! @brief Move constructor. Moves Values stored in the other varray to this one.
  337. //!
  338. //! @param other The varray which content will be moved to this one.
  339. //!
  340. //! @par Throws
  341. //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
  342. //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
  343. //! @internal
  344. //! @li It throws only if \c use_memop_in_swap_and_move is false_type - default.
  345. //! @endinternal
  346. //! @internal
  347. //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
  348. //! @endinternal
  349. //!
  350. //! @par Complexity
  351. //! Linear O(N).
  352. template <std::size_t C>
  353. varray(BOOST_RV_REF_2_TEMPL_ARGS(varray, value_type, C) other)
  354. : m_size(other.m_size)
  355. {
  356. errh::check_capacity(*this, other.size()); // may throw
  357. typedef typename
  358. vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
  359. this->move_ctor_dispatch(other, use_memop_in_swap_and_move());
  360. }
  361. //! @brief Move assignment. Moves Values stored in the other varray to this one.
  362. //!
  363. //! @param other The varray which content will be moved to this one.
  364. //!
  365. //! @par Throws
  366. //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
  367. //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
  368. //! @internal
  369. //! @li It throws only if \c use_memop_in_swap_and_move is \c false_type - default.
  370. //! @endinternal
  371. //!
  372. //! @par Complexity
  373. //! Linear O(N).
  374. varray & operator=(BOOST_RV_REF(varray) other)
  375. {
  376. if ( &other == this )
  377. return *this;
  378. typedef typename
  379. vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
  380. this->move_assign_dispatch(other, use_memop_in_swap_and_move());
  381. return *this;
  382. }
  383. //! @pre <tt>other.size() <= capacity()</tt>
  384. //!
  385. //! @brief Move assignment. Moves Values stored in the other varray to this one.
  386. //!
  387. //! @param other The varray which content will be moved to this one.
  388. //!
  389. //! @par Throws
  390. //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
  391. //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
  392. //! @internal
  393. //! @li It throws only if \c use_memop_in_swap_and_move is \c false_type - default.
  394. //! @endinternal
  395. //! @internal
  396. //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
  397. //! @endinternal
  398. //!
  399. //! @par Complexity
  400. //! Linear O(N).
  401. template <std::size_t C>
  402. varray & operator=(BOOST_RV_REF_2_TEMPL_ARGS(varray, value_type, C) other)
  403. {
  404. errh::check_capacity(*this, other.size()); // may throw
  405. typedef typename
  406. vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
  407. this->move_assign_dispatch(other, use_memop_in_swap_and_move());
  408. return *this;
  409. }
  410. //! @brief Destructor. Destroys Values stored in this container.
  411. //!
  412. //! @par Throws
  413. //! Nothing
  414. //!
  415. //! @par Complexity
  416. //! Linear O(N).
  417. ~varray()
  418. {
  419. namespace sv = varray_detail;
  420. sv::destroy(this->begin(), this->end());
  421. }
  422. //! @brief Swaps contents of the other varray and this one.
  423. //!
  424. //! @param other The varray which content will be swapped with this one's content.
  425. //!
  426. //! @par Throws
  427. //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
  428. //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
  429. //! @internal
  430. //! @li It throws only if \c use_memop_in_swap_and_move and \c use_optimized_swap are \c false_type - default.
  431. //! @endinternal
  432. //!
  433. //! @par Complexity
  434. //! Linear O(N).
  435. void swap(varray & other)
  436. {
  437. typedef typename
  438. vt::use_optimized_swap use_optimized_swap;
  439. this->swap_dispatch(other, use_optimized_swap());
  440. }
  441. //! @pre <tt>other.size() <= capacity() && size() <= other.capacity()</tt>
  442. //!
  443. //! @brief Swaps contents of the other varray and this one.
  444. //!
  445. //! @param other The varray which content will be swapped with this one's content.
  446. //!
  447. //! @par Throws
  448. //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
  449. //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
  450. //! @internal
  451. //! @li It throws only if \c use_memop_in_swap_and_move and \c use_optimized_swap are \c false_type - default.
  452. //! @endinternal
  453. //! @internal
  454. //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
  455. //! @endinternal
  456. //!
  457. //! @par Complexity
  458. //! Linear O(N).
  459. template <std::size_t C>
  460. void swap(varray<value_type, C> & other)
  461. {
  462. errh::check_capacity(*this, other.size());
  463. errh::check_capacity(other, this->size());
  464. typedef typename
  465. vt::use_optimized_swap use_optimized_swap;
  466. this->swap_dispatch(other, use_optimized_swap());
  467. }
  468. //! @pre <tt>count <= capacity()</tt>
  469. //!
  470. //! @brief Inserts or erases elements at the end such that
  471. //! the size becomes count. New elements are default constructed.
  472. //!
  473. //! @param count The number of elements which will be stored in the container.
  474. //!
  475. //! @par Throws
  476. //! If Value's default constructor throws.
  477. //! @internal
  478. //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
  479. //! @endinternal
  480. //!
  481. //! @par Complexity
  482. //! Linear O(N).
  483. void resize(size_type count)
  484. {
  485. namespace sv = varray_detail;
  486. typedef typename vt::disable_trivial_init dti;
  487. if ( count < m_size )
  488. {
  489. sv::destroy(this->begin() + count, this->end());
  490. }
  491. else
  492. {
  493. errh::check_capacity(*this, count); // may throw
  494. sv::uninitialized_fill(this->end(), this->begin() + count, dti()); // may throw
  495. }
  496. m_size = count; // update end
  497. }
  498. //! @pre <tt>count <= capacity()</tt>
  499. //!
  500. //! @brief Inserts or erases elements at the end such that
  501. //! the size becomes count. New elements are copy constructed from value.
  502. //!
  503. //! @param count The number of elements which will be stored in the container.
  504. //! @param value The value used to copy construct the new element.
  505. //!
  506. //! @par Throws
  507. //! If Value's copy constructor throws.
  508. //! @internal
  509. //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
  510. //! @endinternal
  511. //!
  512. //! @par Complexity
  513. //! Linear O(N).
  514. void resize(size_type count, value_type const& value)
  515. {
  516. if ( count < m_size )
  517. {
  518. namespace sv = varray_detail;
  519. sv::destroy(this->begin() + count, this->end());
  520. }
  521. else
  522. {
  523. errh::check_capacity(*this, count); // may throw
  524. std::uninitialized_fill(this->end(), this->begin() + count, value); // may throw
  525. }
  526. m_size = count; // update end
  527. }
  528. //! @pre <tt>count <= capacity()</tt>
  529. //!
  530. //! @brief This call has no effect because the Capacity of this container is constant.
  531. //!
  532. //! @param count The number of elements which the container should be able to contain.
  533. //!
  534. //! @par Throws
  535. //! Nothing.
  536. //! @internal
  537. //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
  538. //! @endinternal
  539. //!
  540. //! @par Complexity
  541. //! Linear O(N).
  542. void reserve(size_type count)
  543. {
  544. errh::check_capacity(*this, count); // may throw
  545. }
  546. //! @pre <tt>size() < capacity()</tt>
  547. //!
  548. //! @brief Adds a copy of value at the end.
  549. //!
  550. //! @param value The value used to copy construct the new element.
  551. //!
  552. //! @par Throws
  553. //! If Value's copy constructor throws.
  554. //! @internal
  555. //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
  556. //! @endinternal
  557. //!
  558. //! @par Complexity
  559. //! Constant O(1).
  560. void push_back(value_type const& value)
  561. {
  562. typedef typename vt::disable_trivial_init dti;
  563. errh::check_capacity(*this, m_size + 1); // may throw
  564. namespace sv = varray_detail;
  565. sv::construct(dti(), this->end(), value); // may throw
  566. ++m_size; // update end
  567. }
  568. //! @pre <tt>size() < capacity()</tt>
  569. //!
  570. //! @brief Moves value to the end.
  571. //!
  572. //! @param value The value to move construct the new element.
  573. //!
  574. //! @par Throws
  575. //! If Value's move constructor throws.
  576. //! @internal
  577. //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
  578. //! @endinternal
  579. //!
  580. //! @par Complexity
  581. //! Constant O(1).
  582. void push_back(BOOST_RV_REF(value_type) value)
  583. {
  584. typedef typename vt::disable_trivial_init dti;
  585. errh::check_capacity(*this, m_size + 1); // may throw
  586. namespace sv = varray_detail;
  587. sv::construct(dti(), this->end(), ::boost::move(value)); // may throw
  588. ++m_size; // update end
  589. }
  590. //! @pre <tt>!empty()</tt>
  591. //!
  592. //! @brief Destroys last value and decreases the size.
  593. //!
  594. //! @par Throws
  595. //! Nothing by default.
  596. //!
  597. //! @par Complexity
  598. //! Constant O(1).
  599. void pop_back()
  600. {
  601. errh::check_not_empty(*this);
  602. namespace sv = varray_detail;
  603. sv::destroy(this->end() - 1);
  604. --m_size; // update end
  605. }
  606. //! @pre
  607. //! @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
  608. //! @li <tt>size() < capacity()</tt>
  609. //!
  610. //! @brief Inserts a copy of element at position.
  611. //!
  612. //! @param position The position at which the new value will be inserted.
  613. //! @param value The value used to copy construct the new element.
  614. //!
  615. //! @par Throws
  616. //! @li If Value's copy constructor or copy assignment throws
  617. //! @li If Value's move constructor or move assignment throws.
  618. //! @internal
  619. //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
  620. //! @endinternal
  621. //!
  622. //! @par Complexity
  623. //! Constant or linear.
  624. iterator insert(iterator position, value_type const& value)
  625. {
  626. typedef typename vt::disable_trivial_init dti;
  627. namespace sv = varray_detail;
  628. errh::check_iterator_end_eq(*this, position);
  629. errh::check_capacity(*this, m_size + 1); // may throw
  630. if ( position == this->end() )
  631. {
  632. sv::construct(dti(), position, value); // may throw
  633. ++m_size; // update end
  634. }
  635. else
  636. {
  637. // TODO - should move be used only if it's nonthrowing?
  638. value_type & r = *(this->end() - 1);
  639. sv::construct(dti(), this->end(), boost::move(r)); // may throw
  640. ++m_size; // update end
  641. sv::move_backward(position, this->end() - 2, this->end() - 1); // may throw
  642. sv::assign(position, value); // may throw
  643. }
  644. return position;
  645. }
  646. //! @pre
  647. //! @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
  648. //! @li <tt>size() < capacity()</tt>
  649. //!
  650. //! @brief Inserts a move-constructed element at position.
  651. //!
  652. //! @param position The position at which the new value will be inserted.
  653. //! @param value The value used to move construct the new element.
  654. //!
  655. //! @par Throws
  656. //! If Value's move constructor or move assignment throws.
  657. //! @internal
  658. //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
  659. //! @endinternal
  660. //!
  661. //! @par Complexity
  662. //! Constant or linear.
  663. iterator insert(iterator position, BOOST_RV_REF(value_type) value)
  664. {
  665. typedef typename vt::disable_trivial_init dti;
  666. namespace sv = varray_detail;
  667. errh::check_iterator_end_eq(*this, position);
  668. errh::check_capacity(*this, m_size + 1); // may throw
  669. if ( position == this->end() )
  670. {
  671. sv::construct(dti(), position, boost::move(value)); // may throw
  672. ++m_size; // update end
  673. }
  674. else
  675. {
  676. // TODO - should move be used only if it's nonthrowing?
  677. value_type & r = *(this->end() - 1);
  678. sv::construct(dti(), this->end(), boost::move(r)); // may throw
  679. ++m_size; // update end
  680. sv::move_backward(position, this->end() - 2, this->end() - 1); // may throw
  681. sv::assign(position, boost::move(value)); // may throw
  682. }
  683. return position;
  684. }
  685. //! @pre
  686. //! @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
  687. //! @li <tt>size() + count <= capacity()</tt>
  688. //!
  689. //! @brief Inserts a count copies of value at position.
  690. //!
  691. //! @param position The position at which new elements will be inserted.
  692. //! @param count The number of new elements which will be inserted.
  693. //! @param value The value used to copy construct new elements.
  694. //!
  695. //! @par Throws
  696. //! @li If Value's copy constructor or copy assignment throws.
  697. //! @li If Value's move constructor or move assignment throws.
  698. //! @internal
  699. //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
  700. //! @endinternal
  701. //!
  702. //! @par Complexity
  703. //! Linear O(N).
  704. iterator insert(iterator position, size_type count, value_type const& value)
  705. {
  706. errh::check_iterator_end_eq(*this, position);
  707. errh::check_capacity(*this, m_size + count); // may throw
  708. if ( position == this->end() )
  709. {
  710. std::uninitialized_fill(position, position + count, value); // may throw
  711. m_size += count; // update end
  712. }
  713. else
  714. {
  715. namespace sv = varray_detail;
  716. difference_type to_move = std::distance(position, this->end());
  717. // TODO - should following lines check for exception and revert to the old size?
  718. if ( count < static_cast<size_type>(to_move) )
  719. {
  720. sv::uninitialized_move(this->end() - count, this->end(), this->end()); // may throw
  721. m_size += count; // update end
  722. sv::move_backward(position, position + to_move - count, this->end() - count); // may throw
  723. std::fill_n(position, count, value); // may throw
  724. }
  725. else
  726. {
  727. std::uninitialized_fill(this->end(), position + count, value); // may throw
  728. m_size += count - to_move; // update end
  729. sv::uninitialized_move(position, position + to_move, position + count); // may throw
  730. m_size += to_move; // update end
  731. std::fill_n(position, to_move, value); // may throw
  732. }
  733. }
  734. return position;
  735. }
  736. //! @pre
  737. //! @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
  738. //! @li <tt>distance(first, last) <= capacity()</tt>
  739. //! @li \c Iterator must meet the \c ForwardTraversalIterator concept.
  740. //!
  741. //! @brief Inserts a copy of a range <tt>[first, last)</tt> at position.
  742. //!
  743. //! @param position The position at which new elements will be inserted.
  744. //! @param first The iterator to the first element of a range used to construct new elements.
  745. //! @param last The iterator to the one after the last element of a range used to construct new elements.
  746. //!
  747. //! @par Throws
  748. //! @li If Value's constructor and assignment taking a dereferenced \c Iterator.
  749. //! @li If Value's move constructor or move assignment throws.
  750. //! @internal
  751. //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
  752. //! @endinternal
  753. //!
  754. //! @par Complexity
  755. //! Linear O(N).
  756. template <typename Iterator>
  757. iterator insert(iterator position, Iterator first, Iterator last)
  758. {
  759. BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<Iterator>)); // Make sure you passed a ForwardIterator
  760. typedef typename boost::iterator_traversal<Iterator>::type traversal;
  761. this->insert_dispatch(position, first, last, traversal());
  762. return position;
  763. }
  764. //! @pre \c position must be a valid iterator of \c *this in range <tt>[begin(), end())</tt>
  765. //!
  766. //! @brief Erases Value from position.
  767. //!
  768. //! @param position The position of the element which will be erased from the container.
  769. //!
  770. //! @par Throws
  771. //! If Value's move assignment throws.
  772. //!
  773. //! @par Complexity
  774. //! Linear O(N).
  775. iterator erase(iterator position)
  776. {
  777. namespace sv = varray_detail;
  778. errh::check_iterator_end_neq(*this, position);
  779. //TODO - add empty check?
  780. //errh::check_empty(*this);
  781. sv::move(position + 1, this->end(), position); // may throw
  782. sv::destroy(this->end() - 1);
  783. --m_size;
  784. return position;
  785. }
  786. //! @pre
  787. //! @li \c first and \c last must define a valid range
  788. //! @li iterators must be in range <tt>[begin(), end()]</tt>
  789. //!
  790. //! @brief Erases Values from a range <tt>[first, last)</tt>.
  791. //!
  792. //! @param first The position of the first element of a range which will be erased from the container.
  793. //! @param last The position of the one after the last element of a range which will be erased from the container.
  794. //!
  795. //! @par Throws
  796. //! If Value's move assignment throws.
  797. //!
  798. //! @par Complexity
  799. //! Linear O(N).
  800. iterator erase(iterator first, iterator last)
  801. {
  802. namespace sv = varray_detail;
  803. errh::check_iterator_end_eq(*this, first);
  804. errh::check_iterator_end_eq(*this, last);
  805. difference_type n = std::distance(first, last);
  806. //TODO - add invalid range check?
  807. //BOOST_GEOMETRY_INDEX_ASSERT(0 <= n, "invalid range");
  808. //TODO - add this->size() check?
  809. //BOOST_GEOMETRY_INDEX_ASSERT(n <= this->size(), "invalid range");
  810. sv::move(last, this->end(), first); // may throw
  811. sv::destroy(this->end() - n, this->end());
  812. m_size -= n;
  813. return first;
  814. }
  815. //! @pre <tt>distance(first, last) <= capacity()</tt>
  816. //!
  817. //! @brief Assigns a range <tt>[first, last)</tt> of Values to this container.
  818. //!
  819. //! @param first The iterator to the first element of a range used to construct new content of this container.
  820. //! @param last The iterator to the one after the last element of a range used to construct new content of this container.
  821. //!
  822. //! @par Throws
  823. //! If Value's copy constructor or copy assignment throws,
  824. //!
  825. //! @par Complexity
  826. //! Linear O(N).
  827. template <typename Iterator>
  828. void assign(Iterator first, Iterator last)
  829. {
  830. BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<Iterator>)); // Make sure you passed a ForwardIterator
  831. typedef typename boost::iterator_traversal<Iterator>::type traversal;
  832. this->assign_dispatch(first, last, traversal()); // may throw
  833. }
  834. //! @pre <tt>count <= capacity()</tt>
  835. //!
  836. //! @brief Assigns a count copies of value to this container.
  837. //!
  838. //! @param count The new number of elements which will be container in the container.
  839. //! @param value The value which will be used to copy construct the new content.
  840. //!
  841. //! @par Throws
  842. //! If Value's copy constructor or copy assignment throws.
  843. //!
  844. //! @par Complexity
  845. //! Linear O(N).
  846. void assign(size_type count, value_type const& value)
  847. {
  848. if ( count < m_size )
  849. {
  850. namespace sv = varray_detail;
  851. std::fill_n(this->begin(), count, value); // may throw
  852. sv::destroy(this->begin() + count, this->end());
  853. }
  854. else
  855. {
  856. errh::check_capacity(*this, count); // may throw
  857. std::fill_n(this->begin(), m_size, value); // may throw
  858. std::uninitialized_fill(this->end(), this->begin() + count, value); // may throw
  859. }
  860. m_size = count; // update end
  861. }
  862. #if !defined(BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE)
  863. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  864. //! @pre <tt>size() < capacity()</tt>
  865. //!
  866. //! @brief Inserts a Value constructed with
  867. //! \c std::forward<Args>(args)... in the end of the container.
  868. //!
  869. //! @param args The arguments of the constructor of the new element which will be created at the end of the container.
  870. //!
  871. //! @par Throws
  872. //! If in-place constructor throws or Value's move constructor throws.
  873. //! @internal
  874. //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
  875. //! @endinternal
  876. //!
  877. //! @par Complexity
  878. //! Constant O(1).
  879. template<class ...Args>
  880. void emplace_back(BOOST_FWD_REF(Args) ...args)
  881. {
  882. typedef typename vt::disable_trivial_init dti;
  883. errh::check_capacity(*this, m_size + 1); // may throw
  884. namespace sv = varray_detail;
  885. sv::construct(dti(), this->end(), ::boost::forward<Args>(args)...); // may throw
  886. ++m_size; // update end
  887. }
  888. //! @pre
  889. //! @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>
  890. //! @li <tt>size() < capacity()</tt>
  891. //!
  892. //! @brief Inserts a Value constructed with
  893. //! \c std::forward<Args>(args)... before position
  894. //!
  895. //! @param position The position at which new elements will be inserted.
  896. //! @param args The arguments of the constructor of the new element.
  897. //!
  898. //! @par Throws
  899. //! If in-place constructor throws or if Value's move constructor or move assignment throws.
  900. //! @internal
  901. //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
  902. //! @endinternal
  903. //!
  904. //! @par Complexity
  905. //! Constant or linear.
  906. template<class ...Args>
  907. iterator emplace(iterator position, BOOST_FWD_REF(Args) ...args)
  908. {
  909. typedef typename vt::disable_trivial_init dti;
  910. namespace sv = varray_detail;
  911. errh::check_iterator_end_eq(*this, position);
  912. errh::check_capacity(*this, m_size + 1); // may throw
  913. if ( position == this->end() )
  914. {
  915. sv::construct(dti(), position, ::boost::forward<Args>(args)...); // may throw
  916. ++m_size; // update end
  917. }
  918. else
  919. {
  920. // TODO - should following lines check for exception and revert to the old size?
  921. // TODO - should move be used only if it's nonthrowing?
  922. value_type & r = *(this->end() - 1);
  923. sv::construct(dti(), this->end(), boost::move(r)); // may throw
  924. ++m_size; // update end
  925. sv::move_backward(position, this->end() - 2, this->end() - 1); // may throw
  926. aligned_storage<sizeof(value_type), alignment_of<value_type>::value> temp_storage;
  927. value_type * val_p = static_cast<value_type *>(temp_storage.address());
  928. sv::construct(dti(), val_p, ::boost::forward<Args>(args)...); // may throw
  929. sv::scoped_destructor<value_type> d(val_p);
  930. sv::assign(position, ::boost::move(*val_p)); // may throw
  931. }
  932. return position;
  933. }
  934. #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  935. #define BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_EMPLACE(N) \
  936. BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
  937. void emplace_back(BOOST_MOVE_UREF##N) \
  938. { \
  939. typedef typename vt::disable_trivial_init dti; \
  940. \
  941. errh::check_capacity(*this, m_size + 1); /*may throw*/\
  942. \
  943. namespace sv = varray_detail; \
  944. sv::construct(dti(), this->end() BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); /*may throw*/\
  945. ++m_size; /*update end*/ \
  946. } \
  947. \
  948. BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
  949. iterator emplace(iterator position BOOST_MOVE_I##N BOOST_MOVE_UREF##N) \
  950. { \
  951. typedef typename vt::disable_trivial_init dti; \
  952. namespace sv = varray_detail; \
  953. \
  954. errh::check_iterator_end_eq(*this, position); \
  955. errh::check_capacity(*this, m_size + 1); /*may throw*/\
  956. \
  957. if ( position == this->end() ) \
  958. { \
  959. sv::construct(dti(), position BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); /*may throw*/\
  960. ++m_size; /*update end*/ \
  961. } \
  962. else \
  963. { \
  964. /* TODO - should following lines check for exception and revert to the old size? */ \
  965. /* TODO - should move be used only if it's nonthrowing? */ \
  966. \
  967. value_type & r = *(this->end() - 1); \
  968. sv::construct(dti(), this->end(), boost::move(r)); /*may throw*/\
  969. ++m_size; /*update end*/ \
  970. sv::move_backward(position, this->end() - 2, this->end() - 1); /*may throw*/\
  971. \
  972. aligned_storage<sizeof(value_type), alignment_of<value_type>::value> temp_storage; \
  973. value_type * val_p = static_cast<value_type *>(temp_storage.address()); \
  974. sv::construct(dti(), val_p BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); /*may throw*/\
  975. sv::scoped_destructor<value_type> d(val_p); \
  976. sv::assign(position, ::boost::move(*val_p)); /*may throw*/\
  977. } \
  978. \
  979. return position; \
  980. } \
  981. BOOST_MOVE_ITERATE_0TO9(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_EMPLACE)
  982. #undef BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_EMPLACE
  983. #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  984. #endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE
  985. //! @brief Removes all elements from the container.
  986. //!
  987. //! @par Throws
  988. //! Nothing.
  989. //!
  990. //! @par Complexity
  991. //! Constant O(1).
  992. void clear()
  993. {
  994. namespace sv = varray_detail;
  995. sv::destroy(this->begin(), this->end());
  996. m_size = 0; // update end
  997. }
  998. //! @pre <tt>i < size()</tt>
  999. //!
  1000. //! @brief Returns reference to the i-th element.
  1001. //!
  1002. //! @param i The element's index.
  1003. //!
  1004. //! @return reference to the i-th element
  1005. //! from the beginning of the container.
  1006. //!
  1007. //! @par Throws
  1008. //! \c std::out_of_range exception by default.
  1009. //!
  1010. //! @par Complexity
  1011. //! Constant O(1).
  1012. reference at(size_type i)
  1013. {
  1014. errh::throw_out_of_bounds(*this, i); // may throw
  1015. return *(this->begin() + i);
  1016. }
  1017. //! @pre <tt>i < size()</tt>
  1018. //!
  1019. //! @brief Returns const reference to the i-th element.
  1020. //!
  1021. //! @param i The element's index.
  1022. //!
  1023. //! @return const reference to the i-th element
  1024. //! from the beginning of the container.
  1025. //!
  1026. //! @par Throws
  1027. //! \c std::out_of_range exception by default.
  1028. //!
  1029. //! @par Complexity
  1030. //! Constant O(1).
  1031. const_reference at(size_type i) const
  1032. {
  1033. errh::throw_out_of_bounds(*this, i); // may throw
  1034. return *(this->begin() + i);
  1035. }
  1036. //! @pre <tt>i < size()</tt>
  1037. //!
  1038. //! @brief Returns reference to the i-th element.
  1039. //!
  1040. //! @param i The element's index.
  1041. //!
  1042. //! @return reference to the i-th element
  1043. //! from the beginning of the container.
  1044. //!
  1045. //! @par Throws
  1046. //! Nothing by default.
  1047. //!
  1048. //! @par Complexity
  1049. //! Constant O(1).
  1050. reference operator[](size_type i)
  1051. {
  1052. // TODO: Remove bounds check? std::vector and std::array operator[] don't check.
  1053. errh::check_index(*this, i);
  1054. return *(this->begin() + i);
  1055. }
  1056. //! @pre <tt>i < size()</tt>
  1057. //!
  1058. //! @brief Returns const reference to the i-th element.
  1059. //!
  1060. //! @param i The element's index.
  1061. //!
  1062. //! @return const reference to the i-th element
  1063. //! from the beginning of the container.
  1064. //!
  1065. //! @par Throws
  1066. //! Nothing by default.
  1067. //!
  1068. //! @par Complexity
  1069. //! Constant O(1).
  1070. const_reference operator[](size_type i) const
  1071. {
  1072. errh::check_index(*this, i);
  1073. return *(this->begin() + i);
  1074. }
  1075. //! @pre \c !empty()
  1076. //!
  1077. //! @brief Returns reference to the first element.
  1078. //!
  1079. //! @return reference to the first element
  1080. //! from the beginning of the container.
  1081. //!
  1082. //! @par Throws
  1083. //! Nothing by default.
  1084. //!
  1085. //! @par Complexity
  1086. //! Constant O(1).
  1087. reference front()
  1088. {
  1089. errh::check_not_empty(*this);
  1090. return *(this->begin());
  1091. }
  1092. //! @pre \c !empty()
  1093. //!
  1094. //! @brief Returns const reference to the first element.
  1095. //!
  1096. //! @return const reference to the first element
  1097. //! from the beginning of the container.
  1098. //!
  1099. //! @par Throws
  1100. //! Nothing by default.
  1101. //!
  1102. //! @par Complexity
  1103. //! Constant O(1).
  1104. const_reference front() const
  1105. {
  1106. errh::check_not_empty(*this);
  1107. return *(this->begin());
  1108. }
  1109. //! @pre \c !empty()
  1110. //!
  1111. //! @brief Returns reference to the last element.
  1112. //!
  1113. //! @return reference to the last element
  1114. //! from the beginning of the container.
  1115. //!
  1116. //! @par Throws
  1117. //! Nothing by default.
  1118. //!
  1119. //! @par Complexity
  1120. //! Constant O(1).
  1121. reference back()
  1122. {
  1123. errh::check_not_empty(*this);
  1124. return *(this->end() - 1);
  1125. }
  1126. //! @pre \c !empty()
  1127. //!
  1128. //! @brief Returns const reference to the first element.
  1129. //!
  1130. //! @return const reference to the last element
  1131. //! from the beginning of the container.
  1132. //!
  1133. //! @par Throws
  1134. //! Nothing by default.
  1135. //!
  1136. //! @par Complexity
  1137. //! Constant O(1).
  1138. const_reference back() const
  1139. {
  1140. errh::check_not_empty(*this);
  1141. return *(this->end() - 1);
  1142. }
  1143. //! @brief Pointer such that <tt>[data(), data() + size())</tt> is a valid range.
  1144. //! For a non-empty vector <tt>data() == &front()</tt>.
  1145. //!
  1146. //! @par Throws
  1147. //! Nothing.
  1148. //!
  1149. //! @par Complexity
  1150. //! Constant O(1).
  1151. Value * data()
  1152. {
  1153. return boost::addressof(*(this->ptr()));
  1154. }
  1155. //! @brief Const pointer such that <tt>[data(), data() + size())</tt> is a valid range.
  1156. //! For a non-empty vector <tt>data() == &front()</tt>.
  1157. //!
  1158. //! @par Throws
  1159. //! Nothing.
  1160. //!
  1161. //! @par Complexity
  1162. //! Constant O(1).
  1163. const Value * data() const
  1164. {
  1165. return boost::addressof(*(this->ptr()));
  1166. }
  1167. //! @brief Returns iterator to the first element.
  1168. //!
  1169. //! @return iterator to the first element contained in the vector.
  1170. //!
  1171. //! @par Throws
  1172. //! Nothing.
  1173. //!
  1174. //! @par Complexity
  1175. //! Constant O(1).
  1176. iterator begin() { return this->ptr(); }
  1177. //! @brief Returns const iterator to the first element.
  1178. //!
  1179. //! @return const_iterator to the first element contained in the vector.
  1180. //!
  1181. //! @par Throws
  1182. //! Nothing.
  1183. //!
  1184. //! @par Complexity
  1185. //! Constant O(1).
  1186. const_iterator begin() const { return this->ptr(); }
  1187. //! @brief Returns const iterator to the first element.
  1188. //!
  1189. //! @return const_iterator to the first element contained in the vector.
  1190. //!
  1191. //! @par Throws
  1192. //! Nothing.
  1193. //!
  1194. //! @par Complexity
  1195. //! Constant O(1).
  1196. const_iterator cbegin() const { return this->ptr(); }
  1197. //! @brief Returns iterator to the one after the last element.
  1198. //!
  1199. //! @return iterator pointing to the one after the last element contained in the vector.
  1200. //!
  1201. //! @par Throws
  1202. //! Nothing.
  1203. //!
  1204. //! @par Complexity
  1205. //! Constant O(1).
  1206. iterator end() { return this->begin() + m_size; }
  1207. //! @brief Returns const iterator to the one after the last element.
  1208. //!
  1209. //! @return const_iterator pointing to the one after the last element contained in the vector.
  1210. //!
  1211. //! @par Throws
  1212. //! Nothing.
  1213. //!
  1214. //! @par Complexity
  1215. //! Constant O(1).
  1216. const_iterator end() const { return this->begin() + m_size; }
  1217. //! @brief Returns const iterator to the one after the last element.
  1218. //!
  1219. //! @return const_iterator pointing to the one after the last element contained in the vector.
  1220. //!
  1221. //! @par Throws
  1222. //! Nothing.
  1223. //!
  1224. //! @par Complexity
  1225. //! Constant O(1).
  1226. const_iterator cend() const { return this->cbegin() + m_size; }
  1227. //! @brief Returns reverse iterator to the first element of the reversed container.
  1228. //!
  1229. //! @return reverse_iterator pointing to the beginning
  1230. //! of the reversed varray.
  1231. //!
  1232. //! @par Throws
  1233. //! Nothing.
  1234. //!
  1235. //! @par Complexity
  1236. //! Constant O(1).
  1237. reverse_iterator rbegin() { return reverse_iterator(this->end()); }
  1238. //! @brief Returns const reverse iterator to the first element of the reversed container.
  1239. //!
  1240. //! @return const_reverse_iterator pointing to the beginning
  1241. //! of the reversed varray.
  1242. //!
  1243. //! @par Throws
  1244. //! Nothing.
  1245. //!
  1246. //! @par Complexity
  1247. //! Constant O(1).
  1248. const_reverse_iterator rbegin() const { return const_reverse_iterator(this->end()); }
  1249. //! @brief Returns const reverse iterator to the first element of the reversed container.
  1250. //!
  1251. //! @return const_reverse_iterator pointing to the beginning
  1252. //! of the reversed varray.
  1253. //!
  1254. //! @par Throws
  1255. //! Nothing.
  1256. //!
  1257. //! @par Complexity
  1258. //! Constant O(1).
  1259. const_reverse_iterator crbegin() const { return const_reverse_iterator(this->end()); }
  1260. //! @brief Returns reverse iterator to the one after the last element of the reversed container.
  1261. //!
  1262. //! @return reverse_iterator pointing to the one after the last element
  1263. //! of the reversed varray.
  1264. //!
  1265. //! @par Throws
  1266. //! Nothing.
  1267. //!
  1268. //! @par Complexity
  1269. //! Constant O(1).
  1270. reverse_iterator rend() { return reverse_iterator(this->begin()); }
  1271. //! @brief Returns const reverse iterator to the one after the last element of the reversed container.
  1272. //!
  1273. //! @return const_reverse_iterator pointing to the one after the last element
  1274. //! of the reversed varray.
  1275. //!
  1276. //! @par Throws
  1277. //! Nothing.
  1278. //!
  1279. //! @par Complexity
  1280. //! Constant O(1).
  1281. const_reverse_iterator rend() const { return const_reverse_iterator(this->begin()); }
  1282. //! @brief Returns const reverse iterator to the one after the last element of the reversed container.
  1283. //!
  1284. //! @return const_reverse_iterator pointing to the one after the last element
  1285. //! of the reversed varray.
  1286. //!
  1287. //! @par Throws
  1288. //! Nothing.
  1289. //!
  1290. //! @par Complexity
  1291. //! Constant O(1).
  1292. const_reverse_iterator crend() const { return const_reverse_iterator(this->begin()); }
  1293. //! @brief Returns container's capacity.
  1294. //!
  1295. //! @return container's capacity.
  1296. //!
  1297. //! @par Throws
  1298. //! Nothing.
  1299. //!
  1300. //! @par Complexity
  1301. //! Constant O(1).
  1302. static size_type capacity() { return Capacity; }
  1303. //! @brief Returns container's capacity.
  1304. //!
  1305. //! @return container's capacity.
  1306. //!
  1307. //! @par Throws
  1308. //! Nothing.
  1309. //!
  1310. //! @par Complexity
  1311. //! Constant O(1).
  1312. static size_type max_size() { return Capacity; }
  1313. //! @brief Returns the number of stored elements.
  1314. //!
  1315. //! @return Number of elements contained in the container.
  1316. //!
  1317. //! @par Throws
  1318. //! Nothing.
  1319. //!
  1320. //! @par Complexity
  1321. //! Constant O(1).
  1322. size_type size() const { return m_size; }
  1323. //! @brief Queries if the container contains elements.
  1324. //!
  1325. //! @return true if the number of elements contained in the
  1326. //! container is equal to 0.
  1327. //!
  1328. //! @par Throws
  1329. //! Nothing.
  1330. //!
  1331. //! @par Complexity
  1332. //! Constant O(1).
  1333. bool empty() const { return 0 == m_size; }
  1334. private:
  1335. // @par Throws
  1336. // Nothing.
  1337. // @par Complexity
  1338. // Linear O(N).
  1339. template <std::size_t C>
  1340. void move_ctor_dispatch(varray<value_type, C> & other, std::true_type /*use_memop*/)
  1341. {
  1342. ::memcpy(this->data(), other.data(), sizeof(Value) * other.m_size);
  1343. m_size = other.m_size;
  1344. }
  1345. // @par Throws
  1346. // @li If boost::has_nothrow_move<Value>::value is true and Value's move constructor throws
  1347. // @li If boost::has_nothrow_move<Value>::value is false and Value's copy constructor throws.
  1348. // @par Complexity
  1349. // Linear O(N).
  1350. template <std::size_t C>
  1351. void move_ctor_dispatch(varray<value_type, C> & other, std::false_type /*use_memop*/)
  1352. {
  1353. namespace sv = varray_detail;
  1354. sv::uninitialized_move_if_noexcept(other.begin(), other.end(), this->begin()); // may throw
  1355. m_size = other.m_size;
  1356. }
  1357. // @par Throws
  1358. // Nothing.
  1359. // @par Complexity
  1360. // Linear O(N).
  1361. template <std::size_t C>
  1362. void move_assign_dispatch(varray<value_type, C> & other, std::true_type /*use_memop*/)
  1363. {
  1364. this->clear();
  1365. ::memcpy(this->data(), other.data(), sizeof(Value) * other.m_size);
  1366. std::swap(m_size, other.m_size);
  1367. }
  1368. // @par Throws
  1369. // @li If boost::has_nothrow_move<Value>::value is true and Value's move constructor or move assignment throws
  1370. // @li If boost::has_nothrow_move<Value>::value is false and Value's copy constructor or move assignment throws.
  1371. // @par Complexity
  1372. // Linear O(N).
  1373. template <std::size_t C>
  1374. void move_assign_dispatch(varray<value_type, C> & other, std::false_type /*use_memop*/)
  1375. {
  1376. namespace sv = varray_detail;
  1377. if ( m_size <= static_cast<size_type>(other.size()) )
  1378. {
  1379. sv::move_if_noexcept(other.begin(), other.begin() + m_size, this->begin()); // may throw
  1380. // TODO - perform uninitialized_copy first?
  1381. sv::uninitialized_move_if_noexcept(other.begin() + m_size, other.end(), this->end()); // may throw
  1382. }
  1383. else
  1384. {
  1385. sv::move_if_noexcept(other.begin(), other.end(), this->begin()); // may throw
  1386. sv::destroy(this->begin() + other.size(), this->end());
  1387. }
  1388. m_size = other.size(); // update end
  1389. }
  1390. // @par Throws
  1391. // Nothing.
  1392. // @par Complexity
  1393. // Linear O(N).
  1394. template <std::size_t C>
  1395. void swap_dispatch(varray<value_type, C> & other, std::true_type /*use_optimized_swap*/)
  1396. {
  1397. typedef std::conditional_t
  1398. <
  1399. (Capacity < C),
  1400. aligned_storage_type,
  1401. typename varray<value_type, C>::aligned_storage_type
  1402. > storage_type;
  1403. storage_type temp;
  1404. Value * temp_ptr = reinterpret_cast<Value*>(temp.address());
  1405. ::memcpy(temp_ptr, this->data(), sizeof(Value) * this->size());
  1406. ::memcpy(this->data(), other.data(), sizeof(Value) * other.size());
  1407. ::memcpy(other.data(), temp_ptr, sizeof(Value) * this->size());
  1408. std::swap(m_size, other.m_size);
  1409. }
  1410. // @par Throws
  1411. // If Value's move constructor or move assignment throws
  1412. // but only if use_memop_in_swap_and_move is false_type - default.
  1413. // @par Complexity
  1414. // Linear O(N).
  1415. template <std::size_t C>
  1416. void swap_dispatch(varray<value_type, C> & other, std::false_type /*use_optimized_swap*/)
  1417. {
  1418. namespace sv = varray_detail;
  1419. typedef typename
  1420. vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
  1421. if ( this->size() < other.size() )
  1422. swap_dispatch_impl(this->begin(), this->end(), other.begin(), other.end(), use_memop_in_swap_and_move()); // may throw
  1423. else
  1424. swap_dispatch_impl(other.begin(), other.end(), this->begin(), this->end(), use_memop_in_swap_and_move()); // may throw
  1425. std::swap(m_size, other.m_size);
  1426. }
  1427. // @par Throws
  1428. // Nothing.
  1429. // @par Complexity
  1430. // Linear O(N).
  1431. void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, std::true_type /*use_memop*/)
  1432. {
  1433. //BOOST_GEOMETRY_INDEX_ASSERT(std::distance(first_sm, last_sm) <= std::distance(first_la, last_la),
  1434. // "incompatible ranges");
  1435. namespace sv = varray_detail;
  1436. for (; first_sm != last_sm ; ++first_sm, ++first_la)
  1437. {
  1438. boost::aligned_storage<
  1439. sizeof(value_type),
  1440. boost::alignment_of<value_type>::value
  1441. > temp_storage;
  1442. value_type * temp_ptr = reinterpret_cast<value_type*>(temp_storage.address());
  1443. ::memcpy(temp_ptr, boost::addressof(*first_sm), sizeof(value_type));
  1444. ::memcpy(boost::addressof(*first_sm), boost::addressof(*first_la), sizeof(value_type));
  1445. ::memcpy(boost::addressof(*first_la), temp_ptr, sizeof(value_type));
  1446. }
  1447. ::memcpy(first_sm, first_la, sizeof(value_type) * std::distance(first_la, last_la));
  1448. }
  1449. // @par Throws
  1450. // If Value's move constructor or move assignment throws.
  1451. // @par Complexity
  1452. // Linear O(N).
  1453. void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, std::false_type /*use_memop*/)
  1454. {
  1455. //BOOST_GEOMETRY_INDEX_ASSERT(std::distance(first_sm, last_sm) <= std::distance(first_la, last_la),
  1456. // "incompatible ranges");
  1457. namespace sv = varray_detail;
  1458. for (; first_sm != last_sm ; ++first_sm, ++first_la)
  1459. {
  1460. //boost::swap(*first_sm, *first_la); // may throw
  1461. value_type temp(boost::move(*first_sm)); // may throw
  1462. *first_sm = boost::move(*first_la); // may throw
  1463. *first_la = boost::move(temp); // may throw
  1464. }
  1465. sv::uninitialized_move(first_la, last_la, first_sm); // may throw
  1466. sv::destroy(first_la, last_la);
  1467. }
  1468. // insert
  1469. // @par Throws
  1470. // If Value's move constructor, move assignment throws
  1471. // or if Value's copy constructor or copy assignment throws.
  1472. // @par Complexity
  1473. // Linear O(N).
  1474. template <typename Iterator>
  1475. void insert_dispatch(iterator position, Iterator first, Iterator last, boost::random_access_traversal_tag const&)
  1476. {
  1477. BOOST_CONCEPT_ASSERT((boost_concepts::RandomAccessTraversal<Iterator>)); // Make sure you passed a RandomAccessIterator
  1478. errh::check_iterator_end_eq(*this, position);
  1479. typename boost::iterator_difference<Iterator>::type
  1480. count = std::distance(first, last);
  1481. errh::check_capacity(*this, m_size + count); // may throw
  1482. if ( position == this->end() )
  1483. {
  1484. namespace sv = varray_detail;
  1485. sv::uninitialized_copy(first, last, position); // may throw
  1486. m_size += count; // update end
  1487. }
  1488. else
  1489. {
  1490. this->insert_in_the_middle(position, first, last, count); // may throw
  1491. }
  1492. }
  1493. // @par Throws
  1494. // If Value's move constructor, move assignment throws
  1495. // or if Value's copy constructor or copy assignment throws.
  1496. // @par Complexity
  1497. // Linear O(N).
  1498. template <typename Iterator, typename Traversal>
  1499. void insert_dispatch(iterator position, Iterator first, Iterator last, Traversal const& /*not_random_access*/)
  1500. {
  1501. errh::check_iterator_end_eq(*this, position);
  1502. if ( position == this->end() )
  1503. {
  1504. namespace sv = varray_detail;
  1505. std::ptrdiff_t d = std::distance(position, this->begin() + Capacity);
  1506. std::size_t count = sv::uninitialized_copy_s(first, last, position, d); // may throw
  1507. errh::check_capacity(*this, count <= static_cast<std::size_t>(d) ? m_size + count : Capacity + 1); // may throw
  1508. m_size += count;
  1509. }
  1510. else
  1511. {
  1512. typename boost::iterator_difference<Iterator>::type
  1513. count = std::distance(first, last);
  1514. errh::check_capacity(*this, m_size + count); // may throw
  1515. this->insert_in_the_middle(position, first, last, count); // may throw
  1516. }
  1517. }
  1518. // @par Throws
  1519. // If Value's move constructor, move assignment throws
  1520. // or if Value's copy constructor or copy assignment throws.
  1521. // @par Complexity
  1522. // Linear O(N).
  1523. template <typename Iterator>
  1524. void insert_in_the_middle(iterator position, Iterator first, Iterator last, difference_type count)
  1525. {
  1526. namespace sv = varray_detail;
  1527. difference_type to_move = std::distance(position, this->end());
  1528. // TODO - should following lines check for exception and revert to the old size?
  1529. if ( count < to_move )
  1530. {
  1531. sv::uninitialized_move(this->end() - count, this->end(), this->end()); // may throw
  1532. m_size += count; // update end
  1533. sv::move_backward(position, position + to_move - count, this->end() - count); // may throw
  1534. sv::copy(first, last, position); // may throw
  1535. }
  1536. else
  1537. {
  1538. Iterator middle_iter = first;
  1539. std::advance(middle_iter, to_move);
  1540. sv::uninitialized_copy(middle_iter, last, this->end()); // may throw
  1541. m_size += count - to_move; // update end
  1542. sv::uninitialized_move(position, position + to_move, position + count); // may throw
  1543. m_size += to_move; // update end
  1544. sv::copy(first, middle_iter, position); // may throw
  1545. }
  1546. }
  1547. // assign
  1548. // @par Throws
  1549. // If Value's constructor or assignment taking dereferenced Iterator throws.
  1550. // @par Complexity
  1551. // Linear O(N).
  1552. template <typename Iterator>
  1553. void assign_dispatch(Iterator first, Iterator last, boost::random_access_traversal_tag const& /*not_random_access*/)
  1554. {
  1555. namespace sv = varray_detail;
  1556. typename boost::iterator_difference<Iterator>::type
  1557. s = std::distance(first, last);
  1558. errh::check_capacity(*this, s); // may throw
  1559. if ( m_size <= static_cast<size_type>(s) )
  1560. {
  1561. sv::copy(first, first + m_size, this->begin()); // may throw
  1562. // TODO - perform uninitialized_copy first?
  1563. sv::uninitialized_copy(first + m_size, last, this->end()); // may throw
  1564. }
  1565. else
  1566. {
  1567. sv::copy(first, last, this->begin()); // may throw
  1568. sv::destroy(this->begin() + s, this->end());
  1569. }
  1570. m_size = s; // update end
  1571. }
  1572. // @par Throws
  1573. // If Value's constructor or assignment taking dereferenced Iterator throws.
  1574. // @par Complexity
  1575. // Linear O(N).
  1576. template <typename Iterator, typename Traversal>
  1577. void assign_dispatch(Iterator first, Iterator last, Traversal const& /*not_random_access*/)
  1578. {
  1579. namespace sv = varray_detail;
  1580. size_type s = 0;
  1581. iterator it = this->begin();
  1582. for ( ; it != this->end() && first != last ; ++it, ++first, ++s )
  1583. *it = *first; // may throw
  1584. sv::destroy(it, this->end());
  1585. std::ptrdiff_t d = std::distance(it, this->begin() + Capacity);
  1586. std::size_t count = sv::uninitialized_copy_s(first, last, it, d); // may throw
  1587. s += count;
  1588. errh::check_capacity(*this, count <= static_cast<std::size_t>(d) ? s : Capacity + 1); // may throw
  1589. m_size = s; // update end
  1590. }
  1591. pointer ptr()
  1592. {
  1593. return pointer(static_cast<Value*>(m_storage.address()));
  1594. }
  1595. const_pointer ptr() const
  1596. {
  1597. return const_pointer(static_cast<const Value*>(m_storage.address()));
  1598. }
  1599. size_type m_size;
  1600. aligned_storage_type m_storage;
  1601. };
  1602. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1603. template<typename Value>
  1604. class varray<Value, 0>
  1605. {
  1606. typedef varray_detail::varray_traits<Value, 0> vt;
  1607. typedef varray_detail::checker<varray> errh;
  1608. public:
  1609. typedef typename vt::value_type value_type;
  1610. typedef typename vt::size_type size_type;
  1611. typedef typename vt::difference_type difference_type;
  1612. typedef typename vt::pointer pointer;
  1613. typedef typename vt::const_pointer const_pointer;
  1614. typedef typename vt::reference reference;
  1615. typedef typename vt::const_reference const_reference;
  1616. typedef pointer iterator;
  1617. typedef const_pointer const_iterator;
  1618. typedef boost::reverse_iterator<iterator> reverse_iterator;
  1619. typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
  1620. // nothrow
  1621. varray() {}
  1622. // strong
  1623. explicit varray(size_type count)
  1624. {
  1625. errh::check_capacity(*this, count); // may throw
  1626. }
  1627. // strong
  1628. varray(size_type count, value_type const&)
  1629. {
  1630. errh::check_capacity(*this, count); // may throw
  1631. }
  1632. // strong
  1633. varray(varray const& /*other*/)
  1634. {
  1635. //errh::check_capacity(*this, count);
  1636. }
  1637. // strong
  1638. template <std::size_t C>
  1639. varray(varray<value_type, C> const& other)
  1640. {
  1641. errh::check_capacity(*this, other.size()); // may throw
  1642. }
  1643. // strong
  1644. template <typename Iterator>
  1645. varray(Iterator first, Iterator last)
  1646. {
  1647. errh::check_capacity(*this, std::distance(first, last)); // may throw
  1648. }
  1649. // basic
  1650. varray & operator=(varray const& /*other*/)
  1651. {
  1652. //errh::check_capacity(*this, other.size());
  1653. return *this;
  1654. }
  1655. // basic
  1656. template <size_t C>
  1657. varray & operator=(varray<value_type, C> const& other)
  1658. {
  1659. errh::check_capacity(*this, other.size()); // may throw
  1660. return *this;
  1661. }
  1662. // nothrow
  1663. ~varray() {}
  1664. // strong
  1665. void resize(size_type count)
  1666. {
  1667. errh::check_capacity(*this, count); // may throw
  1668. }
  1669. // strong
  1670. void resize(size_type count, value_type const&)
  1671. {
  1672. errh::check_capacity(*this, count); // may throw
  1673. }
  1674. // nothrow
  1675. void reserve(size_type count)
  1676. {
  1677. errh::check_capacity(*this, count); // may throw
  1678. }
  1679. // strong
  1680. void push_back(value_type const&)
  1681. {
  1682. errh::check_capacity(*this, 1); // may throw
  1683. }
  1684. // nothrow
  1685. void pop_back()
  1686. {
  1687. errh::check_not_empty(*this);
  1688. }
  1689. // basic
  1690. void insert(iterator position, value_type const&)
  1691. {
  1692. errh::check_iterator_end_eq(*this, position);
  1693. errh::check_capacity(*this, 1); // may throw
  1694. }
  1695. // basic
  1696. void insert(iterator position, size_type count, value_type const&)
  1697. {
  1698. errh::check_iterator_end_eq(*this, position);
  1699. errh::check_capacity(*this, count); // may throw
  1700. }
  1701. // basic
  1702. template <typename Iterator>
  1703. void insert(iterator, Iterator first, Iterator last)
  1704. {
  1705. // TODO - add BOOST_GEOMETRY_STATIC_ASSERT, check if Iterator is really an iterator
  1706. errh::check_capacity(*this, std::distance(first, last)); // may throw
  1707. }
  1708. // basic
  1709. void erase(iterator position)
  1710. {
  1711. errh::check_iterator_end_neq(*this, position);
  1712. }
  1713. // basic
  1714. void erase(iterator first, iterator last)
  1715. {
  1716. errh::check_iterator_end_eq(*this, first);
  1717. errh::check_iterator_end_eq(*this, last);
  1718. //BOOST_GEOMETRY_INDEX_ASSERT(0 <= n, "invalid range");
  1719. }
  1720. // basic
  1721. template <typename Iterator>
  1722. void assign(Iterator first, Iterator last)
  1723. {
  1724. // TODO - add BOOST_GEOMETRY_STATIC_ASSERT, check if Iterator is really an iterator
  1725. errh::check_capacity(*this, std::distance(first, last)); // may throw
  1726. }
  1727. // basic
  1728. void assign(size_type count, value_type const&)
  1729. {
  1730. errh::check_capacity(*this, count); // may throw
  1731. }
  1732. // nothrow
  1733. void clear() {}
  1734. // strong
  1735. reference at(size_type i)
  1736. {
  1737. errh::throw_out_of_bounds(*this, i); // may throw
  1738. return *(this->begin() + i);
  1739. }
  1740. // strong
  1741. const_reference at(size_type i) const
  1742. {
  1743. errh::throw_out_of_bounds(*this, i); // may throw
  1744. return *(this->begin() + i);
  1745. }
  1746. // nothrow
  1747. reference operator[](size_type i)
  1748. {
  1749. errh::check_index(*this, i);
  1750. return *(this->begin() + i);
  1751. }
  1752. // nothrow
  1753. const_reference operator[](size_type i) const
  1754. {
  1755. errh::check_index(*this, i);
  1756. return *(this->begin() + i);
  1757. }
  1758. // nothrow
  1759. reference front()
  1760. {
  1761. errh::check_not_empty(*this);
  1762. return *(this->begin());
  1763. }
  1764. // nothrow
  1765. const_reference front() const
  1766. {
  1767. errh::check_not_empty(*this);
  1768. return *(this->begin());
  1769. }
  1770. // nothrow
  1771. reference back()
  1772. {
  1773. errh::check_not_empty(*this);
  1774. return *(this->end() - 1);
  1775. }
  1776. // nothrow
  1777. const_reference back() const
  1778. {
  1779. errh::check_not_empty(*this);
  1780. return *(this->end() - 1);
  1781. }
  1782. // nothrow
  1783. Value * data() { return boost::addressof(*(this->ptr())); }
  1784. const Value * data() const { return boost::addressof(*(this->ptr())); }
  1785. // nothrow
  1786. iterator begin() { return this->ptr(); }
  1787. const_iterator begin() const { return this->ptr(); }
  1788. const_iterator cbegin() const { return this->ptr(); }
  1789. iterator end() { return this->begin(); }
  1790. const_iterator end() const { return this->begin(); }
  1791. const_iterator cend() const { return this->cbegin(); }
  1792. // nothrow
  1793. reverse_iterator rbegin() { return reverse_iterator(this->end()); }
  1794. const_reverse_iterator rbegin() const { return reverse_iterator(this->end()); }
  1795. const_reverse_iterator crbegin() const { return reverse_iterator(this->end()); }
  1796. reverse_iterator rend() { return reverse_iterator(this->begin()); }
  1797. const_reverse_iterator rend() const { return reverse_iterator(this->begin()); }
  1798. const_reverse_iterator crend() const { return reverse_iterator(this->begin()); }
  1799. // nothrow
  1800. size_type capacity() const { return 0; }
  1801. size_type max_size() const { return 0; }
  1802. size_type size() const { return 0; }
  1803. bool empty() const { return true; }
  1804. private:
  1805. pointer ptr()
  1806. {
  1807. return pointer(reinterpret_cast<Value*>(this));
  1808. }
  1809. const_pointer ptr() const
  1810. {
  1811. return const_pointer(reinterpret_cast<const Value*>(this));
  1812. }
  1813. };
  1814. #endif // !BOOST_CONTAINER_DOXYGEN_INVOKED
  1815. //! @brief Checks if contents of two varrays are equal.
  1816. //!
  1817. //! @ingroup varray_non_member
  1818. //!
  1819. //! @param x The first varray.
  1820. //! @param y The second varray.
  1821. //!
  1822. //! @return \c true if containers have the same size and elements in both containers are equal.
  1823. //!
  1824. //! @par Complexity
  1825. //! Linear O(N).
  1826. template<typename V, std::size_t C1, std::size_t C2>
  1827. bool operator== (varray<V, C1> const& x, varray<V, C2> const& y)
  1828. {
  1829. return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin());
  1830. }
  1831. //! @brief Checks if contents of two varrays are not equal.
  1832. //!
  1833. //! @ingroup varray_non_member
  1834. //!
  1835. //! @param x The first varray.
  1836. //! @param y The second varray.
  1837. //!
  1838. //! @return \c true if containers have different size or elements in both containers are not equal.
  1839. //!
  1840. //! @par Complexity
  1841. //! Linear O(N).
  1842. template<typename V, std::size_t C1, std::size_t C2>
  1843. bool operator!= (varray<V, C1> const& x, varray<V, C2> const& y)
  1844. {
  1845. return !(x==y);
  1846. }
  1847. //! @brief Lexicographically compares varrays.
  1848. //!
  1849. //! @ingroup varray_non_member
  1850. //!
  1851. //! @param x The first varray.
  1852. //! @param y The second varray.
  1853. //!
  1854. //! @return \c true if x compares lexicographically less than y.
  1855. //!
  1856. //! @par Complexity
  1857. //! Linear O(N).
  1858. template<typename V, std::size_t C1, std::size_t C2>
  1859. bool operator< (varray<V, C1> const& x, varray<V, C2> const& y)
  1860. {
  1861. return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
  1862. }
  1863. //! @brief Lexicographically compares varrays.
  1864. //!
  1865. //! @ingroup varray_non_member
  1866. //!
  1867. //! @param x The first varray.
  1868. //! @param y The second varray.
  1869. //!
  1870. //! @return \c true if y compares lexicographically less than x.
  1871. //!
  1872. //! @par Complexity
  1873. //! Linear O(N).
  1874. template<typename V, std::size_t C1, std::size_t C2>
  1875. bool operator> (varray<V, C1> const& x, varray<V, C2> const& y)
  1876. {
  1877. return y<x;
  1878. }
  1879. //! @brief Lexicographically compares varrays.
  1880. //!
  1881. //! @ingroup varray_non_member
  1882. //!
  1883. //! @param x The first varray.
  1884. //! @param y The second varray.
  1885. //!
  1886. //! @return \c true if y don't compare lexicographically less than x.
  1887. //!
  1888. //! @par Complexity
  1889. //! Linear O(N).
  1890. template<typename V, std::size_t C1, std::size_t C2>
  1891. bool operator<= (varray<V, C1> const& x, varray<V, C2> const& y)
  1892. {
  1893. return !(y<x);
  1894. }
  1895. //! @brief Lexicographically compares varrays.
  1896. //!
  1897. //! @ingroup varray_non_member
  1898. //!
  1899. //! @param x The first varray.
  1900. //! @param y The second varray.
  1901. //!
  1902. //! @return \c true if x don't compare lexicographically less than y.
  1903. //!
  1904. //! @par Complexity
  1905. //! Linear O(N).
  1906. template<typename V, std::size_t C1, std::size_t C2>
  1907. bool operator>= (varray<V, C1> const& x, varray<V, C2> const& y)
  1908. {
  1909. return !(x<y);
  1910. }
  1911. //! @brief Swaps contents of two varrays.
  1912. //!
  1913. //! This function calls varray::swap().
  1914. //!
  1915. //! @ingroup varray_non_member
  1916. //!
  1917. //! @param x The first varray.
  1918. //! @param y The second varray.
  1919. //!
  1920. //! @par Complexity
  1921. //! Linear O(N).
  1922. template<typename V, std::size_t C1, std::size_t C2>
  1923. inline void swap(varray<V, C1> & x, varray<V, C2> & y)
  1924. {
  1925. x.swap(y);
  1926. }
  1927. }}}} // namespace boost::geometry::index::detail
  1928. // TODO - REMOVE/CHANGE
  1929. #include <boost/container/detail/config_end.hpp>
  1930. #endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_HPP