vector.hpp 135 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2005-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. #ifndef BOOST_CONTAINER_CONTAINER_VECTOR_HPP
  11. #define BOOST_CONTAINER_CONTAINER_VECTOR_HPP
  12. #ifndef BOOST_CONFIG_HPP
  13. # include <boost/config.hpp>
  14. #endif
  15. #if defined(BOOST_HAS_PRAGMA_ONCE)
  16. # pragma once
  17. #endif
  18. #include <boost/container/detail/config_begin.hpp>
  19. #include <boost/container/detail/workaround.hpp>
  20. // container
  21. #include <boost/container/container_fwd.hpp>
  22. #include <boost/container/allocator_traits.hpp>
  23. #include <boost/container/new_allocator.hpp> //new_allocator
  24. #include <boost/container/throw_exception.hpp>
  25. #include <boost/container/options.hpp>
  26. // container detail
  27. #include <boost/container/detail/advanced_insert_int.hpp>
  28. #include <boost/container/detail/algorithm.hpp> //equal()
  29. #include <boost/container/detail/alloc_helpers.hpp>
  30. #include <boost/container/detail/allocation_type.hpp>
  31. #include <boost/container/detail/copy_move_algo.hpp>
  32. #include <boost/container/detail/destroyers.hpp>
  33. #include <boost/container/detail/iterator.hpp>
  34. #include <boost/container/detail/iterators.hpp>
  35. #include <boost/move/detail/iterator_to_raw_pointer.hpp>
  36. #include <boost/container/detail/mpl.hpp>
  37. #include <boost/container/detail/next_capacity.hpp>
  38. #include <boost/container/detail/value_functors.hpp>
  39. #include <boost/move/detail/to_raw_pointer.hpp>
  40. #include <boost/container/detail/type_traits.hpp>
  41. #include <boost/container/detail/version_type.hpp>
  42. // intrusive
  43. #include <boost/intrusive/pointer_traits.hpp>
  44. // move
  45. #include <boost/move/adl_move_swap.hpp>
  46. #include <boost/move/iterator.hpp>
  47. #include <boost/move/traits.hpp>
  48. #include <boost/move/utility_core.hpp>
  49. // move/detail
  50. #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  51. #include <boost/move/detail/fwd_macros.hpp>
  52. #endif
  53. #include <boost/move/detail/move_helpers.hpp>
  54. // move/algo
  55. #include <boost/move/algo/adaptive_merge.hpp>
  56. #include <boost/move/algo/unique.hpp>
  57. #include <boost/move/algo/predicate.hpp>
  58. #include <boost/move/algo/detail/set_difference.hpp>
  59. // other
  60. #include <boost/core/no_exceptions_support.hpp>
  61. #include <boost/assert.hpp>
  62. #include <boost/cstdint.hpp>
  63. //std
  64. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  65. #include <initializer_list> //for std::initializer_list
  66. #endif
  67. namespace boost {
  68. namespace container {
  69. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  70. template <class Pointer, bool IsConst>
  71. class vec_iterator
  72. {
  73. public:
  74. typedef std::random_access_iterator_tag iterator_category;
  75. typedef typename boost::intrusive::pointer_traits<Pointer>::element_type value_type;
  76. typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type difference_type;
  77. typedef typename dtl::if_c
  78. < IsConst
  79. , typename boost::intrusive::pointer_traits<Pointer>::template
  80. rebind_pointer<const value_type>::type
  81. , Pointer
  82. >::type pointer;
  83. typedef typename boost::intrusive::pointer_traits<pointer> ptr_traits;
  84. typedef typename ptr_traits::reference reference;
  85. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  86. private:
  87. Pointer m_ptr;
  88. public:
  89. BOOST_CONTAINER_FORCEINLINE const Pointer &get_ptr() const BOOST_NOEXCEPT_OR_NOTHROW
  90. { return m_ptr; }
  91. BOOST_CONTAINER_FORCEINLINE Pointer &get_ptr() BOOST_NOEXCEPT_OR_NOTHROW
  92. { return m_ptr; }
  93. BOOST_CONTAINER_FORCEINLINE explicit vec_iterator(Pointer ptr) BOOST_NOEXCEPT_OR_NOTHROW
  94. : m_ptr(ptr)
  95. {}
  96. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  97. public:
  98. //Constructors
  99. BOOST_CONTAINER_FORCEINLINE vec_iterator() BOOST_NOEXCEPT_OR_NOTHROW
  100. : m_ptr() //Value initialization to achieve "null iterators" (N3644)
  101. {}
  102. BOOST_CONTAINER_FORCEINLINE vec_iterator(vec_iterator<Pointer, false> const& other) BOOST_NOEXCEPT_OR_NOTHROW
  103. : m_ptr(other.get_ptr())
  104. {}
  105. //Pointer like operators
  106. BOOST_CONTAINER_FORCEINLINE reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
  107. { BOOST_ASSERT(!!m_ptr); return *m_ptr; }
  108. BOOST_CONTAINER_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
  109. { return m_ptr; }
  110. BOOST_CONTAINER_FORCEINLINE reference operator[](difference_type off) const BOOST_NOEXCEPT_OR_NOTHROW
  111. { BOOST_ASSERT(!!m_ptr); return m_ptr[off]; }
  112. //Increment / Decrement
  113. BOOST_CONTAINER_FORCEINLINE vec_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
  114. { BOOST_ASSERT(!!m_ptr); ++m_ptr; return *this; }
  115. BOOST_CONTAINER_FORCEINLINE vec_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
  116. { BOOST_ASSERT(!!m_ptr); return vec_iterator(m_ptr++); }
  117. BOOST_CONTAINER_FORCEINLINE vec_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
  118. { BOOST_ASSERT(!!m_ptr); --m_ptr; return *this; }
  119. BOOST_CONTAINER_FORCEINLINE vec_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
  120. { BOOST_ASSERT(!!m_ptr); return vec_iterator(m_ptr--); }
  121. //Arithmetic
  122. BOOST_CONTAINER_FORCEINLINE vec_iterator& operator+=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
  123. { BOOST_ASSERT(!!m_ptr); m_ptr += off; return *this; }
  124. BOOST_CONTAINER_FORCEINLINE vec_iterator& operator-=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
  125. { BOOST_ASSERT(!!m_ptr); m_ptr -= off; return *this; }
  126. BOOST_CONTAINER_FORCEINLINE friend vec_iterator operator+(const vec_iterator &x, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
  127. { BOOST_ASSERT(!!x.m_ptr); return vec_iterator(x.m_ptr+off); }
  128. BOOST_CONTAINER_FORCEINLINE friend vec_iterator operator+(difference_type off, vec_iterator right) BOOST_NOEXCEPT_OR_NOTHROW
  129. { BOOST_ASSERT(!!right.m_ptr); right.m_ptr += off; return right; }
  130. BOOST_CONTAINER_FORCEINLINE friend vec_iterator operator-(vec_iterator left, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
  131. { BOOST_ASSERT(!!left.m_ptr); left.m_ptr -= off; return left; }
  132. BOOST_CONTAINER_FORCEINLINE friend difference_type operator-(const vec_iterator &left, const vec_iterator& right) BOOST_NOEXCEPT_OR_NOTHROW
  133. { return left.m_ptr - right.m_ptr; }
  134. //Comparison operators
  135. BOOST_CONTAINER_FORCEINLINE friend bool operator== (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  136. { return l.m_ptr == r.m_ptr; }
  137. BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  138. { return l.m_ptr != r.m_ptr; }
  139. BOOST_CONTAINER_FORCEINLINE friend bool operator< (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  140. { return l.m_ptr < r.m_ptr; }
  141. BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  142. { return l.m_ptr <= r.m_ptr; }
  143. BOOST_CONTAINER_FORCEINLINE friend bool operator> (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  144. { return l.m_ptr > r.m_ptr; }
  145. BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  146. { return l.m_ptr >= r.m_ptr; }
  147. };
  148. template<class BiDirPosConstIt, class BiDirValueIt>
  149. struct vector_insert_ordered_cursor
  150. {
  151. typedef typename iterator_traits<BiDirPosConstIt>::value_type size_type;
  152. typedef typename iterator_traits<BiDirValueIt>::reference reference;
  153. BOOST_CONTAINER_FORCEINLINE vector_insert_ordered_cursor(BiDirPosConstIt posit, BiDirValueIt valueit)
  154. : last_position_it(posit), last_value_it(valueit)
  155. {}
  156. void operator --()
  157. {
  158. --last_value_it;
  159. --last_position_it;
  160. while(this->get_pos() == size_type(-1)){
  161. --last_value_it;
  162. --last_position_it;
  163. }
  164. }
  165. BOOST_CONTAINER_FORCEINLINE size_type get_pos() const
  166. { return *last_position_it; }
  167. BOOST_CONTAINER_FORCEINLINE reference get_val()
  168. { return *last_value_it; }
  169. BiDirPosConstIt last_position_it;
  170. BiDirValueIt last_value_it;
  171. };
  172. struct initial_capacity_t{};
  173. template<class Pointer, bool IsConst>
  174. BOOST_CONTAINER_FORCEINLINE const Pointer &vector_iterator_get_ptr(const vec_iterator<Pointer, IsConst> &it) BOOST_NOEXCEPT_OR_NOTHROW
  175. { return it.get_ptr(); }
  176. template<class Pointer, bool IsConst>
  177. BOOST_CONTAINER_FORCEINLINE Pointer &get_ptr(vec_iterator<Pointer, IsConst> &it) BOOST_NOEXCEPT_OR_NOTHROW
  178. { return it.get_ptr(); }
  179. struct vector_uninitialized_size_t {};
  180. static const vector_uninitialized_size_t vector_uninitialized_size = vector_uninitialized_size_t();
  181. template <class T>
  182. struct vector_value_traits_base
  183. {
  184. static const bool trivial_dctr = dtl::is_trivially_destructible<T>::value;
  185. static const bool trivial_dctr_after_move = has_trivial_destructor_after_move<T>::value;
  186. static const bool trivial_copy = dtl::is_trivially_copy_constructible<T>::value;
  187. static const bool nothrow_copy = dtl::is_nothrow_copy_constructible<T>::value || trivial_copy;
  188. static const bool trivial_assign = dtl::is_trivially_copy_assignable<T>::value;
  189. static const bool nothrow_assign = dtl::is_nothrow_copy_assignable<T>::value || trivial_assign;
  190. };
  191. template <class Allocator>
  192. struct vector_value_traits
  193. : public vector_value_traits_base<typename Allocator::value_type>
  194. {
  195. typedef vector_value_traits_base<typename Allocator::value_type> base_t;
  196. //This is the anti-exception array destructor
  197. //to deallocate values already constructed
  198. typedef typename dtl::if_c
  199. <base_t::trivial_dctr
  200. ,dtl::null_scoped_destructor_n<Allocator>
  201. ,dtl::scoped_destructor_n<Allocator>
  202. >::type ArrayDestructor;
  203. //This is the anti-exception array deallocator
  204. typedef dtl::scoped_array_deallocator<Allocator> ArrayDeallocator;
  205. };
  206. //!This struct deallocates and allocated memory
  207. template < class Allocator
  208. , class StoredSizeType
  209. , class AllocatorVersion = typename dtl::version<Allocator>::type
  210. >
  211. struct vector_alloc_holder
  212. : public Allocator
  213. {
  214. private:
  215. BOOST_MOVABLE_BUT_NOT_COPYABLE(vector_alloc_holder)
  216. public:
  217. typedef Allocator allocator_type;
  218. typedef StoredSizeType stored_size_type;
  219. typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
  220. typedef typename allocator_traits_type::pointer pointer;
  221. typedef typename allocator_traits_type::size_type size_type;
  222. typedef typename allocator_traits_type::value_type value_type;
  223. static bool is_propagable_from(const allocator_type &from_alloc, pointer p, const allocator_type &to_alloc, bool const propagate_allocator)
  224. {
  225. (void)propagate_allocator; (void)p; (void)to_alloc; (void)from_alloc;
  226. const bool all_storage_propagable = !allocator_traits_type::is_partially_propagable::value ||
  227. !allocator_traits_type::storage_is_unpropagable(from_alloc, p);
  228. return all_storage_propagable && (propagate_allocator || allocator_traits_type::equal(from_alloc, to_alloc));
  229. }
  230. static bool are_swap_propagable(const allocator_type &l_a, pointer l_p, const allocator_type &r_a, pointer r_p, bool const propagate_allocator)
  231. {
  232. (void)propagate_allocator; (void)l_p; (void)r_p; (void)l_a; (void)r_a;
  233. const bool all_storage_propagable = !allocator_traits_type::is_partially_propagable::value ||
  234. !(allocator_traits_type::storage_is_unpropagable(l_a, l_p) || allocator_traits_type::storage_is_unpropagable(r_a, r_p));
  235. return all_storage_propagable && (propagate_allocator || allocator_traits_type::equal(l_a, r_a));
  236. }
  237. //Constructor, does not throw
  238. vector_alloc_holder()
  239. BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value)
  240. : Allocator(), m_start(), m_size(), m_capacity()
  241. {}
  242. //Constructor, does not throw
  243. template<class AllocConvertible>
  244. explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_NOEXCEPT_OR_NOTHROW
  245. : Allocator(boost::forward<AllocConvertible>(a)), m_start(), m_size(), m_capacity()
  246. {}
  247. //Constructor, does not throw
  248. template<class AllocConvertible>
  249. vector_alloc_holder(vector_uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, size_type initial_size)
  250. : Allocator(boost::forward<AllocConvertible>(a))
  251. , m_start()
  252. //Size is initialized here so vector should only call uninitialized_xxx after this
  253. , m_size(static_cast<stored_size_type>(initial_size))
  254. , m_capacity()
  255. {
  256. if(initial_size){
  257. pointer reuse = pointer();
  258. size_type final_cap = initial_size;
  259. m_start = this->allocation_command(allocate_new, initial_size, final_cap, reuse);
  260. m_capacity = static_cast<stored_size_type>(final_cap);
  261. }
  262. }
  263. //Constructor, does not throw
  264. vector_alloc_holder(vector_uninitialized_size_t, size_type initial_size)
  265. : Allocator()
  266. , m_start()
  267. //Size is initialized here so vector should only call uninitialized_xxx after this
  268. , m_size(static_cast<stored_size_type>(initial_size))
  269. , m_capacity()
  270. {
  271. if(initial_size){
  272. pointer reuse = pointer();
  273. size_type final_cap = initial_size;
  274. m_start = this->allocation_command(allocate_new, initial_size, final_cap, reuse);
  275. m_capacity = static_cast<stored_size_type>(final_cap);
  276. }
  277. }
  278. vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder) BOOST_NOEXCEPT_OR_NOTHROW
  279. : Allocator(BOOST_MOVE_BASE(Allocator, holder))
  280. , m_start(holder.m_start)
  281. , m_size(holder.m_size)
  282. , m_capacity(holder.m_capacity)
  283. {
  284. holder.m_start = pointer();
  285. holder.m_size = holder.m_capacity = 0;
  286. }
  287. vector_alloc_holder(initial_capacity_t, pointer p, size_type capacity, BOOST_RV_REF(vector_alloc_holder) holder)
  288. : Allocator(BOOST_MOVE_BASE(Allocator, holder))
  289. , m_start(p)
  290. , m_size(holder.m_size)
  291. , m_capacity(static_cast<stored_size_type>(capacity))
  292. {
  293. allocator_type &this_alloc = this->alloc();
  294. allocator_type &x_alloc = holder.alloc();
  295. if(this->is_propagable_from(x_alloc, holder.start(), this_alloc, true)){
  296. if(this->m_capacity){
  297. this->deallocate(this->m_start, this->m_capacity);
  298. }
  299. m_start = holder.m_start;
  300. m_capacity = holder.m_capacity;
  301. holder.m_start = pointer();
  302. holder.m_capacity = holder.m_size = 0;
  303. }
  304. else if(this->m_capacity < holder.m_size){
  305. size_type const n = holder.m_size;
  306. pointer reuse = pointer();
  307. size_type final_cap = n;
  308. m_start = this->allocation_command(allocate_new, n, final_cap, reuse);
  309. m_capacity = static_cast<stored_size_type>(final_cap);
  310. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  311. this->num_alloc += n != 0;
  312. #endif
  313. }
  314. }
  315. vector_alloc_holder(initial_capacity_t, pointer p, size_type n)
  316. BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value)
  317. : Allocator()
  318. , m_start(p)
  319. , m_size()
  320. //n is guaranteed to fit into stored_size_type
  321. , m_capacity(static_cast<stored_size_type>(n))
  322. {}
  323. template<class AllocFwd>
  324. vector_alloc_holder(initial_capacity_t, pointer p, size_type n, BOOST_FWD_REF(AllocFwd) a)
  325. : Allocator(::boost::forward<AllocFwd>(a))
  326. , m_start(p)
  327. , m_size()
  328. , m_capacity(n)
  329. {}
  330. BOOST_CONTAINER_FORCEINLINE ~vector_alloc_holder() BOOST_NOEXCEPT_OR_NOTHROW
  331. {
  332. if(this->m_capacity){
  333. this->deallocate(this->m_start, this->m_capacity);
  334. }
  335. }
  336. BOOST_CONTAINER_FORCEINLINE pointer allocation_command(boost::container::allocation_type command,
  337. size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
  338. {
  339. typedef typename dtl::version<Allocator>::type alloc_version;
  340. return this->priv_allocation_command(alloc_version(), command, limit_size, prefer_in_recvd_out_size, reuse);
  341. }
  342. BOOST_CONTAINER_FORCEINLINE pointer allocate(size_type n)
  343. {
  344. const size_type max_alloc = allocator_traits_type::max_size(this->alloc());
  345. const size_type max = max_alloc <= stored_size_type(-1) ? max_alloc : stored_size_type(-1);
  346. if ( max < n )
  347. boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
  348. return allocator_traits_type::allocate(this->alloc(), n);
  349. }
  350. BOOST_CONTAINER_FORCEINLINE void deallocate(const pointer &p, size_type n)
  351. {
  352. allocator_traits_type::deallocate(this->alloc(), p, n);
  353. }
  354. bool try_expand_fwd(size_type at_least)
  355. {
  356. //There is not enough memory, try to expand the old one
  357. const size_type new_cap = this->capacity() + at_least;
  358. size_type real_cap = new_cap;
  359. pointer reuse = this->start();
  360. bool const success = !!this->allocation_command(expand_fwd, new_cap, real_cap, reuse);
  361. //Check for forward expansion
  362. if(success){
  363. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  364. ++this->num_expand_fwd;
  365. #endif
  366. this->capacity(real_cap);
  367. }
  368. return success;
  369. }
  370. template<class GrowthFactorType>
  371. size_type next_capacity(size_type additional_objects) const
  372. {
  373. BOOST_ASSERT(additional_objects > size_type(this->m_capacity - this->m_size));
  374. size_type max = allocator_traits_type::max_size(this->alloc());
  375. (clamp_by_stored_size_type)(max, stored_size_type());
  376. const size_type remaining_cap = max - size_type(this->m_capacity);
  377. const size_type min_additional_cap = additional_objects - size_type(this->m_capacity - this->m_size);
  378. if ( remaining_cap < min_additional_cap )
  379. boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
  380. return GrowthFactorType()( size_type(this->m_capacity), min_additional_cap, max);
  381. }
  382. pointer m_start;
  383. stored_size_type m_size;
  384. stored_size_type m_capacity;
  385. void swap_resources(vector_alloc_holder &x) BOOST_NOEXCEPT_OR_NOTHROW
  386. {
  387. boost::adl_move_swap(this->m_start, x.m_start);
  388. boost::adl_move_swap(this->m_size, x.m_size);
  389. boost::adl_move_swap(this->m_capacity, x.m_capacity);
  390. }
  391. void steal_resources(vector_alloc_holder &x) BOOST_NOEXCEPT_OR_NOTHROW
  392. {
  393. this->m_start = x.m_start;
  394. this->m_size = x.m_size;
  395. this->m_capacity = x.m_capacity;
  396. x.m_start = pointer();
  397. x.m_size = x.m_capacity = 0;
  398. }
  399. BOOST_CONTAINER_FORCEINLINE Allocator &alloc() BOOST_NOEXCEPT_OR_NOTHROW
  400. { return *this; }
  401. BOOST_CONTAINER_FORCEINLINE const Allocator &alloc() const BOOST_NOEXCEPT_OR_NOTHROW
  402. { return *this; }
  403. BOOST_CONTAINER_FORCEINLINE const pointer &start() const BOOST_NOEXCEPT_OR_NOTHROW
  404. { return m_start; }
  405. BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
  406. { return m_capacity; }
  407. BOOST_CONTAINER_FORCEINLINE void start(const pointer &p) BOOST_NOEXCEPT_OR_NOTHROW
  408. { m_start = p; }
  409. BOOST_CONTAINER_FORCEINLINE void capacity(const size_type &c) BOOST_NOEXCEPT_OR_NOTHROW
  410. { BOOST_ASSERT( c <= stored_size_type(-1)); m_capacity = c; }
  411. private:
  412. void priv_first_allocation(size_type cap)
  413. {
  414. if(cap){
  415. pointer reuse = pointer();
  416. m_start = this->allocation_command(allocate_new, cap, cap, reuse);
  417. m_capacity = cap;
  418. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  419. ++this->num_alloc;
  420. #endif
  421. }
  422. }
  423. BOOST_CONTAINER_FORCEINLINE static void clamp_by_stored_size_type(size_type &, size_type)
  424. {}
  425. template<class SomeStoredSizeType>
  426. BOOST_CONTAINER_FORCEINLINE static void clamp_by_stored_size_type(size_type &s, SomeStoredSizeType)
  427. {
  428. if (s >= SomeStoredSizeType(-1) )
  429. s = SomeStoredSizeType(-1);
  430. }
  431. BOOST_CONTAINER_FORCEINLINE pointer priv_allocation_command(version_1, boost::container::allocation_type command,
  432. size_type limit_size,
  433. size_type &prefer_in_recvd_out_size,
  434. pointer &reuse)
  435. {
  436. (void)command;
  437. BOOST_ASSERT( (command & allocate_new));
  438. BOOST_ASSERT(!(command & nothrow_allocation));
  439. //First detect overflow on smaller stored_size_types
  440. if (limit_size > stored_size_type(-1)){
  441. boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
  442. }
  443. (clamp_by_stored_size_type)(prefer_in_recvd_out_size, stored_size_type());
  444. pointer const p = this->allocate(prefer_in_recvd_out_size);
  445. reuse = pointer();
  446. return p;
  447. }
  448. pointer priv_allocation_command(version_2, boost::container::allocation_type command,
  449. size_type limit_size,
  450. size_type &prefer_in_recvd_out_size,
  451. pointer &reuse)
  452. {
  453. //First detect overflow on smaller stored_size_types
  454. if (limit_size > stored_size_type(-1)){
  455. boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
  456. }
  457. (clamp_by_stored_size_type)(prefer_in_recvd_out_size, stored_size_type());
  458. //Allocate memory
  459. pointer p = this->alloc().allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);
  460. //If after allocation prefer_in_recvd_out_size is not representable by stored_size_type, truncate it.
  461. (clamp_by_stored_size_type)(prefer_in_recvd_out_size, stored_size_type());
  462. return p;
  463. }
  464. };
  465. //!This struct deallocates and allocated memory
  466. template <class Allocator, class StoredSizeType>
  467. struct vector_alloc_holder<Allocator, StoredSizeType, version_0>
  468. : public Allocator
  469. {
  470. private:
  471. BOOST_MOVABLE_BUT_NOT_COPYABLE(vector_alloc_holder)
  472. public:
  473. typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
  474. typedef typename allocator_traits_type::pointer pointer;
  475. typedef typename allocator_traits_type::size_type size_type;
  476. typedef typename allocator_traits_type::value_type value_type;
  477. typedef StoredSizeType stored_size_type;
  478. template <class OtherAllocator, class OtherStoredSizeType, class OtherAllocatorVersion>
  479. friend struct vector_alloc_holder;
  480. //Constructor, does not throw
  481. vector_alloc_holder()
  482. BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value)
  483. : Allocator(), m_size()
  484. {}
  485. //Constructor, does not throw
  486. template<class AllocConvertible>
  487. explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_NOEXCEPT_OR_NOTHROW
  488. : Allocator(boost::forward<AllocConvertible>(a)), m_size()
  489. {}
  490. //Constructor, does not throw
  491. template<class AllocConvertible>
  492. vector_alloc_holder(vector_uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, size_type initial_size)
  493. : Allocator(boost::forward<AllocConvertible>(a))
  494. , m_size(initial_size) //Size is initialized here...
  495. {
  496. //... and capacity here, so vector, must call uninitialized_xxx in the derived constructor
  497. this->priv_first_allocation(initial_size);
  498. }
  499. //Constructor, does not throw
  500. vector_alloc_holder(vector_uninitialized_size_t, size_type initial_size)
  501. : Allocator()
  502. , m_size(initial_size) //Size is initialized here...
  503. {
  504. //... and capacity here, so vector, must call uninitialized_xxx in the derived constructor
  505. this->priv_first_allocation(initial_size);
  506. }
  507. vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder)
  508. : Allocator(BOOST_MOVE_BASE(Allocator, holder))
  509. , m_size(holder.m_size) //Size is initialized here so vector should only call uninitialized_xxx after this
  510. {
  511. ::boost::container::uninitialized_move_alloc_n
  512. (this->alloc(), boost::movelib::to_raw_pointer(holder.start()), m_size, boost::movelib::to_raw_pointer(this->start()));
  513. }
  514. template<class OtherAllocator, class OtherStoredSizeType, class OtherAllocatorVersion>
  515. vector_alloc_holder(BOOST_RV_REF_BEG vector_alloc_holder<OtherAllocator, OtherStoredSizeType, OtherAllocatorVersion> BOOST_RV_REF_END holder)
  516. : Allocator()
  517. , m_size(holder.m_size) //Initialize it to m_size as first_allocation can only succeed or abort
  518. {
  519. //Different allocator type so we must check we have enough storage
  520. const size_type n = holder.m_size;
  521. this->priv_first_allocation(n);
  522. ::boost::container::uninitialized_move_alloc_n
  523. (this->alloc(), boost::movelib::to_raw_pointer(holder.start()), n, boost::movelib::to_raw_pointer(this->start()));
  524. }
  525. BOOST_CONTAINER_FORCEINLINE void priv_first_allocation(size_type cap)
  526. {
  527. if(cap > Allocator::internal_capacity){
  528. throw_bad_alloc();
  529. }
  530. }
  531. BOOST_CONTAINER_FORCEINLINE void deep_swap(vector_alloc_holder &x)
  532. {
  533. this->priv_deep_swap(x);
  534. }
  535. template<class OtherAllocator, class OtherStoredSizeType, class OtherAllocatorVersion>
  536. void deep_swap(vector_alloc_holder<OtherAllocator, OtherStoredSizeType, OtherAllocatorVersion> &x)
  537. {
  538. if(this->m_size > OtherAllocator::internal_capacity || x.m_size > Allocator::internal_capacity){
  539. throw_bad_alloc();
  540. }
  541. this->priv_deep_swap(x);
  542. }
  543. BOOST_CONTAINER_FORCEINLINE void swap_resources(vector_alloc_holder &) BOOST_NOEXCEPT_OR_NOTHROW
  544. { //Containers with version 0 allocators can't be moved without moving elements one by one
  545. throw_bad_alloc();
  546. }
  547. BOOST_CONTAINER_FORCEINLINE void steal_resources(vector_alloc_holder &)
  548. { //Containers with version 0 allocators can't be moved without moving elements one by one
  549. throw_bad_alloc();
  550. }
  551. BOOST_CONTAINER_FORCEINLINE Allocator &alloc() BOOST_NOEXCEPT_OR_NOTHROW
  552. { return *this; }
  553. BOOST_CONTAINER_FORCEINLINE const Allocator &alloc() const BOOST_NOEXCEPT_OR_NOTHROW
  554. { return *this; }
  555. BOOST_CONTAINER_FORCEINLINE bool try_expand_fwd(size_type at_least)
  556. { return !at_least; }
  557. BOOST_CONTAINER_FORCEINLINE pointer start() const BOOST_NOEXCEPT_OR_NOTHROW { return Allocator::internal_storage(); }
  558. BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW { return Allocator::internal_capacity; }
  559. stored_size_type m_size;
  560. private:
  561. template<class OtherAllocator, class OtherStoredSizeType, class OtherAllocatorVersion>
  562. void priv_deep_swap(vector_alloc_holder<OtherAllocator, OtherStoredSizeType, OtherAllocatorVersion> &x)
  563. {
  564. const size_type MaxTmpStorage = sizeof(value_type)*Allocator::internal_capacity;
  565. value_type *const first_this = boost::movelib::to_raw_pointer(this->start());
  566. value_type *const first_x = boost::movelib::to_raw_pointer(x.start());
  567. if(this->m_size < x.m_size){
  568. boost::container::deep_swap_alloc_n<MaxTmpStorage>(this->alloc(), first_this, this->m_size, first_x, x.m_size);
  569. }
  570. else{
  571. boost::container::deep_swap_alloc_n<MaxTmpStorage>(this->alloc(), first_x, x.m_size, first_this, this->m_size);
  572. }
  573. boost::adl_move_swap(this->m_size, x.m_size);
  574. }
  575. };
  576. struct growth_factor_60;
  577. template<class T, class Default>
  578. struct default_if_void
  579. {
  580. typedef T type;
  581. };
  582. template<class Default>
  583. struct default_if_void<void, Default>
  584. {
  585. typedef Default type;
  586. };
  587. template<class Options, class AllocatorSizeType>
  588. struct get_vector_opt
  589. {
  590. typedef vector_opt< typename default_if_void<typename Options::growth_factor_type, growth_factor_60>::type
  591. , typename default_if_void<typename Options::stored_size_type, AllocatorSizeType>::type
  592. > type;
  593. };
  594. template<class AllocatorSizeType>
  595. struct get_vector_opt<void, AllocatorSizeType>
  596. {
  597. typedef vector_opt<growth_factor_60, AllocatorSizeType> type;
  598. };
  599. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  600. //! A vector is a sequence that supports random access to elements, constant
  601. //! time insertion and removal of elements at the end, and linear time insertion
  602. //! and removal of elements at the beginning or in the middle. The number of
  603. //! elements in a vector may vary dynamically; memory management is automatic.
  604. //!
  605. //! \tparam T The type of object that is stored in the vector
  606. //! \tparam Allocator The allocator used for all internal memory management
  607. //! \tparam Options A type produced from \c boost::container::vector_options.
  608. template <class T, class Allocator BOOST_CONTAINER_DOCONLY(= new_allocator<T>), class Options BOOST_CONTAINER_DOCONLY(= void) >
  609. class vector
  610. {
  611. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  612. typedef typename boost::container::allocator_traits<Allocator>::size_type alloc_size_type;
  613. typedef typename get_vector_opt<Options, alloc_size_type>::type options_type;
  614. typedef typename options_type::growth_factor_type growth_factor_type;
  615. typedef typename options_type::stored_size_type stored_size_type;
  616. typedef value_less<T> value_less_t;
  617. //If provided the stored_size option must specify a type that is equal or a type that is smaller.
  618. BOOST_STATIC_ASSERT( (sizeof(stored_size_type) < sizeof(alloc_size_type) ||
  619. dtl::is_same<stored_size_type, alloc_size_type>::value) );
  620. typedef typename dtl::version<Allocator>::type alloc_version;
  621. typedef boost::container::vector_alloc_holder<Allocator, stored_size_type> alloc_holder_t;
  622. alloc_holder_t m_holder;
  623. typedef allocator_traits<Allocator> allocator_traits_type;
  624. template <class U, class UAllocator, class UOptions>
  625. friend class vector;
  626. typedef typename allocator_traits_type::pointer pointer_impl;
  627. typedef vec_iterator<pointer_impl, false> iterator_impl;
  628. typedef vec_iterator<pointer_impl, true > const_iterator_impl;
  629. protected:
  630. static bool is_propagable_from(const Allocator &from_alloc, pointer_impl p, const Allocator &to_alloc, bool const propagate_allocator)
  631. { return alloc_holder_t::is_propagable_from(from_alloc, p, to_alloc, propagate_allocator); }
  632. static bool are_swap_propagable( const Allocator &l_a, pointer_impl l_p
  633. , const Allocator &r_a, pointer_impl r_p, bool const propagate_allocator)
  634. { return alloc_holder_t::are_swap_propagable(l_a, l_p, r_a, r_p, propagate_allocator); }
  635. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  636. public:
  637. //////////////////////////////////////////////
  638. //
  639. // types
  640. //
  641. //////////////////////////////////////////////
  642. typedef T value_type;
  643. typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
  644. typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
  645. typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
  646. typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
  647. typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
  648. typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
  649. typedef Allocator allocator_type;
  650. typedef Allocator stored_allocator_type;
  651. typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
  652. typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
  653. typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator;
  654. typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
  655. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  656. private:
  657. BOOST_COPYABLE_AND_MOVABLE(vector)
  658. typedef vector_value_traits<Allocator> value_traits;
  659. typedef constant_iterator<T, difference_type> cvalue_iterator;
  660. protected:
  661. BOOST_CONTAINER_FORCEINLINE void steal_resources(vector &x)
  662. { return this->m_holder.steal_resources(x.m_holder); }
  663. template<class AllocFwd>
  664. BOOST_CONTAINER_FORCEINLINE vector(initial_capacity_t, pointer initial_memory, size_type capacity, BOOST_FWD_REF(AllocFwd) a)
  665. : m_holder(initial_capacity_t(), initial_memory, capacity, ::boost::forward<AllocFwd>(a))
  666. {}
  667. BOOST_CONTAINER_FORCEINLINE vector(initial_capacity_t, pointer initial_memory, size_type capacity)
  668. : m_holder(initial_capacity_t(), initial_memory, capacity)
  669. {}
  670. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  671. public:
  672. //////////////////////////////////////////////
  673. //
  674. // construct/copy/destroy
  675. //
  676. //////////////////////////////////////////////
  677. //! <b>Effects</b>: Constructs a vector taking the allocator as parameter.
  678. //!
  679. //! <b>Throws</b>: Nothing.
  680. //!
  681. //! <b>Complexity</b>: Constant.
  682. vector() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value)
  683. : m_holder()
  684. {}
  685. //! <b>Effects</b>: Constructs a vector taking the allocator as parameter.
  686. //!
  687. //! <b>Throws</b>: Nothing
  688. //!
  689. //! <b>Complexity</b>: Constant.
  690. explicit vector(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW
  691. : m_holder(a)
  692. {}
  693. //! <b>Effects</b>: Constructs a vector and inserts n value initialized values.
  694. //!
  695. //! <b>Throws</b>: If allocator_type's allocation
  696. //! throws or T's value initialization throws.
  697. //!
  698. //! <b>Complexity</b>: Linear to n.
  699. explicit vector(size_type n)
  700. : m_holder(vector_uninitialized_size, n)
  701. {
  702. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  703. this->num_alloc += n != 0;
  704. #endif
  705. boost::container::uninitialized_value_init_alloc_n
  706. (this->m_holder.alloc(), n, this->priv_raw_begin());
  707. }
  708. //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
  709. //! and inserts n value initialized values.
  710. //!
  711. //! <b>Throws</b>: If allocator_type's allocation
  712. //! throws or T's value initialization throws.
  713. //!
  714. //! <b>Complexity</b>: Linear to n.
  715. explicit vector(size_type n, const allocator_type &a)
  716. : m_holder(vector_uninitialized_size, a, n)
  717. {
  718. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  719. this->num_alloc += n != 0;
  720. #endif
  721. boost::container::uninitialized_value_init_alloc_n
  722. (this->m_holder.alloc(), n, this->priv_raw_begin());
  723. }
  724. //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
  725. //! and inserts n default initialized values.
  726. //!
  727. //! <b>Throws</b>: If allocator_type's allocation
  728. //! throws or T's default initialization throws.
  729. //!
  730. //! <b>Complexity</b>: Linear to n.
  731. //!
  732. //! <b>Note</b>: Non-standard extension
  733. vector(size_type n, default_init_t)
  734. : m_holder(vector_uninitialized_size, n)
  735. {
  736. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  737. this->num_alloc += n != 0;
  738. #endif
  739. boost::container::uninitialized_default_init_alloc_n
  740. (this->m_holder.alloc(), n, this->priv_raw_begin());
  741. }
  742. //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
  743. //! and inserts n default initialized values.
  744. //!
  745. //! <b>Throws</b>: If allocator_type's allocation
  746. //! throws or T's default initialization throws.
  747. //!
  748. //! <b>Complexity</b>: Linear to n.
  749. //!
  750. //! <b>Note</b>: Non-standard extension
  751. vector(size_type n, default_init_t, const allocator_type &a)
  752. : m_holder(vector_uninitialized_size, a, n)
  753. {
  754. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  755. this->num_alloc += n != 0;
  756. #endif
  757. boost::container::uninitialized_default_init_alloc_n
  758. (this->m_holder.alloc(), n, this->priv_raw_begin());
  759. }
  760. //! <b>Effects</b>: Constructs a vector
  761. //! and inserts n copies of value.
  762. //!
  763. //! <b>Throws</b>: If allocator_type's allocation
  764. //! throws or T's copy constructor throws.
  765. //!
  766. //! <b>Complexity</b>: Linear to n.
  767. vector(size_type n, const T& value)
  768. : m_holder(vector_uninitialized_size, n)
  769. {
  770. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  771. this->num_alloc += n != 0;
  772. #endif
  773. boost::container::uninitialized_fill_alloc_n
  774. (this->m_holder.alloc(), value, n, this->priv_raw_begin());
  775. }
  776. //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
  777. //! and inserts n copies of value.
  778. //!
  779. //! <b>Throws</b>: If allocation
  780. //! throws or T's copy constructor throws.
  781. //!
  782. //! <b>Complexity</b>: Linear to n.
  783. vector(size_type n, const T& value, const allocator_type& a)
  784. : m_holder(vector_uninitialized_size, a, n)
  785. {
  786. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  787. this->num_alloc += n != 0;
  788. #endif
  789. boost::container::uninitialized_fill_alloc_n
  790. (this->m_holder.alloc(), value, n, this->priv_raw_begin());
  791. }
  792. //! <b>Effects</b>: Constructs a vector
  793. //! and inserts a copy of the range [first, last) in the vector.
  794. //!
  795. //! <b>Throws</b>: If allocator_type's allocation
  796. //! throws or T's constructor taking a dereferenced InIt throws.
  797. //!
  798. //! <b>Complexity</b>: Linear to the range [first, last).
  799. // template <class InIt>
  800. // vector(InIt first, InIt last
  801. // BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c
  802. // < dtl::is_convertible<InIt BOOST_MOVE_I size_type>::value
  803. // BOOST_MOVE_I dtl::nat >::type * = 0)
  804. // ) -> vector<typename iterator_traits<InIt>::value_type, new_allocator<typename iterator_traits<InIt>::value_type>>;
  805. template <class InIt>
  806. vector(InIt first, InIt last
  807. BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c
  808. < dtl::is_convertible<InIt BOOST_MOVE_I size_type>::value
  809. BOOST_MOVE_I dtl::nat >::type * = 0)
  810. )
  811. : m_holder()
  812. { this->assign(first, last); }
  813. //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
  814. //! and inserts a copy of the range [first, last) in the vector.
  815. //!
  816. //! <b>Throws</b>: If allocator_type's allocation
  817. //! throws or T's constructor taking a dereferenced InIt throws.
  818. //!
  819. //! <b>Complexity</b>: Linear to the range [first, last).
  820. // template <class InIt>
  821. // vector(InIt first, InIt last, const allocator_type& a
  822. // BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c
  823. // < dtl::is_convertible<InIt BOOST_MOVE_I size_type>::value
  824. // BOOST_MOVE_I dtl::nat >::type * = 0)
  825. // ) -> vector<typename iterator_traits<InIt>::value_type, new_allocator<typename iterator_traits<InIt>::value_type>>;
  826. template <class InIt>
  827. vector(InIt first, InIt last, const allocator_type& a
  828. BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c
  829. < dtl::is_convertible<InIt BOOST_MOVE_I size_type>::value
  830. BOOST_MOVE_I dtl::nat >::type * = 0)
  831. )
  832. : m_holder(a)
  833. { this->assign(first, last); }
  834. //! <b>Effects</b>: Copy constructs a vector.
  835. //!
  836. //! <b>Postcondition</b>: x == *this.
  837. //!
  838. //! <b>Throws</b>: If allocator_type's allocation
  839. //! throws or T's copy constructor throws.
  840. //!
  841. //! <b>Complexity</b>: Linear to the elements x contains.
  842. vector(const vector &x)
  843. : m_holder( vector_uninitialized_size
  844. , allocator_traits_type::select_on_container_copy_construction(x.m_holder.alloc())
  845. , x.size())
  846. {
  847. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  848. this->num_alloc += x.size() != 0;
  849. #endif
  850. ::boost::container::uninitialized_copy_alloc_n
  851. ( this->m_holder.alloc(), x.priv_raw_begin()
  852. , x.size(), this->priv_raw_begin());
  853. }
  854. //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
  855. //!
  856. //! <b>Throws</b>: Nothing
  857. //!
  858. //! <b>Complexity</b>: Constant.
  859. vector(BOOST_RV_REF(vector) x) BOOST_NOEXCEPT_OR_NOTHROW
  860. : m_holder(boost::move(x.m_holder))
  861. { BOOST_STATIC_ASSERT((!allocator_traits_type::is_partially_propagable::value)); }
  862. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  863. //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
  864. //! and inserts a copy of the range [il.begin(), il.last()) in the vector
  865. //!
  866. //! <b>Throws</b>: If T's constructor taking a dereferenced initializer_list iterator throws.
  867. //!
  868. //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
  869. vector(std::initializer_list<value_type> il, const allocator_type& a = allocator_type())
  870. : m_holder(a)
  871. {
  872. this->assign(il.begin(), il.end());
  873. }
  874. #endif
  875. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  876. //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
  877. //!
  878. //! <b>Throws</b>: If T's move constructor or allocation throws
  879. //!
  880. //! <b>Complexity</b>: Linear.
  881. //!
  882. //! <b>Note</b>: Non-standard extension to support static_vector
  883. template<class OtherAllocator>
  884. vector(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x
  885. , typename dtl::enable_if_c
  886. < dtl::is_version<OtherAllocator, 0>::value>::type * = 0
  887. )
  888. : m_holder(boost::move(x.m_holder))
  889. {}
  890. #endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  891. //! <b>Effects</b>: Copy constructs a vector using the specified allocator.
  892. //!
  893. //! <b>Postcondition</b>: x == *this.
  894. //!
  895. //! <b>Throws</b>: If allocation
  896. //! throws or T's copy constructor throws.
  897. //!
  898. //! <b>Complexity</b>: Linear to the elements x contains.
  899. vector(const vector &x, const allocator_type &a)
  900. : m_holder(vector_uninitialized_size, a, x.size())
  901. {
  902. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  903. this->num_alloc += x.size() != 0;
  904. #endif
  905. ::boost::container::uninitialized_copy_alloc_n_source
  906. ( this->m_holder.alloc(), x.priv_raw_begin()
  907. , x.size(), this->priv_raw_begin());
  908. }
  909. //! <b>Effects</b>: Move constructor using the specified allocator.
  910. //! Moves x's resources to *this if a == allocator_type().
  911. //! Otherwise copies values from x to *this.
  912. //!
  913. //! <b>Throws</b>: If allocation or T's copy constructor throws.
  914. //!
  915. //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
  916. vector(BOOST_RV_REF(vector) x, const allocator_type &a)
  917. : m_holder( vector_uninitialized_size, a
  918. , is_propagable_from(x.get_stored_allocator(), x.m_holder.start(), a, true) ? 0 : x.size()
  919. )
  920. {
  921. if(is_propagable_from(x.get_stored_allocator(), x.m_holder.start(), a, true)){
  922. this->m_holder.steal_resources(x.m_holder);
  923. }
  924. else{
  925. const size_type n = x.size();
  926. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  927. this->num_alloc += n != 0;
  928. #endif
  929. ::boost::container::uninitialized_move_alloc_n_source
  930. ( this->m_holder.alloc(), x.priv_raw_begin()
  931. , n, this->priv_raw_begin());
  932. }
  933. }
  934. //! <b>Effects</b>: Destroys the vector. All stored values are destroyed
  935. //! and used memory is deallocated.
  936. //!
  937. //! <b>Throws</b>: Nothing.
  938. //!
  939. //! <b>Complexity</b>: Linear to the number of elements.
  940. ~vector() BOOST_NOEXCEPT_OR_NOTHROW
  941. {
  942. boost::container::destroy_alloc_n
  943. (this->get_stored_allocator(), this->priv_raw_begin(), this->m_holder.m_size);
  944. //vector_alloc_holder deallocates the data
  945. }
  946. //! <b>Effects</b>: Makes *this contain the same elements as x.
  947. //!
  948. //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
  949. //! of each of x's elements.
  950. //!
  951. //! <b>Throws</b>: If memory allocation throws or T's copy/move constructor/assignment throws.
  952. //!
  953. //! <b>Complexity</b>: Linear to the number of elements in x.
  954. BOOST_CONTAINER_FORCEINLINE vector& operator=(BOOST_COPY_ASSIGN_REF(vector) x)
  955. {
  956. if (&x != this){
  957. this->priv_copy_assign(x);
  958. }
  959. return *this;
  960. }
  961. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  962. //! <b>Effects</b>: Make *this container contains elements from il.
  963. //!
  964. //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
  965. BOOST_CONTAINER_FORCEINLINE vector& operator=(std::initializer_list<value_type> il)
  966. {
  967. this->assign(il.begin(), il.end());
  968. return *this;
  969. }
  970. #endif
  971. //! <b>Effects</b>: Move assignment. All x's values are transferred to *this.
  972. //!
  973. //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
  974. //! before the function.
  975. //!
  976. //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
  977. //! is false and (allocation throws or value_type's move constructor throws)
  978. //!
  979. //! <b>Complexity</b>: Constant if allocator_traits_type::
  980. //! propagate_on_container_move_assignment is true or
  981. //! this->get>allocator() == x.get_allocator(). Linear otherwise.
  982. BOOST_CONTAINER_FORCEINLINE vector& operator=(BOOST_RV_REF(vector) x)
  983. BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
  984. || allocator_traits_type::is_always_equal::value)
  985. {
  986. BOOST_ASSERT(&x != this);
  987. this->priv_move_assign(boost::move(x));
  988. return *this;
  989. }
  990. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  991. //! <b>Effects</b>: Move assignment. All x's values are transferred to *this.
  992. //!
  993. //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
  994. //! before the function.
  995. //!
  996. //! <b>Throws</b>: If move constructor/assignment of T throws or allocation throws
  997. //!
  998. //! <b>Complexity</b>: Linear.
  999. //!
  1000. //! <b>Note</b>: Non-standard extension to support static_vector
  1001. template<class OtherAllocator>
  1002. BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and
  1003. < vector&
  1004. , dtl::is_version<OtherAllocator, 0>
  1005. , dtl::is_different<OtherAllocator, allocator_type>
  1006. >::type
  1007. operator=(BOOST_RV_REF_BEG vector<value_type, OtherAllocator> BOOST_RV_REF_END x)
  1008. {
  1009. this->priv_move_assign(boost::move(x));
  1010. return *this;
  1011. }
  1012. //! <b>Effects</b>: Copy assignment. All x's values are copied to *this.
  1013. //!
  1014. //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
  1015. //! before the function.
  1016. //!
  1017. //! <b>Throws</b>: If move constructor/assignment of T throws or allocation throws
  1018. //!
  1019. //! <b>Complexity</b>: Linear.
  1020. //!
  1021. //! <b>Note</b>: Non-standard extension to support static_vector
  1022. template<class OtherAllocator>
  1023. BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and
  1024. < vector&
  1025. , dtl::is_version<OtherAllocator, 0>
  1026. , dtl::is_different<OtherAllocator, allocator_type>
  1027. >::type
  1028. operator=(const vector<value_type, OtherAllocator> &x)
  1029. {
  1030. this->priv_copy_assign(x);
  1031. return *this;
  1032. }
  1033. #endif
  1034. //! <b>Effects</b>: Assigns the the range [first, last) to *this.
  1035. //!
  1036. //! <b>Throws</b>: If memory allocation throws or T's copy/move constructor/assignment or
  1037. //! T's constructor/assignment from dereferencing InpIt throws.
  1038. //!
  1039. //! <b>Complexity</b>: Linear to n.
  1040. template <class InIt>
  1041. void assign(InIt first, InIt last
  1042. //Input iterators or version 0 allocator
  1043. BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or
  1044. < void
  1045. BOOST_MOVE_I dtl::is_convertible<InIt BOOST_MOVE_I size_type>
  1046. BOOST_MOVE_I dtl::and_
  1047. < dtl::is_different<alloc_version BOOST_MOVE_I version_0>
  1048. BOOST_MOVE_I dtl::is_not_input_iterator<InIt>
  1049. >
  1050. >::type * = 0)
  1051. )
  1052. {
  1053. //Overwrite all elements we can from [first, last)
  1054. iterator cur = this->begin();
  1055. const iterator end_it = this->end();
  1056. for ( ; first != last && cur != end_it; ++cur, ++first){
  1057. *cur = *first;
  1058. }
  1059. if (first == last){
  1060. //There are no more elements in the sequence, erase remaining
  1061. T* const end_pos = this->priv_raw_end();
  1062. const size_type n = static_cast<size_type>(end_pos - boost::movelib::iterator_to_raw_pointer(cur));
  1063. this->priv_destroy_last_n(n);
  1064. }
  1065. else{
  1066. //There are more elements in the range, insert the remaining ones
  1067. this->insert(this->cend(), first, last);
  1068. }
  1069. }
  1070. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  1071. //! <b>Effects</b>: Assigns the the range [il.begin(), il.end()) to *this.
  1072. //!
  1073. //! <b>Throws</b>: If memory allocation throws or
  1074. //! T's constructor from dereferencing iniializer_list iterator throws.
  1075. //!
  1076. BOOST_CONTAINER_FORCEINLINE void assign(std::initializer_list<T> il)
  1077. {
  1078. this->assign(il.begin(), il.end());
  1079. }
  1080. #endif
  1081. //! <b>Effects</b>: Assigns the the range [first, last) to *this.
  1082. //!
  1083. //! <b>Throws</b>: If memory allocation throws or T's copy/move constructor/assignment or
  1084. //! T's constructor/assignment from dereferencing InpIt throws.
  1085. //!
  1086. //! <b>Complexity</b>: Linear to n.
  1087. template <class FwdIt>
  1088. void assign(FwdIt first, FwdIt last
  1089. //Forward iterators and version > 0 allocator
  1090. BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or
  1091. < void
  1092. BOOST_MOVE_I dtl::is_same<alloc_version BOOST_MOVE_I version_0>
  1093. BOOST_MOVE_I dtl::is_convertible<FwdIt BOOST_MOVE_I size_type>
  1094. BOOST_MOVE_I dtl::is_input_iterator<FwdIt>
  1095. >::type * = 0)
  1096. )
  1097. {
  1098. //For Fwd iterators the standard only requires EmplaceConstructible and assignable from *first
  1099. //so we can't do any backwards allocation
  1100. const size_type input_sz = static_cast<size_type>(boost::container::iterator_distance(first, last));
  1101. const size_type old_capacity = this->capacity();
  1102. if(input_sz > old_capacity){ //If input range is too big, we need to reallocate
  1103. size_type real_cap = 0;
  1104. pointer reuse(this->m_holder.start());
  1105. pointer const ret(this->m_holder.allocation_command(allocate_new|expand_fwd, input_sz, real_cap = input_sz, reuse));
  1106. if(!reuse){ //New allocation, just emplace new values
  1107. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  1108. ++this->num_alloc;
  1109. #endif
  1110. pointer const old_p = this->m_holder.start();
  1111. if(old_p){
  1112. this->priv_destroy_all();
  1113. this->m_holder.deallocate(old_p, old_capacity);
  1114. }
  1115. this->m_holder.start(ret);
  1116. this->m_holder.capacity(real_cap);
  1117. this->m_holder.m_size = 0;
  1118. this->priv_uninitialized_construct_at_end(first, last);
  1119. return;
  1120. }
  1121. else{
  1122. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  1123. ++this->num_expand_fwd;
  1124. #endif
  1125. this->m_holder.capacity(real_cap);
  1126. //Forward expansion, use assignment + back deletion/construction that comes later
  1127. }
  1128. }
  1129. boost::container::copy_assign_range_alloc_n(this->m_holder.alloc(), first, input_sz, this->priv_raw_begin(), this->size());
  1130. this->m_holder.m_size = input_sz;
  1131. }
  1132. //! <b>Effects</b>: Assigns the n copies of val to *this.
  1133. //!
  1134. //! <b>Throws</b>: If memory allocation throws or
  1135. //! T's copy/move constructor/assignment throws.
  1136. //!
  1137. //! <b>Complexity</b>: Linear to n.
  1138. BOOST_CONTAINER_FORCEINLINE void assign(size_type n, const value_type& val)
  1139. { this->assign(cvalue_iterator(val, n), cvalue_iterator()); }
  1140. //! <b>Effects</b>: Returns a copy of the internal allocator.
  1141. //!
  1142. //! <b>Throws</b>: If allocator's copy constructor throws.
  1143. //!
  1144. //! <b>Complexity</b>: Constant.
  1145. allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
  1146. { return this->m_holder.alloc(); }
  1147. //! <b>Effects</b>: Returns a reference to the internal allocator.
  1148. //!
  1149. //! <b>Throws</b>: Nothing
  1150. //!
  1151. //! <b>Complexity</b>: Constant.
  1152. //!
  1153. //! <b>Note</b>: Non-standard extension.
  1154. BOOST_CONTAINER_FORCEINLINE stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
  1155. { return this->m_holder.alloc(); }
  1156. //! <b>Effects</b>: Returns a reference to the internal allocator.
  1157. //!
  1158. //! <b>Throws</b>: Nothing
  1159. //!
  1160. //! <b>Complexity</b>: Constant.
  1161. //!
  1162. //! <b>Note</b>: Non-standard extension.
  1163. BOOST_CONTAINER_FORCEINLINE const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
  1164. { return this->m_holder.alloc(); }
  1165. //////////////////////////////////////////////
  1166. //
  1167. // iterators
  1168. //
  1169. //////////////////////////////////////////////
  1170. //! <b>Effects</b>: Returns an iterator to the first element contained in the vector.
  1171. //!
  1172. //! <b>Throws</b>: Nothing.
  1173. //!
  1174. //! <b>Complexity</b>: Constant.
  1175. BOOST_CONTAINER_FORCEINLINE iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
  1176. { return iterator(this->m_holder.start()); }
  1177. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
  1178. //!
  1179. //! <b>Throws</b>: Nothing.
  1180. //!
  1181. //! <b>Complexity</b>: Constant.
  1182. BOOST_CONTAINER_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
  1183. { return const_iterator(this->m_holder.start()); }
  1184. //! <b>Effects</b>: Returns an iterator to the end of the vector.
  1185. //!
  1186. //! <b>Throws</b>: Nothing.
  1187. //!
  1188. //! <b>Complexity</b>: Constant.
  1189. BOOST_CONTAINER_FORCEINLINE iterator end() BOOST_NOEXCEPT_OR_NOTHROW
  1190. { return iterator(this->m_holder.start() + this->m_holder.m_size); }
  1191. //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
  1192. //!
  1193. //! <b>Throws</b>: Nothing.
  1194. //!
  1195. //! <b>Complexity</b>: Constant.
  1196. BOOST_CONTAINER_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
  1197. { return this->cend(); }
  1198. //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
  1199. //! of the reversed vector.
  1200. //!
  1201. //! <b>Throws</b>: Nothing.
  1202. //!
  1203. //! <b>Complexity</b>: Constant.
  1204. BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
  1205. { return reverse_iterator(this->end()); }
  1206. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
  1207. //! of the reversed vector.
  1208. //!
  1209. //! <b>Throws</b>: Nothing.
  1210. //!
  1211. //! <b>Complexity</b>: Constant.
  1212. BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
  1213. { return this->crbegin(); }
  1214. //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
  1215. //! of the reversed vector.
  1216. //!
  1217. //! <b>Throws</b>: Nothing.
  1218. //!
  1219. //! <b>Complexity</b>: Constant.
  1220. BOOST_CONTAINER_FORCEINLINE reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
  1221. { return reverse_iterator(this->begin()); }
  1222. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
  1223. //! of the reversed vector.
  1224. //!
  1225. //! <b>Throws</b>: Nothing.
  1226. //!
  1227. //! <b>Complexity</b>: Constant.
  1228. BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
  1229. { return this->crend(); }
  1230. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
  1231. //!
  1232. //! <b>Throws</b>: Nothing.
  1233. //!
  1234. //! <b>Complexity</b>: Constant.
  1235. BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
  1236. { return const_iterator(this->m_holder.start()); }
  1237. //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
  1238. //!
  1239. //! <b>Throws</b>: Nothing.
  1240. //!
  1241. //! <b>Complexity</b>: Constant.
  1242. BOOST_CONTAINER_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
  1243. { return const_iterator(this->m_holder.start() + this->m_holder.m_size); }
  1244. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
  1245. //! of the reversed vector.
  1246. //!
  1247. //! <b>Throws</b>: Nothing.
  1248. //!
  1249. //! <b>Complexity</b>: Constant.
  1250. BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
  1251. { return const_reverse_iterator(this->end());}
  1252. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
  1253. //! of the reversed vector.
  1254. //!
  1255. //! <b>Throws</b>: Nothing.
  1256. //!
  1257. //! <b>Complexity</b>: Constant.
  1258. BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
  1259. { return const_reverse_iterator(this->begin()); }
  1260. //////////////////////////////////////////////
  1261. //
  1262. // capacity
  1263. //
  1264. //////////////////////////////////////////////
  1265. //! <b>Effects</b>: Returns true if the vector contains no elements.
  1266. //!
  1267. //! <b>Throws</b>: Nothing.
  1268. //!
  1269. //! <b>Complexity</b>: Constant.
  1270. BOOST_CONTAINER_FORCEINLINE bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
  1271. { return !this->m_holder.m_size; }
  1272. //! <b>Effects</b>: Returns the number of the elements contained in the vector.
  1273. //!
  1274. //! <b>Throws</b>: Nothing.
  1275. //!
  1276. //! <b>Complexity</b>: Constant.
  1277. BOOST_CONTAINER_FORCEINLINE size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
  1278. { return this->m_holder.m_size; }
  1279. //! <b>Effects</b>: Returns the largest possible size of the vector.
  1280. //!
  1281. //! <b>Throws</b>: Nothing.
  1282. //!
  1283. //! <b>Complexity</b>: Constant.
  1284. BOOST_CONTAINER_FORCEINLINE size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
  1285. { return allocator_traits_type::max_size(this->m_holder.alloc()); }
  1286. //! <b>Effects</b>: Inserts or erases elements at the end such that
  1287. //! the size becomes n. New elements are value initialized.
  1288. //!
  1289. //! <b>Throws</b>: If memory allocation throws, or T's copy/move or value initialization throws.
  1290. //!
  1291. //! <b>Complexity</b>: Linear to the difference between size() and new_size.
  1292. void resize(size_type new_size)
  1293. { this->priv_resize(new_size, value_init); }
  1294. //! <b>Effects</b>: Inserts or erases elements at the end such that
  1295. //! the size becomes n. New elements are default initialized.
  1296. //!
  1297. //! <b>Throws</b>: If memory allocation throws, or T's copy/move or default initialization throws.
  1298. //!
  1299. //! <b>Complexity</b>: Linear to the difference between size() and new_size.
  1300. //!
  1301. //! <b>Note</b>: Non-standard extension
  1302. void resize(size_type new_size, default_init_t)
  1303. { this->priv_resize(new_size, default_init); }
  1304. //! <b>Effects</b>: Inserts or erases elements at the end such that
  1305. //! the size becomes n. New elements are copy constructed from x.
  1306. //!
  1307. //! <b>Throws</b>: If memory allocation throws, or T's copy/move constructor throws.
  1308. //!
  1309. //! <b>Complexity</b>: Linear to the difference between size() and new_size.
  1310. void resize(size_type new_size, const T& x)
  1311. { this->priv_resize(new_size, x); }
  1312. //! <b>Effects</b>: Number of elements for which memory has been allocated.
  1313. //! capacity() is always greater than or equal to size().
  1314. //!
  1315. //! <b>Throws</b>: Nothing.
  1316. //!
  1317. //! <b>Complexity</b>: Constant.
  1318. BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
  1319. { return this->m_holder.capacity(); }
  1320. //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
  1321. //! effect. Otherwise, it is a request for allocation of additional memory.
  1322. //! If the request is successful, then capacity() is greater than or equal to
  1323. //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
  1324. //!
  1325. //! <b>Throws</b>: If memory allocation allocation throws or T's copy/move constructor throws.
  1326. BOOST_CONTAINER_FORCEINLINE void reserve(size_type new_cap)
  1327. {
  1328. if (this->capacity() < new_cap){
  1329. this->priv_reserve_no_capacity(new_cap, alloc_version());
  1330. }
  1331. }
  1332. //! <b>Effects</b>: Tries to deallocate the excess of memory created
  1333. //! with previous allocations. The size of the vector is unchanged
  1334. //!
  1335. //! <b>Throws</b>: If memory allocation throws, or T's copy/move constructor throws.
  1336. //!
  1337. //! <b>Complexity</b>: Linear to size().
  1338. BOOST_CONTAINER_FORCEINLINE void shrink_to_fit()
  1339. { this->priv_shrink_to_fit(alloc_version()); }
  1340. //////////////////////////////////////////////
  1341. //
  1342. // element access
  1343. //
  1344. //////////////////////////////////////////////
  1345. //! <b>Requires</b>: !empty()
  1346. //!
  1347. //! <b>Effects</b>: Returns a reference to the first
  1348. //! element of the container.
  1349. //!
  1350. //! <b>Throws</b>: Nothing.
  1351. //!
  1352. //! <b>Complexity</b>: Constant.
  1353. reference front() BOOST_NOEXCEPT_OR_NOTHROW
  1354. {
  1355. BOOST_ASSERT(!this->empty());
  1356. return *this->m_holder.start();
  1357. }
  1358. //! <b>Requires</b>: !empty()
  1359. //!
  1360. //! <b>Effects</b>: Returns a const reference to the first
  1361. //! element of the container.
  1362. //!
  1363. //! <b>Throws</b>: Nothing.
  1364. //!
  1365. //! <b>Complexity</b>: Constant.
  1366. const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
  1367. {
  1368. BOOST_ASSERT(!this->empty());
  1369. return *this->m_holder.start();
  1370. }
  1371. //! <b>Requires</b>: !empty()
  1372. //!
  1373. //! <b>Effects</b>: Returns a reference to the last
  1374. //! element of the container.
  1375. //!
  1376. //! <b>Throws</b>: Nothing.
  1377. //!
  1378. //! <b>Complexity</b>: Constant.
  1379. reference back() BOOST_NOEXCEPT_OR_NOTHROW
  1380. {
  1381. BOOST_ASSERT(!this->empty());
  1382. return this->m_holder.start()[this->m_holder.m_size - 1];
  1383. }
  1384. //! <b>Requires</b>: !empty()
  1385. //!
  1386. //! <b>Effects</b>: Returns a const reference to the last
  1387. //! element of the container.
  1388. //!
  1389. //! <b>Throws</b>: Nothing.
  1390. //!
  1391. //! <b>Complexity</b>: Constant.
  1392. const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
  1393. {
  1394. BOOST_ASSERT(!this->empty());
  1395. return this->m_holder.start()[this->m_holder.m_size - 1];
  1396. }
  1397. //! <b>Requires</b>: size() > n.
  1398. //!
  1399. //! <b>Effects</b>: Returns a reference to the nth element
  1400. //! from the beginning of the container.
  1401. //!
  1402. //! <b>Throws</b>: Nothing.
  1403. //!
  1404. //! <b>Complexity</b>: Constant.
  1405. reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
  1406. {
  1407. BOOST_ASSERT(this->m_holder.m_size > n);
  1408. return this->m_holder.start()[n];
  1409. }
  1410. //! <b>Requires</b>: size() > n.
  1411. //!
  1412. //! <b>Effects</b>: Returns a const reference to the nth element
  1413. //! from the beginning of the container.
  1414. //!
  1415. //! <b>Throws</b>: Nothing.
  1416. //!
  1417. //! <b>Complexity</b>: Constant.
  1418. const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
  1419. {
  1420. BOOST_ASSERT(this->m_holder.m_size > n);
  1421. return this->m_holder.start()[n];
  1422. }
  1423. //! <b>Requires</b>: size() >= n.
  1424. //!
  1425. //! <b>Effects</b>: Returns an iterator to the nth element
  1426. //! from the beginning of the container. Returns end()
  1427. //! if n == size().
  1428. //!
  1429. //! <b>Throws</b>: Nothing.
  1430. //!
  1431. //! <b>Complexity</b>: Constant.
  1432. //!
  1433. //! <b>Note</b>: Non-standard extension
  1434. iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
  1435. {
  1436. BOOST_ASSERT(this->m_holder.m_size >= n);
  1437. return iterator(this->m_holder.start()+n);
  1438. }
  1439. //! <b>Requires</b>: size() >= n.
  1440. //!
  1441. //! <b>Effects</b>: Returns a const_iterator to the nth element
  1442. //! from the beginning of the container. Returns end()
  1443. //! if n == size().
  1444. //!
  1445. //! <b>Throws</b>: Nothing.
  1446. //!
  1447. //! <b>Complexity</b>: Constant.
  1448. //!
  1449. //! <b>Note</b>: Non-standard extension
  1450. const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
  1451. {
  1452. BOOST_ASSERT(this->m_holder.m_size >= n);
  1453. return const_iterator(this->m_holder.start()+n);
  1454. }
  1455. //! <b>Requires</b>: begin() <= p <= end().
  1456. //!
  1457. //! <b>Effects</b>: Returns the index of the element pointed by p
  1458. //! and size() if p == end().
  1459. //!
  1460. //! <b>Throws</b>: Nothing.
  1461. //!
  1462. //! <b>Complexity</b>: Constant.
  1463. //!
  1464. //! <b>Note</b>: Non-standard extension
  1465. size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
  1466. {
  1467. //Range check assert done in priv_index_of
  1468. return this->priv_index_of(vector_iterator_get_ptr(p));
  1469. }
  1470. //! <b>Requires</b>: begin() <= p <= end().
  1471. //!
  1472. //! <b>Effects</b>: Returns the index of the element pointed by p
  1473. //! and size() if p == end().
  1474. //!
  1475. //! <b>Throws</b>: Nothing.
  1476. //!
  1477. //! <b>Complexity</b>: Constant.
  1478. //!
  1479. //! <b>Note</b>: Non-standard extension
  1480. size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
  1481. {
  1482. //Range check assert done in priv_index_of
  1483. return this->priv_index_of(vector_iterator_get_ptr(p));
  1484. }
  1485. //! <b>Requires</b>: size() > n.
  1486. //!
  1487. //! <b>Effects</b>: Returns a reference to the nth element
  1488. //! from the beginning of the container.
  1489. //!
  1490. //! <b>Throws</b>: std::range_error if n >= size()
  1491. //!
  1492. //! <b>Complexity</b>: Constant.
  1493. reference at(size_type n)
  1494. {
  1495. this->priv_throw_if_out_of_range(n);
  1496. return this->m_holder.start()[n];
  1497. }
  1498. //! <b>Requires</b>: size() > n.
  1499. //!
  1500. //! <b>Effects</b>: Returns a const reference to the nth element
  1501. //! from the beginning of the container.
  1502. //!
  1503. //! <b>Throws</b>: std::range_error if n >= size()
  1504. //!
  1505. //! <b>Complexity</b>: Constant.
  1506. const_reference at(size_type n) const
  1507. {
  1508. this->priv_throw_if_out_of_range(n);
  1509. return this->m_holder.start()[n];
  1510. }
  1511. //////////////////////////////////////////////
  1512. //
  1513. // data access
  1514. //
  1515. //////////////////////////////////////////////
  1516. //! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range.
  1517. //! For a non-empty vector, data() == &front().
  1518. //!
  1519. //! <b>Throws</b>: Nothing.
  1520. //!
  1521. //! <b>Complexity</b>: Constant.
  1522. T* data() BOOST_NOEXCEPT_OR_NOTHROW
  1523. { return this->priv_raw_begin(); }
  1524. //! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range.
  1525. //! For a non-empty vector, data() == &front().
  1526. //!
  1527. //! <b>Throws</b>: Nothing.
  1528. //!
  1529. //! <b>Complexity</b>: Constant.
  1530. const T * data() const BOOST_NOEXCEPT_OR_NOTHROW
  1531. { return this->priv_raw_begin(); }
  1532. //////////////////////////////////////////////
  1533. //
  1534. // modifiers
  1535. //
  1536. //////////////////////////////////////////////
  1537. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1538. //! <b>Effects</b>: Inserts an object of type T constructed with
  1539. //! std::forward<Args>(args)... in the end of the vector.
  1540. //!
  1541. //! <b>Returns</b>: A reference to the created object.
  1542. //!
  1543. //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws or
  1544. //! T's copy/move constructor throws.
  1545. //!
  1546. //! <b>Complexity</b>: Amortized constant time.
  1547. template<class ...Args>
  1548. BOOST_CONTAINER_FORCEINLINE reference emplace_back(BOOST_FWD_REF(Args)...args)
  1549. {
  1550. if (BOOST_LIKELY(this->room_enough())){
  1551. //There is more memory, just construct a new object at the end
  1552. T* const p = this->priv_raw_end();
  1553. allocator_traits_type::construct(this->m_holder.alloc(), p, ::boost::forward<Args>(args)...);
  1554. ++this->m_holder.m_size;
  1555. return *p;
  1556. }
  1557. else{
  1558. typedef dtl::insert_emplace_proxy<Allocator, T*, Args...> type;
  1559. return *this->priv_forward_range_insert_no_capacity
  1560. (this->back_ptr(), 1, type(::boost::forward<Args>(args)...), alloc_version());
  1561. }
  1562. }
  1563. //! <b>Effects</b>: Inserts an object of type T constructed with
  1564. //! std::forward<Args>(args)... in the end of the vector.
  1565. //!
  1566. //! <b>Throws</b>: If the in-place constructor throws.
  1567. //!
  1568. //! <b>Complexity</b>: Constant time.
  1569. //!
  1570. //! <b>Note</b>: Non-standard extension.
  1571. template<class ...Args>
  1572. BOOST_CONTAINER_FORCEINLINE bool stable_emplace_back(BOOST_FWD_REF(Args)...args)
  1573. {
  1574. const bool is_room_enough = this->room_enough() || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(1u));
  1575. if (BOOST_LIKELY(is_room_enough)){
  1576. //There is more memory, just construct a new object at the end
  1577. allocator_traits_type::construct(this->m_holder.alloc(), this->priv_raw_end(), ::boost::forward<Args>(args)...);
  1578. ++this->m_holder.m_size;
  1579. }
  1580. return is_room_enough;
  1581. }
  1582. //! <b>Requires</b>: position must be a valid iterator of *this.
  1583. //!
  1584. //! <b>Effects</b>: Inserts an object of type T constructed with
  1585. //! std::forward<Args>(args)... before position
  1586. //!
  1587. //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws or
  1588. //! T's copy/move constructor/assignment throws.
  1589. //!
  1590. //! <b>Complexity</b>: If position is end(), amortized constant time
  1591. //! Linear time otherwise.
  1592. template<class ...Args>
  1593. iterator emplace(const_iterator position, BOOST_FWD_REF(Args) ...args)
  1594. {
  1595. BOOST_ASSERT(this->priv_in_range_or_end(position));
  1596. //Just call more general insert(pos, size, value) and return iterator
  1597. typedef dtl::insert_emplace_proxy<Allocator, T*, Args...> type;
  1598. return this->priv_forward_range_insert( vector_iterator_get_ptr(position), 1
  1599. , type(::boost::forward<Args>(args)...));
  1600. }
  1601. #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  1602. #define BOOST_CONTAINER_VECTOR_EMPLACE_CODE(N) \
  1603. BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
  1604. BOOST_CONTAINER_FORCEINLINE reference emplace_back(BOOST_MOVE_UREF##N)\
  1605. {\
  1606. if (BOOST_LIKELY(this->room_enough())){\
  1607. T* const p = this->priv_raw_end();\
  1608. allocator_traits_type::construct (this->m_holder.alloc()\
  1609. , this->priv_raw_end() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
  1610. ++this->m_holder.m_size;\
  1611. return *p;\
  1612. }\
  1613. else{\
  1614. typedef dtl::insert_emplace_proxy_arg##N<Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
  1615. return *this->priv_forward_range_insert_no_capacity\
  1616. ( this->back_ptr(), 1, type(BOOST_MOVE_FWD##N), alloc_version());\
  1617. }\
  1618. }\
  1619. \
  1620. BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
  1621. BOOST_CONTAINER_FORCEINLINE bool stable_emplace_back(BOOST_MOVE_UREF##N)\
  1622. {\
  1623. const bool is_room_enough = this->room_enough() || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(1u));\
  1624. if (BOOST_LIKELY(is_room_enough)){\
  1625. allocator_traits_type::construct (this->m_holder.alloc()\
  1626. , this->priv_raw_end() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
  1627. ++this->m_holder.m_size;\
  1628. }\
  1629. return is_room_enough;\
  1630. }\
  1631. \
  1632. BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
  1633. iterator emplace(const_iterator pos BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
  1634. {\
  1635. BOOST_ASSERT(this->priv_in_range_or_end(pos));\
  1636. typedef dtl::insert_emplace_proxy_arg##N<Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
  1637. return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), 1, type(BOOST_MOVE_FWD##N));\
  1638. }\
  1639. //
  1640. BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_VECTOR_EMPLACE_CODE)
  1641. #undef BOOST_CONTAINER_VECTOR_EMPLACE_CODE
  1642. #endif
  1643. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1644. //! <b>Effects</b>: Inserts a copy of x at the end of the vector.
  1645. //!
  1646. //! <b>Throws</b>: If memory allocation throws or
  1647. //! T's copy/move constructor throws.
  1648. //!
  1649. //! <b>Complexity</b>: Amortized constant time.
  1650. void push_back(const T &x);
  1651. //! <b>Effects</b>: Constructs a new element in the end of the vector
  1652. //! and moves the resources of x to this new element.
  1653. //!
  1654. //! <b>Throws</b>: If memory allocation throws or
  1655. //! T's copy/move constructor throws.
  1656. //!
  1657. //! <b>Complexity</b>: Amortized constant time.
  1658. void push_back(T &&x);
  1659. #else
  1660. BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
  1661. #endif
  1662. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1663. //! <b>Requires</b>: position must be a valid iterator of *this.
  1664. //!
  1665. //! <b>Effects</b>: Insert a copy of x before position.
  1666. //!
  1667. //! <b>Throws</b>: If memory allocation throws or T's copy/move constructor/assignment throws.
  1668. //!
  1669. //! <b>Complexity</b>: If position is end(), amortized constant time
  1670. //! Linear time otherwise.
  1671. iterator insert(const_iterator position, const T &x);
  1672. //! <b>Requires</b>: position must be a valid iterator of *this.
  1673. //!
  1674. //! <b>Effects</b>: Insert a new element before position with x's resources.
  1675. //!
  1676. //! <b>Throws</b>: If memory allocation throws.
  1677. //!
  1678. //! <b>Complexity</b>: If position is end(), amortized constant time
  1679. //! Linear time otherwise.
  1680. iterator insert(const_iterator position, T &&x);
  1681. #else
  1682. BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
  1683. #endif
  1684. //! <b>Requires</b>: p must be a valid iterator of *this.
  1685. //!
  1686. //! <b>Effects</b>: Insert n copies of x before pos.
  1687. //!
  1688. //! <b>Returns</b>: an iterator to the first inserted element or p if n is 0.
  1689. //!
  1690. //! <b>Throws</b>: If memory allocation throws or T's copy/move constructor throws.
  1691. //!
  1692. //! <b>Complexity</b>: Linear to n.
  1693. iterator insert(const_iterator p, size_type n, const T& x)
  1694. {
  1695. BOOST_ASSERT(this->priv_in_range_or_end(p));
  1696. dtl::insert_n_copies_proxy<Allocator, T*> proxy(x);
  1697. return this->priv_forward_range_insert(vector_iterator_get_ptr(p), n, proxy);
  1698. }
  1699. //! <b>Requires</b>: p must be a valid iterator of *this.
  1700. //!
  1701. //! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
  1702. //!
  1703. //! <b>Returns</b>: an iterator to the first inserted element or pos if first == last.
  1704. //!
  1705. //! <b>Throws</b>: If memory allocation throws, T's constructor from a
  1706. //! dereferenced InpIt throws or T's copy/move constructor/assignment throws.
  1707. //!
  1708. //! <b>Complexity</b>: Linear to boost::container::iterator_distance [first, last).
  1709. template <class InIt>
  1710. iterator insert(const_iterator pos, InIt first, InIt last
  1711. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1712. , typename dtl::disable_if_or
  1713. < void
  1714. , dtl::is_convertible<InIt, size_type>
  1715. , dtl::is_not_input_iterator<InIt>
  1716. >::type * = 0
  1717. #endif
  1718. )
  1719. {
  1720. BOOST_ASSERT(this->priv_in_range_or_end(pos));
  1721. const size_type n_pos = pos - this->cbegin();
  1722. iterator it(vector_iterator_get_ptr(pos));
  1723. for(;first != last; ++first){
  1724. it = this->emplace(it, *first);
  1725. ++it;
  1726. }
  1727. return iterator(this->m_holder.start() + n_pos);
  1728. }
  1729. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1730. template <class FwdIt>
  1731. iterator insert(const_iterator pos, FwdIt first, FwdIt last
  1732. , typename dtl::disable_if_or
  1733. < void
  1734. , dtl::is_convertible<FwdIt, size_type>
  1735. , dtl::is_input_iterator<FwdIt>
  1736. >::type * = 0
  1737. )
  1738. {
  1739. BOOST_ASSERT(this->priv_in_range_or_end(pos));
  1740. dtl::insert_range_proxy<Allocator, FwdIt, T*> proxy(first);
  1741. return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), boost::container::iterator_distance(first, last), proxy);
  1742. }
  1743. #endif
  1744. //! <b>Requires</b>: p must be a valid iterator of *this. num, must
  1745. //! be equal to boost::container::iterator_distance(first, last)
  1746. //!
  1747. //! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
  1748. //!
  1749. //! <b>Returns</b>: an iterator to the first inserted element or pos if first == last.
  1750. //!
  1751. //! <b>Throws</b>: If memory allocation throws, T's constructor from a
  1752. //! dereferenced InpIt throws or T's copy/move constructor/assignment throws.
  1753. //!
  1754. //! <b>Complexity</b>: Linear to boost::container::iterator_distance [first, last).
  1755. //!
  1756. //! <b>Note</b>: This function avoids a linear operation to calculate boost::container::iterator_distance[first, last)
  1757. //! for forward and bidirectional iterators, and a one by one insertion for input iterators. This is a
  1758. //! a non-standard extension.
  1759. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1760. template <class InIt>
  1761. iterator insert(const_iterator pos, size_type num, InIt first, InIt last)
  1762. {
  1763. BOOST_ASSERT(this->priv_in_range_or_end(pos));
  1764. BOOST_ASSERT(dtl::is_input_iterator<InIt>::value ||
  1765. num == static_cast<size_type>(boost::container::iterator_distance(first, last)));
  1766. (void)last;
  1767. dtl::insert_range_proxy<Allocator, InIt, T*> proxy(first);
  1768. return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), num, proxy);
  1769. }
  1770. #endif
  1771. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  1772. //! <b>Requires</b>: position must be a valid iterator of *this.
  1773. //!
  1774. //! <b>Effects</b>: Insert a copy of the [il.begin(), il.end()) range before position.
  1775. //!
  1776. //! <b>Returns</b>: an iterator to the first inserted element or position if first == last.
  1777. //!
  1778. //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
  1779. iterator insert(const_iterator position, std::initializer_list<value_type> il)
  1780. {
  1781. //Assertion done in insert()
  1782. return this->insert(position, il.begin(), il.end());
  1783. }
  1784. #endif
  1785. //! <b>Effects</b>: Removes the last element from the container.
  1786. //!
  1787. //! <b>Throws</b>: Nothing.
  1788. //!
  1789. //! <b>Complexity</b>: Constant time.
  1790. void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
  1791. {
  1792. BOOST_ASSERT(!this->empty());
  1793. //Destroy last element
  1794. this->priv_destroy_last();
  1795. }
  1796. //! <b>Effects</b>: Erases the element at position pos.
  1797. //!
  1798. //! <b>Throws</b>: Nothing.
  1799. //!
  1800. //! <b>Complexity</b>: Linear to the elements between pos and the
  1801. //! last element. Constant if pos is the last element.
  1802. iterator erase(const_iterator position)
  1803. {
  1804. BOOST_ASSERT(this->priv_in_range(position));
  1805. const pointer p = vector_iterator_get_ptr(position);
  1806. T *const pos_ptr = boost::movelib::to_raw_pointer(p);
  1807. T *const beg_ptr = this->priv_raw_begin();
  1808. T *const new_end_ptr = ::boost::container::move(pos_ptr + 1, beg_ptr + this->m_holder.m_size, pos_ptr);
  1809. //Move elements forward and destroy last
  1810. this->priv_destroy_last(pos_ptr != new_end_ptr);
  1811. return iterator(p);
  1812. }
  1813. //! <b>Effects</b>: Erases the elements pointed by [first, last).
  1814. //!
  1815. //! <b>Throws</b>: Nothing.
  1816. //!
  1817. //! <b>Complexity</b>: Linear to the distance between first and last
  1818. //! plus linear to the elements between pos and the last element.
  1819. iterator erase(const_iterator first, const_iterator last)
  1820. {
  1821. BOOST_ASSERT(first == last ||
  1822. (first < last && this->priv_in_range(first) && this->priv_in_range_or_end(last)));
  1823. if (first != last){
  1824. T* const old_end_ptr = this->priv_raw_end();
  1825. T* const first_ptr = boost::movelib::to_raw_pointer(vector_iterator_get_ptr(first));
  1826. T* const last_ptr = boost::movelib::to_raw_pointer(vector_iterator_get_ptr(last));
  1827. T* const ptr = boost::movelib::to_raw_pointer(boost::container::move(last_ptr, old_end_ptr, first_ptr));
  1828. this->priv_destroy_last_n(old_end_ptr - ptr);
  1829. }
  1830. return iterator(vector_iterator_get_ptr(first));
  1831. }
  1832. //! <b>Effects</b>: Swaps the contents of *this and x.
  1833. //!
  1834. //! <b>Throws</b>: Nothing.
  1835. //!
  1836. //! <b>Complexity</b>: Constant.
  1837. BOOST_CONTAINER_FORCEINLINE void swap(vector& x)
  1838. BOOST_NOEXCEPT_IF( ((allocator_traits_type::propagate_on_container_swap::value
  1839. || allocator_traits_type::is_always_equal::value) &&
  1840. !dtl::is_version<Allocator, 0>::value))
  1841. {
  1842. this->priv_swap(x, dtl::bool_<dtl::is_version<Allocator, 0>::value>());
  1843. }
  1844. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  1845. //! <b>Effects</b>: Swaps the contents of *this and x.
  1846. //!
  1847. //! <b>Throws</b>: Nothing.
  1848. //!
  1849. //! <b>Complexity</b>: Linear
  1850. //!
  1851. //! <b>Note</b>: Non-standard extension to support static_vector
  1852. template<class OtherAllocator>
  1853. BOOST_CONTAINER_FORCEINLINE void swap(vector<T, OtherAllocator> & x
  1854. , typename dtl::enable_if_and
  1855. < void
  1856. , dtl::is_version<OtherAllocator, 0>
  1857. , dtl::is_different<OtherAllocator, allocator_type>
  1858. >::type * = 0
  1859. )
  1860. { this->m_holder.deep_swap(x.m_holder); }
  1861. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  1862. //! <b>Effects</b>: Erases all the elements of the vector.
  1863. //!
  1864. //! <b>Throws</b>: Nothing.
  1865. //!
  1866. //! <b>Complexity</b>: Linear to the number of elements in the container.
  1867. BOOST_CONTAINER_FORCEINLINE void clear() BOOST_NOEXCEPT_OR_NOTHROW
  1868. { this->priv_destroy_all(); }
  1869. //! <b>Effects</b>: Returns true if x and y are equal
  1870. //!
  1871. //! <b>Complexity</b>: Linear to the number of elements in the container.
  1872. BOOST_CONTAINER_FORCEINLINE friend bool operator==(const vector& x, const vector& y)
  1873. { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
  1874. //! <b>Effects</b>: Returns true if x and y are unequal
  1875. //!
  1876. //! <b>Complexity</b>: Linear to the number of elements in the container.
  1877. BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const vector& x, const vector& y)
  1878. { return !(x == y); }
  1879. //! <b>Effects</b>: Returns true if x is less than y
  1880. //!
  1881. //! <b>Complexity</b>: Linear to the number of elements in the container.
  1882. friend bool operator<(const vector& x, const vector& y)
  1883. {
  1884. const_iterator first1(x.cbegin()), first2(y.cbegin());
  1885. const const_iterator last1(x.cend()), last2(y.cend());
  1886. for ( ; (first1 != last1) && (first2 != last2); ++first1, ++first2 ) {
  1887. if (*first1 < *first2) return true;
  1888. if (*first2 < *first1) return false;
  1889. }
  1890. return (first1 == last1) && (first2 != last2);
  1891. }
  1892. //! <b>Effects</b>: Returns true if x is greater than y
  1893. //!
  1894. //! <b>Complexity</b>: Linear to the number of elements in the container.
  1895. BOOST_CONTAINER_FORCEINLINE friend bool operator>(const vector& x, const vector& y)
  1896. { return y < x; }
  1897. //! <b>Effects</b>: Returns true if x is equal or less than y
  1898. //!
  1899. //! <b>Complexity</b>: Linear to the number of elements in the container.
  1900. BOOST_CONTAINER_FORCEINLINE friend bool operator<=(const vector& x, const vector& y)
  1901. { return !(y < x); }
  1902. //! <b>Effects</b>: Returns true if x is equal or greater than y
  1903. //!
  1904. //! <b>Complexity</b>: Linear to the number of elements in the container.
  1905. BOOST_CONTAINER_FORCEINLINE friend bool operator>=(const vector& x, const vector& y)
  1906. { return !(x < y); }
  1907. //! <b>Effects</b>: x.swap(y)
  1908. //!
  1909. //! <b>Complexity</b>: Constant.
  1910. BOOST_CONTAINER_FORCEINLINE friend void swap(vector& x, vector& y)
  1911. { x.swap(y); }
  1912. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  1913. //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
  1914. //! effect. Otherwise, it is a request for allocation of additional memory
  1915. //! (memory expansion) that will not invalidate iterators.
  1916. //! If the request is successful, then capacity() is greater than or equal to
  1917. //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
  1918. //!
  1919. //! <b>Throws</b>: If memory allocation allocation throws or T's copy/move constructor throws.
  1920. //!
  1921. //! <b>Note</b>: Non-standard extension.
  1922. bool stable_reserve(size_type new_cap)
  1923. {
  1924. const size_type cp = this->capacity();
  1925. return cp >= new_cap || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(new_cap - cp));
  1926. }
  1927. //Absolutely experimental. This function might change, disappear or simply crash!
  1928. template<class BiDirPosConstIt, class BiDirValueIt>
  1929. BOOST_CONTAINER_FORCEINLINE void insert_ordered_at(const size_type element_count, BiDirPosConstIt last_position_it, BiDirValueIt last_value_it)
  1930. {
  1931. typedef vector_insert_ordered_cursor<BiDirPosConstIt, BiDirValueIt> inserter_t;
  1932. return this->priv_insert_ordered_at(element_count, inserter_t(last_position_it, last_value_it));
  1933. }
  1934. template<class InputIt>
  1935. BOOST_CONTAINER_FORCEINLINE void merge(InputIt first, InputIt last)
  1936. { this->merge(first, last, value_less_t()); }
  1937. template<class InputIt, class Compare>
  1938. BOOST_CONTAINER_FORCEINLINE void merge(InputIt first, InputIt last, Compare comp)
  1939. {
  1940. size_type const s = this->size();
  1941. size_type const c = this->capacity();
  1942. size_type n = 0;
  1943. size_type const free_cap = c - s;
  1944. //If not input iterator and new elements don't fit in the remaining capacity, merge in new buffer
  1945. if(!dtl::is_input_iterator<InputIt>::value &&
  1946. free_cap < (n = static_cast<size_type>(boost::container::iterator_distance(first, last)))){
  1947. this->priv_merge_in_new_buffer(first, n, comp, alloc_version());
  1948. }
  1949. else{
  1950. iterator pos(this->insert(this->cend(), first, last));
  1951. T *const raw_beg = this->priv_raw_begin();
  1952. T *const raw_end = this->priv_raw_end();
  1953. T *const raw_pos = raw_beg + s;
  1954. boost::movelib::adaptive_merge(raw_beg, raw_pos, raw_end, comp, raw_end, free_cap - n);
  1955. }
  1956. }
  1957. template<class InputIt>
  1958. BOOST_CONTAINER_FORCEINLINE void merge_unique(InputIt first, InputIt last)
  1959. { this->merge_unique(first, last, value_less_t()); }
  1960. template<class InputIt, class Compare>
  1961. BOOST_CONTAINER_FORCEINLINE void merge_unique(InputIt first, InputIt last, Compare comp)
  1962. {
  1963. size_type const old_size = this->size();
  1964. this->priv_set_difference_back(first, last, comp);
  1965. T *const raw_beg = this->priv_raw_begin();
  1966. T *const raw_end = this->priv_raw_end();
  1967. T *raw_pos = raw_beg + old_size;
  1968. boost::movelib::adaptive_merge(raw_beg, raw_pos, raw_end, comp, raw_end, this->capacity() - this->size());
  1969. }
  1970. private:
  1971. template<class PositionValue>
  1972. void priv_insert_ordered_at(const size_type element_count, PositionValue position_value)
  1973. {
  1974. const size_type old_size_pos = this->size();
  1975. this->reserve(old_size_pos + element_count);
  1976. T* const begin_ptr = this->priv_raw_begin();
  1977. size_type insertions_left = element_count;
  1978. size_type prev_pos = old_size_pos;
  1979. size_type old_hole_size = element_count;
  1980. //Exception rollback. If any copy throws before the hole is filled, values
  1981. //already inserted/copied at the end of the buffer will be destroyed.
  1982. typename value_traits::ArrayDestructor past_hole_values_destroyer
  1983. (begin_ptr + old_size_pos + element_count, this->m_holder.alloc(), size_type(0u));
  1984. //Loop for each insertion backwards, first moving the elements after the insertion point,
  1985. //then inserting the element.
  1986. while(insertions_left){
  1987. --position_value;
  1988. size_type const pos = position_value.get_pos();
  1989. BOOST_ASSERT(pos != size_type(-1) && pos <= old_size_pos && pos <= prev_pos);
  1990. //If needed shift the range after the insertion point and the previous insertion point.
  1991. //Function will take care if the shift crosses the size() boundary, using copy/move
  1992. //or uninitialized copy/move if necessary.
  1993. size_type new_hole_size = (pos != prev_pos)
  1994. ? priv_insert_ordered_at_shift_range(pos, prev_pos, this->size(), insertions_left)
  1995. : old_hole_size
  1996. ;
  1997. if(new_hole_size){
  1998. //The hole was reduced by priv_insert_ordered_at_shift_range so expand exception rollback range backwards
  1999. past_hole_values_destroyer.increment_size_backwards(prev_pos - pos);
  2000. //Insert the new value in the hole
  2001. allocator_traits_type::construct(this->m_holder.alloc(), begin_ptr + pos + insertions_left - 1, position_value.get_val());
  2002. if(--new_hole_size){
  2003. //The hole was reduced by the new insertion by one
  2004. past_hole_values_destroyer.increment_size_backwards(size_type(1u));
  2005. }
  2006. else{
  2007. //Hole was just filled, disable exception rollback and change vector size
  2008. past_hole_values_destroyer.release();
  2009. this->m_holder.m_size += element_count;
  2010. }
  2011. }
  2012. else{
  2013. if(old_hole_size){
  2014. //Hole was just filled by priv_insert_ordered_at_shift_range, disable exception rollback and change vector size
  2015. past_hole_values_destroyer.release();
  2016. this->m_holder.m_size += element_count;
  2017. }
  2018. //Insert the new value in the already constructed range
  2019. begin_ptr[pos + insertions_left - 1] = position_value.get_val();
  2020. }
  2021. --insertions_left;
  2022. old_hole_size = new_hole_size;
  2023. prev_pos = pos;
  2024. }
  2025. }
  2026. template<class InputIt, class Compare>
  2027. void priv_set_difference_back(InputIt first1, InputIt last1, Compare comp)
  2028. {
  2029. T * old_first2 = this->priv_raw_begin();
  2030. T * first2 = old_first2;
  2031. T * last2 = this->priv_raw_end();
  2032. while (first1 != last1) {
  2033. if (first2 == last2){
  2034. this->insert(this->cend(), first1, last1);
  2035. return;
  2036. }
  2037. if (comp(*first1, *first2)) {
  2038. this->emplace_back(*first1);
  2039. T * const raw_begin = this->priv_raw_begin();
  2040. if(old_first2 != raw_begin)
  2041. {
  2042. //Reallocation happened, update range
  2043. first2 = raw_begin + (first2 - old_first2);
  2044. last2 = raw_begin + (last2 - old_first2);
  2045. old_first2 = raw_begin;
  2046. }
  2047. ++first1;
  2048. }
  2049. else {
  2050. if (!comp(*first2, *first1)) {
  2051. ++first1;
  2052. }
  2053. ++first2;
  2054. }
  2055. }
  2056. }
  2057. template<class FwdIt, class Compare>
  2058. BOOST_CONTAINER_FORCEINLINE void priv_merge_in_new_buffer(FwdIt, size_type, Compare, version_0)
  2059. {
  2060. throw_bad_alloc();
  2061. }
  2062. template<class FwdIt, class Compare, class Version>
  2063. void priv_merge_in_new_buffer(FwdIt first, size_type n, Compare comp, Version)
  2064. {
  2065. size_type const new_size = this->size() + n;
  2066. size_type new_cap = new_size;
  2067. pointer p = pointer();
  2068. pointer const new_storage = this->m_holder.allocation_command(allocate_new, new_size, new_cap, p);
  2069. BOOST_ASSERT((new_cap >= this->size() ) && (new_cap - this->size()) >= n);
  2070. allocator_type &a = this->m_holder.alloc();
  2071. typename value_traits::ArrayDeallocator new_buffer_deallocator(new_storage, a, new_cap);
  2072. typename value_traits::ArrayDestructor new_values_destroyer(new_storage, a, 0u);
  2073. T* pbeg = this->priv_raw_begin();
  2074. size_type const old_size = this->size();
  2075. T* const pend = pbeg + old_size;
  2076. T* d_first = boost::movelib::to_raw_pointer(new_storage);
  2077. size_type added = n;
  2078. //Merge in new buffer loop
  2079. while(1){
  2080. if(!n) {
  2081. ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), pbeg, pend, d_first);
  2082. break;
  2083. }
  2084. else if(pbeg == pend) {
  2085. ::boost::container::uninitialized_move_alloc_n(this->m_holder.alloc(), first, n, d_first);
  2086. break;
  2087. }
  2088. //maintain stability moving external values only if they are strictly less
  2089. else if(comp(*first, *pbeg)) {
  2090. allocator_traits_type::construct( this->m_holder.alloc(), d_first, *first );
  2091. new_values_destroyer.increment_size(1u);
  2092. ++first;
  2093. --n;
  2094. ++d_first;
  2095. }
  2096. else{
  2097. allocator_traits_type::construct( this->m_holder.alloc(), d_first, boost::move(*pbeg) );
  2098. new_values_destroyer.increment_size(1u);
  2099. ++pbeg;
  2100. ++d_first;
  2101. }
  2102. }
  2103. //Nothrow operations
  2104. pointer const old_p = this->m_holder.start();
  2105. size_type const old_cap = this->m_holder.capacity();
  2106. boost::container::destroy_alloc_n(a, boost::movelib::to_raw_pointer(old_p), old_size);
  2107. this->m_holder.deallocate(old_p, old_cap);
  2108. this->m_holder.m_size = old_size + added;
  2109. this->m_holder.start(new_storage);
  2110. this->m_holder.capacity(new_cap);
  2111. new_buffer_deallocator.release();
  2112. new_values_destroyer.release();
  2113. }
  2114. BOOST_CONTAINER_FORCEINLINE bool room_enough() const
  2115. { return this->m_holder.m_size < this->m_holder.capacity(); }
  2116. BOOST_CONTAINER_FORCEINLINE pointer back_ptr() const
  2117. { return this->m_holder.start() + this->m_holder.m_size; }
  2118. size_type priv_index_of(pointer p) const
  2119. {
  2120. BOOST_ASSERT(this->m_holder.start() <= p);
  2121. BOOST_ASSERT(p <= (this->m_holder.start()+this->size()));
  2122. return static_cast<size_type>(p - this->m_holder.start());
  2123. }
  2124. template<class OtherAllocator>
  2125. void priv_move_assign(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x
  2126. , typename dtl::enable_if_c
  2127. < dtl::is_version<OtherAllocator, 0>::value >::type * = 0)
  2128. {
  2129. if(!dtl::is_same<OtherAllocator, allocator_type>::value &&
  2130. this->capacity() < x.size()){
  2131. throw_bad_alloc();
  2132. }
  2133. T* const this_start = this->priv_raw_begin();
  2134. T* const other_start = x.priv_raw_begin();
  2135. const size_type this_sz = m_holder.m_size;
  2136. const size_type other_sz = static_cast<size_type>(x.m_holder.m_size);
  2137. boost::container::move_assign_range_alloc_n(this->m_holder.alloc(), other_start, other_sz, this_start, this_sz);
  2138. this->m_holder.m_size = other_sz;
  2139. }
  2140. template<class OtherAllocator>
  2141. void priv_move_assign(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x
  2142. , typename dtl::disable_if_or
  2143. < void
  2144. , dtl::is_version<OtherAllocator, 0>
  2145. , dtl::is_different<OtherAllocator, allocator_type>
  2146. >::type * = 0)
  2147. {
  2148. //for move assignment, no aliasing (&x != this) is assummed.
  2149. BOOST_ASSERT(this != &x);
  2150. allocator_type &this_alloc = this->m_holder.alloc();
  2151. allocator_type &x_alloc = x.m_holder.alloc();
  2152. const bool propagate_alloc = allocator_traits_type::propagate_on_container_move_assignment::value;
  2153. const bool is_propagable_from_x = is_propagable_from(x_alloc, x.m_holder.start(), this_alloc, propagate_alloc);
  2154. const bool is_propagable_from_t = is_propagable_from(this_alloc, m_holder.start(), x_alloc, propagate_alloc);
  2155. const bool are_both_propagable = is_propagable_from_x && is_propagable_from_t;
  2156. //Resources can be transferred if both allocators are
  2157. //going to be equal after this function (either propagated or already equal)
  2158. if(are_both_propagable){
  2159. //Destroy objects but retain memory in case x reuses it in the future
  2160. this->clear();
  2161. this->m_holder.swap_resources(x.m_holder);
  2162. }
  2163. else if(is_propagable_from_x){
  2164. this->clear();
  2165. this->m_holder.deallocate(this->m_holder.m_start, this->m_holder.m_capacity);
  2166. this->m_holder.steal_resources(x.m_holder);
  2167. }
  2168. //Else do a one by one move
  2169. else{
  2170. this->assign( boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.begin()))
  2171. , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.end() ))
  2172. );
  2173. }
  2174. //Move allocator if needed
  2175. dtl::move_alloc(this_alloc, x_alloc, dtl::bool_<propagate_alloc>());
  2176. }
  2177. template<class OtherAllocator>
  2178. void priv_copy_assign(const vector<T, OtherAllocator> &x
  2179. , typename dtl::enable_if_c
  2180. < dtl::is_version<OtherAllocator, 0>::value >::type * = 0)
  2181. {
  2182. if(!dtl::is_same<OtherAllocator, allocator_type>::value &&
  2183. this->capacity() < x.size()){
  2184. throw_bad_alloc();
  2185. }
  2186. T* const this_start = this->priv_raw_begin();
  2187. T* const other_start = x.priv_raw_begin();
  2188. const size_type this_sz = m_holder.m_size;
  2189. const size_type other_sz = static_cast<size_type>(x.m_holder.m_size);
  2190. boost::container::copy_assign_range_alloc_n(this->m_holder.alloc(), other_start, other_sz, this_start, this_sz);
  2191. this->m_holder.m_size = other_sz;
  2192. }
  2193. template<class OtherAllocator>
  2194. typename dtl::disable_if_or
  2195. < void
  2196. , dtl::is_version<OtherAllocator, 0>
  2197. , dtl::is_different<OtherAllocator, allocator_type>
  2198. >::type
  2199. priv_copy_assign(const vector<T, OtherAllocator> &x)
  2200. {
  2201. allocator_type &this_alloc = this->m_holder.alloc();
  2202. const allocator_type &x_alloc = x.m_holder.alloc();
  2203. dtl::bool_<allocator_traits_type::
  2204. propagate_on_container_copy_assignment::value> flag;
  2205. if(flag && this_alloc != x_alloc){
  2206. this->clear();
  2207. this->shrink_to_fit();
  2208. }
  2209. dtl::assign_alloc(this_alloc, x_alloc, flag);
  2210. this->assign( x.priv_raw_begin(), x.priv_raw_end() );
  2211. }
  2212. template<class Vector> //Template it to avoid it in explicit instantiations
  2213. void priv_swap(Vector &x, dtl::true_type) //version_0
  2214. { this->m_holder.deep_swap(x.m_holder); }
  2215. template<class Vector> //Template it to avoid it in explicit instantiations
  2216. void priv_swap(Vector &x, dtl::false_type) //version_N
  2217. {
  2218. const bool propagate_alloc = allocator_traits_type::propagate_on_container_swap::value;
  2219. if(are_swap_propagable( this->get_stored_allocator(), this->m_holder.start()
  2220. , x.get_stored_allocator(), x.m_holder.start(), propagate_alloc)){
  2221. //Just swap internals
  2222. this->m_holder.swap_resources(x.m_holder);
  2223. }
  2224. else{
  2225. //Else swap element by element...
  2226. bool const t_smaller = this->size() < x.size();
  2227. vector &sml = t_smaller ? *this : x;
  2228. vector &big = t_smaller ? x : *this;
  2229. size_type const common_elements = sml.size();
  2230. for(size_type i = 0; i != common_elements; ++i){
  2231. boost::adl_move_swap(sml[i], big[i]);
  2232. }
  2233. //... and move-insert the remaining range
  2234. sml.insert( sml.cend()
  2235. , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(big.nth(common_elements)))
  2236. , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(big.end()))
  2237. );
  2238. //Destroy remaining elements
  2239. big.erase(big.nth(common_elements), big.cend());
  2240. }
  2241. //And now swap the allocator
  2242. dtl::swap_alloc(this->m_holder.alloc(), x.m_holder.alloc(), dtl::bool_<propagate_alloc>());
  2243. }
  2244. void priv_reserve_no_capacity(size_type, version_0)
  2245. { throw_bad_alloc(); }
  2246. dtl::insert_range_proxy<Allocator, boost::move_iterator<T*>, T*> priv_dummy_empty_proxy()
  2247. {
  2248. return dtl::insert_range_proxy<Allocator, boost::move_iterator<T*>, T*>
  2249. (::boost::make_move_iterator((T *)0));
  2250. }
  2251. void priv_reserve_no_capacity(size_type new_cap, version_1)
  2252. {
  2253. //There is not enough memory, allocate a new buffer
  2254. //Pass the hint so that allocators can take advantage of this.
  2255. pointer const p = this->m_holder.allocate(new_cap);
  2256. //We will reuse insert code, so create a dummy input iterator
  2257. this->priv_forward_range_insert_new_allocation
  2258. ( boost::movelib::to_raw_pointer(p), new_cap, this->priv_raw_end(), 0, this->priv_dummy_empty_proxy());
  2259. }
  2260. void priv_reserve_no_capacity(size_type new_cap, version_2)
  2261. {
  2262. //There is not enough memory, allocate a new
  2263. //buffer or expand the old one.
  2264. bool same_buffer_start;
  2265. size_type real_cap = 0;
  2266. pointer reuse(this->m_holder.start());
  2267. pointer const ret(this->m_holder.allocation_command(allocate_new | expand_fwd | expand_bwd, new_cap, real_cap = new_cap, reuse));
  2268. //Check for forward expansion
  2269. same_buffer_start = reuse && this->m_holder.start() == ret;
  2270. if(same_buffer_start){
  2271. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  2272. ++this->num_expand_fwd;
  2273. #endif
  2274. this->m_holder.capacity(real_cap);
  2275. }
  2276. else{ //If there is no forward expansion, move objects, we will reuse insertion code
  2277. T * const new_mem = boost::movelib::to_raw_pointer(ret);
  2278. T * const ins_pos = this->priv_raw_end();
  2279. if(reuse){ //Backwards (and possibly forward) expansion
  2280. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  2281. ++this->num_expand_bwd;
  2282. #endif
  2283. this->priv_forward_range_insert_expand_backwards
  2284. ( new_mem , real_cap, ins_pos, 0, this->priv_dummy_empty_proxy());
  2285. }
  2286. else{ //New buffer
  2287. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  2288. ++this->num_alloc;
  2289. #endif
  2290. this->priv_forward_range_insert_new_allocation
  2291. ( new_mem, real_cap, ins_pos, 0, this->priv_dummy_empty_proxy());
  2292. }
  2293. }
  2294. }
  2295. void priv_destroy_last(const bool moved = false) BOOST_NOEXCEPT_OR_NOTHROW
  2296. {
  2297. (void)moved;
  2298. const bool skip_destructor = value_traits::trivial_dctr || (value_traits::trivial_dctr_after_move && moved);
  2299. if(!skip_destructor){
  2300. value_type* const p = this->priv_raw_end() - 1;
  2301. allocator_traits_type::destroy(this->get_stored_allocator(), p);
  2302. }
  2303. --this->m_holder.m_size;
  2304. }
  2305. void priv_destroy_last_n(const size_type n) BOOST_NOEXCEPT_OR_NOTHROW
  2306. {
  2307. BOOST_ASSERT(n <= this->m_holder.m_size);
  2308. if(!value_traits::trivial_dctr){
  2309. T* const destroy_pos = this->priv_raw_begin() + (this->m_holder.m_size-n);
  2310. boost::container::destroy_alloc_n(this->get_stored_allocator(), destroy_pos, n);
  2311. }
  2312. this->m_holder.m_size -= n;
  2313. }
  2314. template<class InpIt>
  2315. void priv_uninitialized_construct_at_end(InpIt first, InpIt last)
  2316. {
  2317. T* const old_end_pos = this->priv_raw_end();
  2318. T* const new_end_pos = boost::container::uninitialized_copy_alloc(this->m_holder.alloc(), first, last, old_end_pos);
  2319. this->m_holder.m_size += new_end_pos - old_end_pos;
  2320. }
  2321. void priv_destroy_all() BOOST_NOEXCEPT_OR_NOTHROW
  2322. {
  2323. boost::container::destroy_alloc_n
  2324. (this->get_stored_allocator(), this->priv_raw_begin(), this->m_holder.m_size);
  2325. this->m_holder.m_size = 0;
  2326. }
  2327. template<class U>
  2328. iterator priv_insert(const const_iterator &p, BOOST_FWD_REF(U) x)
  2329. {
  2330. BOOST_ASSERT(this->priv_in_range_or_end(p));
  2331. return this->priv_forward_range_insert
  2332. ( vector_iterator_get_ptr(p), 1, dtl::get_insert_value_proxy<T*, Allocator>(::boost::forward<U>(x)));
  2333. }
  2334. dtl::insert_copy_proxy<Allocator, T*> priv_single_insert_proxy(const T &x)
  2335. { return dtl::insert_copy_proxy<Allocator, T*> (x); }
  2336. dtl::insert_move_proxy<Allocator, T*> priv_single_insert_proxy(BOOST_RV_REF(T) x)
  2337. { return dtl::insert_move_proxy<Allocator, T*> (x); }
  2338. template <class U>
  2339. void priv_push_back(BOOST_FWD_REF(U) u)
  2340. {
  2341. if (BOOST_LIKELY(this->room_enough())){
  2342. //There is more memory, just construct a new object at the end
  2343. allocator_traits_type::construct
  2344. ( this->m_holder.alloc(), this->priv_raw_end(), ::boost::forward<U>(u) );
  2345. ++this->m_holder.m_size;
  2346. }
  2347. else{
  2348. this->priv_forward_range_insert_no_capacity
  2349. ( this->back_ptr(), 1
  2350. , this->priv_single_insert_proxy(::boost::forward<U>(u)), alloc_version());
  2351. }
  2352. }
  2353. BOOST_CONTAINER_FORCEINLINE dtl::insert_n_copies_proxy<Allocator, T*> priv_resize_proxy(const T &x)
  2354. { return dtl::insert_n_copies_proxy<Allocator, T*>(x); }
  2355. BOOST_CONTAINER_FORCEINLINE dtl::insert_default_initialized_n_proxy<Allocator, T*> priv_resize_proxy(default_init_t)
  2356. { return dtl::insert_default_initialized_n_proxy<Allocator, T*>(); }
  2357. BOOST_CONTAINER_FORCEINLINE dtl::insert_value_initialized_n_proxy<Allocator, T*> priv_resize_proxy(value_init_t)
  2358. { return dtl::insert_value_initialized_n_proxy<Allocator, T*>(); }
  2359. template <class U>
  2360. void priv_resize(size_type new_size, const U& u)
  2361. {
  2362. const size_type sz = this->size();
  2363. if (new_size < sz){
  2364. //Destroy last elements
  2365. this->priv_destroy_last_n(sz - new_size);
  2366. }
  2367. else{
  2368. const size_type n = new_size - this->size();
  2369. this->priv_forward_range_insert_at_end(n, this->priv_resize_proxy(u), alloc_version());
  2370. }
  2371. }
  2372. BOOST_CONTAINER_FORCEINLINE void priv_shrink_to_fit(version_0) BOOST_NOEXCEPT_OR_NOTHROW
  2373. {}
  2374. void priv_shrink_to_fit(version_1)
  2375. {
  2376. const size_type cp = this->m_holder.capacity();
  2377. if(cp){
  2378. const size_type sz = this->size();
  2379. if(!sz){
  2380. this->m_holder.deallocate(this->m_holder.m_start, cp);
  2381. this->m_holder.m_start = pointer();
  2382. this->m_holder.m_capacity = 0;
  2383. }
  2384. else if(sz < cp){
  2385. //Allocate a new buffer.
  2386. //Pass the hint so that allocators can take advantage of this.
  2387. pointer const p = this->m_holder.allocate(sz);
  2388. //We will reuse insert code, so create a dummy input iterator
  2389. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  2390. ++this->num_alloc;
  2391. #endif
  2392. this->priv_forward_range_insert_new_allocation
  2393. ( boost::movelib::to_raw_pointer(p), sz
  2394. , this->priv_raw_begin(), 0, this->priv_dummy_empty_proxy());
  2395. }
  2396. }
  2397. }
  2398. void priv_shrink_to_fit(version_2) BOOST_NOEXCEPT_OR_NOTHROW
  2399. {
  2400. const size_type cp = this->m_holder.capacity();
  2401. if(cp){
  2402. const size_type sz = this->size();
  2403. if(!sz){
  2404. this->m_holder.deallocate(this->m_holder.m_start, cp);
  2405. this->m_holder.m_start = pointer();
  2406. this->m_holder.m_capacity = 0;
  2407. }
  2408. else{
  2409. size_type received_size = sz;
  2410. pointer reuse(this->m_holder.start());
  2411. if(this->m_holder.allocation_command
  2412. (shrink_in_place | nothrow_allocation, cp, received_size, reuse)){
  2413. this->m_holder.capacity(received_size);
  2414. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  2415. ++this->num_shrink;
  2416. #endif
  2417. }
  2418. }
  2419. }
  2420. }
  2421. template <class InsertionProxy>
  2422. iterator priv_forward_range_insert_no_capacity
  2423. (const pointer &pos, const size_type, const InsertionProxy , version_0)
  2424. {
  2425. throw_bad_alloc();
  2426. return iterator(pos);
  2427. }
  2428. template <class InsertionProxy>
  2429. iterator priv_forward_range_insert_no_capacity
  2430. (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, version_1)
  2431. {
  2432. //Check if we have enough memory or try to expand current memory
  2433. const size_type n_pos = pos - this->m_holder.start();
  2434. T *const raw_pos = boost::movelib::to_raw_pointer(pos);
  2435. const size_type new_cap = this->m_holder.template next_capacity<growth_factor_type>(n);
  2436. //Pass the hint so that allocators can take advantage of this.
  2437. T * const new_buf = boost::movelib::to_raw_pointer(this->m_holder.allocate(new_cap));
  2438. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  2439. ++this->num_alloc;
  2440. #endif
  2441. this->priv_forward_range_insert_new_allocation
  2442. ( new_buf, new_cap, raw_pos, n, insert_range_proxy);
  2443. return iterator(this->m_holder.start() + n_pos);
  2444. }
  2445. template <class InsertionProxy>
  2446. iterator priv_forward_range_insert_no_capacity
  2447. (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, version_2)
  2448. {
  2449. //Check if we have enough memory or try to expand current memory
  2450. T *const raw_pos = boost::movelib::to_raw_pointer(pos);
  2451. const size_type n_pos = raw_pos - this->priv_raw_begin();
  2452. //There is not enough memory, allocate a new
  2453. //buffer or expand the old one.
  2454. size_type real_cap = this->m_holder.template next_capacity<growth_factor_type>(n);
  2455. pointer reuse(this->m_holder.start());
  2456. pointer const ret (this->m_holder.allocation_command
  2457. (allocate_new | expand_fwd | expand_bwd, this->m_holder.m_size + n, real_cap, reuse));
  2458. //Buffer reallocated
  2459. if(reuse){
  2460. //Forward expansion, delay insertion
  2461. if(this->m_holder.start() == ret){
  2462. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  2463. ++this->num_expand_fwd;
  2464. #endif
  2465. this->m_holder.capacity(real_cap);
  2466. //Expand forward
  2467. this->priv_forward_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
  2468. }
  2469. //Backwards (and possibly forward) expansion
  2470. else{
  2471. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  2472. ++this->num_expand_bwd;
  2473. #endif
  2474. this->priv_forward_range_insert_expand_backwards
  2475. (boost::movelib::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy);
  2476. }
  2477. }
  2478. //New buffer
  2479. else{
  2480. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  2481. ++this->num_alloc;
  2482. #endif
  2483. this->priv_forward_range_insert_new_allocation
  2484. ( boost::movelib::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy);
  2485. }
  2486. return iterator(this->m_holder.start() + n_pos);
  2487. }
  2488. template <class InsertionProxy>
  2489. iterator priv_forward_range_insert
  2490. (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy)
  2491. {
  2492. BOOST_ASSERT(this->m_holder.capacity() >= this->m_holder.m_size);
  2493. //Check if we have enough memory or try to expand current memory
  2494. const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
  2495. bool same_buffer_start = n <= remaining;
  2496. if (!same_buffer_start){
  2497. return priv_forward_range_insert_no_capacity(pos, n, insert_range_proxy, alloc_version());
  2498. }
  2499. else{
  2500. //Expand forward
  2501. T *const raw_pos = boost::movelib::to_raw_pointer(pos);
  2502. const size_type n_pos = raw_pos - this->priv_raw_begin();
  2503. this->priv_forward_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
  2504. return iterator(this->m_holder.start() + n_pos);
  2505. }
  2506. }
  2507. template <class InsertionProxy>
  2508. iterator priv_forward_range_insert_at_end
  2509. (const size_type n, const InsertionProxy insert_range_proxy, version_0)
  2510. {
  2511. //Check if we have enough memory or try to expand current memory
  2512. const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
  2513. if (n > remaining){
  2514. //This will trigger an error
  2515. throw_bad_alloc();
  2516. }
  2517. this->priv_forward_range_insert_at_end_expand_forward(n, insert_range_proxy);
  2518. return this->end();
  2519. }
  2520. template <class InsertionProxy, class AllocVersion>
  2521. BOOST_CONTAINER_FORCEINLINE iterator priv_forward_range_insert_at_end
  2522. (const size_type n, const InsertionProxy insert_range_proxy, AllocVersion)
  2523. {
  2524. return this->priv_forward_range_insert(this->back_ptr(), n, insert_range_proxy);
  2525. }
  2526. //Takes the range pointed by [first_pos, last_pos) and shifts it to the right
  2527. //by 'shift_count'. 'limit_pos' marks the end of constructed elements.
  2528. //
  2529. //Precondition: first_pos <= last_pos <= limit_pos
  2530. //
  2531. //The shift operation might cross limit_pos so elements to moved beyond limit_pos
  2532. //are uninitialized_moved with an allocator. Other elements are moved.
  2533. //
  2534. //The shift operation might left uninitialized elements after limit_pos
  2535. //and the number of uninitialized elements is returned by the function.
  2536. //
  2537. //Old situation:
  2538. // first_pos last_pos old_limit
  2539. // | | |
  2540. // ____________V_______V__________________V_____________
  2541. //| prefix | range | suffix |raw_mem ~
  2542. //|____________|_______|__________________|_____________~
  2543. //
  2544. //New situation in Case A (hole_size == 0):
  2545. // range is moved through move assignments
  2546. //
  2547. // first_pos last_pos limit_pos
  2548. // | | |
  2549. // ____________V_______V__________________V_____________
  2550. //| prefix' | | | range |suffix'|raw_mem ~
  2551. //|________________+______|___^___|_______|_____________~
  2552. // | |
  2553. // |_>_>_>_>_>^
  2554. //
  2555. //
  2556. //New situation in Case B (hole_size >= 0):
  2557. // range is moved through uninitialized moves
  2558. //
  2559. // first_pos last_pos limit_pos
  2560. // | | |
  2561. // ____________V_______V__________________V________________
  2562. //| prefix' | | | [hole] | range |
  2563. //|_______________________________________|________|___^___|
  2564. // | |
  2565. // |_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_^
  2566. //
  2567. //New situation in Case C (hole_size == 0):
  2568. // range is moved through move assignments and uninitialized moves
  2569. //
  2570. // first_pos last_pos limit_pos
  2571. // | | |
  2572. // ____________V_______V__________________V___
  2573. //| prefix' | | | range |
  2574. //|___________________________________|___^___|
  2575. // | |
  2576. // |_>_>_>_>_>_>_>_>_>_>_>^
  2577. size_type priv_insert_ordered_at_shift_range
  2578. (size_type first_pos, size_type last_pos, size_type limit_pos, size_type shift_count)
  2579. {
  2580. BOOST_ASSERT(first_pos <= last_pos);
  2581. BOOST_ASSERT(last_pos <= limit_pos);
  2582. //
  2583. T* const begin_ptr = this->priv_raw_begin();
  2584. T* const first_ptr = begin_ptr + first_pos;
  2585. T* const last_ptr = begin_ptr + last_pos;
  2586. size_type hole_size = 0;
  2587. //Case A:
  2588. if((last_pos + shift_count) <= limit_pos){
  2589. //All move assigned
  2590. boost::container::move_backward(first_ptr, last_ptr, last_ptr + shift_count);
  2591. }
  2592. //Case B:
  2593. else if((first_pos + shift_count) >= limit_pos){
  2594. //All uninitialized_moved
  2595. ::boost::container::uninitialized_move_alloc
  2596. (this->m_holder.alloc(), first_ptr, last_ptr, first_ptr + shift_count);
  2597. hole_size = first_pos + shift_count - limit_pos;
  2598. }
  2599. //Case C:
  2600. else{
  2601. //Some uninitialized_moved
  2602. T* const limit_ptr = begin_ptr + limit_pos;
  2603. T* const boundary_ptr = limit_ptr - shift_count;
  2604. ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), boundary_ptr, last_ptr, limit_ptr);
  2605. //The rest is move assigned
  2606. boost::container::move_backward(first_ptr, boundary_ptr, limit_ptr);
  2607. }
  2608. return hole_size;
  2609. }
  2610. private:
  2611. BOOST_CONTAINER_FORCEINLINE T *priv_raw_begin() const
  2612. { return boost::movelib::to_raw_pointer(m_holder.start()); }
  2613. BOOST_CONTAINER_FORCEINLINE T* priv_raw_end() const
  2614. { return this->priv_raw_begin() + this->m_holder.m_size; }
  2615. template <class InsertionProxy>
  2616. void priv_forward_range_insert_at_end_expand_forward(const size_type n, InsertionProxy insert_range_proxy)
  2617. {
  2618. T* const old_finish = this->priv_raw_end();
  2619. insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n);
  2620. this->m_holder.m_size += n;
  2621. }
  2622. template <class InsertionProxy>
  2623. void priv_forward_range_insert_expand_forward(T* const pos, const size_type n, InsertionProxy insert_range_proxy)
  2624. {
  2625. //n can't be 0, because there is nothing to do in that case
  2626. if(BOOST_UNLIKELY(!n)) return;
  2627. //There is enough memory
  2628. T* const old_finish = this->priv_raw_end();
  2629. const size_type elems_after = old_finish - pos;
  2630. if (!elems_after){
  2631. insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n);
  2632. this->m_holder.m_size += n;
  2633. }
  2634. else if (elems_after >= n){
  2635. //New elements can be just copied.
  2636. //Move to uninitialized memory last objects
  2637. ::boost::container::uninitialized_move_alloc
  2638. (this->m_holder.alloc(), old_finish - n, old_finish, old_finish);
  2639. this->m_holder.m_size += n;
  2640. //Copy previous to last objects to the initialized end
  2641. boost::container::move_backward(pos, old_finish - n, old_finish);
  2642. //Insert new objects in the pos
  2643. insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, n);
  2644. }
  2645. else {
  2646. //The new elements don't fit in the [pos, end()) range.
  2647. //Copy old [pos, end()) elements to the uninitialized memory (a gap is created)
  2648. ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), pos, old_finish, pos + n);
  2649. BOOST_TRY{
  2650. //Copy first new elements in pos (gap is still there)
  2651. insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, elems_after);
  2652. //Copy to the beginning of the unallocated zone the last new elements (the gap is closed).
  2653. insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n - elems_after);
  2654. this->m_holder.m_size += n;
  2655. }
  2656. BOOST_CATCH(...){
  2657. boost::container::destroy_alloc_n(this->get_stored_allocator(), pos + n, elems_after);
  2658. BOOST_RETHROW
  2659. }
  2660. BOOST_CATCH_END
  2661. }
  2662. }
  2663. template <class InsertionProxy>
  2664. void priv_forward_range_insert_new_allocation
  2665. (T* const new_start, size_type new_cap, T* const pos, const size_type n, InsertionProxy insert_range_proxy)
  2666. {
  2667. //n can be zero, if we want to reallocate!
  2668. T *new_finish = new_start;
  2669. T *old_finish;
  2670. //Anti-exception rollbacks
  2671. typename value_traits::ArrayDeallocator new_buffer_deallocator(new_start, this->m_holder.alloc(), new_cap);
  2672. typename value_traits::ArrayDestructor new_values_destroyer(new_start, this->m_holder.alloc(), 0u);
  2673. //Initialize with [begin(), pos) old buffer
  2674. //the start of the new buffer
  2675. T * const old_buffer = this->priv_raw_begin();
  2676. if(old_buffer){
  2677. new_finish = ::boost::container::uninitialized_move_alloc
  2678. (this->m_holder.alloc(), this->priv_raw_begin(), pos, old_finish = new_finish);
  2679. new_values_destroyer.increment_size(new_finish - old_finish);
  2680. }
  2681. //Initialize new objects, starting from previous point
  2682. old_finish = new_finish;
  2683. insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n);
  2684. new_finish += n;
  2685. new_values_destroyer.increment_size(new_finish - old_finish);
  2686. //Initialize from the rest of the old buffer,
  2687. //starting from previous point
  2688. if(old_buffer){
  2689. new_finish = ::boost::container::uninitialized_move_alloc
  2690. (this->m_holder.alloc(), pos, old_buffer + this->m_holder.m_size, new_finish);
  2691. //Destroy and deallocate old elements
  2692. //If there is allocated memory, destroy and deallocate
  2693. if(!value_traits::trivial_dctr_after_move)
  2694. boost::container::destroy_alloc_n(this->get_stored_allocator(), old_buffer, this->m_holder.m_size);
  2695. this->m_holder.deallocate(this->m_holder.start(), this->m_holder.capacity());
  2696. }
  2697. this->m_holder.start(new_start);
  2698. this->m_holder.m_size = size_type(new_finish - new_start);
  2699. this->m_holder.capacity(new_cap);
  2700. //All construction successful, disable rollbacks
  2701. new_values_destroyer.release();
  2702. new_buffer_deallocator.release();
  2703. }
  2704. template <class InsertionProxy>
  2705. void priv_forward_range_insert_expand_backwards
  2706. (T* const new_start, const size_type new_capacity,
  2707. T* const pos, const size_type n, InsertionProxy insert_range_proxy)
  2708. {
  2709. //n can be zero to just expand capacity
  2710. //Backup old data
  2711. T* const old_start = this->priv_raw_begin();
  2712. const size_type old_size = this->m_holder.m_size;
  2713. T* const old_finish = old_start + old_size;
  2714. //We can have 8 possibilities:
  2715. const size_type elemsbefore = static_cast<size_type>(pos - old_start);
  2716. const size_type s_before = static_cast<size_type>(old_start - new_start);
  2717. const size_type before_plus_new = elemsbefore + n;
  2718. //Update the vector buffer information to a safe state
  2719. this->m_holder.start(new_start);
  2720. this->m_holder.capacity(new_capacity);
  2721. this->m_holder.m_size = 0;
  2722. //If anything goes wrong, this object will destroy
  2723. //all the old objects to fulfill previous vector state
  2724. typename value_traits::ArrayDestructor old_values_destroyer(old_start, this->m_holder.alloc(), old_size);
  2725. //Check if s_before is big enough to hold the beginning of old data + new data
  2726. if(s_before >= before_plus_new){
  2727. //Copy first old values before pos, after that the new objects
  2728. T *const new_elem_pos =
  2729. ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), old_start, pos, new_start);
  2730. this->m_holder.m_size = elemsbefore;
  2731. insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), new_elem_pos, n);
  2732. this->m_holder.m_size = before_plus_new;
  2733. const size_type new_size = old_size + n;
  2734. //Check if s_before is so big that even copying the old data + new data
  2735. //there is a gap between the new data and the old data
  2736. if(s_before >= new_size){
  2737. //Old situation:
  2738. // _________________________________________________________
  2739. //| raw_mem | old_begin | old_end |
  2740. //| __________________________________|___________|_________|
  2741. //
  2742. //New situation:
  2743. // _________________________________________________________
  2744. //| old_begin | new | old_end | raw_mem |
  2745. //|___________|__________|_________|________________________|
  2746. //
  2747. //Now initialize the rest of memory with the last old values
  2748. if(before_plus_new != new_size){ //Special case to avoid operations in back insertion
  2749. ::boost::container::uninitialized_move_alloc
  2750. (this->m_holder.alloc(), pos, old_finish, new_start + before_plus_new);
  2751. //All new elements correctly constructed, avoid new element destruction
  2752. this->m_holder.m_size = new_size;
  2753. }
  2754. //Old values destroyed automatically with "old_values_destroyer"
  2755. //when "old_values_destroyer" goes out of scope unless the have trivial
  2756. //destructor after move.
  2757. if(value_traits::trivial_dctr_after_move)
  2758. old_values_destroyer.release();
  2759. }
  2760. //s_before is so big that divides old_end
  2761. else{
  2762. //Old situation:
  2763. // __________________________________________________
  2764. //| raw_mem | old_begin | old_end |
  2765. //| ___________________________|___________|_________|
  2766. //
  2767. //New situation:
  2768. // __________________________________________________
  2769. //| old_begin | new | old_end | raw_mem |
  2770. //|___________|__________|_________|_________________|
  2771. //
  2772. //Now initialize the rest of memory with the last old values
  2773. //All new elements correctly constructed, avoid new element destruction
  2774. const size_type raw_gap = s_before - before_plus_new;
  2775. if(!value_traits::trivial_dctr){
  2776. //Now initialize the rest of s_before memory with the
  2777. //first of elements after new values
  2778. ::boost::container::uninitialized_move_alloc_n
  2779. (this->m_holder.alloc(), pos, raw_gap, new_start + before_plus_new);
  2780. //Now we have a contiguous buffer so program trailing element destruction
  2781. //and update size to the final size.
  2782. old_values_destroyer.shrink_forward(new_size-s_before);
  2783. this->m_holder.m_size = new_size;
  2784. //Now move remaining last objects in the old buffer begin
  2785. T * const remaining_pos = pos + raw_gap;
  2786. if(remaining_pos != old_start){ //Make sure data has to be moved
  2787. ::boost::container::move(remaining_pos, old_finish, old_start);
  2788. }
  2789. //Once moved, avoid calling the destructors if trivial after move
  2790. if(value_traits::trivial_dctr_after_move){
  2791. old_values_destroyer.release();
  2792. }
  2793. }
  2794. else{ //If trivial destructor, we can uninitialized copy + copy in a single uninitialized copy
  2795. ::boost::container::uninitialized_move_alloc_n
  2796. (this->m_holder.alloc(), pos, static_cast<size_type>(old_finish - pos), new_start + before_plus_new);
  2797. this->m_holder.m_size = new_size;
  2798. old_values_destroyer.release();
  2799. }
  2800. }
  2801. }
  2802. else{
  2803. //Check if we have to do the insertion in two phases
  2804. //since maybe s_before is not big enough and
  2805. //the buffer was expanded both sides
  2806. //
  2807. //Old situation:
  2808. // _________________________________________________
  2809. //| raw_mem | old_begin + old_end | raw_mem |
  2810. //|_________|_____________________|_________________|
  2811. //
  2812. //New situation with do_after:
  2813. // _________________________________________________
  2814. //| old_begin + new + old_end | raw_mem |
  2815. //|___________________________________|_____________|
  2816. //
  2817. //New without do_after:
  2818. // _________________________________________________
  2819. //| old_begin + new + old_end | raw_mem |
  2820. //|____________________________|____________________|
  2821. //
  2822. const bool do_after = n > s_before;
  2823. //Now we can have two situations: the raw_mem of the
  2824. //beginning divides the old_begin, or the new elements:
  2825. if (s_before <= elemsbefore) {
  2826. //The raw memory divides the old_begin group:
  2827. //
  2828. //If we need two phase construction (do_after)
  2829. //new group is divided in new = new_beg + new_end groups
  2830. //In this phase only new_beg will be inserted
  2831. //
  2832. //Old situation:
  2833. // _________________________________________________
  2834. //| raw_mem | old_begin | old_end | raw_mem |
  2835. //|_________|___________|_________|_________________|
  2836. //
  2837. //New situation with do_after(1):
  2838. //This is not definitive situation, the second phase
  2839. //will include
  2840. // _________________________________________________
  2841. //| old_begin | new_beg | old_end | raw_mem |
  2842. //|___________|_________|_________|_________________|
  2843. //
  2844. //New situation without do_after:
  2845. // _________________________________________________
  2846. //| old_begin | new | old_end | raw_mem |
  2847. //|___________|_____|_________|_____________________|
  2848. //
  2849. //Copy the first part of old_begin to raw_mem
  2850. ::boost::container::uninitialized_move_alloc_n
  2851. (this->m_holder.alloc(), old_start, s_before, new_start);
  2852. //The buffer is all constructed until old_end,
  2853. //so program trailing destruction and assign final size
  2854. //if !do_after, s_before+n otherwise.
  2855. size_type new_1st_range;
  2856. if(do_after){
  2857. new_1st_range = s_before;
  2858. //release destroyer and update size
  2859. old_values_destroyer.release();
  2860. }
  2861. else{
  2862. new_1st_range = n;
  2863. if(value_traits::trivial_dctr_after_move)
  2864. old_values_destroyer.release();
  2865. else{
  2866. old_values_destroyer.shrink_forward(old_size - (s_before - n));
  2867. }
  2868. }
  2869. this->m_holder.m_size = old_size + new_1st_range;
  2870. //Now copy the second part of old_begin overwriting itself
  2871. T *const next = ::boost::container::move(old_start + s_before, pos, old_start);
  2872. //Now copy the new_beg elements
  2873. insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), next, new_1st_range);
  2874. //If there is no after work and the last old part needs to be moved to front, do it
  2875. if(!do_after && (n != s_before)){
  2876. //Now displace old_end elements
  2877. ::boost::container::move(pos, old_finish, next + new_1st_range);
  2878. }
  2879. }
  2880. else {
  2881. //If we have to expand both sides,
  2882. //we will play if the first new values so
  2883. //calculate the upper bound of new values
  2884. //The raw memory divides the new elements
  2885. //
  2886. //If we need two phase construction (do_after)
  2887. //new group is divided in new = new_beg + new_end groups
  2888. //In this phase only new_beg will be inserted
  2889. //
  2890. //Old situation:
  2891. // _______________________________________________________
  2892. //| raw_mem | old_begin | old_end | raw_mem |
  2893. //|_______________|___________|_________|_________________|
  2894. //
  2895. //New situation with do_after():
  2896. // ____________________________________________________
  2897. //| old_begin | new_beg | old_end | raw_mem |
  2898. //|___________|_______________|_________|______________|
  2899. //
  2900. //New situation without do_after:
  2901. // ______________________________________________________
  2902. //| old_begin | new | old_end | raw_mem |
  2903. //|___________|_____|_________|__________________________|
  2904. //
  2905. //First copy whole old_begin and part of new to raw_mem
  2906. T * const new_pos = ::boost::container::uninitialized_move_alloc
  2907. (this->m_holder.alloc(), old_start, pos, new_start);
  2908. this->m_holder.m_size = elemsbefore;
  2909. const size_type mid_n = s_before - elemsbefore;
  2910. insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), new_pos, mid_n);
  2911. //The buffer is all constructed until old_end,
  2912. //release destroyer
  2913. this->m_holder.m_size = old_size + s_before;
  2914. old_values_destroyer.release();
  2915. if(do_after){
  2916. //Copy new_beg part
  2917. insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), old_start, elemsbefore);
  2918. }
  2919. else{
  2920. //Copy all new elements
  2921. const size_type rest_new = n - mid_n;
  2922. insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), old_start, rest_new);
  2923. T* const move_start = old_start + rest_new;
  2924. //Displace old_end, but make sure data has to be moved
  2925. T* const move_end = move_start != pos ? ::boost::container::move(pos, old_finish, move_start)
  2926. : old_finish;
  2927. //Destroy remaining moved elements from old_end except if they
  2928. //have trivial destructor after being moved
  2929. size_type n_destroy = s_before - n;
  2930. if(!value_traits::trivial_dctr_after_move)
  2931. boost::container::destroy_alloc_n(this->get_stored_allocator(), move_end, n_destroy);
  2932. this->m_holder.m_size -= n_destroy;
  2933. }
  2934. }
  2935. //This is only executed if two phase construction is needed
  2936. if(do_after){
  2937. //The raw memory divides the new elements
  2938. //
  2939. //Old situation:
  2940. // ______________________________________________________
  2941. //| raw_mem | old_begin | old_end | raw_mem |
  2942. //|______________|___________|____________|______________|
  2943. //
  2944. //New situation with do_after(1):
  2945. // _______________________________________________________
  2946. //| old_begin + new_beg | new_end |old_end | raw_mem |
  2947. //|__________________________|_________|________|_________|
  2948. //
  2949. //New situation with do_after(2):
  2950. // ______________________________________________________
  2951. //| old_begin + new | old_end |raw |
  2952. //|_______________________________________|_________|____|
  2953. //
  2954. const size_type n_after = n - s_before;
  2955. const size_type elemsafter = old_size - elemsbefore;
  2956. //We can have two situations:
  2957. if (elemsafter >= n_after){
  2958. //The raw_mem from end will divide displaced old_end
  2959. //
  2960. //Old situation:
  2961. // ______________________________________________________
  2962. //| raw_mem | old_begin | old_end | raw_mem |
  2963. //|______________|___________|____________|______________|
  2964. //
  2965. //New situation with do_after(1):
  2966. // _______________________________________________________
  2967. //| old_begin + new_beg | new_end |old_end | raw_mem |
  2968. //|__________________________|_________|________|_________|
  2969. //
  2970. //First copy the part of old_end raw_mem
  2971. T* finish_n = old_finish - n_after;
  2972. ::boost::container::uninitialized_move_alloc
  2973. (this->m_holder.alloc(), finish_n, old_finish, old_finish);
  2974. this->m_holder.m_size += n_after;
  2975. //Displace the rest of old_end to the new position
  2976. boost::container::move_backward(pos, finish_n, old_finish);
  2977. //Now overwrite with new_end
  2978. //The new_end part is [first + (n - n_after), last)
  2979. insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, n_after);
  2980. }
  2981. else {
  2982. //The raw_mem from end will divide new_end part
  2983. //
  2984. //Old situation:
  2985. // _____________________________________________________________
  2986. //| raw_mem | old_begin | old_end | raw_mem |
  2987. //|______________|___________|____________|_____________________|
  2988. //
  2989. //New situation with do_after(2):
  2990. // _____________________________________________________________
  2991. //| old_begin + new_beg | new_end |old_end | raw_mem |
  2992. //|__________________________|_______________|________|_________|
  2993. //
  2994. const size_type mid_last_dist = n_after - elemsafter;
  2995. //First initialize data in raw memory
  2996. //Copy to the old_end part to the uninitialized zone leaving a gap.
  2997. ::boost::container::uninitialized_move_alloc
  2998. (this->m_holder.alloc(), pos, old_finish, old_finish + mid_last_dist);
  2999. typename value_traits::ArrayDestructor old_end_destroyer
  3000. (old_finish + mid_last_dist, this->m_holder.alloc(), old_finish - pos);
  3001. //Copy the first part to the already constructed old_end zone
  3002. insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, elemsafter);
  3003. //Copy the rest to the uninitialized zone filling the gap
  3004. insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, mid_last_dist);
  3005. this->m_holder.m_size += n_after;
  3006. old_end_destroyer.release();
  3007. }
  3008. }
  3009. }
  3010. }
  3011. void priv_throw_if_out_of_range(size_type n) const
  3012. {
  3013. //If n is out of range, throw an out_of_range exception
  3014. if (n >= this->size()){
  3015. throw_out_of_range("vector::at out of range");
  3016. }
  3017. }
  3018. BOOST_CONTAINER_FORCEINLINE bool priv_in_range(const_iterator pos) const
  3019. {
  3020. return (this->begin() <= pos) && (pos < this->end());
  3021. }
  3022. BOOST_CONTAINER_FORCEINLINE bool priv_in_range_or_end(const_iterator pos) const
  3023. {
  3024. return (this->begin() <= pos) && (pos <= this->end());
  3025. }
  3026. #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
  3027. public:
  3028. unsigned int num_expand_fwd;
  3029. unsigned int num_expand_bwd;
  3030. unsigned int num_shrink;
  3031. unsigned int num_alloc;
  3032. void reset_alloc_stats()
  3033. { num_expand_fwd = num_expand_bwd = num_alloc = 0, num_shrink = 0; }
  3034. #endif
  3035. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  3036. };
  3037. #if __cplusplus >= 201703L
  3038. template <typename InputIterator>
  3039. vector(InputIterator, InputIterator) ->
  3040. vector<typename iterator_traits<InputIterator>::value_type>;
  3041. template <typename InputIterator, typename Allocator>
  3042. vector(InputIterator, InputIterator, Allocator const&) ->
  3043. vector<typename iterator_traits<InputIterator>::value_type, Allocator>;
  3044. #endif
  3045. }} //namespace boost::container
  3046. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  3047. namespace boost {
  3048. //!has_trivial_destructor_after_move<> == true_type
  3049. //!specialization for optimizations
  3050. template <class T, class Allocator>
  3051. struct has_trivial_destructor_after_move<boost::container::vector<T, Allocator> >
  3052. {
  3053. typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
  3054. static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
  3055. ::boost::has_trivial_destructor_after_move<pointer>::value;
  3056. };
  3057. }
  3058. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  3059. #include <boost/container/detail/config_end.hpp>
  3060. #endif // #ifndef BOOST_CONTAINER_CONTAINER_VECTOR_HPP