comparison DEPENDENCIES/generic/include/boost/container/deque.hpp @ 101:c530137014c0

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