stable_vector.hpp 83 KB

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