stable_vector.hpp 85 KB

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