varray.hpp 76 KB

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