deque.hpp 80 KB

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