deque.hpp 88 KB

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