deque.hpp 87 KB

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