varray.hpp 75 KB

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