stable_vector.hpp 77 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2008-2015. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/container for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. // Stable vector.
  11. //
  12. // Copyright 2008 Joaquin M Lopez Munoz.
  13. // Distributed under the Boost Software License, Version 1.0.
  14. // (See accompanying file LICENSE_1_0.txt or copy at
  15. // http://www.boost.org/LICENSE_1_0.txt)
  16. //
  17. //////////////////////////////////////////////////////////////////////////////
  18. #ifndef BOOST_CONTAINER_STABLE_VECTOR_HPP
  19. #define BOOST_CONTAINER_STABLE_VECTOR_HPP
  20. #ifndef BOOST_CONFIG_HPP
  21. # include <boost/config.hpp>
  22. #endif
  23. #if defined(BOOST_HAS_PRAGMA_ONCE)
  24. # pragma once
  25. #endif
  26. #include <boost/container/detail/config_begin.hpp>
  27. #include <boost/container/detail/workaround.hpp>
  28. // container
  29. #include <boost/container/allocator_traits.hpp>
  30. #include <boost/container/container_fwd.hpp>
  31. #include <boost/container/new_allocator.hpp> //new_allocator
  32. #include <boost/container/throw_exception.hpp>
  33. // container/detail
  34. #include <boost/container/detail/addressof.hpp>
  35. #include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
  36. #include <boost/container/detail/alloc_helpers.hpp>
  37. #include <boost/container/detail/allocator_version_traits.hpp>
  38. #include <boost/container/detail/construct_in_place.hpp>
  39. #include <boost/container/detail/iterator.hpp>
  40. #include <boost/container/detail/iterators.hpp>
  41. #include <boost/container/detail/placement_new.hpp>
  42. #include <boost/container/detail/to_raw_pointer.hpp>
  43. #include <boost/container/detail/type_traits.hpp>
  44. // intrusive
  45. #include <boost/intrusive/pointer_traits.hpp>
  46. // intrusive/detail
  47. #include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
  48. // move
  49. #include <boost/move/utility_core.hpp>
  50. #include <boost/move/iterator.hpp>
  51. #include <boost/move/adl_move_swap.hpp>
  52. // move/detail
  53. #include <boost/move/detail/move_helpers.hpp>
  54. // other
  55. #include <boost/assert.hpp>
  56. #include <boost/core/no_exceptions_support.hpp>
  57. // std
  58. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  59. #include <initializer_list>
  60. #endif
  61. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  62. #include <boost/container/vector.hpp>
  63. //#define STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
  64. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  65. namespace boost {
  66. namespace container {
  67. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  68. namespace stable_vector_detail{
  69. template <class C>
  70. class clear_on_destroy
  71. {
  72. public:
  73. clear_on_destroy(C &c)
  74. : c_(c), do_clear_(true)
  75. {}
  76. void release()
  77. { do_clear_ = false; }
  78. ~clear_on_destroy()
  79. {
  80. if(do_clear_){
  81. c_.clear();
  82. c_.priv_clear_pool();
  83. }
  84. }
  85. private:
  86. clear_on_destroy(const clear_on_destroy &);
  87. clear_on_destroy &operator=(const clear_on_destroy &);
  88. C &c_;
  89. bool do_clear_;
  90. };
  91. template<typename Pointer>
  92. struct node;
  93. template<class VoidPtr>
  94. struct node_base
  95. {
  96. private:
  97. typedef typename boost::intrusive::
  98. pointer_traits<VoidPtr> void_ptr_traits;
  99. typedef typename void_ptr_traits::
  100. template rebind_pointer
  101. <node_base>::type node_base_ptr;
  102. typedef typename void_ptr_traits::
  103. template rebind_pointer
  104. <node_base_ptr>::type node_base_ptr_ptr;
  105. public:
  106. node_base(const node_base_ptr_ptr &n)
  107. : up(n)
  108. {}
  109. node_base()
  110. : up()
  111. {}
  112. node_base_ptr_ptr up;
  113. };
  114. template<typename Pointer>
  115. struct node
  116. : public node_base
  117. <typename ::boost::intrusive::pointer_traits<Pointer>::template
  118. rebind_pointer<void>::type
  119. >
  120. {
  121. private:
  122. node();
  123. public:
  124. typename ::boost::intrusive::pointer_traits<Pointer>::element_type value;
  125. };
  126. template<class VoidPtr, class VoidAllocator>
  127. struct index_traits
  128. {
  129. typedef boost::intrusive::
  130. pointer_traits
  131. <VoidPtr> void_ptr_traits;
  132. typedef stable_vector_detail::
  133. node_base<VoidPtr> node_base_type;
  134. typedef typename void_ptr_traits::template
  135. rebind_pointer<node_base_type>::type node_base_ptr;
  136. typedef typename void_ptr_traits::template
  137. rebind_pointer<node_base_ptr>::type node_base_ptr_ptr;
  138. typedef boost::intrusive::
  139. pointer_traits<node_base_ptr> node_base_ptr_traits;
  140. typedef boost::intrusive::
  141. pointer_traits<node_base_ptr_ptr> node_base_ptr_ptr_traits;
  142. typedef typename allocator_traits<VoidAllocator>::
  143. template portable_rebind_alloc
  144. <node_base_ptr>::type node_base_ptr_allocator;
  145. typedef ::boost::container::vector
  146. <node_base_ptr, node_base_ptr_allocator> index_type;
  147. typedef typename index_type::iterator index_iterator;
  148. typedef typename index_type::const_iterator const_index_iterator;
  149. typedef typename index_type::size_type size_type;
  150. static const size_type ExtraPointers = 3;
  151. //Stable vector stores metadata at the end of the index (node_base_ptr vector) with additional 3 pointers:
  152. // back() is this->index.back() - ExtraPointers;
  153. // end node index is *(this->index.end() - 3)
  154. // Node cache first is *(this->index.end() - 2);
  155. // Node cache last is this->index.back();
  156. static node_base_ptr_ptr ptr_to_node_base_ptr(node_base_ptr &n)
  157. { return node_base_ptr_ptr_traits::pointer_to(n); }
  158. static void fix_up_pointers(index_iterator first, index_iterator last)
  159. {
  160. while(first != last){
  161. typedef typename index_type::reference node_base_ptr_ref;
  162. node_base_ptr_ref nbp = *first;
  163. nbp->up = index_traits::ptr_to_node_base_ptr(nbp);
  164. ++first;
  165. }
  166. }
  167. static index_iterator get_fix_up_end(index_type &index)
  168. { return index.end() - (ExtraPointers - 1); }
  169. static void fix_up_pointers_from(index_type & index, index_iterator first)
  170. { index_traits::fix_up_pointers(first, index_traits::get_fix_up_end(index)); }
  171. static void readjust_end_node(index_type &index, node_base_type &end_node)
  172. {
  173. if(!index.empty()){
  174. index_iterator end_node_it(index_traits::get_fix_up_end(index));
  175. node_base_ptr &end_node_idx_ref = *(--end_node_it);
  176. end_node_idx_ref = node_base_ptr_traits::pointer_to(end_node);
  177. end_node.up = node_base_ptr_ptr_traits::pointer_to(end_node_idx_ref);
  178. }
  179. else{
  180. end_node.up = node_base_ptr_ptr();
  181. }
  182. }
  183. static void initialize_end_node(index_type &index, node_base_type &end_node, const size_type index_capacity_if_empty)
  184. {
  185. if(index.empty()){
  186. index.reserve(index_capacity_if_empty + ExtraPointers);
  187. index.resize(ExtraPointers);
  188. node_base_ptr &end_node_ref = *index.data();
  189. end_node_ref = node_base_ptr_traits::pointer_to(end_node);
  190. end_node.up = index_traits::ptr_to_node_base_ptr(end_node_ref);
  191. }
  192. }
  193. #ifdef STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
  194. static bool invariants(index_type &index)
  195. {
  196. for( index_iterator it = index.begin()
  197. , it_end = index_traits::get_fix_up_end(index)
  198. ; it != it_end
  199. ; ++it){
  200. if((*it)->up != index_traits::ptr_to_node_base_ptr(*it)){
  201. return false;
  202. }
  203. }
  204. return true;
  205. }
  206. #endif //STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
  207. };
  208. } //namespace stable_vector_detail
  209. template<typename Pointer, bool IsConst>
  210. class stable_vector_iterator
  211. {
  212. typedef boost::intrusive::pointer_traits<Pointer> non_const_ptr_traits;
  213. public:
  214. typedef std::random_access_iterator_tag iterator_category;
  215. typedef typename non_const_ptr_traits::element_type value_type;
  216. typedef typename non_const_ptr_traits::difference_type difference_type;
  217. typedef typename ::boost::container::container_detail::if_c
  218. < IsConst
  219. , typename non_const_ptr_traits::template
  220. rebind_pointer<const value_type>::type
  221. , Pointer
  222. >::type pointer;
  223. typedef boost::intrusive::pointer_traits<pointer> ptr_traits;
  224. typedef typename ptr_traits::reference reference;
  225. private:
  226. typedef typename non_const_ptr_traits::template
  227. rebind_pointer<void>::type void_ptr;
  228. typedef stable_vector_detail::node<Pointer> node_type;
  229. typedef stable_vector_detail::node_base<void_ptr> node_base_type;
  230. typedef typename non_const_ptr_traits::template
  231. rebind_pointer<node_type>::type node_ptr;
  232. typedef boost::intrusive::
  233. pointer_traits<node_ptr> node_ptr_traits;
  234. typedef typename non_const_ptr_traits::template
  235. rebind_pointer<node_base_type>::type node_base_ptr;
  236. typedef typename non_const_ptr_traits::template
  237. rebind_pointer<node_base_ptr>::type node_base_ptr_ptr;
  238. node_base_ptr m_pn;
  239. public:
  240. explicit stable_vector_iterator(node_base_ptr p) BOOST_NOEXCEPT_OR_NOTHROW
  241. : m_pn(p)
  242. {}
  243. stable_vector_iterator() BOOST_NOEXCEPT_OR_NOTHROW
  244. : m_pn() //Value initialization to achieve "null iterators" (N3644)
  245. {}
  246. stable_vector_iterator(stable_vector_iterator<Pointer, false> const& other) BOOST_NOEXCEPT_OR_NOTHROW
  247. : m_pn(other.node_pointer())
  248. {}
  249. node_ptr node_pointer() const BOOST_NOEXCEPT_OR_NOTHROW
  250. { return node_ptr_traits::static_cast_from(m_pn); }
  251. public:
  252. //Pointer like operators
  253. reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
  254. { return node_pointer()->value; }
  255. pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
  256. { return ptr_traits::pointer_to(this->operator*()); }
  257. //Increment / Decrement
  258. stable_vector_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
  259. {
  260. node_base_ptr_ptr p(this->m_pn->up);
  261. this->m_pn = *(++p);
  262. return *this;
  263. }
  264. stable_vector_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
  265. { stable_vector_iterator tmp(*this); ++*this; return stable_vector_iterator(tmp); }
  266. stable_vector_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
  267. {
  268. node_base_ptr_ptr p(this->m_pn->up);
  269. this->m_pn = *(--p);
  270. return *this;
  271. }
  272. stable_vector_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
  273. { stable_vector_iterator tmp(*this); --*this; return stable_vector_iterator(tmp); }
  274. reference operator[](difference_type off) const BOOST_NOEXCEPT_OR_NOTHROW
  275. { return node_ptr_traits::static_cast_from(this->m_pn->up[off])->value; }
  276. stable_vector_iterator& operator+=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
  277. {
  278. if(off) this->m_pn = this->m_pn->up[off];
  279. return *this;
  280. }
  281. friend stable_vector_iterator operator+(const stable_vector_iterator &left, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
  282. {
  283. stable_vector_iterator tmp(left);
  284. tmp += off;
  285. return tmp;
  286. }
  287. friend stable_vector_iterator operator+(difference_type off, const stable_vector_iterator& right) BOOST_NOEXCEPT_OR_NOTHROW
  288. {
  289. stable_vector_iterator tmp(right);
  290. tmp += off;
  291. return tmp;
  292. }
  293. stable_vector_iterator& operator-=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
  294. { *this += -off; return *this; }
  295. friend stable_vector_iterator operator-(const stable_vector_iterator &left, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
  296. {
  297. stable_vector_iterator tmp(left);
  298. tmp -= off;
  299. return tmp;
  300. }
  301. friend difference_type operator-(const stable_vector_iterator &left, const stable_vector_iterator &right) BOOST_NOEXCEPT_OR_NOTHROW
  302. { return left.m_pn->up - right.m_pn->up; }
  303. //Comparison operators
  304. friend bool operator== (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  305. { return l.m_pn == r.m_pn; }
  306. friend bool operator!= (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  307. { return l.m_pn != r.m_pn; }
  308. friend bool operator< (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  309. { return l.m_pn->up < r.m_pn->up; }
  310. friend bool operator<= (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  311. { return l.m_pn->up <= r.m_pn->up; }
  312. friend bool operator> (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  313. { return l.m_pn->up > r.m_pn->up; }
  314. friend bool operator>= (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  315. { return l.m_pn->up >= r.m_pn->up; }
  316. };
  317. #if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
  318. #define STABLE_VECTOR_CHECK_INVARIANT \
  319. invariant_checker BOOST_JOIN(check_invariant_,__LINE__)(*this); \
  320. BOOST_JOIN(check_invariant_,__LINE__).touch();
  321. #else //STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
  322. #define STABLE_VECTOR_CHECK_INVARIANT
  323. #endif //#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
  324. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  325. //! Originally developed by Joaquin M. Lopez Munoz, stable_vector is a std::vector
  326. //! drop-in replacement implemented as a node container, offering iterator and reference
  327. //! stability.
  328. //!
  329. //! Here are the details taken from the author's blog
  330. //! (<a href="http://bannalia.blogspot.com/2008/09/introducing-stablevector.html" >
  331. //! Introducing stable_vector</a>):
  332. //!
  333. //! We present stable_vector, a fully STL-compliant stable container that provides
  334. //! most of the features of std::vector except element contiguity.
  335. //!
  336. //! General properties: stable_vector satisfies all the requirements of a container,
  337. //! a reversible container and a sequence and provides all the optional operations
  338. //! present in std::vector. Like std::vector, iterators are random access.
  339. //! stable_vector does not provide element contiguity; in exchange for this absence,
  340. //! the container is stable, i.e. references and iterators to an element of a stable_vector
  341. //! remain valid as long as the element is not erased, and an iterator that has been
  342. //! assigned the return value of end() always remain valid until the destruction of
  343. //! the associated stable_vector.
  344. //!
  345. //! Operation complexity: The big-O complexities of stable_vector operations match
  346. //! exactly those of std::vector. In general, insertion/deletion is constant time at
  347. //! the end of the sequence and linear elsewhere. Unlike std::vector, stable_vector
  348. //! does not internally perform any value_type destruction, copy or assignment
  349. //! operations other than those exactly corresponding to the insertion of new
  350. //! elements or deletion of stored elements, which can sometimes compensate in terms
  351. //! of performance for the extra burden of doing more pointer manipulation and an
  352. //! additional allocation per element.
  353. //!
  354. //! Exception safety: As stable_vector does not internally copy elements around, some
  355. //! operations provide stronger exception safety guarantees than in std::vector.
  356. //!
  357. //! \tparam T The type of object that is stored in the stable_vector
  358. //! \tparam Allocator The allocator used for all internal memory management
  359. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
  360. template <class T, class Allocator = new_allocator<T> >
  361. #else
  362. template <class T, class Allocator>
  363. #endif
  364. class stable_vector
  365. {
  366. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  367. typedef allocator_traits<Allocator> allocator_traits_type;
  368. typedef boost::intrusive::
  369. pointer_traits
  370. <typename allocator_traits_type::pointer> ptr_traits;
  371. typedef typename ptr_traits::
  372. template rebind_pointer<void>::type void_ptr;
  373. typedef typename allocator_traits_type::
  374. template portable_rebind_alloc
  375. <void>::type void_allocator_type;
  376. typedef stable_vector_detail::index_traits
  377. <void_ptr, void_allocator_type> index_traits_type;
  378. typedef typename index_traits_type::node_base_type node_base_type;
  379. typedef typename index_traits_type::node_base_ptr node_base_ptr;
  380. typedef typename index_traits_type::
  381. node_base_ptr_ptr node_base_ptr_ptr;
  382. typedef typename index_traits_type::
  383. node_base_ptr_traits node_base_ptr_traits;
  384. typedef typename index_traits_type::
  385. node_base_ptr_ptr_traits node_base_ptr_ptr_traits;
  386. typedef typename index_traits_type::index_type index_type;
  387. typedef typename index_traits_type::index_iterator index_iterator;
  388. typedef typename index_traits_type::
  389. const_index_iterator const_index_iterator;
  390. typedef stable_vector_detail::node
  391. <typename ptr_traits::pointer> node_type;
  392. typedef typename ptr_traits::template
  393. rebind_pointer<node_type>::type node_ptr;
  394. typedef boost::intrusive::
  395. pointer_traits<node_ptr> node_ptr_traits;
  396. typedef typename ptr_traits::template
  397. rebind_pointer<const node_type>::type const_node_ptr;
  398. typedef boost::intrusive::
  399. pointer_traits<const_node_ptr> const_node_ptr_traits;
  400. typedef typename node_ptr_traits::reference node_reference;
  401. typedef typename const_node_ptr_traits::reference const_node_reference;
  402. typedef ::boost::container::container_detail::integral_constant
  403. <unsigned, boost::container::container_detail::
  404. version<Allocator>::value> alloc_version;
  405. typedef typename allocator_traits_type::
  406. template portable_rebind_alloc
  407. <node_type>::type node_allocator_type;
  408. typedef ::boost::container::container_detail::
  409. allocator_version_traits<node_allocator_type> allocator_version_traits_t;
  410. typedef typename allocator_version_traits_t::multiallocation_chain multiallocation_chain;
  411. node_ptr allocate_one()
  412. { return allocator_version_traits_t::allocate_one(this->priv_node_alloc()); }
  413. void deallocate_one(const node_ptr &p)
  414. { allocator_version_traits_t::deallocate_one(this->priv_node_alloc(), p); }
  415. void allocate_individual(typename allocator_traits_type::size_type n, multiallocation_chain &m)
  416. { allocator_version_traits_t::allocate_individual(this->priv_node_alloc(), n, m); }
  417. void deallocate_individual(multiallocation_chain &holder)
  418. { allocator_version_traits_t::deallocate_individual(this->priv_node_alloc(), holder); }
  419. friend class stable_vector_detail::clear_on_destroy<stable_vector>;
  420. typedef stable_vector_iterator
  421. < typename allocator_traits<Allocator>::pointer
  422. , false> iterator_impl;
  423. typedef stable_vector_iterator
  424. < typename allocator_traits<Allocator>::pointer
  425. , true> const_iterator_impl;
  426. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  427. public:
  428. //////////////////////////////////////////////
  429. //
  430. // types
  431. //
  432. //////////////////////////////////////////////
  433. typedef T value_type;
  434. typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
  435. typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
  436. typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
  437. typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
  438. typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
  439. typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
  440. typedef Allocator allocator_type;
  441. typedef node_allocator_type stored_allocator_type;
  442. typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
  443. typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
  444. typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator;
  445. typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
  446. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  447. private:
  448. BOOST_COPYABLE_AND_MOVABLE(stable_vector)
  449. static const size_type ExtraPointers = index_traits_type::ExtraPointers;
  450. class insert_rollback;
  451. friend class insert_rollback;
  452. class push_back_rollback;
  453. friend class push_back_rollback;
  454. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  455. public:
  456. //////////////////////////////////////////////
  457. //
  458. // construct/copy/destroy
  459. //
  460. //////////////////////////////////////////////
  461. //! <b>Effects</b>: Default constructs a stable_vector.
  462. //!
  463. //! <b>Throws</b>: If allocator_type's default constructor throws.
  464. //!
  465. //! <b>Complexity</b>: Constant.
  466. stable_vector()
  467. : internal_data(), index()
  468. {
  469. STABLE_VECTOR_CHECK_INVARIANT;
  470. }
  471. //! <b>Effects</b>: Constructs a stable_vector taking the allocator as parameter.
  472. //!
  473. //! <b>Throws</b>: Nothing
  474. //!
  475. //! <b>Complexity</b>: Constant.
  476. explicit stable_vector(const allocator_type& al) BOOST_NOEXCEPT_OR_NOTHROW
  477. : internal_data(al), index(al)
  478. {
  479. STABLE_VECTOR_CHECK_INVARIANT;
  480. }
  481. //! <b>Effects</b>: Constructs a stable_vector
  482. //! and inserts n value initialized values.
  483. //!
  484. //! <b>Throws</b>: If allocator_type's default constructor
  485. //! throws or T's default or copy constructor throws.
  486. //!
  487. //! <b>Complexity</b>: Linear to n.
  488. explicit stable_vector(size_type n)
  489. : internal_data(), index()
  490. {
  491. stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
  492. this->resize(n);
  493. STABLE_VECTOR_CHECK_INVARIANT;
  494. cod.release();
  495. }
  496. //! <b>Effects</b>: Constructs a stable_vector
  497. //! and inserts n default initialized values.
  498. //!
  499. //! <b>Throws</b>: If allocator_type's default constructor
  500. //! throws or T's default or copy constructor throws.
  501. //!
  502. //! <b>Complexity</b>: Linear to n.
  503. //!
  504. //! <b>Note</b>: Non-standard extension
  505. stable_vector(size_type n, default_init_t)
  506. : internal_data(), index()
  507. {
  508. stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
  509. this->resize(n, default_init);
  510. STABLE_VECTOR_CHECK_INVARIANT;
  511. cod.release();
  512. }
  513. //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
  514. //! and inserts n value initialized values.
  515. //!
  516. //! <b>Throws</b>: If allocator_type's default constructor
  517. //! throws or T's default or copy constructor throws.
  518. //!
  519. //! <b>Complexity</b>: Linear to n.
  520. explicit stable_vector(size_type n, const allocator_type &a)
  521. : internal_data(), index(a)
  522. {
  523. stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
  524. this->resize(n);
  525. STABLE_VECTOR_CHECK_INVARIANT;
  526. cod.release();
  527. }
  528. //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
  529. //! and inserts n default initialized values.
  530. //!
  531. //! <b>Throws</b>: If allocator_type's default constructor
  532. //! throws or T's default or copy constructor throws.
  533. //!
  534. //! <b>Complexity</b>: Linear to n.
  535. //!
  536. //! <b>Note</b>: Non-standard extension
  537. stable_vector(size_type n, default_init_t, const allocator_type &a)
  538. : internal_data(), index(a)
  539. {
  540. stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
  541. this->resize(n, default_init);
  542. STABLE_VECTOR_CHECK_INVARIANT;
  543. cod.release();
  544. }
  545. //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
  546. //! and inserts n copies of value.
  547. //!
  548. //! <b>Throws</b>: If allocator_type's default constructor
  549. //! throws or T's default or copy constructor throws.
  550. //!
  551. //! <b>Complexity</b>: Linear to n.
  552. stable_vector(size_type n, const T& t, const allocator_type& al = allocator_type())
  553. : internal_data(al), index(al)
  554. {
  555. stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
  556. this->insert(this->cend(), n, t);
  557. STABLE_VECTOR_CHECK_INVARIANT;
  558. cod.release();
  559. }
  560. //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
  561. //! and inserts a copy of the range [first, last) in the stable_vector.
  562. //!
  563. //! <b>Throws</b>: If allocator_type's default constructor
  564. //! throws or T's constructor taking a dereferenced InIt throws.
  565. //!
  566. //! <b>Complexity</b>: Linear to the range [first, last).
  567. template <class InputIterator>
  568. stable_vector(InputIterator first,InputIterator last, const allocator_type& al = allocator_type())
  569. : internal_data(al), index(al)
  570. {
  571. stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
  572. this->insert(this->cend(), first, last);
  573. STABLE_VECTOR_CHECK_INVARIANT;
  574. cod.release();
  575. }
  576. //! <b>Effects</b>: Copy constructs a stable_vector.
  577. //!
  578. //! <b>Postcondition</b>: x == *this.
  579. //!
  580. //! <b>Complexity</b>: Linear to the elements x contains.
  581. stable_vector(const stable_vector& x)
  582. : internal_data(allocator_traits<node_allocator_type>::
  583. select_on_container_copy_construction(x.priv_node_alloc()))
  584. , index(allocator_traits<allocator_type>::
  585. select_on_container_copy_construction(x.index.get_stored_allocator()))
  586. {
  587. stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
  588. this->insert(this->cend(), x.begin(), x.end());
  589. STABLE_VECTOR_CHECK_INVARIANT;
  590. cod.release();
  591. }
  592. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  593. //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
  594. //! and inserts a copy of the range [il.begin(), il.last()) in the stable_vector
  595. //!
  596. //! <b>Throws</b>: If allocator_type's default constructor
  597. //! throws or T's constructor taking a dereferenced initializer_list iterator throws.
  598. //!
  599. //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
  600. stable_vector(std::initializer_list<value_type> il, const allocator_type& l = allocator_type())
  601. : internal_data(l), index(l)
  602. {
  603. stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
  604. insert(cend(), il.begin(), il.end());
  605. STABLE_VECTOR_CHECK_INVARIANT;
  606. cod.release();
  607. }
  608. #endif
  609. //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
  610. //!
  611. //! <b>Throws</b>: If allocator_type's copy constructor throws.
  612. //!
  613. //! <b>Complexity</b>: Constant.
  614. stable_vector(BOOST_RV_REF(stable_vector) x)
  615. : internal_data(boost::move(x.priv_node_alloc())), index(boost::move(x.index))
  616. {
  617. this->priv_swap_members(x);
  618. }
  619. //! <b>Effects</b>: Copy constructs a stable_vector using the specified allocator.
  620. //!
  621. //! <b>Postcondition</b>: x == *this.
  622. //!
  623. //! <b>Complexity</b>: Linear to the elements x contains.
  624. stable_vector(const stable_vector& x, const allocator_type &a)
  625. : internal_data(a), index(a)
  626. {
  627. stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
  628. this->insert(this->cend(), x.begin(), x.end());
  629. STABLE_VECTOR_CHECK_INVARIANT;
  630. cod.release();
  631. }
  632. //! <b>Effects</b>: Move constructor using the specified allocator.
  633. //! Moves x's resources to *this.
  634. //!
  635. //! <b>Throws</b>: If allocator_type's copy constructor throws.
  636. //!
  637. //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise
  638. stable_vector(BOOST_RV_REF(stable_vector) x, const allocator_type &a)
  639. : internal_data(a), index(a)
  640. {
  641. if(this->priv_node_alloc() == x.priv_node_alloc()){
  642. this->index.swap(x.index);
  643. this->priv_swap_members(x);
  644. }
  645. else{
  646. stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
  647. this->insert(this->cend(), boost::make_move_iterator(x.begin()), boost::make_move_iterator(x.end()));
  648. STABLE_VECTOR_CHECK_INVARIANT;
  649. cod.release();
  650. }
  651. }
  652. //! <b>Effects</b>: Destroys the stable_vector. All stored values are destroyed
  653. //! and used memory is deallocated.
  654. //!
  655. //! <b>Throws</b>: Nothing.
  656. //!
  657. //! <b>Complexity</b>: Linear to the number of elements.
  658. ~stable_vector()
  659. {
  660. this->clear();
  661. this->priv_clear_pool();
  662. }
  663. //! <b>Effects</b>: Makes *this contain the same elements as x.
  664. //!
  665. //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
  666. //! of each of x's elements.
  667. //!
  668. //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
  669. //!
  670. //! <b>Complexity</b>: Linear to the number of elements in x.
  671. stable_vector& operator=(BOOST_COPY_ASSIGN_REF(stable_vector) x)
  672. {
  673. STABLE_VECTOR_CHECK_INVARIANT;
  674. if (&x != this){
  675. node_allocator_type &this_alloc = this->priv_node_alloc();
  676. const node_allocator_type &x_alloc = x.priv_node_alloc();
  677. container_detail::bool_<allocator_traits_type::
  678. propagate_on_container_copy_assignment::value> flag;
  679. if(flag && this_alloc != x_alloc){
  680. this->clear();
  681. this->shrink_to_fit();
  682. }
  683. container_detail::assign_alloc(this->priv_node_alloc(), x.priv_node_alloc(), flag);
  684. container_detail::assign_alloc(this->index.get_stored_allocator(), x.index.get_stored_allocator(), flag);
  685. this->assign(x.begin(), x.end());
  686. }
  687. return *this;
  688. }
  689. //! <b>Effects</b>: Move assignment. All x's values are transferred to *this.
  690. //!
  691. //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
  692. //! before the function.
  693. //!
  694. //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
  695. //! is false and (allocation throws or T's move constructor throws)
  696. //!
  697. //! <b>Complexity</b>: Constant if allocator_traits_type::
  698. //! propagate_on_container_move_assignment is true or
  699. //! this->get>allocator() == x.get_allocator(). Linear otherwise.
  700. stable_vector& operator=(BOOST_RV_REF(stable_vector) x)
  701. BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
  702. || allocator_traits_type::is_always_equal::value)
  703. {
  704. //for move constructor, no aliasing (&x != this) is assummed.
  705. BOOST_ASSERT(this != &x);
  706. node_allocator_type &this_alloc = this->priv_node_alloc();
  707. node_allocator_type &x_alloc = x.priv_node_alloc();
  708. const bool propagate_alloc = allocator_traits_type::
  709. propagate_on_container_move_assignment::value;
  710. container_detail::bool_<propagate_alloc> flag;
  711. const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
  712. //Resources can be transferred if both allocators are
  713. //going to be equal after this function (either propagated or already equal)
  714. if(propagate_alloc || allocators_equal){
  715. STABLE_VECTOR_CHECK_INVARIANT
  716. //Destroy objects but retain memory in case x reuses it in the future
  717. this->clear();
  718. //Move allocator if needed
  719. container_detail::move_alloc(this_alloc, x_alloc, flag);
  720. //Take resources
  721. this->index.swap(x.index);
  722. this->priv_swap_members(x);
  723. }
  724. //Else do a one by one move
  725. else{
  726. this->assign( boost::make_move_iterator(x.begin())
  727. , boost::make_move_iterator(x.end()));
  728. }
  729. return *this;
  730. }
  731. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  732. //! <b>Effects</b>: Make *this container contains elements from il.
  733. //!
  734. //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
  735. stable_vector& operator=(std::initializer_list<value_type> il)
  736. {
  737. STABLE_VECTOR_CHECK_INVARIANT;
  738. assign(il.begin(), il.end());
  739. return *this;
  740. }
  741. #endif
  742. //! <b>Effects</b>: Assigns the n copies of val to *this.
  743. //!
  744. //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
  745. //!
  746. //! <b>Complexity</b>: Linear to n.
  747. void assign(size_type n, const T& t)
  748. {
  749. typedef constant_iterator<value_type, difference_type> cvalue_iterator;
  750. this->assign(cvalue_iterator(t, n), cvalue_iterator());
  751. }
  752. //! <b>Effects</b>: Assigns the the range [first, last) to *this.
  753. //!
  754. //! <b>Throws</b>: If memory allocation throws or
  755. //! T's constructor from dereferencing InpIt throws.
  756. //!
  757. //! <b>Complexity</b>: Linear to n.
  758. template<typename InputIterator>
  759. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  760. typename container_detail::disable_if_convertible<InputIterator, size_type>::type
  761. #else
  762. void
  763. #endif
  764. assign(InputIterator first,InputIterator last)
  765. {
  766. STABLE_VECTOR_CHECK_INVARIANT;
  767. iterator first1 = this->begin();
  768. iterator last1 = this->end();
  769. for ( ; first1 != last1 && first != last; ++first1, ++first)
  770. *first1 = *first;
  771. if (first == last){
  772. this->erase(first1, last1);
  773. }
  774. else{
  775. this->insert(last1, first, last);
  776. }
  777. }
  778. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  779. //! <b>Effects</b>: Assigns the the range [il.begin(), il.end()) to *this.
  780. //!
  781. //! <b>Throws</b>: If memory allocation throws or
  782. //! T's constructor from dereferencing initializer_list iterator throws.
  783. //!
  784. void assign(std::initializer_list<value_type> il)
  785. {
  786. STABLE_VECTOR_CHECK_INVARIANT;
  787. assign(il.begin(), il.end());
  788. }
  789. #endif
  790. //! <b>Effects</b>: Returns a copy of the internal allocator.
  791. //!
  792. //! <b>Throws</b>: If allocator's copy constructor throws.
  793. //!
  794. //! <b>Complexity</b>: Constant.
  795. allocator_type get_allocator() const
  796. { return this->priv_node_alloc(); }
  797. //! <b>Effects</b>: Returns a reference to the internal allocator.
  798. //!
  799. //! <b>Throws</b>: Nothing
  800. //!
  801. //! <b>Complexity</b>: Constant.
  802. //!
  803. //! <b>Note</b>: Non-standard extension.
  804. const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
  805. { return this->priv_node_alloc(); }
  806. //! <b>Effects</b>: Returns a reference to the internal allocator.
  807. //!
  808. //! <b>Throws</b>: Nothing
  809. //!
  810. //! <b>Complexity</b>: Constant.
  811. //!
  812. //! <b>Note</b>: Non-standard extension.
  813. stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
  814. { return this->priv_node_alloc(); }
  815. //////////////////////////////////////////////
  816. //
  817. // iterators
  818. //
  819. //////////////////////////////////////////////
  820. //! <b>Effects</b>: Returns an iterator to the first element contained in the stable_vector.
  821. //!
  822. //! <b>Throws</b>: Nothing.
  823. //!
  824. //! <b>Complexity</b>: Constant.
  825. iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
  826. { return (this->index.empty()) ? this->end(): iterator(node_ptr_traits::static_cast_from(this->index.front())); }
  827. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the stable_vector.
  828. //!
  829. //! <b>Throws</b>: Nothing.
  830. //!
  831. //! <b>Complexity</b>: Constant.
  832. const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
  833. { return (this->index.empty()) ? this->cend() : const_iterator(node_ptr_traits::static_cast_from(this->index.front())) ; }
  834. //! <b>Effects</b>: Returns an iterator to the end of the stable_vector.
  835. //!
  836. //! <b>Throws</b>: Nothing.
  837. //!
  838. //! <b>Complexity</b>: Constant.
  839. iterator end() BOOST_NOEXCEPT_OR_NOTHROW
  840. { return iterator(this->priv_get_end_node()); }
  841. //! <b>Effects</b>: Returns a const_iterator to the end of the stable_vector.
  842. //!
  843. //! <b>Throws</b>: Nothing.
  844. //!
  845. //! <b>Complexity</b>: Constant.
  846. const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
  847. { return const_iterator(this->priv_get_end_node()); }
  848. //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
  849. //! of the reversed stable_vector.
  850. //!
  851. //! <b>Throws</b>: Nothing.
  852. //!
  853. //! <b>Complexity</b>: Constant.
  854. reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
  855. { return reverse_iterator(this->end()); }
  856. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
  857. //! of the reversed stable_vector.
  858. //!
  859. //! <b>Throws</b>: Nothing.
  860. //!
  861. //! <b>Complexity</b>: Constant.
  862. const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
  863. { return const_reverse_iterator(this->end()); }
  864. //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
  865. //! of the reversed stable_vector.
  866. //!
  867. //! <b>Throws</b>: Nothing.
  868. //!
  869. //! <b>Complexity</b>: Constant.
  870. reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
  871. { return reverse_iterator(this->begin()); }
  872. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
  873. //! of the reversed stable_vector.
  874. //!
  875. //! <b>Throws</b>: Nothing.
  876. //!
  877. //! <b>Complexity</b>: Constant.
  878. const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
  879. { return const_reverse_iterator(this->begin()); }
  880. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the stable_vector.
  881. //!
  882. //! <b>Throws</b>: Nothing.
  883. //!
  884. //! <b>Complexity</b>: Constant.
  885. const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
  886. { return this->begin(); }
  887. //! <b>Effects</b>: Returns a const_iterator to the end of the stable_vector.
  888. //!
  889. //! <b>Throws</b>: Nothing.
  890. //!
  891. //! <b>Complexity</b>: Constant.
  892. const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
  893. { return this->end(); }
  894. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
  895. //! of the reversed stable_vector.
  896. //!
  897. //! <b>Throws</b>: Nothing.
  898. //!
  899. //! <b>Complexity</b>: Constant.
  900. const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
  901. { return this->rbegin(); }
  902. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
  903. //! of the reversed stable_vector.
  904. //!
  905. //! <b>Throws</b>: Nothing.
  906. //!
  907. //! <b>Complexity</b>: Constant.
  908. const_reverse_iterator crend()const BOOST_NOEXCEPT_OR_NOTHROW
  909. { return this->rend(); }
  910. //////////////////////////////////////////////
  911. //
  912. // capacity
  913. //
  914. //////////////////////////////////////////////
  915. //! <b>Effects</b>: Returns true if the stable_vector contains no elements.
  916. //!
  917. //! <b>Throws</b>: Nothing.
  918. //!
  919. //! <b>Complexity</b>: Constant.
  920. bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
  921. { return this->index.size() <= ExtraPointers; }
  922. //! <b>Effects</b>: Returns the number of the elements contained in the stable_vector.
  923. //!
  924. //! <b>Throws</b>: Nothing.
  925. //!
  926. //! <b>Complexity</b>: Constant.
  927. size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
  928. {
  929. const size_type index_size = this->index.size();
  930. return (index_size - ExtraPointers) & (size_type(0u) -size_type(index_size != 0));
  931. }
  932. //! <b>Effects</b>: Returns the largest possible size of the stable_vector.
  933. //!
  934. //! <b>Throws</b>: Nothing.
  935. //!
  936. //! <b>Complexity</b>: Constant.
  937. size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
  938. { return this->index.max_size() - ExtraPointers; }
  939. //! <b>Effects</b>: Inserts or erases elements at the end such that
  940. //! the size becomes n. New elements are value initialized.
  941. //!
  942. //! <b>Throws</b>: If memory allocation throws, or T's value initialization throws.
  943. //!
  944. //! <b>Complexity</b>: Linear to the difference between size() and new_size.
  945. void resize(size_type n)
  946. {
  947. typedef value_init_construct_iterator<value_type, difference_type> value_init_iterator;
  948. STABLE_VECTOR_CHECK_INVARIANT;
  949. if(n > this->size())
  950. this->insert(this->cend(), value_init_iterator(n - this->size()), value_init_iterator());
  951. else if(n < this->size())
  952. this->erase(this->cbegin() + n, this->cend());
  953. }
  954. //! <b>Effects</b>: Inserts or erases elements at the end such that
  955. //! the size becomes n. New elements are default initialized.
  956. //!
  957. //! <b>Throws</b>: If memory allocation throws, or T's default initialization throws.
  958. //!
  959. //! <b>Complexity</b>: Linear to the difference between size() and new_size.
  960. //!
  961. //! <b>Note</b>: Non-standard extension
  962. void resize(size_type n, default_init_t)
  963. {
  964. typedef default_init_construct_iterator<value_type, difference_type> default_init_iterator;
  965. STABLE_VECTOR_CHECK_INVARIANT;
  966. if(n > this->size())
  967. this->insert(this->cend(), default_init_iterator(n - this->size()), default_init_iterator());
  968. else if(n < this->size())
  969. this->erase(this->cbegin() + n, this->cend());
  970. }
  971. //! <b>Effects</b>: Inserts or erases elements at the end such that
  972. //! the size becomes n. New elements are copy constructed from x.
  973. //!
  974. //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
  975. //!
  976. //! <b>Complexity</b>: Linear to the difference between size() and new_size.
  977. void resize(size_type n, const T& t)
  978. {
  979. STABLE_VECTOR_CHECK_INVARIANT;
  980. if(n > this->size())
  981. this->insert(this->cend(), n - this->size(), t);
  982. else if(n < this->size())
  983. this->erase(this->cbegin() + n, this->cend());
  984. }
  985. //! <b>Effects</b>: Number of elements for which memory has been allocated.
  986. //! capacity() is always greater than or equal to size().
  987. //!
  988. //! <b>Throws</b>: Nothing.
  989. //!
  990. //! <b>Complexity</b>: Constant.
  991. size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
  992. {
  993. const size_type index_size = this->index.size();
  994. BOOST_ASSERT(!index_size || index_size >= ExtraPointers);
  995. const size_type node_extra_capacity = this->internal_data.pool_size;
  996. //Pool count must be less than index capacity, as index is a vector
  997. BOOST_ASSERT(node_extra_capacity <= (this->index.capacity()- index_size));
  998. const size_type index_offset =
  999. (node_extra_capacity - ExtraPointers) & (size_type(0u) - size_type(index_size != 0));
  1000. return index_size + index_offset;
  1001. }
  1002. //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
  1003. //! effect. Otherwise, it is a request for allocation of additional memory.
  1004. //! If the request is successful, then capacity() is greater than or equal to
  1005. //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
  1006. //!
  1007. //! <b>Throws</b>: If memory allocation allocation throws.
  1008. void reserve(size_type n)
  1009. {
  1010. STABLE_VECTOR_CHECK_INVARIANT;
  1011. if(n > this->max_size()){
  1012. throw_length_error("stable_vector::reserve max_size() exceeded");
  1013. }
  1014. size_type sz = this->size();
  1015. size_type old_capacity = this->capacity();
  1016. if(n > old_capacity){
  1017. index_traits_type::initialize_end_node(this->index, this->internal_data.end_node, n);
  1018. const void * old_ptr = &index[0];
  1019. this->index.reserve(n + ExtraPointers);
  1020. bool realloced = &index[0] != old_ptr;
  1021. //Fix the pointers for the newly allocated buffer
  1022. if(realloced){
  1023. index_traits_type::fix_up_pointers_from(this->index, this->index.begin());
  1024. }
  1025. //Now fill pool if data is not enough
  1026. if((n - sz) > this->internal_data.pool_size){
  1027. this->priv_increase_pool((n - sz) - this->internal_data.pool_size);
  1028. }
  1029. }
  1030. }
  1031. //! <b>Effects</b>: Tries to deallocate the excess of memory created
  1032. //! with previous allocations. The size of the stable_vector is unchanged
  1033. //!
  1034. //! <b>Throws</b>: If memory allocation throws.
  1035. //!
  1036. //! <b>Complexity</b>: Linear to size().
  1037. void shrink_to_fit()
  1038. {
  1039. if(this->capacity()){
  1040. //First empty allocated node pool
  1041. this->priv_clear_pool();
  1042. //If empty completely destroy the index, let's recover default-constructed state
  1043. if(this->empty()){
  1044. this->index.clear();
  1045. this->index.shrink_to_fit();
  1046. this->internal_data.end_node.up = node_base_ptr_ptr();
  1047. }
  1048. //Otherwise, try to shrink-to-fit the index and readjust pointers if necessary
  1049. else{
  1050. const void* old_ptr = &index[0];
  1051. this->index.shrink_to_fit();
  1052. bool realloced = &index[0] != old_ptr;
  1053. //Fix the pointers for the newly allocated buffer
  1054. if(realloced){
  1055. index_traits_type::fix_up_pointers_from(this->index, this->index.begin());
  1056. }
  1057. }
  1058. }
  1059. }
  1060. //////////////////////////////////////////////
  1061. //
  1062. // element access
  1063. //
  1064. //////////////////////////////////////////////
  1065. //! <b>Requires</b>: !empty()
  1066. //!
  1067. //! <b>Effects</b>: Returns a reference to the first
  1068. //! element of the container.
  1069. //!
  1070. //! <b>Throws</b>: Nothing.
  1071. //!
  1072. //! <b>Complexity</b>: Constant.
  1073. reference front() BOOST_NOEXCEPT_OR_NOTHROW
  1074. {
  1075. BOOST_ASSERT(!this->empty());
  1076. return static_cast<node_reference>(*this->index.front()).value;
  1077. }
  1078. //! <b>Requires</b>: !empty()
  1079. //!
  1080. //! <b>Effects</b>: Returns a const reference to the first
  1081. //! element of the container.
  1082. //!
  1083. //! <b>Throws</b>: Nothing.
  1084. //!
  1085. //! <b>Complexity</b>: Constant.
  1086. const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
  1087. {
  1088. BOOST_ASSERT(!this->empty());
  1089. return static_cast<const_node_reference>(*this->index.front()).value;
  1090. }
  1091. //! <b>Requires</b>: !empty()
  1092. //!
  1093. //! <b>Effects</b>: Returns a reference to the last
  1094. //! element of the container.
  1095. //!
  1096. //! <b>Throws</b>: Nothing.
  1097. //!
  1098. //! <b>Complexity</b>: Constant.
  1099. reference back() BOOST_NOEXCEPT_OR_NOTHROW
  1100. {
  1101. BOOST_ASSERT(!this->empty());
  1102. return static_cast<node_reference>(*this->index[this->size()-1u]).value;
  1103. }
  1104. //! <b>Requires</b>: !empty()
  1105. //!
  1106. //! <b>Effects</b>: Returns a const reference to the last
  1107. //! element of the container.
  1108. //!
  1109. //! <b>Throws</b>: Nothing.
  1110. //!
  1111. //! <b>Complexity</b>: Constant.
  1112. const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
  1113. {
  1114. BOOST_ASSERT(!this->empty());
  1115. return static_cast<const_node_reference>(*this->index[this->size()-1u]).value;
  1116. }
  1117. //! <b>Requires</b>: size() > n.
  1118. //!
  1119. //! <b>Effects</b>: Returns a reference to the nth element
  1120. //! from the beginning of the container.
  1121. //!
  1122. //! <b>Throws</b>: Nothing.
  1123. //!
  1124. //! <b>Complexity</b>: Constant.
  1125. reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
  1126. {
  1127. BOOST_ASSERT(this->size() > n);
  1128. return static_cast<node_reference>(*this->index[n]).value;
  1129. }
  1130. //! <b>Requires</b>: size() > n.
  1131. //!
  1132. //! <b>Effects</b>: Returns a const reference to the nth element
  1133. //! from the beginning of the container.
  1134. //!
  1135. //! <b>Throws</b>: Nothing.
  1136. //!
  1137. //! <b>Complexity</b>: Constant.
  1138. const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
  1139. {
  1140. BOOST_ASSERT(this->size() > n);
  1141. return static_cast<const_node_reference>(*this->index[n]).value;
  1142. }
  1143. //! <b>Requires</b>: size() >= n.
  1144. //!
  1145. //! <b>Effects</b>: Returns an iterator to the nth element
  1146. //! from the beginning of the container. Returns end()
  1147. //! if n == size().
  1148. //!
  1149. //! <b>Throws</b>: Nothing.
  1150. //!
  1151. //! <b>Complexity</b>: Constant.
  1152. //!
  1153. //! <b>Note</b>: Non-standard extension
  1154. iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
  1155. {
  1156. BOOST_ASSERT(this->size() >= n);
  1157. return (this->index.empty()) ? this->end() : iterator(node_ptr_traits::static_cast_from(this->index[n]));
  1158. }
  1159. //! <b>Requires</b>: size() >= n.
  1160. //!
  1161. //! <b>Effects</b>: Returns a const_iterator to the nth element
  1162. //! from the beginning of the container. Returns end()
  1163. //! if n == size().
  1164. //!
  1165. //! <b>Throws</b>: Nothing.
  1166. //!
  1167. //! <b>Complexity</b>: Constant.
  1168. //!
  1169. //! <b>Note</b>: Non-standard extension
  1170. const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
  1171. {
  1172. BOOST_ASSERT(this->size() >= n);
  1173. return (this->index.empty()) ? this->cend() : iterator(node_ptr_traits::static_cast_from(this->index[n]));
  1174. }
  1175. //! <b>Requires</b>: begin() <= p <= end().
  1176. //!
  1177. //! <b>Effects</b>: Returns the index of the element pointed by p
  1178. //! and size() if p == end().
  1179. //!
  1180. //! <b>Throws</b>: Nothing.
  1181. //!
  1182. //! <b>Complexity</b>: Constant.
  1183. //!
  1184. //! <b>Note</b>: Non-standard extension
  1185. size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
  1186. { return this->priv_index_of(p.node_pointer()); }
  1187. //! <b>Requires</b>: begin() <= p <= end().
  1188. //!
  1189. //! <b>Effects</b>: Returns the index of the element pointed by p
  1190. //! and size() if p == end().
  1191. //!
  1192. //! <b>Throws</b>: Nothing.
  1193. //!
  1194. //! <b>Complexity</b>: Constant.
  1195. //!
  1196. //! <b>Note</b>: Non-standard extension
  1197. size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
  1198. { return this->priv_index_of(p.node_pointer()); }
  1199. //! <b>Requires</b>: size() > n.
  1200. //!
  1201. //! <b>Effects</b>: Returns a reference to the nth element
  1202. //! from the beginning of the container.
  1203. //!
  1204. //! <b>Throws</b>: std::range_error if n >= size()
  1205. //!
  1206. //! <b>Complexity</b>: Constant.
  1207. reference at(size_type n)
  1208. {
  1209. if(n >= this->size()){
  1210. throw_out_of_range("vector::at invalid subscript");
  1211. }
  1212. return operator[](n);
  1213. }
  1214. //! <b>Requires</b>: size() > n.
  1215. //!
  1216. //! <b>Effects</b>: Returns a const reference to the nth element
  1217. //! from the beginning of the container.
  1218. //!
  1219. //! <b>Throws</b>: std::range_error if n >= size()
  1220. //!
  1221. //! <b>Complexity</b>: Constant.
  1222. const_reference at(size_type n)const
  1223. {
  1224. if(n >= this->size()){
  1225. throw_out_of_range("vector::at invalid subscript");
  1226. }
  1227. return operator[](n);
  1228. }
  1229. //////////////////////////////////////////////
  1230. //
  1231. // modifiers
  1232. //
  1233. //////////////////////////////////////////////
  1234. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1235. //! <b>Effects</b>: Inserts an object of type T constructed with
  1236. //! std::forward<Args>(args)... in the end of the stable_vector.
  1237. //!
  1238. //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
  1239. //!
  1240. //! <b>Complexity</b>: Amortized constant time.
  1241. template<class ...Args>
  1242. void emplace_back(Args &&...args)
  1243. {
  1244. typedef emplace_functor<Args...> EmplaceFunctor;
  1245. typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;
  1246. EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
  1247. this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator());
  1248. }
  1249. //! <b>Requires</b>: p must be a valid iterator of *this.
  1250. //!
  1251. //! <b>Effects</b>: Inserts an object of type T constructed with
  1252. //! std::forward<Args>(args)... before p
  1253. //!
  1254. //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
  1255. //!
  1256. //! <b>Complexity</b>: If p is end(), amortized constant time
  1257. //! Linear time otherwise.
  1258. template<class ...Args>
  1259. iterator emplace(const_iterator p, Args && ...args)
  1260. {
  1261. BOOST_ASSERT(this->priv_in_range_or_end(p));
  1262. size_type pos_n = p - cbegin();
  1263. typedef emplace_functor<Args...> EmplaceFunctor;
  1264. typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;
  1265. EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
  1266. this->insert(p, EmplaceIterator(ef), EmplaceIterator());
  1267. return iterator(this->begin() + pos_n);
  1268. }
  1269. #else
  1270. #define BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE(N) \
  1271. BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
  1272. void emplace_back(BOOST_MOVE_UREF##N)\
  1273. {\
  1274. typedef emplace_functor##N\
  1275. BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N EmplaceFunctor;\
  1276. typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;\
  1277. EmplaceFunctor ef BOOST_MOVE_LP##N BOOST_MOVE_FWD##N BOOST_MOVE_RP##N;\
  1278. this->insert(this->cend() , EmplaceIterator(ef), EmplaceIterator());\
  1279. }\
  1280. \
  1281. BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
  1282. iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
  1283. {\
  1284. BOOST_ASSERT(this->priv_in_range_or_end(p));\
  1285. typedef emplace_functor##N\
  1286. BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N EmplaceFunctor;\
  1287. typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;\
  1288. EmplaceFunctor ef BOOST_MOVE_LP##N BOOST_MOVE_FWD##N BOOST_MOVE_RP##N;\
  1289. const size_type pos_n = p - this->cbegin();\
  1290. this->insert(p, EmplaceIterator(ef), EmplaceIterator());\
  1291. return this->begin() += pos_n;\
  1292. }\
  1293. //
  1294. BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE)
  1295. #undef BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE
  1296. #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  1297. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1298. //! <b>Effects</b>: Inserts a copy of x at the end of the stable_vector.
  1299. //!
  1300. //! <b>Throws</b>: If memory allocation throws or
  1301. //! T's copy constructor throws.
  1302. //!
  1303. //! <b>Complexity</b>: Amortized constant time.
  1304. void push_back(const T &x);
  1305. //! <b>Effects</b>: Constructs a new element in the end of the stable_vector
  1306. //! and moves the resources of x to this new element.
  1307. //!
  1308. //! <b>Throws</b>: If memory allocation throws.
  1309. //!
  1310. //! <b>Complexity</b>: Amortized constant time.
  1311. void push_back(T &&x);
  1312. #else
  1313. BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
  1314. #endif
  1315. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1316. //! <b>Requires</b>: p must be a valid iterator of *this.
  1317. //!
  1318. //! <b>Effects</b>: Insert a copy of x before p.
  1319. //!
  1320. //! <b>Returns</b>: An iterator to the inserted element.
  1321. //!
  1322. //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
  1323. //!
  1324. //! <b>Complexity</b>: If p is end(), amortized constant time
  1325. //! Linear time otherwise.
  1326. iterator insert(const_iterator p, const T &x);
  1327. //! <b>Requires</b>: p must be a valid iterator of *this.
  1328. //!
  1329. //! <b>Effects</b>: Insert a new element before p with x's resources.
  1330. //!
  1331. //! <b>Returns</b>: an iterator to the inserted element.
  1332. //!
  1333. //! <b>Throws</b>: If memory allocation throws.
  1334. //!
  1335. //! <b>Complexity</b>: If p is end(), amortized constant time
  1336. //! Linear time otherwise.
  1337. iterator insert(const_iterator p, T &&x);
  1338. #else
  1339. BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
  1340. #endif
  1341. //! <b>Requires</b>: p must be a valid iterator of *this.
  1342. //!
  1343. //! <b>Effects</b>: Insert n copies of x before p.
  1344. //!
  1345. //! <b>Returns</b>: an iterator to the first inserted element or p if n is 0.
  1346. //!
  1347. //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
  1348. //!
  1349. //! <b>Complexity</b>: Linear to n.
  1350. iterator insert(const_iterator p, size_type n, const T& t)
  1351. {
  1352. BOOST_ASSERT(this->priv_in_range_or_end(p));
  1353. STABLE_VECTOR_CHECK_INVARIANT;
  1354. typedef constant_iterator<value_type, difference_type> cvalue_iterator;
  1355. return this->insert(p, cvalue_iterator(t, n), cvalue_iterator());
  1356. }
  1357. //! <b>Requires</b>: p must be a valid iterator of *this.
  1358. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  1359. //! <b>Requires</b>: p must be a valid iterator of *this.
  1360. //!
  1361. //! <b>Effects</b>: Insert a copy of the [il.begin(), il.end()) range before p.
  1362. //!
  1363. //! <b>Returns</b>: an iterator to the first inserted element or p if first == last.
  1364. //!
  1365. //! <b>Complexity</b>: Linear to distance [il.begin(), il.end()).
  1366. iterator insert(const_iterator p, std::initializer_list<value_type> il)
  1367. {
  1368. //Position checks done by insert()
  1369. STABLE_VECTOR_CHECK_INVARIANT;
  1370. return insert(p, il.begin(), il.end());
  1371. }
  1372. #endif
  1373. //! <b>Requires</b>: pos must be a valid iterator of *this.
  1374. //!
  1375. //! <b>Effects</b>: Insert a copy of the [first, last) range before p.
  1376. //!
  1377. //! <b>Returns</b>: an iterator to the first inserted element or p if first == last.
  1378. //!
  1379. //! <b>Throws</b>: If memory allocation throws, T's constructor from a
  1380. //! dereferenced InpIt throws or T's copy constructor throws.
  1381. //!
  1382. //! <b>Complexity</b>: Linear to distance [first, last).
  1383. template <class InputIterator>
  1384. iterator insert(const_iterator p, InputIterator first, InputIterator last
  1385. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1386. //Put this as argument instead of the return type as old GCC's like 3.4
  1387. //detect this and the next disable_if_or as overloads
  1388. , typename container_detail::disable_if_or
  1389. < void
  1390. , container_detail::is_convertible<InputIterator, size_type>
  1391. , container_detail::is_not_input_iterator<InputIterator>
  1392. >::type* = 0
  1393. #endif
  1394. )
  1395. {
  1396. BOOST_ASSERT(this->priv_in_range_or_end(p));
  1397. STABLE_VECTOR_CHECK_INVARIANT;
  1398. const size_type pos_n = p - this->cbegin();
  1399. for(; first != last; ++first){
  1400. this->emplace(p, *first);
  1401. }
  1402. return this->begin() + pos_n;
  1403. }
  1404. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1405. template <class FwdIt>
  1406. typename container_detail::disable_if_or
  1407. < iterator
  1408. , container_detail::is_convertible<FwdIt, size_type>
  1409. , container_detail::is_input_iterator<FwdIt>
  1410. >::type
  1411. insert(const_iterator p, FwdIt first, FwdIt last)
  1412. {
  1413. BOOST_ASSERT(this->priv_in_range_or_end(p));
  1414. const size_type num_new = static_cast<size_type>(boost::container::iterator_distance(first, last));
  1415. const size_type idx = static_cast<size_type>(p - this->cbegin());
  1416. if(num_new){
  1417. //Fills the node pool and inserts num_new null pointers in idx.
  1418. //If a new buffer was needed fixes up pointers up to idx so
  1419. //past-new nodes are not aligned until the end of this function
  1420. //or in a rollback in case of exception
  1421. index_iterator it_past_newly_constructed(this->priv_insert_forward_non_templated(idx, num_new));
  1422. const index_iterator it_past_new(it_past_newly_constructed + num_new);
  1423. {
  1424. //Prepare rollback
  1425. insert_rollback rollback(*this, it_past_newly_constructed, it_past_new);
  1426. while(first != last){
  1427. const node_ptr n = this->priv_get_from_pool();
  1428. BOOST_ASSERT(!!n);
  1429. //Put it in the index so rollback can return it in pool if construct_in_place throws
  1430. *it_past_newly_constructed = n;
  1431. //Constructs and fixes up pointers This can throw
  1432. this->priv_build_node_from_it(n, it_past_newly_constructed, first);
  1433. ++first;
  1434. ++it_past_newly_constructed;
  1435. }
  1436. //rollback.~insert_rollback() called in case of exception
  1437. }
  1438. //Fix up pointers for past-new nodes (new nodes were fixed during construction) and
  1439. //nodes before insertion p in priv_insert_forward_non_templated(...)
  1440. index_traits_type::fix_up_pointers_from(this->index, it_past_newly_constructed);
  1441. }
  1442. return this->begin() + idx;
  1443. }
  1444. #endif
  1445. //! <b>Effects</b>: Removes the last element from the stable_vector.
  1446. //!
  1447. //! <b>Throws</b>: Nothing.
  1448. //!
  1449. //! <b>Complexity</b>: Constant time.
  1450. void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
  1451. {
  1452. BOOST_ASSERT(!this->empty());
  1453. this->erase(--this->cend());
  1454. }
  1455. //! <b>Effects</b>: Erases the element at p.
  1456. //!
  1457. //! <b>Throws</b>: Nothing.
  1458. //!
  1459. //! <b>Complexity</b>: Linear to the elements between p and the
  1460. //! last element. Constant if p is the last element.
  1461. iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
  1462. {
  1463. BOOST_ASSERT(this->priv_in_range(p));
  1464. STABLE_VECTOR_CHECK_INVARIANT;
  1465. const size_type d = p - this->cbegin();
  1466. index_iterator it = this->index.begin() + d;
  1467. this->priv_delete_node(p.node_pointer());
  1468. it = this->index.erase(it);
  1469. index_traits_type::fix_up_pointers_from(this->index, it);
  1470. return iterator(node_ptr_traits::static_cast_from(*it));
  1471. }
  1472. //! <b>Effects</b>: Erases the elements pointed by [first, last).
  1473. //!
  1474. //! <b>Throws</b>: Nothing.
  1475. //!
  1476. //! <b>Complexity</b>: Linear to the distance between first and last
  1477. //! plus linear to the elements between p and the last element.
  1478. iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
  1479. {
  1480. BOOST_ASSERT(first == last ||
  1481. (first < last && this->priv_in_range(first) && this->priv_in_range_or_end(last)));
  1482. STABLE_VECTOR_CHECK_INVARIANT;
  1483. const const_iterator cbeg(this->cbegin());
  1484. const size_type d1 = static_cast<size_type>(first - cbeg),
  1485. d2 = static_cast<size_type>(last - cbeg);
  1486. size_type d_dif = d2 - d1;
  1487. if(d_dif){
  1488. multiallocation_chain holder;
  1489. const index_iterator it1(this->index.begin() + d1);
  1490. const index_iterator it2(it1 + d_dif);
  1491. index_iterator it(it1);
  1492. while(d_dif--){
  1493. node_base_ptr &nb = *it;
  1494. ++it;
  1495. node_type &n = *node_ptr_traits::static_cast_from(nb);
  1496. this->priv_destroy_node(n);
  1497. holder.push_back(node_ptr_traits::pointer_to(n));
  1498. }
  1499. this->priv_put_in_pool(holder);
  1500. const index_iterator e = this->index.erase(it1, it2);
  1501. index_traits_type::fix_up_pointers_from(this->index, e);
  1502. }
  1503. return iterator(last.node_pointer());
  1504. }
  1505. //! <b>Effects</b>: Swaps the contents of *this and x.
  1506. //!
  1507. //! <b>Throws</b>: Nothing.
  1508. //!
  1509. //! <b>Complexity</b>: Constant.
  1510. void swap(stable_vector & x)
  1511. BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value
  1512. || allocator_traits_type::is_always_equal::value)
  1513. {
  1514. BOOST_ASSERT(allocator_traits_type::propagate_on_container_swap::value ||
  1515. allocator_traits_type::is_always_equal::value ||
  1516. this->get_stored_allocator() == x.get_stored_allocator());
  1517. STABLE_VECTOR_CHECK_INVARIANT;
  1518. container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
  1519. container_detail::swap_alloc(this->priv_node_alloc(), x.priv_node_alloc(), flag);
  1520. //vector's allocator is swapped here
  1521. this->index.swap(x.index);
  1522. this->priv_swap_members(x);
  1523. }
  1524. //! <b>Effects</b>: Erases all the elements of the stable_vector.
  1525. //!
  1526. //! <b>Throws</b>: Nothing.
  1527. //!
  1528. //! <b>Complexity</b>: Linear to the number of elements in the stable_vector.
  1529. void clear() BOOST_NOEXCEPT_OR_NOTHROW
  1530. { this->erase(this->cbegin(),this->cend()); }
  1531. //! <b>Effects</b>: Returns true if x and y are equal
  1532. //!
  1533. //! <b>Complexity</b>: Linear to the number of elements in the container.
  1534. friend bool operator==(const stable_vector& x, const stable_vector& y)
  1535. { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
  1536. //! <b>Effects</b>: Returns true if x and y are unequal
  1537. //!
  1538. //! <b>Complexity</b>: Linear to the number of elements in the container.
  1539. friend bool operator!=(const stable_vector& x, const stable_vector& y)
  1540. { return !(x == y); }
  1541. //! <b>Effects</b>: Returns true if x is less than y
  1542. //!
  1543. //! <b>Complexity</b>: Linear to the number of elements in the container.
  1544. friend bool operator<(const stable_vector& x, const stable_vector& y)
  1545. { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
  1546. //! <b>Effects</b>: Returns true if x is greater than y
  1547. //!
  1548. //! <b>Complexity</b>: Linear to the number of elements in the container.
  1549. friend bool operator>(const stable_vector& x, const stable_vector& y)
  1550. { return y < x; }
  1551. //! <b>Effects</b>: Returns true if x is equal or less than y
  1552. //!
  1553. //! <b>Complexity</b>: Linear to the number of elements in the container.
  1554. friend bool operator<=(const stable_vector& x, const stable_vector& y)
  1555. { return !(y < x); }
  1556. //! <b>Effects</b>: Returns true if x is equal or greater than y
  1557. //!
  1558. //! <b>Complexity</b>: Linear to the number of elements in the container.
  1559. friend bool operator>=(const stable_vector& x, const stable_vector& y)
  1560. { return !(x < y); }
  1561. //! <b>Effects</b>: x.swap(y)
  1562. //!
  1563. //! <b>Complexity</b>: Constant.
  1564. friend void swap(stable_vector& x, stable_vector& y)
  1565. { x.swap(y); }
  1566. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  1567. private:
  1568. bool priv_in_range(const_iterator pos) const
  1569. {
  1570. return (this->begin() <= pos) && (pos < this->end());
  1571. }
  1572. bool priv_in_range_or_end(const_iterator pos) const
  1573. {
  1574. return (this->begin() <= pos) && (pos <= this->end());
  1575. }
  1576. size_type priv_index_of(node_ptr p) const
  1577. {
  1578. //Check range
  1579. BOOST_ASSERT(this->index.empty() || (this->index.data() <= p->up));
  1580. BOOST_ASSERT(this->index.empty() || p->up <= (this->index.data() + this->index.size()));
  1581. return this->index.empty() ? 0 : p->up - this->index.data();
  1582. }
  1583. class insert_rollback
  1584. {
  1585. public:
  1586. insert_rollback(stable_vector &sv, index_iterator &it_past_constructed, const index_iterator &it_past_new)
  1587. : m_sv(sv), m_it_past_constructed(it_past_constructed), m_it_past_new(it_past_new)
  1588. {}
  1589. ~insert_rollback()
  1590. {
  1591. if(m_it_past_constructed != m_it_past_new){
  1592. m_sv.priv_put_in_pool(node_ptr_traits::static_cast_from(*m_it_past_constructed));
  1593. index_iterator e = m_sv.index.erase(m_it_past_constructed, m_it_past_new);
  1594. index_traits_type::fix_up_pointers_from(m_sv.index, e);
  1595. }
  1596. }
  1597. private:
  1598. stable_vector &m_sv;
  1599. index_iterator &m_it_past_constructed;
  1600. const index_iterator &m_it_past_new;
  1601. };
  1602. class push_back_rollback
  1603. {
  1604. public:
  1605. push_back_rollback(stable_vector &sv, const node_ptr &p)
  1606. : m_sv(sv), m_p(p)
  1607. {}
  1608. ~push_back_rollback()
  1609. {
  1610. if(m_p){
  1611. m_sv.priv_put_in_pool(m_p);
  1612. }
  1613. }
  1614. void release()
  1615. { m_p = node_ptr(); }
  1616. private:
  1617. stable_vector &m_sv;
  1618. node_ptr m_p;
  1619. };
  1620. index_iterator priv_insert_forward_non_templated(size_type idx, size_type num_new)
  1621. {
  1622. index_traits_type::initialize_end_node(this->index, this->internal_data.end_node, num_new);
  1623. //Now try to fill the pool with new data
  1624. if(this->internal_data.pool_size < num_new){
  1625. this->priv_increase_pool(num_new - this->internal_data.pool_size);
  1626. }
  1627. //Now try to make room in the vector
  1628. const node_base_ptr_ptr old_buffer = this->index.data();
  1629. this->index.insert(this->index.begin() + idx, num_new, node_ptr());
  1630. bool new_buffer = this->index.data() != old_buffer;
  1631. //Fix the pointers for the newly allocated buffer
  1632. const index_iterator index_beg = this->index.begin();
  1633. if(new_buffer){
  1634. index_traits_type::fix_up_pointers(index_beg, index_beg + idx);
  1635. }
  1636. return index_beg + idx;
  1637. }
  1638. bool priv_capacity_bigger_than_size() const
  1639. {
  1640. return this->index.capacity() > this->index.size() &&
  1641. this->internal_data.pool_size > 0;
  1642. }
  1643. template <class U>
  1644. void priv_push_back(BOOST_MOVE_CATCH_FWD(U) x)
  1645. {
  1646. if(BOOST_LIKELY(this->priv_capacity_bigger_than_size())){
  1647. //Enough memory in the pool and in the index
  1648. const node_ptr p = this->priv_get_from_pool();
  1649. BOOST_ASSERT(!!p);
  1650. {
  1651. push_back_rollback rollback(*this, p);
  1652. //This might throw
  1653. this->priv_build_node_from_convertible(p, ::boost::forward<U>(x));
  1654. rollback.release();
  1655. }
  1656. //This can't throw as there is room for a new elements in the index
  1657. index_iterator new_index = this->index.insert(this->index.end() - ExtraPointers, p);
  1658. index_traits_type::fix_up_pointers_from(this->index, new_index);
  1659. }
  1660. else{
  1661. this->insert(this->cend(), ::boost::forward<U>(x));
  1662. }
  1663. }
  1664. iterator priv_insert(const_iterator p, const value_type &t)
  1665. {
  1666. BOOST_ASSERT(this->priv_in_range_or_end(p));
  1667. typedef constant_iterator<value_type, difference_type> cvalue_iterator;
  1668. return this->insert(p, cvalue_iterator(t, 1), cvalue_iterator());
  1669. }
  1670. iterator priv_insert(const_iterator p, BOOST_RV_REF(T) x)
  1671. {
  1672. BOOST_ASSERT(this->priv_in_range_or_end(p));
  1673. typedef repeat_iterator<T, difference_type> repeat_it;
  1674. typedef boost::move_iterator<repeat_it> repeat_move_it;
  1675. //Just call more general insert(p, size, value) and return iterator
  1676. return this->insert(p, repeat_move_it(repeat_it(x, 1)), repeat_move_it(repeat_it()));
  1677. }
  1678. void priv_clear_pool()
  1679. {
  1680. if(!this->index.empty() && this->index.back()){
  1681. node_base_ptr &pool_first_ref = *(this->index.end() - 2);
  1682. node_base_ptr &pool_last_ref = this->index.back();
  1683. multiallocation_chain holder;
  1684. holder.incorporate_after( holder.before_begin()
  1685. , node_ptr_traits::static_cast_from(pool_first_ref)
  1686. , node_ptr_traits::static_cast_from(pool_last_ref)
  1687. , internal_data.pool_size);
  1688. this->deallocate_individual(holder);
  1689. pool_first_ref = pool_last_ref = 0;
  1690. this->internal_data.pool_size = 0;
  1691. }
  1692. }
  1693. void priv_increase_pool(size_type n)
  1694. {
  1695. node_base_ptr &pool_first_ref = *(this->index.end() - 2);
  1696. node_base_ptr &pool_last_ref = this->index.back();
  1697. multiallocation_chain holder;
  1698. holder.incorporate_after( holder.before_begin()
  1699. , node_ptr_traits::static_cast_from(pool_first_ref)
  1700. , node_ptr_traits::static_cast_from(pool_last_ref)
  1701. , internal_data.pool_size);
  1702. multiallocation_chain m;
  1703. this->allocate_individual(n, m);
  1704. holder.splice_after(holder.before_begin(), m, m.before_begin(), m.last(), n);
  1705. this->internal_data.pool_size += n;
  1706. std::pair<node_ptr, node_ptr> data(holder.extract_data());
  1707. pool_first_ref = data.first;
  1708. pool_last_ref = data.second;
  1709. }
  1710. void priv_put_in_pool(const node_ptr &p)
  1711. {
  1712. node_base_ptr &pool_first_ref = *(this->index.end()-2);
  1713. node_base_ptr &pool_last_ref = this->index.back();
  1714. multiallocation_chain holder;
  1715. holder.incorporate_after( holder.before_begin()
  1716. , node_ptr_traits::static_cast_from(pool_first_ref)
  1717. , node_ptr_traits::static_cast_from(pool_last_ref)
  1718. , internal_data.pool_size);
  1719. holder.push_front(p);
  1720. ++this->internal_data.pool_size;
  1721. std::pair<node_ptr, node_ptr> ret(holder.extract_data());
  1722. pool_first_ref = ret.first;
  1723. pool_last_ref = ret.second;
  1724. }
  1725. void priv_put_in_pool(multiallocation_chain &ch)
  1726. {
  1727. node_base_ptr &pool_first_ref = *(this->index.end()-(ExtraPointers-1));
  1728. node_base_ptr &pool_last_ref = this->index.back();
  1729. ch.incorporate_after( ch.before_begin()
  1730. , node_ptr_traits::static_cast_from(pool_first_ref)
  1731. , node_ptr_traits::static_cast_from(pool_last_ref)
  1732. , internal_data.pool_size);
  1733. this->internal_data.pool_size = ch.size();
  1734. const std::pair<node_ptr, node_ptr> ret(ch.extract_data());
  1735. pool_first_ref = ret.first;
  1736. pool_last_ref = ret.second;
  1737. }
  1738. node_ptr priv_get_from_pool()
  1739. {
  1740. //Precondition: index is not empty
  1741. BOOST_ASSERT(!this->index.empty());
  1742. node_base_ptr &pool_first_ref = *(this->index.end() - (ExtraPointers-1));
  1743. node_base_ptr &pool_last_ref = this->index.back();
  1744. multiallocation_chain holder;
  1745. holder.incorporate_after( holder.before_begin()
  1746. , node_ptr_traits::static_cast_from(pool_first_ref)
  1747. , node_ptr_traits::static_cast_from(pool_last_ref)
  1748. , internal_data.pool_size);
  1749. node_ptr ret = holder.pop_front();
  1750. --this->internal_data.pool_size;
  1751. if(!internal_data.pool_size){
  1752. pool_first_ref = pool_last_ref = node_ptr();
  1753. }
  1754. else{
  1755. const std::pair<node_ptr, node_ptr> data(holder.extract_data());
  1756. pool_first_ref = data.first;
  1757. pool_last_ref = data.second;
  1758. }
  1759. return ret;
  1760. }
  1761. node_base_ptr priv_get_end_node() const
  1762. { return node_base_ptr_traits::pointer_to(const_cast<node_base_type&>(this->internal_data.end_node)); }
  1763. void priv_destroy_node(const node_type &n)
  1764. {
  1765. allocator_traits<node_allocator_type>::
  1766. destroy(this->priv_node_alloc(), container_detail::addressof(n.value));
  1767. static_cast<const node_base_type*>(&n)->~node_base_type();
  1768. }
  1769. void priv_delete_node(const node_ptr &n)
  1770. {
  1771. this->priv_destroy_node(*n);
  1772. this->priv_put_in_pool(n);
  1773. }
  1774. template<class Iterator>
  1775. void priv_build_node_from_it(const node_ptr &p, const index_iterator &up_index, const Iterator &it)
  1776. {
  1777. //This can throw
  1778. boost::container::construct_in_place
  1779. ( this->priv_node_alloc()
  1780. , container_detail::addressof(p->value)
  1781. , it);
  1782. //This does not throw
  1783. ::new(static_cast<node_base_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t())
  1784. node_base_type(index_traits_type::ptr_to_node_base_ptr(*up_index));
  1785. }
  1786. template<class ValueConvertible>
  1787. void priv_build_node_from_convertible(const node_ptr &p, BOOST_FWD_REF(ValueConvertible) value_convertible)
  1788. {
  1789. //This can throw
  1790. boost::container::allocator_traits<node_allocator_type>::construct
  1791. ( this->priv_node_alloc()
  1792. , container_detail::addressof(p->value)
  1793. , ::boost::forward<ValueConvertible>(value_convertible));
  1794. //This does not throw
  1795. ::new(static_cast<node_base_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) node_base_type;
  1796. }
  1797. void priv_swap_members(stable_vector &x)
  1798. {
  1799. boost::adl_move_swap(this->internal_data.pool_size, x.internal_data.pool_size);
  1800. index_traits_type::readjust_end_node(this->index, this->internal_data.end_node);
  1801. index_traits_type::readjust_end_node(x.index, x.internal_data.end_node);
  1802. }
  1803. #if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
  1804. bool priv_invariant()const
  1805. {
  1806. index_type & index_ref = const_cast<index_type&>(this->index);
  1807. const size_type index_size = this->index.size();
  1808. if(!index_size)
  1809. return !this->capacity() && !this->size();
  1810. if(index_size < ExtraPointers)
  1811. return false;
  1812. const size_type bucket_extra_capacity = this->index.capacity()- index_size;
  1813. const size_type node_extra_capacity = this->internal_data.pool_size;
  1814. if(bucket_extra_capacity < node_extra_capacity){
  1815. return false;
  1816. }
  1817. if(this->priv_get_end_node() != *(index.end() - ExtraPointers)){
  1818. return false;
  1819. }
  1820. if(!index_traits_type::invariants(index_ref)){
  1821. return false;
  1822. }
  1823. size_type n = this->capacity() - this->size();
  1824. node_base_ptr &pool_first_ref = *(index_ref.end() - (ExtraPointers-1));
  1825. node_base_ptr &pool_last_ref = index_ref.back();
  1826. multiallocation_chain holder;
  1827. holder.incorporate_after( holder.before_begin()
  1828. , node_ptr_traits::static_cast_from(pool_first_ref)
  1829. , node_ptr_traits::static_cast_from(pool_last_ref)
  1830. , internal_data.pool_size);
  1831. typename multiallocation_chain::iterator beg(holder.begin()), end(holder.end());
  1832. size_type num_pool = 0;
  1833. while(beg != end){
  1834. ++num_pool;
  1835. ++beg;
  1836. }
  1837. return n >= num_pool && num_pool == internal_data.pool_size;
  1838. }
  1839. class invariant_checker
  1840. {
  1841. invariant_checker(const invariant_checker &);
  1842. invariant_checker & operator=(const invariant_checker &);
  1843. const stable_vector* p;
  1844. public:
  1845. invariant_checker(const stable_vector& v):p(&v){}
  1846. ~invariant_checker(){BOOST_ASSERT(p->priv_invariant());}
  1847. void touch(){}
  1848. };
  1849. #endif
  1850. class ebo_holder
  1851. : public node_allocator_type
  1852. {
  1853. private:
  1854. BOOST_MOVABLE_BUT_NOT_COPYABLE(ebo_holder)
  1855. public:
  1856. template<class AllocatorRLValue>
  1857. explicit ebo_holder(BOOST_FWD_REF(AllocatorRLValue) a)
  1858. : node_allocator_type(boost::forward<AllocatorRLValue>(a))
  1859. , pool_size(0)
  1860. , end_node()
  1861. {}
  1862. ebo_holder()
  1863. : node_allocator_type()
  1864. , pool_size(0)
  1865. , end_node()
  1866. {}
  1867. size_type pool_size;
  1868. node_base_type end_node;
  1869. } internal_data;
  1870. node_allocator_type &priv_node_alloc() { return internal_data; }
  1871. const node_allocator_type &priv_node_alloc() const { return internal_data; }
  1872. index_type index;
  1873. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  1874. };
  1875. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  1876. #undef STABLE_VECTOR_CHECK_INVARIANT
  1877. } //namespace container {
  1878. //!has_trivial_destructor_after_move<> == true_type
  1879. //!specialization for optimizations
  1880. template <class T, class Allocator>
  1881. struct has_trivial_destructor_after_move<boost::container::stable_vector<T, Allocator> >
  1882. {
  1883. typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
  1884. static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
  1885. ::boost::has_trivial_destructor_after_move<pointer>::value;
  1886. };
  1887. namespace container {
  1888. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  1889. }} //namespace boost{ namespace container {
  1890. #include <boost/container/detail/config_end.hpp>
  1891. #endif //BOOST_CONTAINER_STABLE_VECTOR_HPP