varray.hpp 76 KB

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