deque.hpp 105 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883
  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_DEQUE_HPP
  11. #define BOOST_CONTAINER_DEQUE_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/allocator_traits.hpp>
  22. #include <boost/container/container_fwd.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> //algo_equal(), algo_lexicographical_compare
  29. #include <boost/container/detail/alloc_helpers.hpp>
  30. #include <boost/container/detail/copy_move_algo.hpp>
  31. #include <boost/container/detail/iterator.hpp>
  32. #include <boost/move/detail/iterator_to_raw_pointer.hpp>
  33. #include <boost/container/detail/iterators.hpp>
  34. #include <boost/container/detail/min_max.hpp>
  35. #include <boost/container/detail/mpl.hpp>
  36. #include <boost/move/detail/to_raw_pointer.hpp>
  37. #include <boost/container/detail/type_traits.hpp>
  38. // move
  39. #include <boost/move/adl_move_swap.hpp>
  40. #include <boost/move/iterator.hpp>
  41. #include <boost/move/traits.hpp>
  42. #include <boost/move/utility_core.hpp>
  43. // move/detail
  44. #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  45. #include <boost/move/detail/fwd_macros.hpp>
  46. #endif
  47. #include <boost/move/detail/move_helpers.hpp>
  48. // other
  49. #include <boost/assert.hpp>
  50. // std
  51. #include <cstddef>
  52. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  53. #include <initializer_list>
  54. #endif
  55. namespace boost {
  56. namespace container {
  57. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  58. template <class T, class Allocator, class Options>
  59. class deque;
  60. template <class T>
  61. struct deque_value_traits
  62. {
  63. typedef T value_type;
  64. BOOST_STATIC_CONSTEXPR bool trivial_dctr = dtl::is_trivially_destructible<value_type>::value;
  65. BOOST_STATIC_CONSTEXPR bool trivial_dctr_after_move = ::boost::has_trivial_destructor_after_move<value_type>::value;
  66. };
  67. template<class T, std::size_t BlockBytes, std::size_t BlockSize>
  68. struct deque_block_size
  69. {
  70. BOOST_CONTAINER_STATIC_ASSERT_MSG(!(BlockBytes && BlockSize), "BlockBytes and BlockSize can't be specified at the same time");
  71. BOOST_STATIC_CONSTEXPR std::size_t block_bytes = BlockBytes ? BlockBytes : 512u;
  72. BOOST_STATIC_CONSTEXPR std::size_t value = BlockSize ? BlockSize : (sizeof(T) < block_bytes ? (block_bytes/sizeof(T)) : std::size_t(1));
  73. };
  74. namespace dtl {
  75. // Class invariants:
  76. // For any nonsingular iterator i:
  77. // i.node is the address of an element in the map array. The
  78. // contents of i.node is a pointer to the beginning of a node.
  79. // i.first == //(i.node)
  80. // i.last == i.first + node_size
  81. // i.cur is a pointer in the range [i.first, i.last). NOTE:
  82. // the implication of this is that i.cur is always a dereferenceable
  83. // pointer, even if i is a past-the-end iterator.
  84. // Start and Finish are always nonsingular iterators. NOTE: this means
  85. // that an empty deque must have one node, and that a deque
  86. // with N elements, where N is the buffer size, must have two nodes.
  87. // For every node other than start.node and finish.node, every element
  88. // in the node is an initialized object. If start.node == finish.node,
  89. // then [start.cur, finish.cur) are initialized objects, and
  90. // the elements outside that range are uninitialized storage. Otherwise,
  91. // [start.cur, start.last) and [finish.first, finish.cur) are initialized
  92. // objects, and [start.first, start.cur) and [finish.cur, finish.last)
  93. // are uninitialized storage.
  94. // [map, map + map_size) is a valid, non-empty range.
  95. // [start.node, finish.node] is a valid range contained within
  96. // [map, map + map_size).
  97. // A pointer in the range [map, map + map_size) points to an allocated node
  98. // if and only if the pointer is in the range [start.node, finish.node].
  99. #define BOOST_CONTAINER_DEQUE_LIGHTER_ITERATOR_LEVEL 0
  100. #if BOOST_CONTAINER_DEQUE_LIGHTER_ITERATOR_LEVEL == 0
  101. template<class Pointer, bool IsConst>
  102. class deque_iterator
  103. {
  104. public:
  105. typedef std::random_access_iterator_tag iterator_category;
  106. typedef typename boost::intrusive::pointer_traits<Pointer>::element_type value_type;
  107. typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type difference_type;
  108. typedef typename boost::intrusive::pointer_traits<Pointer>::size_type size_type;
  109. typedef typename if_c
  110. < IsConst
  111. , typename boost::intrusive::pointer_traits<Pointer>::template
  112. rebind_pointer<const value_type>::type
  113. , Pointer
  114. >::type pointer;
  115. typedef typename if_c
  116. < IsConst
  117. , const value_type&
  118. , value_type&
  119. >::type reference;
  120. class nat;
  121. typedef typename dtl::if_c< IsConst
  122. , deque_iterator<Pointer, false>
  123. , nat>::type nonconst_iterator;
  124. typedef Pointer val_alloc_ptr;
  125. typedef typename boost::intrusive::pointer_traits<Pointer>::
  126. template rebind_pointer<Pointer>::type index_pointer;
  127. Pointer m_cur;
  128. Pointer m_first;
  129. Pointer m_last;
  130. index_pointer m_node;
  131. public:
  132. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_cur() const { return m_cur; }
  133. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_first() const { return m_first; }
  134. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_last() const { return m_last; }
  135. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline index_pointer get_node() const { return m_node; }
  136. inline deque_iterator(val_alloc_ptr x, index_pointer y, difference_type block_size) BOOST_NOEXCEPT_OR_NOTHROW
  137. : m_cur(x), m_first(*y), m_last(*y + block_size), m_node(y)
  138. {}
  139. inline deque_iterator(val_alloc_ptr x, index_pointer y, size_type block_size) BOOST_NOEXCEPT_OR_NOTHROW
  140. : m_cur(x), m_first(*y), m_last(*y + difference_type(block_size)), m_node(y)
  141. {}
  142. inline deque_iterator() BOOST_NOEXCEPT_OR_NOTHROW
  143. : m_cur(), m_first(), m_last(), m_node() //Value initialization to achieve "null iterators" (N3644)
  144. {}
  145. inline deque_iterator(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
  146. : m_cur(x.get_cur()), m_first(x.get_first()), m_last(x.get_last()), m_node(x.get_node())
  147. {}
  148. inline deque_iterator(const nonconst_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
  149. : m_cur(x.get_cur()), m_first(x.get_first()), m_last(x.get_last()), m_node(x.get_node())
  150. {}
  151. inline deque_iterator(Pointer cur, Pointer first, Pointer last, index_pointer node) BOOST_NOEXCEPT_OR_NOTHROW
  152. : m_cur(cur), m_first(first), m_last(last), m_node(node)
  153. {}
  154. inline deque_iterator& operator=(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
  155. { m_cur = x.get_cur(); m_first = x.get_first(); m_last = x.get_last(); m_node = x.get_node(); return *this; }
  156. inline deque_iterator<Pointer, false> unconst() const BOOST_NOEXCEPT_OR_NOTHROW
  157. {
  158. return deque_iterator<Pointer, false>(this->get_cur(), this->get_first(), this->get_last(), this->get_node());
  159. }
  160. inline reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
  161. { return *this->m_cur; }
  162. inline pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
  163. { return this->m_cur; }
  164. BOOST_CONTAINER_ATTRIBUTE_NODISCARD difference_type operator-(const deque_iterator& x) const BOOST_NOEXCEPT_OR_NOTHROW
  165. {
  166. if(!this->m_cur && !x.m_cur){
  167. return 0;
  168. }
  169. const difference_type block_size = m_last - m_first;
  170. BOOST_ASSERT(block_size);
  171. return block_size * (this->m_node - x.m_node - 1) +
  172. (this->m_cur - this->m_first) + (x.m_last - x.m_cur);
  173. }
  174. deque_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
  175. {
  176. BOOST_ASSERT(!!m_cur);
  177. ++this->m_cur;
  178. if (this->m_cur == this->m_last) {
  179. const difference_type block_size = m_last - m_first;
  180. BOOST_ASSERT(block_size);
  181. this->priv_set_node(this->m_node + 1, block_size);
  182. this->m_cur = this->m_first;
  183. }
  184. return *this;
  185. }
  186. inline deque_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
  187. {
  188. deque_iterator tmp(*this);
  189. ++*this;
  190. return tmp;
  191. }
  192. deque_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
  193. {
  194. BOOST_ASSERT(!!m_cur);
  195. if (this->m_cur == this->m_first) {
  196. const difference_type block_size = m_last - m_first;
  197. BOOST_ASSERT(block_size);
  198. this->priv_set_node(this->m_node - 1, block_size);
  199. this->m_cur = this->m_last;
  200. }
  201. --this->m_cur;
  202. return *this;
  203. }
  204. inline deque_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
  205. {
  206. deque_iterator tmp(*this);
  207. --*this;
  208. return tmp;
  209. }
  210. deque_iterator& operator+=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
  211. {
  212. if (!n)
  213. return *this;
  214. BOOST_ASSERT(!!m_cur);
  215. const difference_type offset = n + (this->m_cur - this->m_first);
  216. const difference_type block_size = m_last - m_first;
  217. BOOST_ASSERT(block_size);
  218. if (offset >= 0 && offset < block_size)
  219. this->m_cur += difference_type(n);
  220. else {
  221. const difference_type node_offset =
  222. offset > 0 ? (offset / block_size)
  223. : (-difference_type((-offset - 1) / block_size) - 1);
  224. this->priv_set_node(this->m_node + node_offset, size_type(block_size));
  225. this->m_cur = this->m_first +
  226. (offset - node_offset * block_size);
  227. }
  228. return *this;
  229. }
  230. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  231. deque_iterator operator+(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
  232. { deque_iterator tmp(*this); return tmp += n; }
  233. inline
  234. deque_iterator& operator-=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
  235. { return *this += -n; }
  236. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  237. deque_iterator operator-(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
  238. { deque_iterator tmp(*this); return tmp -= n; }
  239. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  240. reference operator[](difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
  241. { return *(*this + n); }
  242. //Comparisons
  243. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  244. friend bool operator==(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  245. { return l.m_cur == r.m_cur; }
  246. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  247. friend bool operator!=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  248. { return l.m_cur != r.m_cur; }
  249. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  250. friend bool operator<(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  251. { return (l.m_node == r.m_node) ? (l.m_cur < r.m_cur) : (l.m_node < r.m_node); }
  252. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  253. friend bool operator>(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  254. { return r < l; }
  255. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  256. friend bool operator<=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  257. { return !(r < l); }
  258. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  259. friend bool operator>=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  260. { return !(l < r); }
  261. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  262. friend deque_iterator operator+(difference_type n, deque_iterator x) BOOST_NOEXCEPT_OR_NOTHROW
  263. { return x += n; }
  264. inline void priv_set_node(index_pointer new_node, size_type block_size) BOOST_NOEXCEPT_OR_NOTHROW
  265. { return this->priv_set_node(new_node, difference_type(block_size)); }
  266. inline void priv_set_node(index_pointer new_node, difference_type block_size) BOOST_NOEXCEPT_OR_NOTHROW
  267. {
  268. this->m_node = new_node;
  269. this->m_first = *new_node;
  270. this->m_last = this->m_first + block_size;
  271. }
  272. };
  273. #elif BOOST_CONTAINER_DEQUE_LIGHTER_ITERATOR_LEVEL == 1
  274. template<class Pointer, bool IsConst, unsigned BlockBytes, unsigned BlockSize>
  275. class deque_iterator
  276. {
  277. public:
  278. typedef std::random_access_iterator_tag iterator_category;
  279. typedef typename boost::intrusive::pointer_traits<Pointer>::element_type value_type;
  280. typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type difference_type;
  281. typedef typename boost::intrusive::pointer_traits<Pointer>::size_type size_type;
  282. typedef typename if_c
  283. < IsConst
  284. , typename boost::intrusive::pointer_traits<Pointer>::template
  285. rebind_pointer<const value_type>::type
  286. , Pointer
  287. >::type pointer;
  288. typedef typename if_c
  289. < IsConst
  290. , const value_type&
  291. , value_type&
  292. >::type reference;
  293. BOOST_CONSTEXPR inline static size_type get_block_size() BOOST_NOEXCEPT_OR_NOTHROW
  294. { return deque_block_size<value_type, BlockBytes, BlockSize>::value; }
  295. BOOST_CONSTEXPR inline static difference_type get_block_ssize() BOOST_NOEXCEPT_OR_NOTHROW
  296. { return difference_type((get_block_size())); }
  297. class nat;
  298. typedef typename dtl::if_c< IsConst
  299. , deque_iterator<Pointer, false, BlockBytes, BlockSize>
  300. , nat>::type nonconst_iterator;
  301. typedef Pointer val_alloc_ptr;
  302. typedef typename boost::intrusive::pointer_traits<Pointer>::
  303. template rebind_pointer<Pointer>::type index_pointer;
  304. Pointer m_cur;
  305. Pointer m_first;
  306. index_pointer m_node;
  307. public:
  308. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_cur() const { return m_cur; }
  309. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_first() const { return m_first; }
  310. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_last() const { return m_first + get_block_ssize(); }
  311. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline index_pointer get_node() const { return m_node; }
  312. inline deque_iterator(val_alloc_ptr x, index_pointer y, difference_type ) BOOST_NOEXCEPT_OR_NOTHROW
  313. : m_cur(x), m_first(*y), m_node(y)
  314. {}
  315. inline deque_iterator(val_alloc_ptr x, index_pointer y, size_type ) BOOST_NOEXCEPT_OR_NOTHROW
  316. : m_cur(x), m_first(*y), m_node(y)
  317. {}
  318. inline deque_iterator() BOOST_NOEXCEPT_OR_NOTHROW
  319. : m_cur(), m_first(), m_node() //Value initialization to achieve "null iterators" (N3644)
  320. {}
  321. inline deque_iterator(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
  322. : m_cur(x.get_cur()), m_first(x.get_first()), m_node(x.get_node())
  323. {}
  324. inline deque_iterator(const nonconst_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
  325. : m_cur(x.get_cur()), m_first(x.get_first()), m_node(x.get_node())
  326. {}
  327. inline deque_iterator(Pointer cur, Pointer first, index_pointer node) BOOST_NOEXCEPT_OR_NOTHROW
  328. : m_cur(cur), m_first(first), m_node(node)
  329. {}
  330. inline deque_iterator& operator=(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
  331. { m_cur = x.get_cur(); m_first = x.get_first(); m_node = x.get_node(); return *this; }
  332. inline nonconst_iterator unconst() const BOOST_NOEXCEPT_OR_NOTHROW
  333. {
  334. return nonconst_iterator(this->get_cur(), this->get_first(), this->get_node());
  335. }
  336. inline reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
  337. { return *this->m_cur; }
  338. inline pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
  339. { return this->m_cur; }
  340. BOOST_CONTAINER_ATTRIBUTE_NODISCARD difference_type operator-(const deque_iterator& x) const BOOST_NOEXCEPT_OR_NOTHROW
  341. {
  342. if(!this->m_cur && !x.m_cur){
  343. return 0;
  344. }
  345. const difference_type block_size = get_block_ssize();
  346. BOOST_ASSERT(block_size);
  347. return block_size * (this->m_node - x.m_node - 1) +
  348. (this->m_cur - this->m_first) + ((x.m_first+block_size) - x.m_cur);
  349. }
  350. deque_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
  351. {
  352. BOOST_ASSERT(!!m_cur);
  353. ++this->m_cur;
  354. const difference_type block_size = get_block_ssize();
  355. if (this->m_cur == (this->m_first+block_size)) {
  356. BOOST_ASSERT(block_size);
  357. ++this->m_node;
  358. this->m_first = *this->m_node;
  359. this->m_cur = this->m_first;
  360. }
  361. return *this;
  362. }
  363. inline deque_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
  364. {
  365. deque_iterator tmp(*this);
  366. ++*this;
  367. return tmp;
  368. }
  369. deque_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
  370. {
  371. BOOST_ASSERT(!!m_cur);
  372. if (this->m_cur == this->m_first) {
  373. --this->m_node;
  374. this->m_first = *this->m_node;
  375. this->m_cur = this->m_first + get_block_ssize();
  376. }
  377. --this->m_cur;
  378. return *this;
  379. }
  380. inline deque_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
  381. {
  382. deque_iterator tmp(*this);
  383. --*this;
  384. return tmp;
  385. }
  386. deque_iterator& operator+=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
  387. {
  388. if (!n)
  389. return *this;
  390. BOOST_ASSERT(!!m_cur);
  391. const difference_type offset = n + (this->m_cur - this->m_first);
  392. const difference_type block_size = get_block_ssize();
  393. BOOST_ASSERT(block_size);
  394. if (offset >= 0 && offset < block_size)
  395. this->m_cur += difference_type(n);
  396. else {
  397. const difference_type node_offset =
  398. offset > 0 ? (offset / block_size)
  399. : (-difference_type((-offset - 1) / block_size) - 1);
  400. this->m_node += node_offset;
  401. this->m_first = *this->m_node;
  402. this->m_cur = this->m_first + (offset - node_offset * block_size);
  403. }
  404. return *this;
  405. }
  406. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  407. deque_iterator operator+(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
  408. { deque_iterator tmp(*this); return tmp += n; }
  409. inline
  410. deque_iterator& operator-=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
  411. { return *this += -n; }
  412. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  413. deque_iterator operator-(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
  414. { deque_iterator tmp(*this); return tmp -= n; }
  415. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  416. reference operator[](difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
  417. { return *(*this + n); }
  418. //Comparisons
  419. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  420. friend bool operator==(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  421. { return l.m_cur == r.m_cur; }
  422. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  423. friend bool operator!=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  424. { return l.m_cur != r.m_cur; }
  425. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  426. friend bool operator<(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  427. { return (l.m_node == r.m_node) ? (l.m_cur < r.m_cur) : (l.m_node < r.m_node); }
  428. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  429. friend bool operator>(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  430. { return r < l; }
  431. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  432. friend bool operator<=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  433. { return !(r < l); }
  434. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  435. friend bool operator>=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  436. { return !(l < r); }
  437. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  438. friend deque_iterator operator+(difference_type n, deque_iterator x) BOOST_NOEXCEPT_OR_NOTHROW
  439. { return x += n; }
  440. inline void priv_set_node(index_pointer new_node, size_type ) BOOST_NOEXCEPT_OR_NOTHROW
  441. { return this->priv_set_node(new_node, difference_type()); }
  442. inline void priv_set_node(index_pointer new_node, difference_type) BOOST_NOEXCEPT_OR_NOTHROW
  443. {
  444. this->m_node = new_node;
  445. this->m_first = *new_node;
  446. }
  447. };
  448. #elif BOOST_CONTAINER_DEQUE_LIGHTER_ITERATOR_LEVEL == 2
  449. template<class Pointer, bool IsConst, unsigned BlockBytes, unsigned BlockSize>
  450. class deque_iterator
  451. {
  452. public:
  453. typedef std::random_access_iterator_tag iterator_category;
  454. typedef typename boost::intrusive::pointer_traits<Pointer>::element_type value_type;
  455. typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type difference_type;
  456. typedef typename boost::intrusive::pointer_traits<Pointer>::size_type size_type;
  457. typedef typename if_c
  458. < IsConst
  459. , typename boost::intrusive::pointer_traits<Pointer>::template
  460. rebind_pointer<const value_type>::type
  461. , Pointer
  462. >::type pointer;
  463. typedef typename if_c
  464. < IsConst
  465. , const value_type&
  466. , value_type&
  467. >::type reference;
  468. BOOST_CONSTEXPR inline static size_type get_block_size() BOOST_NOEXCEPT_OR_NOTHROW
  469. {
  470. BOOST_CONTAINER_STATIC_ASSERT((deque_block_size<value_type, BlockBytes, BlockSize>::value));
  471. return deque_block_size<value_type, BlockBytes, BlockSize>::value;
  472. }
  473. BOOST_CONSTEXPR inline static difference_type get_block_ssize() BOOST_NOEXCEPT_OR_NOTHROW
  474. { return difference_type((get_block_size())); }
  475. class nat;
  476. typedef typename dtl::if_c< IsConst
  477. , deque_iterator<Pointer, false, BlockBytes, BlockSize>
  478. , nat>::type nonconst_iterator;
  479. typedef Pointer val_alloc_ptr;
  480. typedef typename boost::intrusive::pointer_traits<Pointer>::
  481. template rebind_pointer<Pointer>::type index_pointer;
  482. Pointer m_cur;
  483. index_pointer m_node;
  484. public:
  485. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_cur() const { return m_cur; }
  486. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_first() const { return *m_node; }
  487. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_last() const { return *m_node + get_block_ssize(); }
  488. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline index_pointer get_node() const { return m_node; }
  489. inline deque_iterator(val_alloc_ptr x, index_pointer y, difference_type ) BOOST_NOEXCEPT_OR_NOTHROW
  490. : m_cur(x), m_node(y)
  491. {}
  492. inline deque_iterator(val_alloc_ptr x, index_pointer y, size_type ) BOOST_NOEXCEPT_OR_NOTHROW
  493. : m_cur(x), m_node(y)
  494. {}
  495. inline deque_iterator() BOOST_NOEXCEPT_OR_NOTHROW
  496. : m_cur(), m_node() //Value initialization to achieve "null iterators" (N3644)
  497. {}
  498. inline deque_iterator(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
  499. : m_cur(x.get_cur()), m_node(x.get_node())
  500. {}
  501. inline deque_iterator(const nonconst_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
  502. : m_cur(x.get_cur()), m_node(x.get_node())
  503. {}
  504. inline deque_iterator(Pointer cur, index_pointer node) BOOST_NOEXCEPT_OR_NOTHROW
  505. : m_cur(cur), m_node(node)
  506. {}
  507. inline deque_iterator& operator=(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
  508. { m_cur = x.get_cur(); m_node = x.get_node(); return *this; }
  509. inline nonconst_iterator unconst() const BOOST_NOEXCEPT_OR_NOTHROW
  510. {
  511. return nonconst_iterator(this->get_cur(), this->get_node());
  512. }
  513. inline reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
  514. { return *this->m_cur; }
  515. inline pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
  516. { return this->m_cur; }
  517. BOOST_CONTAINER_ATTRIBUTE_NODISCARD difference_type operator-(const deque_iterator& x) const BOOST_NOEXCEPT_OR_NOTHROW
  518. {
  519. if(!this->m_cur && !x.m_cur){
  520. return 0;
  521. }
  522. const difference_type block_size = get_block_ssize();
  523. BOOST_ASSERT(block_size);
  524. return block_size * (this->m_node - x.m_node - 1) +
  525. (this->m_cur - this->get_first()) + (x.get_last() - x.m_cur);
  526. }
  527. deque_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
  528. {
  529. BOOST_ASSERT(!!m_cur);
  530. ++this->m_cur;
  531. if (this->m_cur == (this->get_last())) {
  532. ++this->m_node;
  533. this->m_cur = *this->m_node;
  534. }
  535. return *this;
  536. }
  537. inline deque_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
  538. {
  539. deque_iterator tmp(*this);
  540. ++*this;
  541. return tmp;
  542. }
  543. deque_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
  544. {
  545. BOOST_ASSERT(!!m_cur);
  546. if (this->m_cur == this->get_first()) {
  547. --this->m_node;
  548. this->m_cur = this->get_last();
  549. }
  550. --this->m_cur;
  551. return *this;
  552. }
  553. inline deque_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
  554. {
  555. deque_iterator tmp(*this);
  556. --*this;
  557. return tmp;
  558. }
  559. deque_iterator& operator+=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
  560. {
  561. if (!n)
  562. return *this;
  563. BOOST_ASSERT(!!m_cur);
  564. const difference_type offset = n + (this->m_cur - this->get_first());
  565. const difference_type block_size = get_block_ssize();
  566. BOOST_ASSERT(block_size);
  567. if (offset >= 0 && offset < block_size)
  568. this->m_cur += difference_type(n);
  569. else {
  570. const difference_type node_offset =
  571. offset > 0 ? (offset / block_size)
  572. : (-difference_type((-offset - 1) / block_size) - 1);
  573. this->m_node += node_offset;
  574. this->m_cur = this->get_first() + (offset - node_offset * block_size);
  575. }
  576. return *this;
  577. }
  578. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  579. deque_iterator operator+(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
  580. { deque_iterator tmp(*this); return tmp += n; }
  581. inline
  582. deque_iterator& operator-=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
  583. { return *this += -n; }
  584. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  585. deque_iterator operator-(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
  586. { deque_iterator tmp(*this); return tmp -= n; }
  587. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  588. reference operator[](difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
  589. {
  590. BOOST_ASSERT(!!m_cur);
  591. const difference_type offset = n + (this->m_cur - this->get_first());
  592. const difference_type block_size = get_block_ssize();
  593. if (offset >= 0 && offset < block_size)
  594. return this->m_cur[difference_type(n)];
  595. else {
  596. const difference_type node_offset = offset > 0
  597. ? (offset / block_size)
  598. : (-difference_type((-offset - 1) / block_size) - 1);
  599. return (this->m_node[node_offset]) [offset - node_offset * block_size];
  600. }
  601. }
  602. //Comparisons
  603. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  604. friend bool operator==(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  605. { return l.m_cur == r.m_cur; }
  606. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  607. friend bool operator!=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  608. { return l.m_cur != r.m_cur; }
  609. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  610. friend bool operator<(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  611. { return (l.m_node == r.m_node) ? (l.m_cur < r.m_cur) : (l.m_node < r.m_node); }
  612. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  613. friend bool operator>(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  614. { return r < l; }
  615. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  616. friend bool operator<=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  617. { return !(r < l); }
  618. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  619. friend bool operator>=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  620. { return !(l < r); }
  621. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  622. friend deque_iterator operator+(difference_type n, deque_iterator x) BOOST_NOEXCEPT_OR_NOTHROW
  623. { return x += n; }
  624. inline void priv_set_node(index_pointer new_node, size_type ) BOOST_NOEXCEPT_OR_NOTHROW
  625. { return this->priv_set_node(new_node, difference_type()); }
  626. inline void priv_set_node(index_pointer new_node, difference_type) BOOST_NOEXCEPT_OR_NOTHROW
  627. {
  628. this->m_node = new_node;
  629. }
  630. };
  631. #else
  632. #error "Invalid BOOST_CONTAINER_DEQUE_LIGHTER_ITERATOR_LEVEL"
  633. #endif
  634. } //namespace dtl {
  635. template<class Options>
  636. struct get_deque_opt
  637. {
  638. typedef Options type;
  639. };
  640. template<>
  641. struct get_deque_opt<void>
  642. {
  643. typedef deque_null_opt type;
  644. };
  645. // Deque base class. It has two purposes. First, its constructor
  646. // and destructor allocate (but don't initialize) storage. This makes
  647. // exception safety easier.
  648. template <class Allocator, class Options>
  649. class deque_base
  650. {
  651. BOOST_COPYABLE_AND_MOVABLE(deque_base)
  652. public:
  653. typedef allocator_traits<Allocator> val_alloc_traits_type;
  654. typedef typename val_alloc_traits_type::value_type val_alloc_val;
  655. typedef typename val_alloc_traits_type::pointer val_alloc_ptr;
  656. typedef typename val_alloc_traits_type::const_pointer val_alloc_cptr;
  657. typedef typename val_alloc_traits_type::reference val_alloc_ref;
  658. typedef typename val_alloc_traits_type::const_reference val_alloc_cref;
  659. typedef typename val_alloc_traits_type::difference_type val_alloc_diff;
  660. typedef typename val_alloc_traits_type::size_type val_alloc_size;
  661. typedef typename val_alloc_traits_type::template
  662. portable_rebind_alloc<val_alloc_ptr>::type ptr_alloc_t;
  663. typedef allocator_traits<ptr_alloc_t> ptr_alloc_traits_type;
  664. typedef typename ptr_alloc_traits_type::value_type ptr_alloc_val;
  665. typedef typename ptr_alloc_traits_type::pointer ptr_alloc_ptr;
  666. typedef typename ptr_alloc_traits_type::const_pointer ptr_alloc_cptr;
  667. typedef typename ptr_alloc_traits_type::reference ptr_alloc_ref;
  668. typedef typename ptr_alloc_traits_type::const_reference ptr_alloc_cref;
  669. typedef Allocator allocator_type;
  670. typedef allocator_type stored_allocator_type;
  671. typedef val_alloc_size size_type;
  672. typedef val_alloc_diff difference_type;
  673. private:
  674. typedef typename get_deque_opt<Options>::type options_type;
  675. protected:
  676. #if BOOST_CONTAINER_DEQUE_LIGHTER_ITERATOR_LEVEL == 0
  677. typedef dtl::deque_iterator<val_alloc_ptr, false> iterator;
  678. typedef dtl::deque_iterator<val_alloc_ptr, true> const_iterator;
  679. #else
  680. typedef dtl::deque_iterator<val_alloc_ptr, false, options_type::block_bytes, options_type::block_size> iterator;
  681. typedef dtl::deque_iterator<val_alloc_ptr, true, options_type::block_bytes, options_type::block_size> const_iterator;
  682. #endif
  683. BOOST_CONSTEXPR inline static val_alloc_diff get_block_ssize() BOOST_NOEXCEPT_OR_NOTHROW
  684. { return val_alloc_diff((get_block_size())); }
  685. BOOST_CONSTEXPR inline static size_type get_block_size() BOOST_NOEXCEPT_OR_NOTHROW
  686. { return deque_block_size<val_alloc_val, options_type::block_bytes, options_type::block_size>::value; }
  687. typedef deque_value_traits<val_alloc_val> traits_t;
  688. typedef ptr_alloc_t map_allocator_type;
  689. inline val_alloc_ptr priv_allocate_node()
  690. { return this->alloc().allocate(get_block_size()); }
  691. inline void priv_deallocate_node(val_alloc_ptr p) BOOST_NOEXCEPT_OR_NOTHROW
  692. { this->alloc().deallocate(p, get_block_size()); }
  693. inline ptr_alloc_ptr priv_allocate_map(size_type n)
  694. { return this->ptr_alloc().allocate(n); }
  695. inline void priv_deallocate_map(ptr_alloc_ptr p, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
  696. { this->ptr_alloc().deallocate(p, n); }
  697. inline deque_base(size_type num_elements, const allocator_type& a)
  698. : members_(a)
  699. { this->priv_initialize_map(num_elements); }
  700. inline explicit deque_base(const allocator_type& a)
  701. : members_(a)
  702. {}
  703. inline deque_base()
  704. : members_()
  705. {}
  706. inline explicit deque_base(BOOST_RV_REF(deque_base) x)
  707. : members_( boost::move(x.ptr_alloc())
  708. , boost::move(x.alloc()) )
  709. {}
  710. ~deque_base()
  711. {
  712. if (this->members_.m_map) {
  713. this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1);
  714. this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
  715. }
  716. }
  717. private:
  718. deque_base(const deque_base&);
  719. protected:
  720. void swap_members(deque_base &x) BOOST_NOEXCEPT_OR_NOTHROW
  721. {
  722. ::boost::adl_move_swap(this->members_.m_start, x.members_.m_start);
  723. ::boost::adl_move_swap(this->members_.m_finish, x.members_.m_finish);
  724. ::boost::adl_move_swap(this->members_.m_map, x.members_.m_map);
  725. ::boost::adl_move_swap(this->members_.m_map_size, x.members_.m_map_size);
  726. }
  727. void priv_initialize_map(size_type num_elements)
  728. {
  729. // if(num_elements){
  730. size_type num_nodes = num_elements / get_block_size() + 1;
  731. this->members_.m_map_size = dtl::max_value((size_type) InitialMapSize, num_nodes + 2);
  732. this->members_.m_map = this->priv_allocate_map(this->members_.m_map_size);
  733. ptr_alloc_ptr nstart = this->members_.m_map + difference_type(this->members_.m_map_size - num_nodes) / 2;
  734. ptr_alloc_ptr nfinish = nstart + difference_type(num_nodes);
  735. BOOST_CONTAINER_TRY {
  736. this->priv_create_nodes(nstart, nfinish);
  737. }
  738. BOOST_CONTAINER_CATCH(...){
  739. this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
  740. this->members_.m_map = 0;
  741. this->members_.m_map_size = 0;
  742. BOOST_CONTAINER_RETHROW
  743. }
  744. BOOST_CONTAINER_CATCH_END
  745. this->members_.m_start.priv_set_node(nstart, get_block_size());
  746. this->members_.m_finish.priv_set_node(nfinish - 1, get_block_size());
  747. this->members_.m_start.m_cur = this->members_.m_start.get_first();
  748. this->members_.m_finish.m_cur = this->members_.m_finish.get_first() + difference_type(num_elements % get_block_size());
  749. // }
  750. }
  751. void priv_create_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish)
  752. {
  753. ptr_alloc_ptr cur = nstart;
  754. BOOST_CONTAINER_TRY {
  755. for (; cur < nfinish; ++cur)
  756. *cur = this->priv_allocate_node();
  757. }
  758. BOOST_CONTAINER_CATCH(...){
  759. this->priv_destroy_nodes(nstart, cur);
  760. BOOST_CONTAINER_RETHROW
  761. }
  762. BOOST_CONTAINER_CATCH_END
  763. }
  764. void priv_destroy_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish) BOOST_NOEXCEPT_OR_NOTHROW
  765. {
  766. for (ptr_alloc_ptr n = nstart; n < nfinish; ++n)
  767. this->priv_deallocate_node(*n);
  768. }
  769. void priv_clear_map() BOOST_NOEXCEPT_OR_NOTHROW
  770. {
  771. if (this->members_.m_map) {
  772. this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1);
  773. this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
  774. this->members_.m_map = 0;
  775. this->members_.m_map_size = 0;
  776. this->members_.m_start = iterator();
  777. this->members_.m_finish = this->members_.m_start;
  778. }
  779. }
  780. enum { InitialMapSize = 8 };
  781. protected:
  782. struct members_holder
  783. : public ptr_alloc_t
  784. , public allocator_type
  785. {
  786. members_holder()
  787. : map_allocator_type(), allocator_type()
  788. , m_map(0), m_map_size(0)
  789. , m_start(), m_finish(m_start)
  790. {}
  791. explicit members_holder(const allocator_type &a)
  792. : map_allocator_type(a), allocator_type(a)
  793. , m_map(0), m_map_size(0)
  794. , m_start(), m_finish(m_start)
  795. {}
  796. template<class ValAllocConvertible, class PtrAllocConvertible>
  797. members_holder(BOOST_FWD_REF(PtrAllocConvertible) pa, BOOST_FWD_REF(ValAllocConvertible) va)
  798. : map_allocator_type(boost::forward<PtrAllocConvertible>(pa))
  799. , allocator_type (boost::forward<ValAllocConvertible>(va))
  800. , m_map(0), m_map_size(0)
  801. , m_start(), m_finish(m_start)
  802. {}
  803. ptr_alloc_ptr m_map;
  804. val_alloc_size m_map_size;
  805. iterator m_start;
  806. iterator m_finish;
  807. } members_;
  808. inline ptr_alloc_t &ptr_alloc() BOOST_NOEXCEPT_OR_NOTHROW
  809. { return members_; }
  810. inline const ptr_alloc_t &ptr_alloc() const BOOST_NOEXCEPT_OR_NOTHROW
  811. { return members_; }
  812. inline allocator_type &alloc() BOOST_NOEXCEPT_OR_NOTHROW
  813. { return members_; }
  814. inline const allocator_type &alloc() const BOOST_NOEXCEPT_OR_NOTHROW
  815. { return members_; }
  816. };
  817. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  818. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
  819. //! A double-ended queue is a sequence that supports random access to elements, constant time insertion
  820. //! and removal of elements at the end of the sequence, and linear time insertion and removal of elements in the middle.
  821. //!
  822. //! \tparam T The type of object that is stored in the deque
  823. //! \tparam A The allocator used for all internal memory management, use void
  824. //! for the default allocator
  825. //! \tparam Options A type produced from \c boost::container::deque_options.
  826. template <class T, class Allocator = void, class Options = void>
  827. #else
  828. template <class T, class Allocator, class Options>
  829. #endif
  830. class deque : protected deque_base<typename real_allocator<T, Allocator>::type, Options>
  831. {
  832. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  833. private:
  834. typedef deque_base<typename real_allocator<T, Allocator>::type, Options> Base;
  835. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  836. typedef typename real_allocator<T, Allocator>::type ValAllocator;
  837. typedef constant_iterator<T> c_it;
  838. public:
  839. //////////////////////////////////////////////
  840. //
  841. // types
  842. //
  843. //////////////////////////////////////////////
  844. typedef T value_type;
  845. typedef ValAllocator allocator_type;
  846. typedef typename ::boost::container::allocator_traits<ValAllocator>::pointer pointer;
  847. typedef typename ::boost::container::allocator_traits<ValAllocator>::const_pointer const_pointer;
  848. typedef typename ::boost::container::allocator_traits<ValAllocator>::reference reference;
  849. typedef typename ::boost::container::allocator_traits<ValAllocator>::const_reference const_reference;
  850. typedef typename ::boost::container::allocator_traits<ValAllocator>::size_type size_type;
  851. typedef typename ::boost::container::allocator_traits<ValAllocator>::difference_type difference_type;
  852. typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type;
  853. typedef BOOST_CONTAINER_IMPDEF(typename Base::iterator) iterator;
  854. typedef BOOST_CONTAINER_IMPDEF(typename Base::const_iterator) const_iterator;
  855. typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator;
  856. typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
  857. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  858. private: // Internal typedefs
  859. BOOST_COPYABLE_AND_MOVABLE(deque)
  860. typedef typename Base::ptr_alloc_ptr index_pointer;
  861. typedef allocator_traits<ValAllocator> allocator_traits_type;
  862. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  863. using Base::get_block_ssize;
  864. public:
  865. using Base::get_block_size;
  866. //////////////////////////////////////////////
  867. //
  868. // construct/copy/destroy
  869. //
  870. //////////////////////////////////////////////
  871. //! <b>Effects</b>: Default constructors a deque.
  872. //!
  873. //! <b>Throws</b>: If allocator_type's default constructor throws.
  874. //!
  875. //! <b>Complexity</b>: Constant.
  876. inline deque()
  877. BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<ValAllocator>::value)
  878. : Base()
  879. {}
  880. //! <b>Effects</b>: Constructs a deque taking the allocator as parameter.
  881. //!
  882. //! <b>Throws</b>: Nothing
  883. //!
  884. //! <b>Complexity</b>: Constant.
  885. inline explicit deque(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW
  886. : Base(a)
  887. {}
  888. //! <b>Effects</b>: Constructs a deque
  889. //! and inserts n value initialized values.
  890. //!
  891. //! <b>Throws</b>: If allocator_type's default constructor
  892. //! throws or T's value initialization throws.
  893. //!
  894. //! <b>Complexity</b>: Linear to n.
  895. inline explicit deque(size_type n)
  896. : Base(n, allocator_type())
  897. {
  898. dtl::insert_value_initialized_n_proxy<ValAllocator> proxy;
  899. proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
  900. //deque_base will deallocate in case of exception...
  901. }
  902. //! <b>Effects</b>: Constructs a deque
  903. //! and inserts n default initialized values.
  904. //!
  905. //! <b>Throws</b>: If allocator_type's default constructor
  906. //! throws or T's default initialization or copy constructor throws.
  907. //!
  908. //! <b>Complexity</b>: Linear to n.
  909. //!
  910. //! <b>Note</b>: Non-standard extension
  911. inline deque(size_type n, default_init_t)
  912. : Base(n, allocator_type())
  913. {
  914. dtl::insert_default_initialized_n_proxy<ValAllocator> proxy;
  915. proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
  916. //deque_base will deallocate in case of exception...
  917. }
  918. //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
  919. //! and inserts n value initialized values.
  920. //!
  921. //! <b>Throws</b>: If allocator_type's default constructor
  922. //! throws or T's value initialization throws.
  923. //!
  924. //! <b>Complexity</b>: Linear to n.
  925. inline explicit deque(size_type n, const allocator_type &a)
  926. : Base(n, a)
  927. {
  928. dtl::insert_value_initialized_n_proxy<ValAllocator> proxy;
  929. proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
  930. //deque_base will deallocate in case of exception...
  931. }
  932. //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
  933. //! and inserts n default initialized values.
  934. //!
  935. //! <b>Throws</b>: If allocator_type's default constructor
  936. //! throws or T's default initialization or copy constructor throws.
  937. //!
  938. //! <b>Complexity</b>: Linear to n.
  939. //!
  940. //! <b>Note</b>: Non-standard extension
  941. inline deque(size_type n, default_init_t, const allocator_type &a)
  942. : Base(n, a)
  943. {
  944. dtl::insert_default_initialized_n_proxy<ValAllocator> proxy;
  945. proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
  946. //deque_base will deallocate in case of exception...
  947. }
  948. //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
  949. //! and inserts n copies of value.
  950. //!
  951. //! <b>Throws</b>: If allocator_type's default constructor
  952. //! throws or T's copy constructor throws.
  953. //!
  954. //! <b>Complexity</b>: Linear to n.
  955. inline deque(size_type n, const value_type& value)
  956. : Base(n, allocator_type())
  957. { this->priv_fill_initialize(value); }
  958. //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
  959. //! and inserts n copies of value.
  960. //!
  961. //! <b>Throws</b>: If allocator_type's default constructor
  962. //! throws or T's copy constructor throws.
  963. //!
  964. //! <b>Complexity</b>: Linear to n.
  965. inline deque(size_type n, const value_type& value, const allocator_type& a)
  966. : Base(n, a)
  967. { this->priv_fill_initialize(value); }
  968. //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
  969. //! and inserts a copy of the range [first, last) in the deque.
  970. //!
  971. //! <b>Throws</b>: If allocator_type's default constructor
  972. //! throws or T's constructor taking a dereferenced InIt throws.
  973. //!
  974. //! <b>Complexity</b>: Linear to the range [first, last).
  975. template <class InIt>
  976. inline deque(InIt first, InIt last
  977. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  978. , typename dtl::disable_if_convertible
  979. <InIt, size_type>::type * = 0
  980. #endif
  981. )
  982. : Base(allocator_type())
  983. {
  984. this->priv_range_initialize(first, last);
  985. }
  986. //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
  987. //! and inserts a copy of the range [first, last) in the deque.
  988. //!
  989. //! <b>Throws</b>: If allocator_type's default constructor
  990. //! throws or T's constructor taking a dereferenced InIt throws.
  991. //!
  992. //! <b>Complexity</b>: Linear to the range [first, last).
  993. template <class InIt>
  994. inline deque(InIt first, InIt last, const allocator_type& a
  995. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  996. , typename dtl::disable_if_convertible
  997. <InIt, size_type>::type * = 0
  998. #endif
  999. )
  1000. : Base(a)
  1001. {
  1002. this->priv_range_initialize(first, last);
  1003. }
  1004. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  1005. //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
  1006. //! and inserts a copy of the range [il.begin(), il.end()) in the deque.
  1007. //!
  1008. //! <b>Throws</b>: If allocator_type's default constructor
  1009. //! throws or T's constructor taking a dereferenced std::initializer_list iterator throws.
  1010. //!
  1011. //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
  1012. inline deque(std::initializer_list<value_type> il, const allocator_type& a = allocator_type())
  1013. : Base(a)
  1014. {
  1015. this->priv_range_initialize(il.begin(), il.end());
  1016. }
  1017. #endif
  1018. //! <b>Effects</b>: Copy constructs a deque.
  1019. //!
  1020. //! <b>Postcondition</b>: x == *this.
  1021. //!
  1022. //! <b>Complexity</b>: Linear to the elements x contains.
  1023. inline deque(const deque& x)
  1024. : Base(allocator_traits_type::select_on_container_copy_construction(x.alloc()))
  1025. {
  1026. if(x.size()){
  1027. this->priv_initialize_map(x.size());
  1028. boost::container::uninitialized_copy_alloc
  1029. (this->alloc(), x.begin(), x.end(), this->members_.m_start);
  1030. }
  1031. }
  1032. //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
  1033. //!
  1034. //! <b>Throws</b>: If allocator_type's copy constructor throws.
  1035. //!
  1036. //! <b>Complexity</b>: Constant.
  1037. inline deque(BOOST_RV_REF(deque) x) BOOST_NOEXCEPT_OR_NOTHROW
  1038. : Base(BOOST_MOVE_BASE(Base, x))
  1039. { this->swap_members(x); }
  1040. //! <b>Effects</b>: Copy constructs a vector using the specified allocator.
  1041. //!
  1042. //! <b>Postcondition</b>: x == *this.
  1043. //!
  1044. //! <b>Throws</b>: If allocation
  1045. //! throws or T's copy constructor throws.
  1046. //!
  1047. //! <b>Complexity</b>: Linear to the elements x contains.
  1048. deque(const deque& x, const allocator_type &a)
  1049. : Base(a)
  1050. {
  1051. if(x.size()){
  1052. this->priv_initialize_map(x.size());
  1053. boost::container::uninitialized_copy_alloc
  1054. (this->alloc(), x.begin(), x.end(), this->members_.m_start);
  1055. }
  1056. }
  1057. //! <b>Effects</b>: Move constructor using the specified allocator.
  1058. //! Moves x's resources to *this if a == allocator_type().
  1059. //! Otherwise copies values from x to *this.
  1060. //!
  1061. //! <b>Throws</b>: If allocation or T's copy constructor throws.
  1062. //!
  1063. //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
  1064. deque(BOOST_RV_REF(deque) x, const allocator_type &a)
  1065. : Base(a)
  1066. {
  1067. if(x.alloc() == a){
  1068. this->swap_members(x);
  1069. }
  1070. else{
  1071. if(x.size()){
  1072. this->priv_initialize_map(x.size());
  1073. boost::container::uninitialized_copy_alloc
  1074. ( this->alloc(), boost::make_move_iterator(x.begin())
  1075. , boost::make_move_iterator(x.end()), this->members_.m_start);
  1076. }
  1077. }
  1078. }
  1079. //! <b>Effects</b>: Destroys the deque. All stored values are destroyed
  1080. //! and used memory is deallocated.
  1081. //!
  1082. //! <b>Throws</b>: Nothing.
  1083. //!
  1084. //! <b>Complexity</b>: Linear to the number of elements.
  1085. inline ~deque() BOOST_NOEXCEPT_OR_NOTHROW
  1086. {
  1087. this->priv_destroy_range(this->members_.m_start, this->members_.m_finish);
  1088. }
  1089. //! <b>Effects</b>: Makes *this contain the same elements as x.
  1090. //!
  1091. //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
  1092. //! of each of x's elements.
  1093. //!
  1094. //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
  1095. //!
  1096. //! <b>Complexity</b>: Linear to the number of elements in x.
  1097. deque& operator= (BOOST_COPY_ASSIGN_REF(deque) x)
  1098. {
  1099. if (BOOST_LIKELY(&x != this)){
  1100. allocator_type &this_alloc = this->alloc();
  1101. const allocator_type &x_alloc = x.alloc();
  1102. dtl::bool_<allocator_traits_type::
  1103. propagate_on_container_copy_assignment::value> flag;
  1104. if(flag && this_alloc != x_alloc){
  1105. this->clear();
  1106. this->shrink_to_fit();
  1107. }
  1108. dtl::assign_alloc(this->alloc(), x.alloc(), flag);
  1109. dtl::assign_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
  1110. this->assign(x.cbegin(), x.cend());
  1111. }
  1112. return *this;
  1113. }
  1114. //! <b>Effects</b>: Move assignment. All x's values are transferred to *this.
  1115. //!
  1116. //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
  1117. //! is false and (allocation throws or value_type's move constructor throws)
  1118. //!
  1119. //! <b>Complexity</b>: Constant if allocator_traits_type::
  1120. //! propagate_on_container_move_assignment is true or
  1121. //! this->get>allocator() == x.get_allocator(). Linear otherwise.
  1122. deque& operator= (BOOST_RV_REF(deque) x)
  1123. BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
  1124. || allocator_traits_type::is_always_equal::value)
  1125. {
  1126. if (BOOST_LIKELY(this != &x)) {
  1127. //We know resources can be transferred at comiple time if both allocators are
  1128. //always equal or the allocator is going to be propagated
  1129. const bool can_steal_resources_alloc
  1130. = allocator_traits_type::propagate_on_container_move_assignment::value
  1131. || allocator_traits_type::is_always_equal::value;
  1132. dtl::bool_<can_steal_resources_alloc> flag;
  1133. this->priv_move_assign(boost::move(x), flag);
  1134. }
  1135. return *this;
  1136. }
  1137. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  1138. //! <b>Effects</b>: Makes *this contain the same elements as il.
  1139. //!
  1140. //! <b>Postcondition</b>: this->size() == il.size(). *this contains a copy
  1141. //! of each of x's elements.
  1142. //!
  1143. //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
  1144. //!
  1145. //! <b>Complexity</b>: Linear to the number of elements in il.
  1146. inline deque& operator=(std::initializer_list<value_type> il)
  1147. {
  1148. this->assign(il.begin(), il.end());
  1149. return *this;
  1150. }
  1151. #endif
  1152. //! <b>Effects</b>: Assigns the n copies of val to *this.
  1153. //!
  1154. //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
  1155. //!
  1156. //! <b>Complexity</b>: Linear to n.
  1157. inline void assign(size_type n, const T& val)
  1158. {
  1159. this->assign(c_it(val, n), c_it());
  1160. }
  1161. //! <b>Effects</b>: Assigns the the range [first, last) to *this.
  1162. //!
  1163. //! <b>Throws</b>: If memory allocation throws or
  1164. //! T's constructor from dereferencing InIt throws.
  1165. //!
  1166. //! <b>Complexity</b>: Linear to n.
  1167. template <class InIt>
  1168. void assign(InIt first, InIt last
  1169. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1170. , typename dtl::disable_if_or
  1171. < void
  1172. , dtl::is_convertible<InIt, size_type>
  1173. , dtl::is_not_input_iterator<InIt>
  1174. >::type * = 0
  1175. #endif
  1176. )
  1177. {
  1178. iterator cur = this->begin();
  1179. for ( ; first != last && cur != end(); ++cur, ++first){
  1180. *cur = *first;
  1181. }
  1182. if (first == last){
  1183. this->erase(cur, this->cend());
  1184. }
  1185. else{
  1186. this->insert(this->cend(), first, last);
  1187. }
  1188. }
  1189. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1190. template <class FwdIt>
  1191. void assign(FwdIt first, FwdIt last
  1192. , typename dtl::disable_if_or
  1193. < void
  1194. , dtl::is_convertible<FwdIt, size_type>
  1195. , dtl::is_input_iterator<FwdIt>
  1196. >::type * = 0
  1197. )
  1198. {
  1199. const size_type len = boost::container::iterator_udistance(first, last);
  1200. if (len > size()) {
  1201. FwdIt mid = first;
  1202. boost::container::iterator_uadvance(mid, this->size());
  1203. boost::container::copy(first, mid, begin());
  1204. this->insert(this->cend(), mid, last);
  1205. }
  1206. else{
  1207. this->erase(boost::container::copy(first, last, this->begin()), cend());
  1208. }
  1209. }
  1210. #endif
  1211. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  1212. //! <b>Effects</b>: Assigns the the range [il.begin(), il.end()) to *this.
  1213. //!
  1214. //! <b>Throws</b>: If memory allocation throws or
  1215. //! T's constructor from dereferencing std::initializer_list iterator throws.
  1216. //!
  1217. //! <b>Complexity</b>: Linear to il.size().
  1218. inline void assign(std::initializer_list<value_type> il)
  1219. { this->assign(il.begin(), il.end()); }
  1220. #endif
  1221. //! <b>Effects</b>: Returns a copy of the internal allocator.
  1222. //!
  1223. //! <b>Throws</b>: If allocator's copy constructor throws.
  1224. //!
  1225. //! <b>Complexity</b>: Constant.
  1226. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1227. allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
  1228. { return Base::alloc(); }
  1229. //! <b>Effects</b>: Returns a reference to the internal allocator.
  1230. //!
  1231. //! <b>Throws</b>: Nothing
  1232. //!
  1233. //! <b>Complexity</b>: Constant.
  1234. //!
  1235. //! <b>Note</b>: Non-standard extension.
  1236. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1237. const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
  1238. { return Base::alloc(); }
  1239. //////////////////////////////////////////////
  1240. //
  1241. // iterators
  1242. //
  1243. //////////////////////////////////////////////
  1244. //! <b>Effects</b>: Returns a reference to the internal allocator.
  1245. //!
  1246. //! <b>Throws</b>: Nothing
  1247. //!
  1248. //! <b>Complexity</b>: Constant.
  1249. //!
  1250. //! <b>Note</b>: Non-standard extension.
  1251. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1252. stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
  1253. { return Base::alloc(); }
  1254. //! <b>Effects</b>: Returns an iterator to the first element contained in the deque.
  1255. //!
  1256. //! <b>Throws</b>: Nothing.
  1257. //!
  1258. //! <b>Complexity</b>: Constant.
  1259. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1260. iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
  1261. { return this->members_.m_start; }
  1262. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the deque.
  1263. //!
  1264. //! <b>Throws</b>: Nothing.
  1265. //!
  1266. //! <b>Complexity</b>: Constant.
  1267. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1268. const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
  1269. { return this->members_.m_start; }
  1270. //! <b>Effects</b>: Returns an iterator to the end of the deque.
  1271. //!
  1272. //! <b>Throws</b>: Nothing.
  1273. //!
  1274. //! <b>Complexity</b>: Constant.
  1275. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1276. iterator end() BOOST_NOEXCEPT_OR_NOTHROW
  1277. { return this->members_.m_finish; }
  1278. //! <b>Effects</b>: Returns a const_iterator to the end of the deque.
  1279. //!
  1280. //! <b>Throws</b>: Nothing.
  1281. //!
  1282. //! <b>Complexity</b>: Constant.
  1283. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1284. const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
  1285. { return this->members_.m_finish; }
  1286. //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
  1287. //! of the reversed deque.
  1288. //!
  1289. //! <b>Throws</b>: Nothing.
  1290. //!
  1291. //! <b>Complexity</b>: Constant.
  1292. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1293. reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
  1294. { return reverse_iterator(this->members_.m_finish); }
  1295. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
  1296. //! of the reversed deque.
  1297. //!
  1298. //! <b>Throws</b>: Nothing.
  1299. //!
  1300. //! <b>Complexity</b>: Constant.
  1301. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1302. const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
  1303. { return const_reverse_iterator(this->members_.m_finish); }
  1304. //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
  1305. //! of the reversed deque.
  1306. //!
  1307. //! <b>Throws</b>: Nothing.
  1308. //!
  1309. //! <b>Complexity</b>: Constant.
  1310. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1311. reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
  1312. { return reverse_iterator(this->members_.m_start); }
  1313. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
  1314. //! of the reversed deque.
  1315. //!
  1316. //! <b>Throws</b>: Nothing.
  1317. //!
  1318. //! <b>Complexity</b>: Constant.
  1319. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1320. const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
  1321. { return const_reverse_iterator(this->members_.m_start); }
  1322. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the deque.
  1323. //!
  1324. //! <b>Throws</b>: Nothing.
  1325. //!
  1326. //! <b>Complexity</b>: Constant.
  1327. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1328. const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
  1329. { return this->members_.m_start; }
  1330. //! <b>Effects</b>: Returns a const_iterator to the end of the deque.
  1331. //!
  1332. //! <b>Throws</b>: Nothing.
  1333. //!
  1334. //! <b>Complexity</b>: Constant.
  1335. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1336. const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
  1337. { return this->members_.m_finish; }
  1338. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
  1339. //! of the reversed deque.
  1340. //!
  1341. //! <b>Throws</b>: Nothing.
  1342. //!
  1343. //! <b>Complexity</b>: Constant.
  1344. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1345. const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
  1346. { return const_reverse_iterator(this->members_.m_finish); }
  1347. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
  1348. //! of the reversed deque.
  1349. //!
  1350. //! <b>Throws</b>: Nothing.
  1351. //!
  1352. //! <b>Complexity</b>: Constant.
  1353. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1354. const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
  1355. { return const_reverse_iterator(this->members_.m_start); }
  1356. //////////////////////////////////////////////
  1357. //
  1358. // capacity
  1359. //
  1360. //////////////////////////////////////////////
  1361. //! <b>Effects</b>: Returns true if the deque contains no elements.
  1362. //!
  1363. //! <b>Throws</b>: Nothing.
  1364. //!
  1365. //! <b>Complexity</b>: Constant.
  1366. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1367. bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
  1368. { return this->members_.m_finish == this->members_.m_start; }
  1369. //! <b>Effects</b>: Returns the number of the elements contained in the deque.
  1370. //!
  1371. //! <b>Throws</b>: Nothing.
  1372. //!
  1373. //! <b>Complexity</b>: Constant.
  1374. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1375. size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
  1376. { return size_type(this->members_.m_finish - this->members_.m_start); }
  1377. //! <b>Effects</b>: Returns the largest possible size of the deque.
  1378. //!
  1379. //! <b>Throws</b>: Nothing.
  1380. //!
  1381. //! <b>Complexity</b>: Constant.
  1382. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1383. size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
  1384. { return allocator_traits_type::max_size(this->alloc()); }
  1385. //! <b>Effects</b>: Inserts or erases elements at the end such that
  1386. //! the size becomes n. New elements are value initialized.
  1387. //!
  1388. //! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
  1389. //!
  1390. //! <b>Complexity</b>: Linear to the difference between size() and new_size.
  1391. void resize(size_type new_size)
  1392. {
  1393. const size_type len = size();
  1394. if (new_size < len)
  1395. this->priv_erase_last_n(len - new_size);
  1396. else{
  1397. const size_type n = new_size - this->size();
  1398. dtl::insert_value_initialized_n_proxy<ValAllocator> proxy;
  1399. priv_insert_back_aux_impl(n, proxy);
  1400. }
  1401. }
  1402. //! <b>Effects</b>: Inserts or erases elements at the end such that
  1403. //! the size becomes n. New elements are default initialized.
  1404. //!
  1405. //! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
  1406. //!
  1407. //! <b>Complexity</b>: Linear to the difference between size() and new_size.
  1408. //!
  1409. //! <b>Note</b>: Non-standard extension
  1410. void resize(size_type new_size, default_init_t)
  1411. {
  1412. const size_type len = size();
  1413. if (new_size < len)
  1414. this->priv_erase_last_n(len - new_size);
  1415. else{
  1416. const size_type n = new_size - this->size();
  1417. dtl::insert_default_initialized_n_proxy<ValAllocator> proxy;
  1418. priv_insert_back_aux_impl(n, proxy);
  1419. }
  1420. }
  1421. //! <b>Effects</b>: Inserts or erases elements at the end such that
  1422. //! the size becomes n. New elements are copy constructed from x.
  1423. //!
  1424. //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
  1425. //!
  1426. //! <b>Complexity</b>: Linear to the difference between size() and new_size.
  1427. void resize(size_type new_size, const value_type& x)
  1428. {
  1429. const size_type len = size();
  1430. if (new_size < len)
  1431. this->erase(this->members_.m_start + difference_type(new_size), this->members_.m_finish);
  1432. else
  1433. this->insert(this->members_.m_finish, new_size - len, x);
  1434. }
  1435. //! <b>Effects</b>: Tries to deallocate the excess of memory created
  1436. //! with previous allocations. The size of the deque is unchanged
  1437. //!
  1438. //! <b>Throws</b>: If memory allocation throws.
  1439. //!
  1440. //! <b>Complexity</b>: Constant.
  1441. void shrink_to_fit()
  1442. {
  1443. //This deque implementation already
  1444. //deallocates excess nodes when erasing
  1445. //so there is nothing to do except for
  1446. //empty deque
  1447. if(this->empty()){
  1448. this->priv_clear_map();
  1449. }
  1450. }
  1451. //////////////////////////////////////////////
  1452. //
  1453. // element access
  1454. //
  1455. //////////////////////////////////////////////
  1456. //! <b>Requires</b>: !empty()
  1457. //!
  1458. //! <b>Effects</b>: Returns a reference to the first
  1459. //! element of the container.
  1460. //!
  1461. //! <b>Throws</b>: Nothing.
  1462. //!
  1463. //! <b>Complexity</b>: Constant.
  1464. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1465. reference front() BOOST_NOEXCEPT_OR_NOTHROW
  1466. {
  1467. BOOST_ASSERT(!this->empty());
  1468. return *this->members_.m_start;
  1469. }
  1470. //! <b>Requires</b>: !empty()
  1471. //!
  1472. //! <b>Effects</b>: Returns a const reference to the first element
  1473. //! from the beginning of the container.
  1474. //!
  1475. //! <b>Throws</b>: Nothing.
  1476. //!
  1477. //! <b>Complexity</b>: Constant.
  1478. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1479. const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
  1480. {
  1481. BOOST_ASSERT(!this->empty());
  1482. return *this->members_.m_start;
  1483. }
  1484. //! <b>Requires</b>: !empty()
  1485. //!
  1486. //! <b>Effects</b>: Returns a reference to the last
  1487. //! element of the container.
  1488. //!
  1489. //! <b>Throws</b>: Nothing.
  1490. //!
  1491. //! <b>Complexity</b>: Constant.
  1492. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1493. reference back() BOOST_NOEXCEPT_OR_NOTHROW
  1494. {
  1495. BOOST_ASSERT(!this->empty());
  1496. return *(end()-1);
  1497. }
  1498. //! <b>Requires</b>: !empty()
  1499. //!
  1500. //! <b>Effects</b>: Returns a const reference to the last
  1501. //! element of the container.
  1502. //!
  1503. //! <b>Throws</b>: Nothing.
  1504. //!
  1505. //! <b>Complexity</b>: Constant.
  1506. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1507. const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
  1508. {
  1509. BOOST_ASSERT(!this->empty());
  1510. return *(cend()-1);
  1511. }
  1512. //! <b>Requires</b>: size() > n.
  1513. //!
  1514. //! <b>Effects</b>: Returns a reference to the nth element
  1515. //! from the beginning of the container.
  1516. //!
  1517. //! <b>Throws</b>: Nothing.
  1518. //!
  1519. //! <b>Complexity</b>: Constant.
  1520. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1521. reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
  1522. {
  1523. BOOST_ASSERT(this->size() > n);
  1524. return this->members_.m_start[difference_type(n)];
  1525. }
  1526. //! <b>Requires</b>: size() > n.
  1527. //!
  1528. //! <b>Effects</b>: Returns a const reference to the nth element
  1529. //! from the beginning of the container.
  1530. //!
  1531. //! <b>Throws</b>: Nothing.
  1532. //!
  1533. //! <b>Complexity</b>: Constant.
  1534. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1535. const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
  1536. {
  1537. BOOST_ASSERT(this->size() > n);
  1538. return this->members_.m_start[difference_type(n)];
  1539. }
  1540. //! <b>Requires</b>: size() >= n.
  1541. //!
  1542. //! <b>Effects</b>: Returns an iterator to the nth element
  1543. //! from the beginning of the container. Returns end()
  1544. //! if n == size().
  1545. //!
  1546. //! <b>Throws</b>: Nothing.
  1547. //!
  1548. //! <b>Complexity</b>: Constant.
  1549. //!
  1550. //! <b>Note</b>: Non-standard extension
  1551. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1552. iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
  1553. {
  1554. BOOST_ASSERT(this->size() >= n);
  1555. return iterator(this->begin()+difference_type(n));
  1556. }
  1557. //! <b>Requires</b>: size() >= n.
  1558. //!
  1559. //! <b>Effects</b>: Returns a const_iterator to the nth element
  1560. //! from the beginning of the container. Returns end()
  1561. //! if n == size().
  1562. //!
  1563. //! <b>Throws</b>: Nothing.
  1564. //!
  1565. //! <b>Complexity</b>: Constant.
  1566. //!
  1567. //! <b>Note</b>: Non-standard extension
  1568. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1569. const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
  1570. {
  1571. BOOST_ASSERT(this->size() >= n);
  1572. return const_iterator(this->cbegin()+difference_type(n));
  1573. }
  1574. //! <b>Requires</b>: begin() <= p <= end().
  1575. //!
  1576. //! <b>Effects</b>: Returns the index of the element pointed by p
  1577. //! and size() if p == end().
  1578. //!
  1579. //! <b>Throws</b>: Nothing.
  1580. //!
  1581. //! <b>Complexity</b>: Constant.
  1582. //!
  1583. //! <b>Note</b>: Non-standard extension
  1584. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1585. size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
  1586. {
  1587. //Range checked priv_index_of
  1588. return this->priv_index_of(p);
  1589. }
  1590. //! <b>Requires</b>: begin() <= p <= end().
  1591. //!
  1592. //! <b>Effects</b>: Returns the index of the element pointed by p
  1593. //! and size() if p == end().
  1594. //!
  1595. //! <b>Throws</b>: Nothing.
  1596. //!
  1597. //! <b>Complexity</b>: Constant.
  1598. //!
  1599. //! <b>Note</b>: Non-standard extension
  1600. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1601. size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
  1602. {
  1603. //Range checked priv_index_of
  1604. return this->priv_index_of(p);
  1605. }
  1606. //! <b>Requires</b>: size() > n.
  1607. //!
  1608. //! <b>Effects</b>: Returns a reference to the nth element
  1609. //! from the beginning of the container.
  1610. //!
  1611. //! <b>Throws</b>: range_error if n >= size()
  1612. //!
  1613. //! <b>Complexity</b>: Constant.
  1614. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1615. reference at(size_type n)
  1616. {
  1617. this->priv_throw_if_out_of_range(n);
  1618. return (*this)[n];
  1619. }
  1620. //! <b>Requires</b>: size() > n.
  1621. //!
  1622. //! <b>Effects</b>: Returns a const reference to the nth element
  1623. //! from the beginning of the container.
  1624. //!
  1625. //! <b>Throws</b>: range_error if n >= size()
  1626. //!
  1627. //! <b>Complexity</b>: Constant.
  1628. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  1629. const_reference at(size_type n) const
  1630. {
  1631. this->priv_throw_if_out_of_range(n);
  1632. return (*this)[n];
  1633. }
  1634. //////////////////////////////////////////////
  1635. //
  1636. // modifiers
  1637. //
  1638. //////////////////////////////////////////////
  1639. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1640. //! <b>Effects</b>: Inserts an object of type T constructed with
  1641. //! std::forward<Args>(args)... in the beginning of the deque.
  1642. //!
  1643. //! <b>Returns</b>: A reference to the created object.
  1644. //!
  1645. //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
  1646. //!
  1647. //! <b>Complexity</b>: Amortized constant time
  1648. template <class... Args>
  1649. reference emplace_front(BOOST_FWD_REF(Args)... args)
  1650. {
  1651. if(this->priv_push_front_simple_available()){
  1652. reference r = *this->priv_push_front_simple_pos();
  1653. allocator_traits_type::construct
  1654. ( this->alloc()
  1655. , this->priv_push_front_simple_pos()
  1656. , boost::forward<Args>(args)...);
  1657. this->priv_push_front_simple_commit();
  1658. return r;
  1659. }
  1660. else{
  1661. typedef dtl::insert_nonmovable_emplace_proxy<ValAllocator, Args...> type;
  1662. return *this->priv_insert_front_aux_impl(1, type(boost::forward<Args>(args)...));
  1663. }
  1664. }
  1665. //! <b>Effects</b>: Inserts an object of type T constructed with
  1666. //! std::forward<Args>(args)... in the end of the deque.
  1667. //!
  1668. //! <b>Returns</b>: A reference to the created object.
  1669. //!
  1670. //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
  1671. //!
  1672. //! <b>Complexity</b>: Amortized constant time
  1673. template <class... Args>
  1674. reference emplace_back(BOOST_FWD_REF(Args)... args)
  1675. {
  1676. if(this->priv_push_back_simple_available()){
  1677. reference r = *this->priv_push_back_simple_pos();
  1678. allocator_traits_type::construct
  1679. ( this->alloc()
  1680. , this->priv_push_back_simple_pos()
  1681. , boost::forward<Args>(args)...);
  1682. this->priv_push_back_simple_commit();
  1683. return r;
  1684. }
  1685. else{
  1686. typedef dtl::insert_nonmovable_emplace_proxy<ValAllocator, Args...> type;
  1687. return *this->priv_insert_back_aux_impl(1, type(boost::forward<Args>(args)...));
  1688. }
  1689. }
  1690. //! <b>Requires</b>: p must be a valid iterator of *this.
  1691. //!
  1692. //! <b>Effects</b>: Inserts an object of type T constructed with
  1693. //! std::forward<Args>(args)... before p
  1694. //!
  1695. //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
  1696. //!
  1697. //! <b>Complexity</b>: If p is end(), amortized constant time
  1698. //! Linear time otherwise.
  1699. template <class... Args>
  1700. iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args)
  1701. {
  1702. BOOST_ASSERT(this->priv_in_range_or_end(p));
  1703. if(p == this->cbegin()){
  1704. this->emplace_front(boost::forward<Args>(args)...);
  1705. return this->begin();
  1706. }
  1707. else if(p == this->cend()){
  1708. this->emplace_back(boost::forward<Args>(args)...);
  1709. return (this->end()-1);
  1710. }
  1711. else{
  1712. typedef dtl::insert_emplace_proxy<ValAllocator, Args...> type;
  1713. return this->priv_insert_aux_impl(p, 1, type(boost::forward<Args>(args)...));
  1714. }
  1715. }
  1716. #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  1717. #define BOOST_CONTAINER_DEQUE_EMPLACE_CODE(N) \
  1718. BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
  1719. reference emplace_front(BOOST_MOVE_UREF##N)\
  1720. {\
  1721. if(priv_push_front_simple_available()){\
  1722. reference r = *this->priv_push_front_simple_pos();\
  1723. allocator_traits_type::construct\
  1724. ( this->alloc(), this->priv_push_front_simple_pos() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
  1725. priv_push_front_simple_commit();\
  1726. return r;\
  1727. }\
  1728. else{\
  1729. typedef dtl::insert_nonmovable_emplace_proxy##N\
  1730. <ValAllocator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
  1731. return *priv_insert_front_aux_impl(1, type(BOOST_MOVE_FWD##N));\
  1732. }\
  1733. }\
  1734. \
  1735. BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
  1736. reference emplace_back(BOOST_MOVE_UREF##N)\
  1737. {\
  1738. if(priv_push_back_simple_available()){\
  1739. reference r = *this->priv_push_back_simple_pos();\
  1740. allocator_traits_type::construct\
  1741. ( this->alloc(), this->priv_push_back_simple_pos() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
  1742. priv_push_back_simple_commit();\
  1743. return r;\
  1744. }\
  1745. else{\
  1746. typedef dtl::insert_nonmovable_emplace_proxy##N\
  1747. <ValAllocator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
  1748. return *priv_insert_back_aux_impl(1, type(BOOST_MOVE_FWD##N));\
  1749. }\
  1750. }\
  1751. \
  1752. BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
  1753. iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
  1754. {\
  1755. BOOST_ASSERT(this->priv_in_range_or_end(p));\
  1756. if(p == this->cbegin()){\
  1757. this->emplace_front(BOOST_MOVE_FWD##N);\
  1758. return this->begin();\
  1759. }\
  1760. else if(p == cend()){\
  1761. this->emplace_back(BOOST_MOVE_FWD##N);\
  1762. return (--this->end());\
  1763. }\
  1764. else{\
  1765. typedef dtl::insert_emplace_proxy_arg##N\
  1766. <ValAllocator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
  1767. return this->priv_insert_aux_impl(p, 1, type(BOOST_MOVE_FWD##N));\
  1768. }\
  1769. }
  1770. //
  1771. BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEQUE_EMPLACE_CODE)
  1772. #undef BOOST_CONTAINER_DEQUE_EMPLACE_CODE
  1773. #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  1774. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1775. //! <b>Effects</b>: Inserts a copy of x at the front of the deque.
  1776. //!
  1777. //! <b>Throws</b>: If memory allocation throws or
  1778. //! T's copy constructor throws.
  1779. //!
  1780. //! <b>Complexity</b>: Amortized constant time.
  1781. void push_front(const T &x);
  1782. //! <b>Effects</b>: Constructs a new element in the front of the deque
  1783. //! and moves the resources of x to this new element.
  1784. //!
  1785. //! <b>Throws</b>: If memory allocation throws.
  1786. //!
  1787. //! <b>Complexity</b>: Amortized constant time.
  1788. void push_front(T &&x);
  1789. #else
  1790. BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
  1791. #endif
  1792. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1793. //! <b>Effects</b>: Inserts a copy of x at the end of the deque.
  1794. //!
  1795. //! <b>Throws</b>: If memory allocation throws or
  1796. //! T's copy constructor throws.
  1797. //!
  1798. //! <b>Complexity</b>: Amortized constant time.
  1799. void push_back(const T &x);
  1800. //! <b>Effects</b>: Constructs a new element in the end of the deque
  1801. //! and moves the resources of x to this new element.
  1802. //!
  1803. //! <b>Throws</b>: If memory allocation throws.
  1804. //!
  1805. //! <b>Complexity</b>: Amortized constant time.
  1806. void push_back(T &&x);
  1807. #else
  1808. BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
  1809. #endif
  1810. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1811. //! <b>Requires</b>: p must be a valid iterator of *this.
  1812. //!
  1813. //! <b>Effects</b>: Insert a copy of x before p.
  1814. //!
  1815. //! <b>Returns</b>: an iterator to the inserted element.
  1816. //!
  1817. //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
  1818. //!
  1819. //! <b>Complexity</b>: If p is end(), amortized constant time
  1820. //! Linear time otherwise.
  1821. iterator insert(const_iterator p, const T &x);
  1822. //! <b>Requires</b>: p must be a valid iterator of *this.
  1823. //!
  1824. //! <b>Effects</b>: Insert a new element before p with x's resources.
  1825. //!
  1826. //! <b>Returns</b>: an iterator to the inserted element.
  1827. //!
  1828. //! <b>Throws</b>: If memory allocation throws.
  1829. //!
  1830. //! <b>Complexity</b>: If p is end(), amortized constant time
  1831. //! Linear time otherwise.
  1832. iterator insert(const_iterator p, T &&x);
  1833. #else
  1834. BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
  1835. #endif
  1836. //! <b>Requires</b>: pos must be a valid iterator of *this.
  1837. //!
  1838. //! <b>Effects</b>: Insert n copies of x before pos.
  1839. //!
  1840. //! <b>Returns</b>: an iterator to the first inserted element or pos if n is 0.
  1841. //!
  1842. //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
  1843. //!
  1844. //! <b>Complexity</b>: Linear to n.
  1845. inline iterator insert(const_iterator pos, size_type n, const value_type& x)
  1846. {
  1847. //Range check of p is done by insert()
  1848. return this->insert(pos, c_it(x, n), c_it());
  1849. }
  1850. //! <b>Requires</b>: pos must be a valid iterator of *this.
  1851. //!
  1852. //! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
  1853. //!
  1854. //! <b>Returns</b>: an iterator to the first inserted element or pos if first == last.
  1855. //!
  1856. //! <b>Throws</b>: If memory allocation throws, T's constructor from a
  1857. //! dereferenced InIt throws or T's copy constructor throws.
  1858. //!
  1859. //! <b>Complexity</b>: Linear to distance [first, last).
  1860. template <class InIt>
  1861. iterator insert(const_iterator pos, InIt first, InIt last
  1862. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1863. , typename dtl::disable_if_or
  1864. < void
  1865. , dtl::is_convertible<InIt, size_type>
  1866. , dtl::is_not_input_iterator<InIt>
  1867. >::type * = 0
  1868. #endif
  1869. )
  1870. {
  1871. BOOST_ASSERT(this->priv_in_range_or_end(pos));
  1872. size_type n = 0;
  1873. iterator it(pos.unconst());
  1874. for(;first != last; ++first, ++n){
  1875. it = this->emplace(it, *first);
  1876. ++it;
  1877. }
  1878. it -= difference_type(n);
  1879. return it;
  1880. }
  1881. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  1882. //! <b>Requires</b>: pos must be a valid iterator of *this.
  1883. //!
  1884. //! <b>Effects</b>: Insert a copy of the [il.begin(), il.end()) range before pos.
  1885. //!
  1886. //! <b>Returns</b>: an iterator to the first inserted element or pos if il.begin() == il.end().
  1887. //!
  1888. //! <b>Throws</b>: If memory allocation throws, T's constructor from a
  1889. //! dereferenced std::initializer_list throws or T's copy constructor throws.
  1890. //!
  1891. //! <b>Complexity</b>: Linear to distance [il.begin(), il.end()).
  1892. inline iterator insert(const_iterator pos, std::initializer_list<value_type> il)
  1893. {
  1894. //Range check os pos is done in insert()
  1895. return insert(pos, il.begin(), il.end());
  1896. }
  1897. #endif
  1898. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1899. template <class FwdIt>
  1900. inline iterator insert(const_iterator p, FwdIt first, FwdIt last
  1901. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1902. , typename dtl::disable_if_or
  1903. < void
  1904. , dtl::is_convertible<FwdIt, size_type>
  1905. , dtl::is_input_iterator<FwdIt>
  1906. >::type * = 0
  1907. #endif
  1908. )
  1909. {
  1910. BOOST_ASSERT(this->priv_in_range_or_end(p));
  1911. dtl::insert_range_proxy<ValAllocator, FwdIt> proxy(first);
  1912. return priv_insert_aux_impl(p, boost::container::iterator_udistance(first, last), proxy);
  1913. }
  1914. #endif
  1915. //! <b>Effects</b>: Removes the first element from the deque.
  1916. //!
  1917. //! <b>Throws</b>: Nothing.
  1918. //!
  1919. //! <b>Complexity</b>: Constant time.
  1920. void pop_front() BOOST_NOEXCEPT_OR_NOTHROW
  1921. {
  1922. BOOST_ASSERT(!this->empty());
  1923. if (this->members_.m_start.m_cur != this->members_.m_start.get_last() - 1) {
  1924. allocator_traits_type::destroy
  1925. ( this->alloc()
  1926. , boost::movelib::to_raw_pointer(this->members_.m_start.m_cur)
  1927. );
  1928. ++this->members_.m_start.m_cur;
  1929. }
  1930. else
  1931. this->priv_pop_front_aux();
  1932. }
  1933. //! <b>Effects</b>: Removes the last element from the deque.
  1934. //!
  1935. //! <b>Throws</b>: Nothing.
  1936. //!
  1937. //! <b>Complexity</b>: Constant time.
  1938. void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
  1939. {
  1940. BOOST_ASSERT(!this->empty());
  1941. if (this->members_.m_finish.m_cur != this->members_.m_finish.get_first()) {
  1942. --this->members_.m_finish.m_cur;
  1943. allocator_traits_type::destroy
  1944. ( this->alloc()
  1945. , boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur)
  1946. );
  1947. }
  1948. else
  1949. this->priv_pop_back_aux();
  1950. }
  1951. //! <b>Effects</b>: Erases the element at p.
  1952. //!
  1953. //! <b>Throws</b>: Nothing.
  1954. //!
  1955. //! <b>Complexity</b>: Linear to the elements between pos and the
  1956. //! last element (if pos is near the end) or the first element
  1957. //! if(pos is near the beginning).
  1958. //! Constant if pos is the first or the last element.
  1959. iterator erase(const_iterator pos) BOOST_NOEXCEPT_OR_NOTHROW
  1960. {
  1961. BOOST_ASSERT(this->priv_in_range(pos));
  1962. iterator next = pos.unconst();
  1963. ++next;
  1964. size_type index = size_type(pos - this->members_.m_start);
  1965. if (index < (this->size()/2)) {
  1966. boost::container::move_backward(this->begin(), pos.unconst(), next);
  1967. pop_front();
  1968. }
  1969. else {
  1970. boost::container::move(next, this->end(), pos.unconst());
  1971. pop_back();
  1972. }
  1973. return this->members_.m_start + difference_type(index);
  1974. }
  1975. //! <b>Effects</b>: Erases the elements pointed by [first, last).
  1976. //!
  1977. //! <b>Throws</b>: Nothing.
  1978. //!
  1979. //! <b>Complexity</b>: Linear to the distance between first and
  1980. //! last plus the elements between pos and the
  1981. //! last element (if pos is near the end) or the first element
  1982. //! if(pos is near the beginning).
  1983. iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
  1984. {
  1985. BOOST_ASSERT(first == last ||
  1986. (first < last && this->priv_in_range(first) && this->priv_in_range_or_end(last)));
  1987. if (first == this->members_.m_start && last == this->members_.m_finish) {
  1988. this->clear();
  1989. return this->members_.m_finish;
  1990. }
  1991. else {
  1992. const size_type n = static_cast<size_type>(last - first);
  1993. const size_type elems_before = static_cast<size_type>(first - this->members_.m_start);
  1994. if (elems_before < (this->size() - n) - elems_before) {
  1995. boost::container::move_backward(begin(), first.unconst(), last.unconst());
  1996. iterator new_start = this->members_.m_start + difference_type(n);
  1997. this->priv_destroy_range(this->members_.m_start, new_start);
  1998. this->priv_destroy_nodes(this->members_.m_start.m_node, new_start.m_node);
  1999. this->members_.m_start = new_start;
  2000. }
  2001. else {
  2002. boost::container::move(last.unconst(), end(), first.unconst());
  2003. iterator new_finish = this->members_.m_finish - difference_type(n);
  2004. this->priv_destroy_range(new_finish, this->members_.m_finish);
  2005. this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
  2006. this->members_.m_finish = new_finish;
  2007. }
  2008. return this->members_.m_start + difference_type(elems_before);
  2009. }
  2010. }
  2011. //! <b>Effects</b>: Swaps the contents of *this and x.
  2012. //!
  2013. //! <b>Throws</b>: Nothing.
  2014. //!
  2015. //! <b>Complexity</b>: Constant.
  2016. inline void swap(deque &x)
  2017. BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_swap::value
  2018. || allocator_traits_type::is_always_equal::value)
  2019. {
  2020. this->swap_members(x);
  2021. dtl::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
  2022. dtl::swap_alloc(this->alloc(), x.alloc(), flag);
  2023. dtl::swap_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
  2024. }
  2025. //! <b>Effects</b>: Erases all the elements of the deque.
  2026. //!
  2027. //! <b>Throws</b>: Nothing.
  2028. //!
  2029. //! <b>Complexity</b>: Linear to the number of elements in the deque.
  2030. void clear() BOOST_NOEXCEPT_OR_NOTHROW
  2031. {
  2032. if (this->members_.m_finish != this->members_.m_start) {
  2033. for (index_pointer node = this->members_.m_start.m_node + 1;
  2034. node < this->members_.m_finish.m_node;
  2035. ++node) {
  2036. this->priv_destroy_range(*node, *node + get_block_ssize());
  2037. this->priv_deallocate_node(*node);
  2038. }
  2039. if (this->members_.m_start.m_node != this->members_.m_finish.m_node) {
  2040. this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_start.get_last());
  2041. this->priv_destroy_range(this->members_.m_finish.get_first(), this->members_.m_finish.m_cur);
  2042. this->priv_deallocate_node(this->members_.m_finish.get_first());
  2043. }
  2044. else
  2045. this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_finish.m_cur);
  2046. this->members_.m_finish = this->members_.m_start;
  2047. }
  2048. }
  2049. //! <b>Effects</b>: Returns true if x and y are equal
  2050. //!
  2051. //! <b>Complexity</b>: Linear to the number of elements in the container.
  2052. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  2053. friend bool operator==(const deque& x, const deque& y)
  2054. { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
  2055. //! <b>Effects</b>: Returns true if x and y are unequal
  2056. //!
  2057. //! <b>Complexity</b>: Linear to the number of elements in the container.
  2058. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  2059. friend bool operator!=(const deque& x, const deque& y)
  2060. { return !(x == y); }
  2061. //! <b>Effects</b>: Returns true if x is less than y
  2062. //!
  2063. //! <b>Complexity</b>: Linear to the number of elements in the container.
  2064. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  2065. friend bool operator<(const deque& x, const deque& y)
  2066. { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
  2067. //! <b>Effects</b>: Returns true if x is greater than y
  2068. //!
  2069. //! <b>Complexity</b>: Linear to the number of elements in the container.
  2070. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  2071. friend bool operator>(const deque& x, const deque& y)
  2072. { return y < x; }
  2073. //! <b>Effects</b>: Returns true if x is equal or less than y
  2074. //!
  2075. //! <b>Complexity</b>: Linear to the number of elements in the container.
  2076. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  2077. friend bool operator<=(const deque& x, const deque& y)
  2078. { return !(y < x); }
  2079. //! <b>Effects</b>: Returns true if x is equal or greater than y
  2080. //!
  2081. //! <b>Complexity</b>: Linear to the number of elements in the container.
  2082. BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
  2083. friend bool operator>=(const deque& x, const deque& y)
  2084. { return !(x < y); }
  2085. //! <b>Effects</b>: x.swap(y)
  2086. //!
  2087. //! <b>Complexity</b>: Constant.
  2088. inline friend void swap(deque& x, deque& y)
  2089. BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y)))
  2090. { x.swap(y); }
  2091. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  2092. private:
  2093. void priv_move_assign(BOOST_RV_REF(deque) x, dtl::bool_<true> /*steal_resources*/)
  2094. {
  2095. //Destroy objects but retain memory in case x reuses it in the future
  2096. this->clear();
  2097. //Move allocator if needed
  2098. dtl::bool_<allocator_traits_type::propagate_on_container_move_assignment::value> flag;
  2099. dtl::move_alloc(this->alloc(), x.alloc(), flag);
  2100. dtl::move_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
  2101. //Nothrow swap
  2102. this->swap_members(x);
  2103. }
  2104. void priv_move_assign(BOOST_RV_REF(deque) x, dtl::bool_<false> /*steal_resources*/)
  2105. {
  2106. //We can't guarantee a compile-time equal allocator or propagation so fallback to runtime
  2107. //Resources can be transferred if both allocators are equal
  2108. if (this->alloc() == x.alloc()) {
  2109. this->priv_move_assign(boost::move(x), dtl::true_());
  2110. }
  2111. else {
  2112. this->assign(boost::make_move_iterator(x.begin()), boost::make_move_iterator(x.end()));
  2113. }
  2114. }
  2115. inline size_type priv_index_of(const_iterator p) const
  2116. {
  2117. BOOST_ASSERT(this->cbegin() <= p);
  2118. BOOST_ASSERT(p <= this->cend());
  2119. return static_cast<size_type>(p - this->cbegin());
  2120. }
  2121. void priv_erase_last_n(size_type n)
  2122. {
  2123. if(n == this->size()) {
  2124. this->clear();
  2125. }
  2126. else {
  2127. iterator new_finish = this->members_.m_finish - difference_type(n);
  2128. this->priv_destroy_range(new_finish, this->members_.m_finish);
  2129. this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
  2130. this->members_.m_finish = new_finish;
  2131. }
  2132. }
  2133. void priv_throw_if_out_of_range(size_type n) const
  2134. {
  2135. if (n >= this->size())
  2136. throw_out_of_range("deque::at out of range");
  2137. }
  2138. inline bool priv_in_range(const_iterator pos) const
  2139. {
  2140. return (this->begin() <= pos) && (pos < this->end());
  2141. }
  2142. inline bool priv_in_range_or_end(const_iterator pos) const
  2143. {
  2144. return (this->begin() <= pos) && (pos <= this->end());
  2145. }
  2146. template <class U>
  2147. iterator priv_insert(const_iterator p, BOOST_FWD_REF(U) x)
  2148. {
  2149. BOOST_ASSERT(this->priv_in_range_or_end(p));
  2150. if (p == cbegin()){
  2151. this->push_front(::boost::forward<U>(x));
  2152. return begin();
  2153. }
  2154. else if (p == cend()){
  2155. this->push_back(::boost::forward<U>(x));
  2156. return --end();
  2157. }
  2158. else {
  2159. return priv_insert_aux_impl
  2160. ( p, (size_type)1
  2161. , dtl::get_insert_value_proxy<iterator, ValAllocator>(::boost::forward<U>(x)));
  2162. }
  2163. }
  2164. template <class U>
  2165. void priv_push_front(BOOST_FWD_REF(U) x)
  2166. {
  2167. if(this->priv_push_front_simple_available()){
  2168. allocator_traits_type::construct
  2169. ( this->alloc(), this->priv_push_front_simple_pos(), ::boost::forward<U>(x));
  2170. this->priv_push_front_simple_commit();
  2171. }
  2172. else{
  2173. priv_insert_aux_impl
  2174. ( this->cbegin(), (size_type)1
  2175. , dtl::get_insert_value_proxy<iterator, ValAllocator>(::boost::forward<U>(x)));
  2176. }
  2177. }
  2178. template <class U>
  2179. void priv_push_back(BOOST_FWD_REF(U) x)
  2180. {
  2181. if(this->priv_push_back_simple_available()){
  2182. allocator_traits_type::construct
  2183. ( this->alloc(), this->priv_push_back_simple_pos(), ::boost::forward<U>(x));
  2184. this->priv_push_back_simple_commit();
  2185. }
  2186. else{
  2187. priv_insert_aux_impl
  2188. ( this->cend(), (size_type)1
  2189. , dtl::get_insert_value_proxy<iterator, ValAllocator>(::boost::forward<U>(x)));
  2190. }
  2191. }
  2192. inline bool priv_push_back_simple_available() const
  2193. {
  2194. return this->members_.m_map &&
  2195. (this->members_.m_finish.m_cur != (this->members_.m_finish.get_last() - 1));
  2196. }
  2197. inline T *priv_push_back_simple_pos() const
  2198. {
  2199. return boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur);
  2200. }
  2201. inline void priv_push_back_simple_commit()
  2202. {
  2203. ++this->members_.m_finish.m_cur;
  2204. }
  2205. inline bool priv_push_front_simple_available() const
  2206. {
  2207. return this->members_.m_map &&
  2208. (this->members_.m_start.m_cur != this->members_.m_start.get_first());
  2209. }
  2210. inline T *priv_push_front_simple_pos() const
  2211. { return boost::movelib::to_raw_pointer(this->members_.m_start.m_cur) - 1; }
  2212. inline void priv_push_front_simple_commit()
  2213. { --this->members_.m_start.m_cur; }
  2214. void priv_destroy_range(iterator p, iterator p2)
  2215. {
  2216. (void)p; (void)p2;
  2217. BOOST_IF_CONSTEXPR(!Base::traits_t::trivial_dctr){
  2218. for(;p != p2; ++p){
  2219. allocator_traits_type::destroy(this->alloc(), boost::movelib::iterator_to_raw_pointer(p));
  2220. }
  2221. }
  2222. }
  2223. void priv_destroy_range(pointer p, pointer p2)
  2224. {
  2225. (void)p; (void)p2;
  2226. BOOST_IF_CONSTEXPR(!Base::traits_t::trivial_dctr){
  2227. for(;p != p2; ++p){
  2228. allocator_traits_type::destroy(this->alloc(), boost::movelib::iterator_to_raw_pointer(p));
  2229. }
  2230. }
  2231. }
  2232. template<class InsertProxy>
  2233. iterator priv_insert_middle_aux_impl(const_iterator p, const size_type elemsbefore, const size_type length, const size_type n, InsertProxy proxy)
  2234. {
  2235. if (!this->members_.m_map) {
  2236. this->priv_initialize_map(0);
  2237. p = this->cbegin();
  2238. }
  2239. iterator pos(p.unconst());
  2240. const size_type pos_n = size_type(p - this->cbegin());
  2241. if (elemsbefore < length / 2) {
  2242. const iterator new_start = this->priv_reserve_elements_at_front(n);
  2243. const iterator old_start = this->members_.m_start;
  2244. pos = this->members_.m_start + difference_type(elemsbefore);
  2245. if (elemsbefore >= n) {
  2246. const iterator start_n = this->members_.m_start + difference_type(n);
  2247. BOOST_CONTAINER_TRY {
  2248. ::boost::container::uninitialized_move_alloc
  2249. (this->alloc(), this->members_.m_start, start_n, new_start);
  2250. }
  2251. BOOST_CONTAINER_CATCH(...) {
  2252. this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node);
  2253. BOOST_CONTAINER_RETHROW
  2254. }
  2255. BOOST_CONTAINER_CATCH_END
  2256. this->members_.m_start = new_start;
  2257. boost::container::move(start_n, pos, old_start);
  2258. proxy.copy_n_and_update(this->alloc(), pos - difference_type(n), n);
  2259. }
  2260. else {
  2261. const size_type mid_count = n - elemsbefore;
  2262. const iterator mid_start = old_start - difference_type(mid_count);
  2263. BOOST_CONTAINER_TRY {
  2264. proxy.uninitialized_copy_n_and_update(this->alloc(), mid_start, mid_count);
  2265. this->members_.m_start = mid_start;
  2266. ::boost::container::uninitialized_move_alloc(this->alloc(), old_start, pos, new_start);
  2267. }
  2268. BOOST_CONTAINER_CATCH(...) {
  2269. this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node);
  2270. BOOST_CONTAINER_RETHROW
  2271. }
  2272. BOOST_CONTAINER_CATCH_END
  2273. this->members_.m_start = new_start;
  2274. proxy.copy_n_and_update(this->alloc(), old_start, elemsbefore);
  2275. }
  2276. }
  2277. else {
  2278. const iterator new_finish = this->priv_reserve_elements_at_back(n);
  2279. const iterator old_finish = this->members_.m_finish;
  2280. const size_type elemsafter = length - elemsbefore;
  2281. pos = old_finish - difference_type(elemsafter);
  2282. if (elemsafter >= n) {
  2283. iterator finish_n = old_finish - difference_type(n);
  2284. BOOST_CONTAINER_TRY {
  2285. ::boost::container::uninitialized_move_alloc(this->alloc(), finish_n, old_finish, old_finish);
  2286. }
  2287. BOOST_CONTAINER_CATCH(...) {
  2288. this->priv_destroy_nodes(this->members_.m_finish.m_node + 1, new_finish.m_node + 1);
  2289. BOOST_CONTAINER_RETHROW
  2290. }
  2291. BOOST_CONTAINER_CATCH_END
  2292. this->members_.m_finish = new_finish;
  2293. boost::container::move_backward(pos, finish_n, old_finish);
  2294. proxy.copy_n_and_update(this->alloc(), pos, n);
  2295. }
  2296. else {
  2297. const size_type raw_gap = n - elemsafter;
  2298. BOOST_CONTAINER_TRY{
  2299. ::boost::container::uninitialized_move_alloc
  2300. (this->alloc(), pos, old_finish, old_finish + difference_type(raw_gap));
  2301. BOOST_CONTAINER_TRY{
  2302. proxy.copy_n_and_update(this->alloc(), pos, elemsafter);
  2303. proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, raw_gap);
  2304. }
  2305. BOOST_CONTAINER_CATCH(...) {
  2306. this->priv_destroy_range(old_finish, old_finish + difference_type(elemsafter));
  2307. BOOST_CONTAINER_RETHROW
  2308. }
  2309. BOOST_CONTAINER_CATCH_END
  2310. }
  2311. BOOST_CONTAINER_CATCH(...) {
  2312. this->priv_destroy_nodes(this->members_.m_finish.m_node + 1, new_finish.m_node + 1);
  2313. BOOST_CONTAINER_RETHROW
  2314. }
  2315. BOOST_CONTAINER_CATCH_END
  2316. this->members_.m_finish = new_finish;
  2317. }
  2318. }
  2319. return this->begin() + difference_type(pos_n);
  2320. }
  2321. template<class InsertProxy>
  2322. iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy proxy)
  2323. {
  2324. iterator pos(p.unconst());
  2325. const size_type elemsbefore = static_cast<size_type>(pos - this->members_.m_start);
  2326. const size_type length = this->size();
  2327. if (!elemsbefore) {
  2328. return this->priv_insert_front_aux_impl(n, proxy);
  2329. }
  2330. else if (elemsbefore == length) {
  2331. return this->priv_insert_back_aux_impl(n, proxy);
  2332. }
  2333. else {
  2334. return this->priv_insert_middle_aux_impl(p, elemsbefore, length, n, proxy);
  2335. }
  2336. }
  2337. template <class InsertProxy>
  2338. iterator priv_insert_back_aux_impl(size_type n, InsertProxy proxy)
  2339. {
  2340. if(!this->members_.m_map){
  2341. this->priv_initialize_map(0);
  2342. }
  2343. iterator new_finish = this->priv_reserve_elements_at_back(n);
  2344. BOOST_CONTAINER_TRY{
  2345. proxy.uninitialized_copy_n_and_update(this->alloc(), this->members_.m_finish, n);
  2346. }
  2347. BOOST_CONTAINER_CATCH(...) {
  2348. this->priv_destroy_nodes(this->members_.m_finish.m_node + 1, new_finish.m_node + 1);
  2349. BOOST_CONTAINER_RETHROW
  2350. }
  2351. BOOST_CONTAINER_CATCH_END
  2352. this->members_.m_finish = new_finish;
  2353. return iterator(this->members_.m_finish - difference_type(n));
  2354. }
  2355. template <class InsertProxy>
  2356. iterator priv_insert_front_aux_impl(size_type n, InsertProxy proxy)
  2357. {
  2358. if(!this->members_.m_map){
  2359. this->priv_initialize_map(0);
  2360. }
  2361. iterator new_start = this->priv_reserve_elements_at_front(n);
  2362. BOOST_CONTAINER_TRY{
  2363. proxy.uninitialized_copy_n_and_update(this->alloc(), new_start, n);
  2364. }
  2365. BOOST_CONTAINER_CATCH(...) {
  2366. this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node);
  2367. BOOST_CONTAINER_RETHROW
  2368. }
  2369. BOOST_CONTAINER_CATCH_END
  2370. this->members_.m_start = new_start;
  2371. return new_start;
  2372. }
  2373. inline iterator priv_fill_insert(const_iterator pos, size_type n, const value_type& x)
  2374. {
  2375. return this->insert(pos, c_it(x, n), c_it());
  2376. }
  2377. // Precondition: this->members_.m_start and this->members_.m_finish have already been initialized,
  2378. // but none of the deque's elements have yet been constructed.
  2379. void priv_fill_initialize(const value_type& value)
  2380. {
  2381. index_pointer cur = this->members_.m_start.m_node;
  2382. BOOST_CONTAINER_TRY {
  2383. for ( ; cur < this->members_.m_finish.m_node; ++cur){
  2384. boost::container::uninitialized_fill_alloc
  2385. (this->alloc(), *cur, *cur + get_block_ssize(), value);
  2386. }
  2387. boost::container::uninitialized_fill_alloc
  2388. (this->alloc(), this->members_.m_finish.get_first(), this->members_.m_finish.m_cur, value);
  2389. }
  2390. BOOST_CONTAINER_CATCH(...){
  2391. this->priv_destroy_range(this->members_.m_start, iterator(*cur, cur, get_block_size()));
  2392. BOOST_CONTAINER_RETHROW
  2393. }
  2394. BOOST_CONTAINER_CATCH_END
  2395. }
  2396. template <class InIt>
  2397. void priv_range_initialize(InIt first, InIt last, typename iterator_enable_if_tag<InIt, std::input_iterator_tag>::type* =0)
  2398. {
  2399. this->priv_initialize_map(0);
  2400. BOOST_CONTAINER_TRY {
  2401. for ( ; first != last; ++first)
  2402. this->emplace_back(*first);
  2403. }
  2404. BOOST_CONTAINER_CATCH(...){
  2405. this->clear();
  2406. BOOST_CONTAINER_RETHROW
  2407. }
  2408. BOOST_CONTAINER_CATCH_END
  2409. }
  2410. template <class FwdIt>
  2411. void priv_range_initialize(FwdIt first, FwdIt last, typename iterator_disable_if_tag<FwdIt, std::input_iterator_tag>::type* =0)
  2412. {
  2413. size_type n = 0;
  2414. n = boost::container::iterator_udistance(first, last);
  2415. this->priv_initialize_map(n);
  2416. index_pointer cur_node = this->members_.m_start.m_node;
  2417. BOOST_CONTAINER_TRY {
  2418. for (; cur_node < this->members_.m_finish.m_node; ++cur_node) {
  2419. FwdIt mid = first;
  2420. boost::container::iterator_uadvance(mid, get_block_size());
  2421. ::boost::container::uninitialized_copy_alloc(this->alloc(), first, mid, *cur_node);
  2422. first = mid;
  2423. }
  2424. ::boost::container::uninitialized_copy_alloc(this->alloc(), first, last, this->members_.m_finish.get_first());
  2425. }
  2426. BOOST_CONTAINER_CATCH(...){
  2427. this->priv_destroy_range(this->members_.m_start, iterator(*cur_node, cur_node, get_block_size()));
  2428. BOOST_CONTAINER_RETHROW
  2429. }
  2430. BOOST_CONTAINER_CATCH_END
  2431. }
  2432. // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.get_first().
  2433. void priv_pop_back_aux() BOOST_NOEXCEPT_OR_NOTHROW
  2434. {
  2435. this->priv_deallocate_node(this->members_.m_finish.get_first());
  2436. this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node - 1, get_block_size());
  2437. this->members_.m_finish.m_cur = this->members_.m_finish.get_last() - 1;
  2438. allocator_traits_type::destroy
  2439. ( this->alloc()
  2440. , boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur)
  2441. );
  2442. }
  2443. // Called only if this->members_.m_start.m_cur == this->members_.m_start.get_last() - 1. Note that
  2444. // if the deque has at least one element (a precondition for this member
  2445. // function), and if this->members_.m_start.m_cur == this->members_.m_start.get_last(), then the deque
  2446. // must have at least two nodes.
  2447. void priv_pop_front_aux() BOOST_NOEXCEPT_OR_NOTHROW
  2448. {
  2449. allocator_traits_type::destroy
  2450. ( this->alloc()
  2451. , boost::movelib::to_raw_pointer(this->members_.m_start.m_cur)
  2452. );
  2453. this->priv_deallocate_node(this->members_.m_start.get_first());
  2454. this->members_.m_start.priv_set_node(this->members_.m_start.m_node + 1, get_block_size());
  2455. this->members_.m_start.m_cur = this->members_.m_start.get_first();
  2456. }
  2457. iterator priv_reserve_elements_at_front(size_type n)
  2458. {
  2459. size_type vacancies = size_type(this->members_.m_start.m_cur - this->members_.m_start.get_first());
  2460. if (n > vacancies){
  2461. size_type new_elems = n-vacancies;
  2462. size_type new_nodes = (new_elems + get_block_size() - 1u) / get_block_size();
  2463. size_type s = (size_type)(this->members_.m_start.m_node - this->members_.m_map);
  2464. if (new_nodes > s){
  2465. this->priv_reallocate_map(new_nodes, true);
  2466. }
  2467. size_type i = 1;
  2468. BOOST_CONTAINER_TRY {
  2469. for (; i <= new_nodes; ++i)
  2470. *(this->members_.m_start.m_node - difference_type(i)) = this->priv_allocate_node();
  2471. }
  2472. BOOST_CONTAINER_CATCH(...) {
  2473. for (size_type j = 1; j < i; ++j)
  2474. this->priv_deallocate_node(*(this->members_.m_start.m_node - difference_type(j)));
  2475. BOOST_CONTAINER_RETHROW
  2476. }
  2477. BOOST_CONTAINER_CATCH_END
  2478. }
  2479. return this->members_.m_start - difference_type(n);
  2480. }
  2481. iterator priv_reserve_elements_at_back(size_type n)
  2482. {
  2483. size_type vacancies = size_type(this->members_.m_finish.get_last() - this->members_.m_finish.m_cur - 1);
  2484. if (n > vacancies){
  2485. size_type new_elems = size_type(n - vacancies);
  2486. size_type new_nodes = size_type(new_elems + get_block_size() - 1u)/get_block_size();
  2487. size_type s = (size_type)(this->members_.m_map_size - size_type(this->members_.m_finish.m_node - this->members_.m_map));
  2488. if (new_nodes + 1 > s){
  2489. this->priv_reallocate_map(new_nodes, false);
  2490. }
  2491. size_type i = 1;
  2492. BOOST_CONTAINER_TRY {
  2493. for (; i <= new_nodes; ++i)
  2494. *(this->members_.m_finish.m_node + difference_type(i)) = this->priv_allocate_node();
  2495. }
  2496. BOOST_CONTAINER_CATCH(...) {
  2497. for (size_type j = 1; j < i; ++j)
  2498. this->priv_deallocate_node(*(this->members_.m_finish.m_node + difference_type(j)));
  2499. BOOST_CONTAINER_RETHROW
  2500. }
  2501. BOOST_CONTAINER_CATCH_END
  2502. }
  2503. return this->members_.m_finish + difference_type(n);
  2504. }
  2505. void priv_reallocate_map(size_type nodes_to_add, bool add_at_front)
  2506. {
  2507. size_type old_num_nodes = size_type(this->members_.m_finish.m_node - this->members_.m_start.m_node + 1);
  2508. size_type new_num_nodes = old_num_nodes + nodes_to_add;
  2509. index_pointer new_nstart;
  2510. if (this->members_.m_map_size > 2 * new_num_nodes) {
  2511. new_nstart = this->members_.m_map + difference_type(this->members_.m_map_size - new_num_nodes) / 2
  2512. + difference_type(add_at_front ? nodes_to_add : 0u);
  2513. if (new_nstart < this->members_.m_start.m_node)
  2514. boost::container::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
  2515. else
  2516. boost::container::move_backward
  2517. (this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart + difference_type(old_num_nodes));
  2518. }
  2519. else {
  2520. size_type new_map_size =
  2521. this->members_.m_map_size + dtl::max_value(this->members_.m_map_size, nodes_to_add) + 2;
  2522. index_pointer new_map = this->priv_allocate_map(new_map_size);
  2523. new_nstart = new_map + difference_type(new_map_size - new_num_nodes) / 2
  2524. + difference_type(add_at_front ? nodes_to_add : 0u);
  2525. boost::container::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
  2526. this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
  2527. this->members_.m_map = new_map;
  2528. this->members_.m_map_size = new_map_size;
  2529. }
  2530. this->members_.m_start.priv_set_node(new_nstart, get_block_size());
  2531. this->members_.m_finish.priv_set_node(new_nstart + difference_type(old_num_nodes - 1u), get_block_size());
  2532. }
  2533. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  2534. };
  2535. #ifndef BOOST_CONTAINER_NO_CXX17_CTAD
  2536. template <typename InputIterator>
  2537. deque(InputIterator, InputIterator) -> deque<typename iterator_traits<InputIterator>::value_type>;
  2538. template <typename InputIterator, typename Allocator>
  2539. deque(InputIterator, InputIterator, Allocator const&) -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>;
  2540. #endif
  2541. } //namespace container
  2542. } //namespace boost
  2543. #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  2544. namespace boost {
  2545. //!has_trivial_destructor_after_move<> == true_type
  2546. //!specialization for optimizations
  2547. template <class T, class Allocator, class Options>
  2548. struct has_trivial_destructor_after_move<boost::container::deque<T, Allocator, Options> >
  2549. {
  2550. typedef typename boost::container::deque<T, Allocator, Options>::allocator_type allocator_type;
  2551. typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer;
  2552. BOOST_STATIC_CONSTEXPR bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value &&
  2553. ::boost::has_trivial_destructor_after_move<pointer>::value;
  2554. };
  2555. }
  2556. #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
  2557. #include <boost/container/detail/config_end.hpp>
  2558. #endif // #ifndef BOOST_CONTAINER_DEQUE_HPP