deque.hpp 74 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2005-2012. 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. #if defined(_MSC_VER)
  13. # pragma once
  14. #endif
  15. #include <boost/container/detail/config_begin.hpp>
  16. #include <boost/container/detail/workaround.hpp>
  17. #include <boost/container/detail/utilities.hpp>
  18. #include <boost/container/detail/iterators.hpp>
  19. #include <boost/container/detail/algorithms.hpp>
  20. #include <boost/container/detail/mpl.hpp>
  21. #include <boost/container/allocator_traits.hpp>
  22. #include <boost/container/container_fwd.hpp>
  23. #include <boost/container/throw_exception.hpp>
  24. #include <cstddef>
  25. #include <iterator>
  26. #include <boost/assert.hpp>
  27. #include <memory>
  28. #include <algorithm>
  29. #include <boost/detail/no_exceptions_support.hpp>
  30. #include <boost/type_traits/has_trivial_destructor.hpp>
  31. #include <boost/type_traits/has_trivial_copy.hpp>
  32. #include <boost/type_traits/has_trivial_assign.hpp>
  33. #include <boost/type_traits/has_nothrow_copy.hpp>
  34. #include <boost/type_traits/has_nothrow_assign.hpp>
  35. #include <boost/move/utility.hpp>
  36. #include <boost/move/iterator.hpp>
  37. #include <boost/move/detail/move_helpers.hpp>
  38. #include <boost/container/detail/advanced_insert_int.hpp>
  39. #include <boost/detail/no_exceptions_support.hpp>
  40. namespace boost {
  41. namespace container {
  42. /// @cond
  43. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
  44. template <class T, class Allocator = std::allocator<T> >
  45. #else
  46. template <class T, class Allocator>
  47. #endif
  48. class deque;
  49. template <class T>
  50. struct deque_value_traits
  51. {
  52. typedef T value_type;
  53. static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
  54. static const bool trivial_dctr_after_move = ::boost::has_trivial_destructor_after_move<value_type>::value;
  55. static const bool trivial_copy = has_trivial_copy<value_type>::value;
  56. static const bool nothrow_copy = has_nothrow_copy<value_type>::value;
  57. static const bool trivial_assign = has_trivial_assign<value_type>::value;
  58. //static const bool nothrow_assign = has_nothrow_assign<value_type>::value;
  59. static const bool nothrow_assign = false;
  60. };
  61. // Note: this function is simply a kludge to work around several compilers'
  62. // bugs in handling constant expressions.
  63. template<class T>
  64. struct deque_buf_size
  65. {
  66. static const std::size_t min_size = 512u;
  67. static const std::size_t sizeof_t = sizeof(T);
  68. static const std::size_t value = sizeof_t < min_size ? (min_size/sizeof_t) : std::size_t(1);
  69. };
  70. namespace container_detail {
  71. // Class invariants:
  72. // For any nonsingular iterator i:
  73. // i.node is the address of an element in the map array. The
  74. // contents of i.node is a pointer to the beginning of a node.
  75. // i.first == //(i.node)
  76. // i.last == i.first + node_size
  77. // i.cur is a pointer in the range [i.first, i.last). NOTE:
  78. // the implication of this is that i.cur is always a dereferenceable
  79. // pointer, even if i is a past-the-end iterator.
  80. // Start and Finish are always nonsingular iterators. NOTE: this means
  81. // that an empty deque must have one node, and that a deque
  82. // with N elements, where N is the buffer size, must have two nodes.
  83. // For every node other than start.node and finish.node, every element
  84. // in the node is an initialized object. If start.node == finish.node,
  85. // then [start.cur, finish.cur) are initialized objects, and
  86. // the elements outside that range are uninitialized storage. Otherwise,
  87. // [start.cur, start.last) and [finish.first, finish.cur) are initialized
  88. // objects, and [start.first, start.cur) and [finish.cur, finish.last)
  89. // are uninitialized storage.
  90. // [map, map + map_size) is a valid, non-empty range.
  91. // [start.node, finish.node] is a valid range contained within
  92. // [map, map + map_size).
  93. // Allocator pointer in the range [map, map + map_size) points to an allocated node
  94. // if and only if the pointer is in the range [start.node, finish.node].
  95. template<class Pointer, bool IsConst>
  96. class deque_iterator
  97. {
  98. public:
  99. typedef std::random_access_iterator_tag iterator_category;
  100. typedef typename boost::intrusive::pointer_traits<Pointer>::element_type value_type;
  101. typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type difference_type;
  102. typedef typename if_c
  103. < IsConst
  104. , typename boost::intrusive::pointer_traits<Pointer>::template
  105. rebind_pointer<const value_type>::type
  106. , Pointer
  107. >::type pointer;
  108. typedef typename if_c
  109. < IsConst
  110. , const value_type&
  111. , value_type&
  112. >::type reference;
  113. static std::size_t s_buffer_size()
  114. { return deque_buf_size<value_type>::value; }
  115. typedef Pointer val_alloc_ptr;
  116. typedef typename boost::intrusive::pointer_traits<Pointer>::
  117. template rebind_pointer<Pointer>::type index_pointer;
  118. Pointer m_cur;
  119. Pointer m_first;
  120. Pointer m_last;
  121. index_pointer m_node;
  122. public:
  123. Pointer get_cur() const { return m_cur; }
  124. Pointer get_first() const { return m_first; }
  125. Pointer get_last() const { return m_last; }
  126. index_pointer get_node() const { return m_node; }
  127. deque_iterator(val_alloc_ptr x, index_pointer y) BOOST_CONTAINER_NOEXCEPT
  128. : m_cur(x), m_first(*y), m_last(*y + s_buffer_size()), m_node(y)
  129. {}
  130. deque_iterator() BOOST_CONTAINER_NOEXCEPT
  131. : m_cur(), m_first(), m_last(), m_node()
  132. {}
  133. deque_iterator(deque_iterator<Pointer, false> const& x) BOOST_CONTAINER_NOEXCEPT
  134. : m_cur(x.get_cur()), m_first(x.get_first()), m_last(x.get_last()), m_node(x.get_node())
  135. {}
  136. deque_iterator(Pointer cur, Pointer first, Pointer last, index_pointer node) BOOST_CONTAINER_NOEXCEPT
  137. : m_cur(cur), m_first(first), m_last(last), m_node(node)
  138. {}
  139. deque_iterator<Pointer, false> unconst() const BOOST_CONTAINER_NOEXCEPT
  140. {
  141. return deque_iterator<Pointer, false>(this->get_cur(), this->get_first(), this->get_last(), this->get_node());
  142. }
  143. reference operator*() const BOOST_CONTAINER_NOEXCEPT
  144. { return *this->m_cur; }
  145. pointer operator->() const BOOST_CONTAINER_NOEXCEPT
  146. { return this->m_cur; }
  147. difference_type operator-(const deque_iterator& x) const BOOST_CONTAINER_NOEXCEPT
  148. {
  149. if(!this->m_cur && !x.m_cur){
  150. return 0;
  151. }
  152. return difference_type(this->s_buffer_size()) * (this->m_node - x.m_node - 1) +
  153. (this->m_cur - this->m_first) + (x.m_last - x.m_cur);
  154. }
  155. deque_iterator& operator++() BOOST_CONTAINER_NOEXCEPT
  156. {
  157. ++this->m_cur;
  158. if (this->m_cur == this->m_last) {
  159. this->priv_set_node(this->m_node + 1);
  160. this->m_cur = this->m_first;
  161. }
  162. return *this;
  163. }
  164. deque_iterator operator++(int) BOOST_CONTAINER_NOEXCEPT
  165. {
  166. deque_iterator tmp(*this);
  167. ++*this;
  168. return tmp;
  169. }
  170. deque_iterator& operator--() BOOST_CONTAINER_NOEXCEPT
  171. {
  172. if (this->m_cur == this->m_first) {
  173. this->priv_set_node(this->m_node - 1);
  174. this->m_cur = this->m_last;
  175. }
  176. --this->m_cur;
  177. return *this;
  178. }
  179. deque_iterator operator--(int) BOOST_CONTAINER_NOEXCEPT
  180. {
  181. deque_iterator tmp(*this);
  182. --*this;
  183. return tmp;
  184. }
  185. deque_iterator& operator+=(difference_type n) BOOST_CONTAINER_NOEXCEPT
  186. {
  187. difference_type offset = n + (this->m_cur - this->m_first);
  188. if (offset >= 0 && offset < difference_type(this->s_buffer_size()))
  189. this->m_cur += n;
  190. else {
  191. difference_type node_offset =
  192. offset > 0 ? offset / difference_type(this->s_buffer_size())
  193. : -difference_type((-offset - 1) / this->s_buffer_size()) - 1;
  194. this->priv_set_node(this->m_node + node_offset);
  195. this->m_cur = this->m_first +
  196. (offset - node_offset * difference_type(this->s_buffer_size()));
  197. }
  198. return *this;
  199. }
  200. deque_iterator operator+(difference_type n) const BOOST_CONTAINER_NOEXCEPT
  201. { deque_iterator tmp(*this); return tmp += n; }
  202. deque_iterator& operator-=(difference_type n) BOOST_CONTAINER_NOEXCEPT
  203. { return *this += -n; }
  204. deque_iterator operator-(difference_type n) const BOOST_CONTAINER_NOEXCEPT
  205. { deque_iterator tmp(*this); return tmp -= n; }
  206. reference operator[](difference_type n) const BOOST_CONTAINER_NOEXCEPT
  207. { return *(*this + n); }
  208. friend bool operator==(const deque_iterator& l, const deque_iterator& r) BOOST_CONTAINER_NOEXCEPT
  209. { return l.m_cur == r.m_cur; }
  210. friend bool operator!=(const deque_iterator& l, const deque_iterator& r) BOOST_CONTAINER_NOEXCEPT
  211. { return l.m_cur != r.m_cur; }
  212. friend bool operator<(const deque_iterator& l, const deque_iterator& r) BOOST_CONTAINER_NOEXCEPT
  213. { return (l.m_node == r.m_node) ? (l.m_cur < r.m_cur) : (l.m_node < r.m_node); }
  214. friend bool operator>(const deque_iterator& l, const deque_iterator& r) BOOST_CONTAINER_NOEXCEPT
  215. { return r < l; }
  216. friend bool operator<=(const deque_iterator& l, const deque_iterator& r) BOOST_CONTAINER_NOEXCEPT
  217. { return !(r < l); }
  218. friend bool operator>=(const deque_iterator& l, const deque_iterator& r) BOOST_CONTAINER_NOEXCEPT
  219. { return !(l < r); }
  220. void priv_set_node(index_pointer new_node) BOOST_CONTAINER_NOEXCEPT
  221. {
  222. this->m_node = new_node;
  223. this->m_first = *new_node;
  224. this->m_last = this->m_first + this->s_buffer_size();
  225. }
  226. friend deque_iterator operator+(difference_type n, deque_iterator x) BOOST_CONTAINER_NOEXCEPT
  227. { return x += n; }
  228. };
  229. } //namespace container_detail {
  230. // Deque base class. It has two purposes. First, its constructor
  231. // and destructor allocate (but don't initialize) storage. This makes
  232. // exception safety easier.
  233. template <class Allocator>
  234. class deque_base
  235. {
  236. BOOST_COPYABLE_AND_MOVABLE(deque_base)
  237. public:
  238. typedef allocator_traits<Allocator> val_alloc_traits_type;
  239. typedef typename val_alloc_traits_type::value_type val_alloc_val;
  240. typedef typename val_alloc_traits_type::pointer val_alloc_ptr;
  241. typedef typename val_alloc_traits_type::const_pointer val_alloc_cptr;
  242. typedef typename val_alloc_traits_type::reference val_alloc_ref;
  243. typedef typename val_alloc_traits_type::const_reference val_alloc_cref;
  244. typedef typename val_alloc_traits_type::difference_type val_alloc_diff;
  245. typedef typename val_alloc_traits_type::size_type val_alloc_size;
  246. typedef typename val_alloc_traits_type::template
  247. portable_rebind_alloc<val_alloc_ptr>::type ptr_alloc_t;
  248. typedef allocator_traits<ptr_alloc_t> ptr_alloc_traits_type;
  249. typedef typename ptr_alloc_traits_type::value_type ptr_alloc_val;
  250. typedef typename ptr_alloc_traits_type::pointer ptr_alloc_ptr;
  251. typedef typename ptr_alloc_traits_type::const_pointer ptr_alloc_cptr;
  252. typedef typename ptr_alloc_traits_type::reference ptr_alloc_ref;
  253. typedef typename ptr_alloc_traits_type::const_reference ptr_alloc_cref;
  254. typedef Allocator allocator_type;
  255. typedef allocator_type stored_allocator_type;
  256. typedef val_alloc_size size_type;
  257. protected:
  258. typedef deque_value_traits<val_alloc_val> traits_t;
  259. typedef ptr_alloc_t map_allocator_type;
  260. static size_type s_buffer_size() BOOST_CONTAINER_NOEXCEPT
  261. { return deque_buf_size<val_alloc_val>::value; }
  262. val_alloc_ptr priv_allocate_node()
  263. { return this->alloc().allocate(s_buffer_size()); }
  264. void priv_deallocate_node(val_alloc_ptr p) BOOST_CONTAINER_NOEXCEPT
  265. { this->alloc().deallocate(p, s_buffer_size()); }
  266. ptr_alloc_ptr priv_allocate_map(size_type n)
  267. { return this->ptr_alloc().allocate(n); }
  268. void priv_deallocate_map(ptr_alloc_ptr p, size_type n) BOOST_CONTAINER_NOEXCEPT
  269. { this->ptr_alloc().deallocate(p, n); }
  270. typedef container_detail::deque_iterator<val_alloc_ptr, false> iterator;
  271. typedef container_detail::deque_iterator<val_alloc_ptr, true > const_iterator;
  272. deque_base(size_type num_elements, const allocator_type& a)
  273. : members_(a)
  274. { this->priv_initialize_map(num_elements); }
  275. explicit deque_base(const allocator_type& a)
  276. : members_(a)
  277. {}
  278. deque_base()
  279. : members_()
  280. {}
  281. explicit deque_base(BOOST_RV_REF(deque_base) x)
  282. : members_( boost::move(x.ptr_alloc())
  283. , boost::move(x.alloc()) )
  284. {}
  285. ~deque_base()
  286. {
  287. if (this->members_.m_map) {
  288. this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1);
  289. this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
  290. }
  291. }
  292. private:
  293. deque_base(const deque_base&);
  294. protected:
  295. void swap_members(deque_base &x) BOOST_CONTAINER_NOEXCEPT
  296. {
  297. std::swap(this->members_.m_start, x.members_.m_start);
  298. std::swap(this->members_.m_finish, x.members_.m_finish);
  299. std::swap(this->members_.m_map, x.members_.m_map);
  300. std::swap(this->members_.m_map_size, x.members_.m_map_size);
  301. }
  302. void priv_initialize_map(size_type num_elements)
  303. {
  304. // if(num_elements){
  305. size_type num_nodes = num_elements / s_buffer_size() + 1;
  306. this->members_.m_map_size = container_detail::max_value((size_type) InitialMapSize, num_nodes + 2);
  307. this->members_.m_map = this->priv_allocate_map(this->members_.m_map_size);
  308. ptr_alloc_ptr nstart = this->members_.m_map + (this->members_.m_map_size - num_nodes) / 2;
  309. ptr_alloc_ptr nfinish = nstart + num_nodes;
  310. BOOST_TRY {
  311. this->priv_create_nodes(nstart, nfinish);
  312. }
  313. BOOST_CATCH(...){
  314. this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
  315. this->members_.m_map = 0;
  316. this->members_.m_map_size = 0;
  317. BOOST_RETHROW
  318. }
  319. BOOST_CATCH_END
  320. this->members_.m_start.priv_set_node(nstart);
  321. this->members_.m_finish.priv_set_node(nfinish - 1);
  322. this->members_.m_start.m_cur = this->members_.m_start.m_first;
  323. this->members_.m_finish.m_cur = this->members_.m_finish.m_first +
  324. num_elements % s_buffer_size();
  325. // }
  326. }
  327. void priv_create_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish)
  328. {
  329. ptr_alloc_ptr cur;
  330. BOOST_TRY {
  331. for (cur = nstart; cur < nfinish; ++cur)
  332. *cur = this->priv_allocate_node();
  333. }
  334. BOOST_CATCH(...){
  335. this->priv_destroy_nodes(nstart, cur);
  336. BOOST_RETHROW
  337. }
  338. BOOST_CATCH_END
  339. }
  340. void priv_destroy_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish) BOOST_CONTAINER_NOEXCEPT
  341. {
  342. for (ptr_alloc_ptr n = nstart; n < nfinish; ++n)
  343. this->priv_deallocate_node(*n);
  344. }
  345. void priv_clear_map() BOOST_CONTAINER_NOEXCEPT
  346. {
  347. if (this->members_.m_map) {
  348. this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1);
  349. this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
  350. this->members_.m_map = 0;
  351. this->members_.m_map_size = 0;
  352. this->members_.m_start = iterator();
  353. this->members_.m_finish = this->members_.m_start;
  354. }
  355. }
  356. enum { InitialMapSize = 8 };
  357. protected:
  358. struct members_holder
  359. : public ptr_alloc_t
  360. , public allocator_type
  361. {
  362. members_holder()
  363. : map_allocator_type(), allocator_type()
  364. , m_map(0), m_map_size(0)
  365. , m_start(), m_finish(m_start)
  366. {}
  367. explicit members_holder(const allocator_type &a)
  368. : map_allocator_type(a), allocator_type(a)
  369. , m_map(0), m_map_size(0)
  370. , m_start(), m_finish(m_start)
  371. {}
  372. template<class ValAllocConvertible, class PtrAllocConvertible>
  373. members_holder(BOOST_FWD_REF(PtrAllocConvertible) pa, BOOST_FWD_REF(ValAllocConvertible) va)
  374. : map_allocator_type(boost::forward<PtrAllocConvertible>(pa))
  375. , allocator_type (boost::forward<ValAllocConvertible>(va))
  376. , m_map(0), m_map_size(0)
  377. , m_start(), m_finish(m_start)
  378. {}
  379. ptr_alloc_ptr m_map;
  380. val_alloc_size m_map_size;
  381. iterator m_start;
  382. iterator m_finish;
  383. } members_;
  384. ptr_alloc_t &ptr_alloc() BOOST_CONTAINER_NOEXCEPT
  385. { return members_; }
  386. const ptr_alloc_t &ptr_alloc() const BOOST_CONTAINER_NOEXCEPT
  387. { return members_; }
  388. allocator_type &alloc() BOOST_CONTAINER_NOEXCEPT
  389. { return members_; }
  390. const allocator_type &alloc() const BOOST_CONTAINER_NOEXCEPT
  391. { return members_; }
  392. };
  393. /// @endcond
  394. //! Deque class
  395. //!
  396. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
  397. template <class T, class Allocator = std::allocator<T> >
  398. #else
  399. template <class T, class Allocator>
  400. #endif
  401. class deque : protected deque_base<Allocator>
  402. {
  403. /// @cond
  404. private:
  405. typedef deque_base<Allocator> Base;
  406. /// @endcond
  407. public:
  408. //////////////////////////////////////////////
  409. //
  410. // types
  411. //
  412. //////////////////////////////////////////////
  413. typedef T value_type;
  414. typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
  415. typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
  416. typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
  417. typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
  418. typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
  419. typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
  420. typedef Allocator allocator_type;
  421. typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type;
  422. typedef BOOST_CONTAINER_IMPDEF(typename Base::iterator) iterator;
  423. typedef BOOST_CONTAINER_IMPDEF(typename Base::const_iterator) const_iterator;
  424. typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
  425. typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
  426. /// @cond
  427. private: // Internal typedefs
  428. BOOST_COPYABLE_AND_MOVABLE(deque)
  429. typedef typename Base::ptr_alloc_ptr index_pointer;
  430. static size_type s_buffer_size()
  431. { return Base::s_buffer_size(); }
  432. typedef allocator_traits<Allocator> allocator_traits_type;
  433. /// @endcond
  434. public:
  435. //////////////////////////////////////////////
  436. //
  437. // construct/copy/destroy
  438. //
  439. //////////////////////////////////////////////
  440. //! <b>Effects</b>: Default constructors a deque.
  441. //!
  442. //! <b>Throws</b>: If allocator_type's default constructor throws.
  443. //!
  444. //! <b>Complexity</b>: Constant.
  445. deque()
  446. : Base()
  447. {}
  448. //! <b>Effects</b>: Constructs a deque taking the allocator as parameter.
  449. //!
  450. //! <b>Throws</b>: Nothing
  451. //!
  452. //! <b>Complexity</b>: Constant.
  453. explicit deque(const allocator_type& a) BOOST_CONTAINER_NOEXCEPT
  454. : Base(a)
  455. {}
  456. //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
  457. //! and inserts n value initialized values.
  458. //!
  459. //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
  460. //! throws or T's default or copy constructor throws.
  461. //!
  462. //! <b>Complexity</b>: Linear to n.
  463. explicit deque(size_type n)
  464. : Base(n, allocator_type())
  465. {
  466. container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
  467. proxy.uninitialized_copy_n_and_update(this->begin(), n);
  468. //deque_base will deallocate in case of exception...
  469. }
  470. //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
  471. //! and inserts n default initialized values.
  472. //!
  473. //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
  474. //! throws or T's default or copy constructor throws.
  475. //!
  476. //! <b>Complexity</b>: Linear to n.
  477. //!
  478. //! <b>Note</b>: Non-standard extension
  479. deque(size_type n, default_init_t)
  480. : Base(n, allocator_type())
  481. {
  482. container_detail::insert_default_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
  483. proxy.uninitialized_copy_n_and_update(this->begin(), n);
  484. //deque_base will deallocate in case of exception...
  485. }
  486. //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
  487. //! and inserts n copies of value.
  488. //!
  489. //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
  490. //! throws or T's default or copy constructor throws.
  491. //!
  492. //! <b>Complexity</b>: Linear to n.
  493. deque(size_type n, const value_type& value,
  494. const allocator_type& a = allocator_type())
  495. : Base(n, a)
  496. { this->priv_fill_initialize(value); }
  497. //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
  498. //! and inserts a copy of the range [first, last) in the deque.
  499. //!
  500. //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
  501. //! throws or T's constructor taking an dereferenced InIt throws.
  502. //!
  503. //! <b>Complexity</b>: Linear to the range [first, last).
  504. template <class InIt>
  505. deque(InIt first, InIt last, const allocator_type& a = allocator_type()
  506. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  507. , typename container_detail::enable_if_c
  508. < !container_detail::is_convertible<InIt, size_type>::value
  509. >::type * = 0
  510. #endif
  511. )
  512. : Base(a)
  513. {
  514. typedef typename std::iterator_traits<InIt>::iterator_category ItCat;
  515. this->priv_range_initialize(first, last, ItCat());
  516. }
  517. //! <b>Effects</b>: Copy constructs a deque.
  518. //!
  519. //! <b>Postcondition</b>: x == *this.
  520. //!
  521. //! <b>Complexity</b>: Linear to the elements x contains.
  522. deque(const deque& x)
  523. : Base(allocator_traits_type::select_on_container_copy_construction(x.alloc()))
  524. {
  525. if(x.size()){
  526. this->priv_initialize_map(x.size());
  527. boost::container::uninitialized_copy_alloc
  528. (this->alloc(), x.begin(), x.end(), this->members_.m_start);
  529. }
  530. }
  531. //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
  532. //!
  533. //! <b>Throws</b>: If allocator_type's copy constructor throws.
  534. //!
  535. //! <b>Complexity</b>: Constant.
  536. deque(BOOST_RV_REF(deque) x)
  537. : Base(boost::move(static_cast<Base&>(x)))
  538. { this->swap_members(x); }
  539. //! <b>Effects</b>: Copy constructs a vector using the specified allocator.
  540. //!
  541. //! <b>Postcondition</b>: x == *this.
  542. //!
  543. //! <b>Throws</b>: If allocation
  544. //! throws or T's copy constructor throws.
  545. //!
  546. //! <b>Complexity</b>: Linear to the elements x contains.
  547. deque(const deque& x, const allocator_type &a)
  548. : Base(a)
  549. {
  550. if(x.size()){
  551. this->priv_initialize_map(x.size());
  552. boost::container::uninitialized_copy_alloc
  553. (this->alloc(), x.begin(), x.end(), this->members_.m_start);
  554. }
  555. }
  556. //! <b>Effects</b>: Move constructor using the specified allocator.
  557. //! Moves mx's resources to *this if a == allocator_type().
  558. //! Otherwise copies values from x to *this.
  559. //!
  560. //! <b>Throws</b>: If allocation or T's copy constructor throws.
  561. //!
  562. //! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise.
  563. deque(BOOST_RV_REF(deque) mx, const allocator_type &a)
  564. : Base(a)
  565. {
  566. if(mx.alloc() == a){
  567. this->swap_members(mx);
  568. }
  569. else{
  570. if(mx.size()){
  571. this->priv_initialize_map(mx.size());
  572. boost::container::uninitialized_copy_alloc
  573. (this->alloc(), mx.begin(), mx.end(), this->members_.m_start);
  574. }
  575. }
  576. }
  577. //! <b>Effects</b>: Destroys the deque. All stored values are destroyed
  578. //! and used memory is deallocated.
  579. //!
  580. //! <b>Throws</b>: Nothing.
  581. //!
  582. //! <b>Complexity</b>: Linear to the number of elements.
  583. ~deque() BOOST_CONTAINER_NOEXCEPT
  584. {
  585. this->priv_destroy_range(this->members_.m_start, this->members_.m_finish);
  586. }
  587. //! <b>Effects</b>: Makes *this contain the same elements as x.
  588. //!
  589. //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
  590. //! of each of x's elements.
  591. //!
  592. //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
  593. //!
  594. //! <b>Complexity</b>: Linear to the number of elements in x.
  595. deque& operator= (BOOST_COPY_ASSIGN_REF(deque) x)
  596. {
  597. if (&x != this){
  598. allocator_type &this_alloc = this->alloc();
  599. const allocator_type &x_alloc = x.alloc();
  600. container_detail::bool_<allocator_traits_type::
  601. propagate_on_container_copy_assignment::value> flag;
  602. if(flag && this_alloc != x_alloc){
  603. this->clear();
  604. this->shrink_to_fit();
  605. }
  606. container_detail::assign_alloc(this->alloc(), x.alloc(), flag);
  607. container_detail::assign_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
  608. this->assign(x.cbegin(), x.cend());
  609. }
  610. return *this;
  611. }
  612. //! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
  613. //!
  614. //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
  615. //! before the function.
  616. //!
  617. //! <b>Throws</b>: If allocator_type's copy constructor throws.
  618. //!
  619. //! <b>Complexity</b>: Linear.
  620. deque& operator= (BOOST_RV_REF(deque) x)
  621. {
  622. if (&x != this){
  623. allocator_type &this_alloc = this->alloc();
  624. allocator_type &x_alloc = x.alloc();
  625. //If allocators are equal we can just swap pointers
  626. if(this_alloc == x_alloc){
  627. //Destroy objects but retain memory in case x reuses it in the future
  628. this->clear();
  629. this->swap_members(x);
  630. //Move allocator if needed
  631. container_detail::bool_<allocator_traits_type::
  632. propagate_on_container_move_assignment::value> flag;
  633. container_detail::move_alloc(this_alloc, x_alloc, flag);
  634. container_detail::move_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
  635. }
  636. //If unequal allocators, then do a one by one move
  637. else{
  638. this->assign( boost::make_move_iterator(x.begin())
  639. , boost::make_move_iterator(x.end()));
  640. }
  641. }
  642. return *this;
  643. }
  644. //! <b>Effects</b>: Assigns the n copies of val to *this.
  645. //!
  646. //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
  647. //!
  648. //! <b>Complexity</b>: Linear to n.
  649. void assign(size_type n, const T& val)
  650. {
  651. typedef constant_iterator<value_type, difference_type> c_it;
  652. this->assign(c_it(val, n), c_it());
  653. }
  654. //! <b>Effects</b>: Assigns the the range [first, last) to *this.
  655. //!
  656. //! <b>Throws</b>: If memory allocation throws or
  657. //! T's constructor from dereferencing InIt throws.
  658. //!
  659. //! <b>Complexity</b>: Linear to n.
  660. template <class InIt>
  661. void assign(InIt first, InIt last
  662. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  663. , typename container_detail::enable_if_c
  664. < !container_detail::is_convertible<InIt, size_type>::value
  665. && container_detail::is_input_iterator<InIt>::value
  666. >::type * = 0
  667. #endif
  668. )
  669. {
  670. iterator cur = this->begin();
  671. for ( ; first != last && cur != end(); ++cur, ++first){
  672. *cur = *first;
  673. }
  674. if (first == last){
  675. this->erase(cur, this->cend());
  676. }
  677. else{
  678. this->insert(this->cend(), first, last);
  679. }
  680. }
  681. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  682. template <class FwdIt>
  683. void assign(FwdIt first, FwdIt last
  684. , typename container_detail::enable_if_c
  685. < !container_detail::is_convertible<FwdIt, size_type>::value
  686. && !container_detail::is_input_iterator<FwdIt>::value
  687. >::type * = 0
  688. )
  689. {
  690. const size_type len = std::distance(first, last);
  691. if (len > size()) {
  692. FwdIt mid = first;
  693. std::advance(mid, this->size());
  694. boost::container::copy(first, mid, begin());
  695. this->insert(this->cend(), mid, last);
  696. }
  697. else{
  698. this->erase(boost::container::copy(first, last, this->begin()), cend());
  699. }
  700. }
  701. #endif
  702. //! <b>Effects</b>: Returns a copy of the internal allocator.
  703. //!
  704. //! <b>Throws</b>: If allocator's copy constructor throws.
  705. //!
  706. //! <b>Complexity</b>: Constant.
  707. allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
  708. { return Base::alloc(); }
  709. //! <b>Effects</b>: Returns a reference to the internal allocator.
  710. //!
  711. //! <b>Throws</b>: Nothing
  712. //!
  713. //! <b>Complexity</b>: Constant.
  714. //!
  715. //! <b>Note</b>: Non-standard extension.
  716. const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
  717. { return Base::alloc(); }
  718. //////////////////////////////////////////////
  719. //
  720. // iterators
  721. //
  722. //////////////////////////////////////////////
  723. //! <b>Effects</b>: Returns a reference to the internal allocator.
  724. //!
  725. //! <b>Throws</b>: Nothing
  726. //!
  727. //! <b>Complexity</b>: Constant.
  728. //!
  729. //! <b>Note</b>: Non-standard extension.
  730. stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
  731. { return Base::alloc(); }
  732. //! <b>Effects</b>: Returns an iterator to the first element contained in the deque.
  733. //!
  734. //! <b>Throws</b>: Nothing.
  735. //!
  736. //! <b>Complexity</b>: Constant.
  737. iterator begin() BOOST_CONTAINER_NOEXCEPT
  738. { return this->members_.m_start; }
  739. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the deque.
  740. //!
  741. //! <b>Throws</b>: Nothing.
  742. //!
  743. //! <b>Complexity</b>: Constant.
  744. const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
  745. { return this->members_.m_start; }
  746. //! <b>Effects</b>: Returns an iterator to the end of the deque.
  747. //!
  748. //! <b>Throws</b>: Nothing.
  749. //!
  750. //! <b>Complexity</b>: Constant.
  751. iterator end() BOOST_CONTAINER_NOEXCEPT
  752. { return this->members_.m_finish; }
  753. //! <b>Effects</b>: Returns a const_iterator to the end of the deque.
  754. //!
  755. //! <b>Throws</b>: Nothing.
  756. //!
  757. //! <b>Complexity</b>: Constant.
  758. const_iterator end() const BOOST_CONTAINER_NOEXCEPT
  759. { return this->members_.m_finish; }
  760. //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
  761. //! of the reversed deque.
  762. //!
  763. //! <b>Throws</b>: Nothing.
  764. //!
  765. //! <b>Complexity</b>: Constant.
  766. reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
  767. { return reverse_iterator(this->members_.m_finish); }
  768. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
  769. //! of the reversed deque.
  770. //!
  771. //! <b>Throws</b>: Nothing.
  772. //!
  773. //! <b>Complexity</b>: Constant.
  774. const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
  775. { return const_reverse_iterator(this->members_.m_finish); }
  776. //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
  777. //! of the reversed deque.
  778. //!
  779. //! <b>Throws</b>: Nothing.
  780. //!
  781. //! <b>Complexity</b>: Constant.
  782. reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
  783. { return reverse_iterator(this->members_.m_start); }
  784. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
  785. //! of the reversed deque.
  786. //!
  787. //! <b>Throws</b>: Nothing.
  788. //!
  789. //! <b>Complexity</b>: Constant.
  790. const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
  791. { return const_reverse_iterator(this->members_.m_start); }
  792. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the deque.
  793. //!
  794. //! <b>Throws</b>: Nothing.
  795. //!
  796. //! <b>Complexity</b>: Constant.
  797. const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
  798. { return this->members_.m_start; }
  799. //! <b>Effects</b>: Returns a const_iterator to the end of the deque.
  800. //!
  801. //! <b>Throws</b>: Nothing.
  802. //!
  803. //! <b>Complexity</b>: Constant.
  804. const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
  805. { return this->members_.m_finish; }
  806. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
  807. //! of the reversed deque.
  808. //!
  809. //! <b>Throws</b>: Nothing.
  810. //!
  811. //! <b>Complexity</b>: Constant.
  812. const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
  813. { return const_reverse_iterator(this->members_.m_finish); }
  814. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
  815. //! of the reversed deque.
  816. //!
  817. //! <b>Throws</b>: Nothing.
  818. //!
  819. //! <b>Complexity</b>: Constant.
  820. const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
  821. { return const_reverse_iterator(this->members_.m_start); }
  822. //////////////////////////////////////////////
  823. //
  824. // capacity
  825. //
  826. //////////////////////////////////////////////
  827. //! <b>Effects</b>: Returns true if the deque contains no elements.
  828. //!
  829. //! <b>Throws</b>: Nothing.
  830. //!
  831. //! <b>Complexity</b>: Constant.
  832. bool empty() const BOOST_CONTAINER_NOEXCEPT
  833. { return this->members_.m_finish == this->members_.m_start; }
  834. //! <b>Effects</b>: Returns the number of the elements contained in the deque.
  835. //!
  836. //! <b>Throws</b>: Nothing.
  837. //!
  838. //! <b>Complexity</b>: Constant.
  839. size_type size() const BOOST_CONTAINER_NOEXCEPT
  840. { return this->members_.m_finish - this->members_.m_start; }
  841. //! <b>Effects</b>: Returns the largest possible size of the deque.
  842. //!
  843. //! <b>Throws</b>: Nothing.
  844. //!
  845. //! <b>Complexity</b>: Constant.
  846. size_type max_size() const BOOST_CONTAINER_NOEXCEPT
  847. { return allocator_traits_type::max_size(this->alloc()); }
  848. //! <b>Effects</b>: Inserts or erases elements at the end such that
  849. //! the size becomes n. New elements are value initialized.
  850. //!
  851. //! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
  852. //!
  853. //! <b>Complexity</b>: Linear to the difference between size() and new_size.
  854. void resize(size_type new_size)
  855. {
  856. const size_type len = size();
  857. if (new_size < len)
  858. this->priv_erase_last_n(len - new_size);
  859. else{
  860. const size_type n = new_size - this->size();
  861. container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
  862. priv_insert_back_aux_impl(n, proxy);
  863. }
  864. }
  865. //! <b>Effects</b>: Inserts or erases elements at the end such that
  866. //! the size becomes n. New elements are default initialized.
  867. //!
  868. //! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
  869. //!
  870. //! <b>Complexity</b>: Linear to the difference between size() and new_size.
  871. //!
  872. //! <b>Note</b>: Non-standard extension
  873. void resize(size_type new_size, default_init_t)
  874. {
  875. const size_type len = size();
  876. if (new_size < len)
  877. this->priv_erase_last_n(len - new_size);
  878. else{
  879. const size_type n = new_size - this->size();
  880. container_detail::insert_default_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
  881. priv_insert_back_aux_impl(n, proxy);
  882. }
  883. }
  884. //! <b>Effects</b>: Inserts or erases elements at the end such that
  885. //! the size becomes n. New elements are copy constructed from x.
  886. //!
  887. //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
  888. //!
  889. //! <b>Complexity</b>: Linear to the difference between size() and new_size.
  890. void resize(size_type new_size, const value_type& x)
  891. {
  892. const size_type len = size();
  893. if (new_size < len)
  894. this->erase(this->members_.m_start + new_size, this->members_.m_finish);
  895. else
  896. this->insert(this->members_.m_finish, new_size - len, x);
  897. }
  898. //! <b>Effects</b>: Tries to deallocate the excess of memory created
  899. //! with previous allocations. The size of the deque is unchanged
  900. //!
  901. //! <b>Throws</b>: If memory allocation throws.
  902. //!
  903. //! <b>Complexity</b>: Constant.
  904. void shrink_to_fit()
  905. {
  906. //This deque implementation already
  907. //deallocates excess nodes when erasing
  908. //so there is nothing to do except for
  909. //empty deque
  910. if(this->empty()){
  911. this->priv_clear_map();
  912. }
  913. }
  914. //////////////////////////////////////////////
  915. //
  916. // element access
  917. //
  918. //////////////////////////////////////////////
  919. //! <b>Requires</b>: !empty()
  920. //!
  921. //! <b>Effects</b>: Returns a reference to the first
  922. //! element of the container.
  923. //!
  924. //! <b>Throws</b>: Nothing.
  925. //!
  926. //! <b>Complexity</b>: Constant.
  927. reference front() BOOST_CONTAINER_NOEXCEPT
  928. { return *this->members_.m_start; }
  929. //! <b>Requires</b>: !empty()
  930. //!
  931. //! <b>Effects</b>: Returns a const reference to the first element
  932. //! from the beginning of the container.
  933. //!
  934. //! <b>Throws</b>: Nothing.
  935. //!
  936. //! <b>Complexity</b>: Constant.
  937. const_reference front() const BOOST_CONTAINER_NOEXCEPT
  938. { return *this->members_.m_start; }
  939. //! <b>Requires</b>: !empty()
  940. //!
  941. //! <b>Effects</b>: Returns a reference to the last
  942. //! element of the container.
  943. //!
  944. //! <b>Throws</b>: Nothing.
  945. //!
  946. //! <b>Complexity</b>: Constant.
  947. reference back() BOOST_CONTAINER_NOEXCEPT
  948. { return *(end()-1); }
  949. //! <b>Requires</b>: !empty()
  950. //!
  951. //! <b>Effects</b>: Returns a const reference to the last
  952. //! element of the container.
  953. //!
  954. //! <b>Throws</b>: Nothing.
  955. //!
  956. //! <b>Complexity</b>: Constant.
  957. const_reference back() const BOOST_CONTAINER_NOEXCEPT
  958. { return *(cend()-1); }
  959. //! <b>Requires</b>: size() > n.
  960. //!
  961. //! <b>Effects</b>: Returns a reference to the nth element
  962. //! from the beginning of the container.
  963. //!
  964. //! <b>Throws</b>: Nothing.
  965. //!
  966. //! <b>Complexity</b>: Constant.
  967. reference operator[](size_type n) BOOST_CONTAINER_NOEXCEPT
  968. { return this->members_.m_start[difference_type(n)]; }
  969. //! <b>Requires</b>: size() > n.
  970. //!
  971. //! <b>Effects</b>: Returns a const reference to the nth element
  972. //! from the beginning of the container.
  973. //!
  974. //! <b>Throws</b>: Nothing.
  975. //!
  976. //! <b>Complexity</b>: Constant.
  977. const_reference operator[](size_type n) const BOOST_CONTAINER_NOEXCEPT
  978. { return this->members_.m_start[difference_type(n)]; }
  979. //! <b>Requires</b>: size() > n.
  980. //!
  981. //! <b>Effects</b>: Returns a reference to the nth element
  982. //! from the beginning of the container.
  983. //!
  984. //! <b>Throws</b>: std::range_error if n >= size()
  985. //!
  986. //! <b>Complexity</b>: Constant.
  987. reference at(size_type n)
  988. { this->priv_range_check(n); return (*this)[n]; }
  989. //! <b>Requires</b>: size() > n.
  990. //!
  991. //! <b>Effects</b>: Returns a const reference to the nth element
  992. //! from the beginning of the container.
  993. //!
  994. //! <b>Throws</b>: std::range_error if n >= size()
  995. //!
  996. //! <b>Complexity</b>: Constant.
  997. const_reference at(size_type n) const
  998. { this->priv_range_check(n); return (*this)[n]; }
  999. //////////////////////////////////////////////
  1000. //
  1001. // modifiers
  1002. //
  1003. //////////////////////////////////////////////
  1004. #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1005. //! <b>Effects</b>: Inserts an object of type T constructed with
  1006. //! std::forward<Args>(args)... in the beginning of the deque.
  1007. //!
  1008. //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
  1009. //!
  1010. //! <b>Complexity</b>: Amortized constant time
  1011. template <class... Args>
  1012. void emplace_front(Args&&... args)
  1013. {
  1014. if(this->priv_push_front_simple_available()){
  1015. allocator_traits_type::construct
  1016. ( this->alloc()
  1017. , this->priv_push_front_simple_pos()
  1018. , boost::forward<Args>(args)...);
  1019. this->priv_push_front_simple_commit();
  1020. }
  1021. else{
  1022. typedef container_detail::insert_non_movable_emplace_proxy<Allocator, iterator, Args...> type;
  1023. this->priv_insert_front_aux_impl(1, type(this->alloc(), boost::forward<Args>(args)...));
  1024. }
  1025. }
  1026. //! <b>Effects</b>: Inserts an object of type T constructed with
  1027. //! std::forward<Args>(args)... in the end of the deque.
  1028. //!
  1029. //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
  1030. //!
  1031. //! <b>Complexity</b>: Amortized constant time
  1032. template <class... Args>
  1033. void emplace_back(Args&&... args)
  1034. {
  1035. if(this->priv_push_back_simple_available()){
  1036. allocator_traits_type::construct
  1037. ( this->alloc()
  1038. , this->priv_push_back_simple_pos()
  1039. , boost::forward<Args>(args)...);
  1040. this->priv_push_back_simple_commit();
  1041. }
  1042. else{
  1043. typedef container_detail::insert_non_movable_emplace_proxy<Allocator, iterator, Args...> type;
  1044. this->priv_insert_back_aux_impl(1, type(this->alloc(), boost::forward<Args>(args)...));
  1045. }
  1046. }
  1047. //! <b>Requires</b>: position must be a valid iterator of *this.
  1048. //!
  1049. //! <b>Effects</b>: Inserts an object of type T constructed with
  1050. //! std::forward<Args>(args)... before position
  1051. //!
  1052. //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
  1053. //!
  1054. //! <b>Complexity</b>: If position is end(), amortized constant time
  1055. //! Linear time otherwise.
  1056. template <class... Args>
  1057. iterator emplace(const_iterator p, Args&&... args)
  1058. {
  1059. if(p == this->cbegin()){
  1060. this->emplace_front(boost::forward<Args>(args)...);
  1061. return this->begin();
  1062. }
  1063. else if(p == this->cend()){
  1064. this->emplace_back(boost::forward<Args>(args)...);
  1065. return (this->end()-1);
  1066. }
  1067. else{
  1068. typedef container_detail::insert_emplace_proxy<Allocator, iterator, Args...> type;
  1069. return this->priv_insert_aux_impl(p, 1, type(this->alloc(), boost::forward<Args>(args)...));
  1070. }
  1071. }
  1072. #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
  1073. //advanced_insert_int.hpp includes all necessary preprocessor machinery...
  1074. #define BOOST_PP_LOCAL_MACRO(n) \
  1075. BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, > ) \
  1076. void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
  1077. { \
  1078. if(priv_push_front_simple_available()){ \
  1079. allocator_traits_type::construct \
  1080. ( this->alloc() \
  1081. , this->priv_push_front_simple_pos() \
  1082. BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
  1083. priv_push_front_simple_commit(); \
  1084. } \
  1085. else{ \
  1086. container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
  1087. <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
  1088. (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
  1089. priv_insert_front_aux_impl(1, proxy); \
  1090. } \
  1091. } \
  1092. \
  1093. BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
  1094. void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
  1095. { \
  1096. if(priv_push_back_simple_available()){ \
  1097. allocator_traits_type::construct \
  1098. ( this->alloc() \
  1099. , this->priv_push_back_simple_pos() \
  1100. BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
  1101. priv_push_back_simple_commit(); \
  1102. } \
  1103. else{ \
  1104. container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
  1105. <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
  1106. (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
  1107. priv_insert_back_aux_impl(1, proxy); \
  1108. } \
  1109. } \
  1110. \
  1111. BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
  1112. iterator emplace(const_iterator p \
  1113. BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
  1114. { \
  1115. if(p == this->cbegin()){ \
  1116. this->emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
  1117. return this->begin(); \
  1118. } \
  1119. else if(p == cend()){ \
  1120. this->emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
  1121. return (this->end()-1); \
  1122. } \
  1123. else{ \
  1124. container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
  1125. <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
  1126. (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
  1127. return this->priv_insert_aux_impl(p, 1, proxy); \
  1128. } \
  1129. } \
  1130. //!
  1131. #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
  1132. #include BOOST_PP_LOCAL_ITERATE()
  1133. #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
  1134. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1135. //! <b>Effects</b>: Inserts a copy of x at the front of the deque.
  1136. //!
  1137. //! <b>Throws</b>: If memory allocation throws or
  1138. //! T's copy constructor throws.
  1139. //!
  1140. //! <b>Complexity</b>: Amortized constant time.
  1141. void push_front(const T &x);
  1142. //! <b>Effects</b>: Constructs a new element in the front of the deque
  1143. //! and moves the resources of mx to this new element.
  1144. //!
  1145. //! <b>Throws</b>: If memory allocation throws.
  1146. //!
  1147. //! <b>Complexity</b>: Amortized constant time.
  1148. void push_front(T &&x);
  1149. #else
  1150. BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
  1151. #endif
  1152. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1153. //! <b>Effects</b>: Inserts a copy of x at the end of the deque.
  1154. //!
  1155. //! <b>Throws</b>: If memory allocation throws or
  1156. //! T's copy constructor throws.
  1157. //!
  1158. //! <b>Complexity</b>: Amortized constant time.
  1159. void push_back(const T &x);
  1160. //! <b>Effects</b>: Constructs a new element in the end of the deque
  1161. //! and moves the resources of mx to this new element.
  1162. //!
  1163. //! <b>Throws</b>: If memory allocation throws.
  1164. //!
  1165. //! <b>Complexity</b>: Amortized constant time.
  1166. void push_back(T &&x);
  1167. #else
  1168. BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
  1169. #endif
  1170. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1171. //! <b>Requires</b>: position must be a valid iterator of *this.
  1172. //!
  1173. //! <b>Effects</b>: Insert a copy of x before position.
  1174. //!
  1175. //! <b>Returns</b>: an iterator to the inserted element.
  1176. //!
  1177. //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
  1178. //!
  1179. //! <b>Complexity</b>: If position is end(), amortized constant time
  1180. //! Linear time otherwise.
  1181. iterator insert(const_iterator position, const T &x);
  1182. //! <b>Requires</b>: position must be a valid iterator of *this.
  1183. //!
  1184. //! <b>Effects</b>: Insert a new element before position with mx's resources.
  1185. //!
  1186. //! <b>Returns</b>: an iterator to the inserted element.
  1187. //!
  1188. //! <b>Throws</b>: If memory allocation throws.
  1189. //!
  1190. //! <b>Complexity</b>: If position is end(), amortized constant time
  1191. //! Linear time otherwise.
  1192. iterator insert(const_iterator position, T &&x);
  1193. #else
  1194. BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
  1195. #endif
  1196. //! <b>Requires</b>: pos must be a valid iterator of *this.
  1197. //!
  1198. //! <b>Effects</b>: Insert n copies of x before pos.
  1199. //!
  1200. //! <b>Returns</b>: an iterator to the first inserted element or pos if n is 0.
  1201. //!
  1202. //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
  1203. //!
  1204. //! <b>Complexity</b>: Linear to n.
  1205. iterator insert(const_iterator pos, size_type n, const value_type& x)
  1206. {
  1207. typedef constant_iterator<value_type, difference_type> c_it;
  1208. return this->insert(pos, c_it(x, n), c_it());
  1209. }
  1210. //! <b>Requires</b>: pos must be a valid iterator of *this.
  1211. //!
  1212. //! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
  1213. //!
  1214. //! <b>Returns</b>: an iterator to the first inserted element or pos if first == last.
  1215. //!
  1216. //! <b>Throws</b>: If memory allocation throws, T's constructor from a
  1217. //! dereferenced InIt throws or T's copy constructor throws.
  1218. //!
  1219. //! <b>Complexity</b>: Linear to std::distance [first, last).
  1220. template <class InIt>
  1221. iterator insert(const_iterator pos, InIt first, InIt last
  1222. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1223. , typename container_detail::enable_if_c
  1224. < !container_detail::is_convertible<InIt, size_type>::value
  1225. && container_detail::is_input_iterator<InIt>::value
  1226. >::type * = 0
  1227. #endif
  1228. )
  1229. {
  1230. size_type n = 0;
  1231. iterator it(pos.unconst());
  1232. for(;first != last; ++first, ++n){
  1233. it = this->emplace(it, *first);
  1234. ++it;
  1235. }
  1236. it -= n;
  1237. return it;
  1238. }
  1239. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1240. template <class FwdIt>
  1241. iterator insert(const_iterator p, FwdIt first, FwdIt last
  1242. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1243. , typename container_detail::enable_if_c
  1244. < !container_detail::is_convertible<FwdIt, size_type>::value
  1245. && !container_detail::is_input_iterator<FwdIt>::value
  1246. >::type * = 0
  1247. #endif
  1248. )
  1249. {
  1250. container_detail::insert_range_proxy<Allocator, FwdIt, iterator> proxy(this->alloc(), first);
  1251. return priv_insert_aux_impl(p, (size_type)std::distance(first, last), proxy);
  1252. }
  1253. #endif
  1254. //! <b>Effects</b>: Removes the first element from the deque.
  1255. //!
  1256. //! <b>Throws</b>: Nothing.
  1257. //!
  1258. //! <b>Complexity</b>: Constant time.
  1259. void pop_front() BOOST_CONTAINER_NOEXCEPT
  1260. {
  1261. if (this->members_.m_start.m_cur != this->members_.m_start.m_last - 1) {
  1262. allocator_traits_type::destroy
  1263. ( this->alloc()
  1264. , container_detail::to_raw_pointer(this->members_.m_start.m_cur)
  1265. );
  1266. ++this->members_.m_start.m_cur;
  1267. }
  1268. else
  1269. this->priv_pop_front_aux();
  1270. }
  1271. //! <b>Effects</b>: Removes the last element from the deque.
  1272. //!
  1273. //! <b>Throws</b>: Nothing.
  1274. //!
  1275. //! <b>Complexity</b>: Constant time.
  1276. void pop_back() BOOST_CONTAINER_NOEXCEPT
  1277. {
  1278. if (this->members_.m_finish.m_cur != this->members_.m_finish.m_first) {
  1279. --this->members_.m_finish.m_cur;
  1280. allocator_traits_type::destroy
  1281. ( this->alloc()
  1282. , container_detail::to_raw_pointer(this->members_.m_finish.m_cur)
  1283. );
  1284. }
  1285. else
  1286. this->priv_pop_back_aux();
  1287. }
  1288. //! <b>Effects</b>: Erases the element at position pos.
  1289. //!
  1290. //! <b>Throws</b>: Nothing.
  1291. //!
  1292. //! <b>Complexity</b>: Linear to the elements between pos and the
  1293. //! last element (if pos is near the end) or the first element
  1294. //! if(pos is near the beginning).
  1295. //! Constant if pos is the first or the last element.
  1296. iterator erase(const_iterator pos) BOOST_CONTAINER_NOEXCEPT
  1297. {
  1298. iterator next = pos.unconst();
  1299. ++next;
  1300. size_type index = pos - this->members_.m_start;
  1301. if (index < (this->size()/2)) {
  1302. boost::move_backward(this->begin(), pos.unconst(), next);
  1303. pop_front();
  1304. }
  1305. else {
  1306. boost::move(next, this->end(), pos.unconst());
  1307. pop_back();
  1308. }
  1309. return this->members_.m_start + index;
  1310. }
  1311. //! <b>Effects</b>: Erases the elements pointed by [first, last).
  1312. //!
  1313. //! <b>Throws</b>: Nothing.
  1314. //!
  1315. //! <b>Complexity</b>: Linear to the distance between first and
  1316. //! last plus the elements between pos and the
  1317. //! last element (if pos is near the end) or the first element
  1318. //! if(pos is near the beginning).
  1319. iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
  1320. {
  1321. if (first == this->members_.m_start && last == this->members_.m_finish) {
  1322. this->clear();
  1323. return this->members_.m_finish;
  1324. }
  1325. else {
  1326. const size_type n = static_cast<size_type>(last - first);
  1327. const size_type elems_before = static_cast<size_type>(first - this->members_.m_start);
  1328. if (elems_before < (this->size() - n) - elems_before) {
  1329. boost::move_backward(begin(), first.unconst(), last.unconst());
  1330. iterator new_start = this->members_.m_start + n;
  1331. if(!Base::traits_t::trivial_dctr_after_move)
  1332. this->priv_destroy_range(this->members_.m_start, new_start);
  1333. this->priv_destroy_nodes(this->members_.m_start.m_node, new_start.m_node);
  1334. this->members_.m_start = new_start;
  1335. }
  1336. else {
  1337. boost::move(last.unconst(), end(), first.unconst());
  1338. iterator new_finish = this->members_.m_finish - n;
  1339. if(!Base::traits_t::trivial_dctr_after_move)
  1340. this->priv_destroy_range(new_finish, this->members_.m_finish);
  1341. this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
  1342. this->members_.m_finish = new_finish;
  1343. }
  1344. return this->members_.m_start + elems_before;
  1345. }
  1346. }
  1347. //! <b>Effects</b>: Swaps the contents of *this and x.
  1348. //!
  1349. //! <b>Throws</b>: Nothing.
  1350. //!
  1351. //! <b>Complexity</b>: Constant.
  1352. void swap(deque &x)
  1353. {
  1354. this->swap_members(x);
  1355. container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
  1356. container_detail::swap_alloc(this->alloc(), x.alloc(), flag);
  1357. container_detail::swap_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
  1358. }
  1359. //! <b>Effects</b>: Erases all the elements of the deque.
  1360. //!
  1361. //! <b>Throws</b>: Nothing.
  1362. //!
  1363. //! <b>Complexity</b>: Linear to the number of elements in the deque.
  1364. void clear() BOOST_CONTAINER_NOEXCEPT
  1365. {
  1366. for (index_pointer node = this->members_.m_start.m_node + 1;
  1367. node < this->members_.m_finish.m_node;
  1368. ++node) {
  1369. this->priv_destroy_range(*node, *node + this->s_buffer_size());
  1370. this->priv_deallocate_node(*node);
  1371. }
  1372. if (this->members_.m_start.m_node != this->members_.m_finish.m_node) {
  1373. this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_start.m_last);
  1374. this->priv_destroy_range(this->members_.m_finish.m_first, this->members_.m_finish.m_cur);
  1375. this->priv_deallocate_node(this->members_.m_finish.m_first);
  1376. }
  1377. else
  1378. this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_finish.m_cur);
  1379. this->members_.m_finish = this->members_.m_start;
  1380. }
  1381. /// @cond
  1382. private:
  1383. void priv_erase_last_n(size_type n)
  1384. {
  1385. if(n == this->size()) {
  1386. this->clear();
  1387. }
  1388. else {
  1389. iterator new_finish = this->members_.m_finish - n;
  1390. if(!Base::traits_t::trivial_dctr_after_move)
  1391. this->priv_destroy_range(new_finish, this->members_.m_finish);
  1392. this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
  1393. this->members_.m_finish = new_finish;
  1394. }
  1395. }
  1396. void priv_range_check(size_type n) const
  1397. { if (n >= this->size()) throw_out_of_range("deque::at out of range"); }
  1398. template <class U>
  1399. iterator priv_insert(const_iterator position, BOOST_FWD_REF(U) x)
  1400. {
  1401. if (position == cbegin()){
  1402. this->push_front(::boost::forward<U>(x));
  1403. return begin();
  1404. }
  1405. else if (position == cend()){
  1406. this->push_back(::boost::forward<U>(x));
  1407. return --end();
  1408. }
  1409. else {
  1410. return priv_insert_aux_impl
  1411. (position, (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
  1412. }
  1413. }
  1414. template <class U>
  1415. void priv_push_front(BOOST_FWD_REF(U) x)
  1416. {
  1417. if(this->priv_push_front_simple_available()){
  1418. allocator_traits_type::construct
  1419. ( this->alloc(), this->priv_push_front_simple_pos(), ::boost::forward<U>(x));
  1420. this->priv_push_front_simple_commit();
  1421. }
  1422. else{
  1423. priv_insert_aux_impl
  1424. (this->cbegin(), (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
  1425. }
  1426. }
  1427. template <class U>
  1428. void priv_push_back(BOOST_FWD_REF(U) x)
  1429. {
  1430. if(this->priv_push_back_simple_available()){
  1431. allocator_traits_type::construct
  1432. ( this->alloc(), this->priv_push_back_simple_pos(), ::boost::forward<U>(x));
  1433. this->priv_push_back_simple_commit();
  1434. }
  1435. else{
  1436. priv_insert_aux_impl
  1437. (this->cend(), (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
  1438. container_detail::insert_copy_proxy<Allocator, iterator> proxy(this->alloc(), x);
  1439. }
  1440. }
  1441. bool priv_push_back_simple_available() const
  1442. {
  1443. return this->members_.m_map &&
  1444. (this->members_.m_finish.m_cur != (this->members_.m_finish.m_last - 1));
  1445. }
  1446. T *priv_push_back_simple_pos() const
  1447. {
  1448. return container_detail::to_raw_pointer(this->members_.m_finish.m_cur);
  1449. }
  1450. void priv_push_back_simple_commit()
  1451. {
  1452. ++this->members_.m_finish.m_cur;
  1453. }
  1454. bool priv_push_front_simple_available() const
  1455. {
  1456. return this->members_.m_map &&
  1457. (this->members_.m_start.m_cur != this->members_.m_start.m_first);
  1458. }
  1459. T *priv_push_front_simple_pos() const
  1460. { return container_detail::to_raw_pointer(this->members_.m_start.m_cur) - 1; }
  1461. void priv_push_front_simple_commit()
  1462. { --this->members_.m_start.m_cur; }
  1463. void priv_destroy_range(iterator p, iterator p2)
  1464. {
  1465. for(;p != p2; ++p){
  1466. allocator_traits_type::destroy
  1467. ( this->alloc()
  1468. , container_detail::to_raw_pointer(&*p)
  1469. );
  1470. }
  1471. }
  1472. void priv_destroy_range(pointer p, pointer p2)
  1473. {
  1474. for(;p != p2; ++p){
  1475. allocator_traits_type::destroy
  1476. ( this->alloc()
  1477. , container_detail::to_raw_pointer(&*p)
  1478. );
  1479. }
  1480. }
  1481. template<class InsertProxy>
  1482. iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy interf)
  1483. {
  1484. iterator pos(p.unconst());
  1485. const size_type pos_n = p - this->cbegin();
  1486. if(!this->members_.m_map){
  1487. this->priv_initialize_map(0);
  1488. pos = this->begin();
  1489. }
  1490. const size_type elemsbefore = static_cast<size_type>(pos - this->members_.m_start);
  1491. const size_type length = this->size();
  1492. if (elemsbefore < length / 2) {
  1493. const iterator new_start = this->priv_reserve_elements_at_front(n);
  1494. const iterator old_start = this->members_.m_start;
  1495. if(!elemsbefore){
  1496. interf.uninitialized_copy_n_and_update(new_start, n);
  1497. this->members_.m_start = new_start;
  1498. }
  1499. else{
  1500. pos = this->members_.m_start + elemsbefore;
  1501. if (elemsbefore >= n) {
  1502. const iterator start_n = this->members_.m_start + n;
  1503. ::boost::container::uninitialized_move_alloc
  1504. (this->alloc(), this->members_.m_start, start_n, new_start);
  1505. this->members_.m_start = new_start;
  1506. boost::move(start_n, pos, old_start);
  1507. interf.copy_n_and_update(pos - n, n);
  1508. }
  1509. else {
  1510. const size_type mid_count = n - elemsbefore;
  1511. const iterator mid_start = old_start - mid_count;
  1512. interf.uninitialized_copy_n_and_update(mid_start, mid_count);
  1513. this->members_.m_start = mid_start;
  1514. ::boost::container::uninitialized_move_alloc
  1515. (this->alloc(), old_start, pos, new_start);
  1516. this->members_.m_start = new_start;
  1517. interf.copy_n_and_update(old_start, elemsbefore);
  1518. }
  1519. }
  1520. }
  1521. else {
  1522. const iterator new_finish = this->priv_reserve_elements_at_back(n);
  1523. const iterator old_finish = this->members_.m_finish;
  1524. const size_type elemsafter = length - elemsbefore;
  1525. if(!elemsafter){
  1526. interf.uninitialized_copy_n_and_update(old_finish, n);
  1527. this->members_.m_finish = new_finish;
  1528. }
  1529. else{
  1530. pos = old_finish - elemsafter;
  1531. if (elemsafter >= n) {
  1532. iterator finish_n = old_finish - difference_type(n);
  1533. ::boost::container::uninitialized_move_alloc
  1534. (this->alloc(), finish_n, old_finish, old_finish);
  1535. this->members_.m_finish = new_finish;
  1536. boost::move_backward(pos, finish_n, old_finish);
  1537. interf.copy_n_and_update(pos, n);
  1538. }
  1539. else {
  1540. const size_type raw_gap = n - elemsafter;
  1541. ::boost::container::uninitialized_move_alloc
  1542. (this->alloc(), pos, old_finish, old_finish + raw_gap);
  1543. BOOST_TRY{
  1544. interf.copy_n_and_update(pos, elemsafter);
  1545. interf.uninitialized_copy_n_and_update(old_finish, raw_gap);
  1546. }
  1547. BOOST_CATCH(...){
  1548. this->priv_destroy_range(old_finish, old_finish + elemsafter);
  1549. BOOST_RETHROW
  1550. }
  1551. BOOST_CATCH_END
  1552. this->members_.m_finish = new_finish;
  1553. }
  1554. }
  1555. }
  1556. return this->begin() + pos_n;
  1557. }
  1558. template <class InsertProxy>
  1559. iterator priv_insert_back_aux_impl(size_type n, InsertProxy interf)
  1560. {
  1561. if(!this->members_.m_map){
  1562. this->priv_initialize_map(0);
  1563. }
  1564. iterator new_finish = this->priv_reserve_elements_at_back(n);
  1565. iterator old_finish = this->members_.m_finish;
  1566. interf.uninitialized_copy_n_and_update(old_finish, n);
  1567. this->members_.m_finish = new_finish;
  1568. return iterator(this->members_.m_finish - n);
  1569. }
  1570. template <class InsertProxy>
  1571. iterator priv_insert_front_aux_impl(size_type n, InsertProxy interf)
  1572. {
  1573. if(!this->members_.m_map){
  1574. this->priv_initialize_map(0);
  1575. }
  1576. iterator new_start = this->priv_reserve_elements_at_front(n);
  1577. interf.uninitialized_copy_n_and_update(new_start, n);
  1578. this->members_.m_start = new_start;
  1579. return new_start;
  1580. }
  1581. iterator priv_fill_insert(const_iterator pos, size_type n, const value_type& x)
  1582. {
  1583. typedef constant_iterator<value_type, difference_type> c_it;
  1584. return this->insert(pos, c_it(x, n), c_it());
  1585. }
  1586. // Precondition: this->members_.m_start and this->members_.m_finish have already been initialized,
  1587. // but none of the deque's elements have yet been constructed.
  1588. void priv_fill_initialize(const value_type& value)
  1589. {
  1590. index_pointer cur;
  1591. BOOST_TRY {
  1592. for (cur = this->members_.m_start.m_node; cur < this->members_.m_finish.m_node; ++cur){
  1593. boost::container::uninitialized_fill_alloc
  1594. (this->alloc(), *cur, *cur + this->s_buffer_size(), value);
  1595. }
  1596. boost::container::uninitialized_fill_alloc
  1597. (this->alloc(), this->members_.m_finish.m_first, this->members_.m_finish.m_cur, value);
  1598. }
  1599. BOOST_CATCH(...){
  1600. this->priv_destroy_range(this->members_.m_start, iterator(*cur, cur));
  1601. BOOST_RETHROW
  1602. }
  1603. BOOST_CATCH_END
  1604. }
  1605. template <class InIt>
  1606. void priv_range_initialize(InIt first, InIt last, std::input_iterator_tag)
  1607. {
  1608. this->priv_initialize_map(0);
  1609. BOOST_TRY {
  1610. for ( ; first != last; ++first)
  1611. this->emplace_back(*first);
  1612. }
  1613. BOOST_CATCH(...){
  1614. this->clear();
  1615. BOOST_RETHROW
  1616. }
  1617. BOOST_CATCH_END
  1618. }
  1619. template <class FwdIt>
  1620. void priv_range_initialize(FwdIt first, FwdIt last, std::forward_iterator_tag)
  1621. {
  1622. size_type n = 0;
  1623. n = std::distance(first, last);
  1624. this->priv_initialize_map(n);
  1625. index_pointer cur_node;
  1626. BOOST_TRY {
  1627. for (cur_node = this->members_.m_start.m_node;
  1628. cur_node < this->members_.m_finish.m_node;
  1629. ++cur_node) {
  1630. FwdIt mid = first;
  1631. std::advance(mid, this->s_buffer_size());
  1632. ::boost::container::uninitialized_copy_alloc(this->alloc(), first, mid, *cur_node);
  1633. first = mid;
  1634. }
  1635. ::boost::container::uninitialized_copy_alloc(this->alloc(), first, last, this->members_.m_finish.m_first);
  1636. }
  1637. BOOST_CATCH(...){
  1638. this->priv_destroy_range(this->members_.m_start, iterator(*cur_node, cur_node));
  1639. BOOST_RETHROW
  1640. }
  1641. BOOST_CATCH_END
  1642. }
  1643. // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.m_first.
  1644. void priv_pop_back_aux() BOOST_CONTAINER_NOEXCEPT
  1645. {
  1646. this->priv_deallocate_node(this->members_.m_finish.m_first);
  1647. this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node - 1);
  1648. this->members_.m_finish.m_cur = this->members_.m_finish.m_last - 1;
  1649. allocator_traits_type::destroy
  1650. ( this->alloc()
  1651. , container_detail::to_raw_pointer(this->members_.m_finish.m_cur)
  1652. );
  1653. }
  1654. // Called only if this->members_.m_start.m_cur == this->members_.m_start.m_last - 1. Note that
  1655. // if the deque has at least one element (a precondition for this member
  1656. // function), and if this->members_.m_start.m_cur == this->members_.m_start.m_last, then the deque
  1657. // must have at least two nodes.
  1658. void priv_pop_front_aux() BOOST_CONTAINER_NOEXCEPT
  1659. {
  1660. allocator_traits_type::destroy
  1661. ( this->alloc()
  1662. , container_detail::to_raw_pointer(this->members_.m_start.m_cur)
  1663. );
  1664. this->priv_deallocate_node(this->members_.m_start.m_first);
  1665. this->members_.m_start.priv_set_node(this->members_.m_start.m_node + 1);
  1666. this->members_.m_start.m_cur = this->members_.m_start.m_first;
  1667. }
  1668. iterator priv_reserve_elements_at_front(size_type n)
  1669. {
  1670. size_type vacancies = this->members_.m_start.m_cur - this->members_.m_start.m_first;
  1671. if (n > vacancies){
  1672. size_type new_elems = n-vacancies;
  1673. size_type new_nodes = (new_elems + this->s_buffer_size() - 1) /
  1674. this->s_buffer_size();
  1675. size_type s = (size_type)(this->members_.m_start.m_node - this->members_.m_map);
  1676. if (new_nodes > s){
  1677. this->priv_reallocate_map(new_nodes, true);
  1678. }
  1679. size_type i = 1;
  1680. BOOST_TRY {
  1681. for (; i <= new_nodes; ++i)
  1682. *(this->members_.m_start.m_node - i) = this->priv_allocate_node();
  1683. }
  1684. BOOST_CATCH(...) {
  1685. for (size_type j = 1; j < i; ++j)
  1686. this->priv_deallocate_node(*(this->members_.m_start.m_node - j));
  1687. BOOST_RETHROW
  1688. }
  1689. BOOST_CATCH_END
  1690. }
  1691. return this->members_.m_start - difference_type(n);
  1692. }
  1693. iterator priv_reserve_elements_at_back(size_type n)
  1694. {
  1695. size_type vacancies = (this->members_.m_finish.m_last - this->members_.m_finish.m_cur) - 1;
  1696. if (n > vacancies){
  1697. size_type new_elems = n - vacancies;
  1698. size_type new_nodes = (new_elems + this->s_buffer_size() - 1)/s_buffer_size();
  1699. size_type s = (size_type)(this->members_.m_map_size - (this->members_.m_finish.m_node - this->members_.m_map));
  1700. if (new_nodes + 1 > s){
  1701. this->priv_reallocate_map(new_nodes, false);
  1702. }
  1703. size_type i;
  1704. BOOST_TRY {
  1705. for (i = 1; i <= new_nodes; ++i)
  1706. *(this->members_.m_finish.m_node + i) = this->priv_allocate_node();
  1707. }
  1708. BOOST_CATCH(...) {
  1709. for (size_type j = 1; j < i; ++j)
  1710. this->priv_deallocate_node(*(this->members_.m_finish.m_node + j));
  1711. BOOST_RETHROW
  1712. }
  1713. BOOST_CATCH_END
  1714. }
  1715. return this->members_.m_finish + difference_type(n);
  1716. }
  1717. void priv_reallocate_map(size_type nodes_to_add, bool add_at_front)
  1718. {
  1719. size_type old_num_nodes = this->members_.m_finish.m_node - this->members_.m_start.m_node + 1;
  1720. size_type new_num_nodes = old_num_nodes + nodes_to_add;
  1721. index_pointer new_nstart;
  1722. if (this->members_.m_map_size > 2 * new_num_nodes) {
  1723. new_nstart = this->members_.m_map + (this->members_.m_map_size - new_num_nodes) / 2
  1724. + (add_at_front ? nodes_to_add : 0);
  1725. if (new_nstart < this->members_.m_start.m_node)
  1726. boost::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
  1727. else
  1728. boost::move_backward
  1729. (this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart + old_num_nodes);
  1730. }
  1731. else {
  1732. size_type new_map_size =
  1733. this->members_.m_map_size + container_detail::max_value(this->members_.m_map_size, nodes_to_add) + 2;
  1734. index_pointer new_map = this->priv_allocate_map(new_map_size);
  1735. new_nstart = new_map + (new_map_size - new_num_nodes) / 2
  1736. + (add_at_front ? nodes_to_add : 0);
  1737. boost::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
  1738. this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
  1739. this->members_.m_map = new_map;
  1740. this->members_.m_map_size = new_map_size;
  1741. }
  1742. this->members_.m_start.priv_set_node(new_nstart);
  1743. this->members_.m_finish.priv_set_node(new_nstart + old_num_nodes - 1);
  1744. }
  1745. /// @endcond
  1746. };
  1747. // Nonmember functions.
  1748. template <class T, class Allocator>
  1749. inline bool operator==(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
  1750. {
  1751. return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
  1752. }
  1753. template <class T, class Allocator>
  1754. inline bool operator<(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
  1755. {
  1756. return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
  1757. }
  1758. template <class T, class Allocator>
  1759. inline bool operator!=(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
  1760. { return !(x == y); }
  1761. template <class T, class Allocator>
  1762. inline bool operator>(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
  1763. { return y < x; }
  1764. template <class T, class Allocator>
  1765. inline bool operator>=(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
  1766. { return !(x < y); }
  1767. template <class T, class Allocator>
  1768. inline bool operator<=(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
  1769. { return !(y < x); }
  1770. template <class T, class Allocator>
  1771. inline void swap(deque<T, Allocator>& x, deque<T, Allocator>& y)
  1772. { x.swap(y); }
  1773. }}
  1774. /// @cond
  1775. namespace boost {
  1776. //!has_trivial_destructor_after_move<> == true_type
  1777. //!specialization for optimizations
  1778. template <class T, class Allocator>
  1779. struct has_trivial_destructor_after_move<boost::container::deque<T, Allocator> >
  1780. : public ::boost::has_trivial_destructor_after_move<Allocator>
  1781. {};
  1782. }
  1783. /// @endcond
  1784. #include <boost/container/detail/config_end.hpp>
  1785. #endif // #ifndef BOOST_CONTAINER_DEQUE_HPP