varray.hpp 70 KB

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