]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/container/list.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / container / list.hpp
CommitLineData
7c673cae
FG
1//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2005-2015. Distributed under the Boost
4// Software License, Version 1.0. (See accompanying file
5// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7// See http://www.boost.org/libs/container for documentation.
8//
9//////////////////////////////////////////////////////////////////////////////
10#ifndef BOOST_CONTAINER_LIST_HPP
11#define BOOST_CONTAINER_LIST_HPP
12
13#ifndef BOOST_CONFIG_HPP
14# include <boost/config.hpp>
15#endif
16
17#if defined(BOOST_HAS_PRAGMA_ONCE)
18# pragma once
19#endif
20
21#include <boost/container/detail/config_begin.hpp>
22#include <boost/container/detail/workaround.hpp>
23
24// container
25#include <boost/container/container_fwd.hpp>
26#include <boost/container/new_allocator.hpp> //new_allocator
27#include <boost/container/throw_exception.hpp>
28// container/detail
29#include <boost/container/detail/algorithm.hpp>
30#include <boost/container/detail/compare_functors.hpp>
31#include <boost/container/detail/iterator.hpp>
32#include <boost/container/detail/iterators.hpp>
33#include <boost/container/detail/mpl.hpp>
34#include <boost/container/detail/node_alloc_holder.hpp>
35#include <boost/container/detail/version_type.hpp>
11fdf7f2 36#include <boost/container/detail/value_functors.hpp>
7c673cae
FG
37// move
38#include <boost/move/utility_core.hpp>
39#include <boost/move/iterator.hpp>
40#include <boost/move/traits.hpp>
41// move/detail
42#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
43# include <boost/move/detail/fwd_macros.hpp>
44#endif
45#include <boost/move/detail/move_helpers.hpp>
46
47// intrusive
48#include <boost/intrusive/pointer_traits.hpp>
49#include <boost/intrusive/list.hpp>
50// other
51#include <boost/assert.hpp>
52// std
53#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
54#include <initializer_list>
55#endif
56
57namespace boost {
58namespace container {
59
60#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
11fdf7f2 61namespace dtl {
7c673cae
FG
62
63template<class VoidPointer>
64struct list_hook
65{
11fdf7f2
TL
66 typedef typename dtl::bi::make_list_base_hook
67 <dtl::bi::void_pointer<VoidPointer>, dtl::bi::link_mode<dtl::bi::normal_link> >::type type;
7c673cae
FG
68};
69
70template <class T, class VoidPointer>
71struct list_node
72 : public list_hook<VoidPointer>::type
73{
7c673cae
FG
74 public:
75 typedef T value_type;
92f5a8d4 76 typedef T internal_type;
7c673cae
FG
77 typedef typename list_hook<VoidPointer>::type hook_type;
78
92f5a8d4
TL
79 typedef typename dtl::aligned_storage<sizeof(T), dtl::alignment_of<T>::value>::type storage_t;
80 storage_t m_storage;
81
82 #if defined(BOOST_GCC) && (BOOST_GCC >= 40600) && (BOOST_GCC < 80000)
83 #pragma GCC diagnostic push
84 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
85 #define BOOST_CONTAINER_DISABLE_ALIASING_WARNING
86 # endif
87
88 BOOST_CONTAINER_FORCEINLINE T &get_data()
89 { return *reinterpret_cast<T*>(this->m_storage.data); }
90
91 BOOST_CONTAINER_FORCEINLINE const T &get_data() const
92 { return *reinterpret_cast<const T*>(this->m_storage.data); }
93
94 BOOST_CONTAINER_FORCEINLINE T *get_data_ptr()
95 { return reinterpret_cast<T*>(this->m_storage.data); }
96
97 BOOST_CONTAINER_FORCEINLINE const T *get_data_ptr() const
98 { return reinterpret_cast<T*>(this->m_storage.data); }
99
100 BOOST_CONTAINER_FORCEINLINE internal_type &get_real_data()
101 { return *reinterpret_cast<internal_type*>(this->m_storage.data); }
102
103 BOOST_CONTAINER_FORCEINLINE const internal_type &get_real_data() const
104 { return *reinterpret_cast<const internal_type*>(this->m_storage.data); }
105
106 BOOST_CONTAINER_FORCEINLINE internal_type *get_real_data_ptr()
107 { return reinterpret_cast<internal_type*>(this->m_storage.data); }
108
109 BOOST_CONTAINER_FORCEINLINE const internal_type *get_real_data_ptr() const
110 { return reinterpret_cast<internal_type*>(this->m_storage.data); }
7c673cae 111
92f5a8d4
TL
112 BOOST_CONTAINER_FORCEINLINE ~list_node()
113 { reinterpret_cast<T*>(this->m_storage.data)->~T(); }
7c673cae 114
92f5a8d4
TL
115 #if defined(BOOST_CONTAINER_DISABLE_ALIASING_WARNING)
116 #pragma GCC diagnostic pop
117 #undef BOOST_CONTAINER_DISABLE_ALIASING_WARNING
118 # endif
119
120 BOOST_CONTAINER_FORCEINLINE void destroy_header()
121 { static_cast<hook_type*>(this)->~hook_type(); }
7c673cae
FG
122};
123
124template <class T, class VoidPointer>
125struct iiterator_node_value_type< list_node<T,VoidPointer> > {
126 typedef T type;
127};
128
129template<class Allocator>
130struct intrusive_list_type
131{
132 typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
133 typedef typename allocator_traits_type::value_type value_type;
134 typedef typename boost::intrusive::pointer_traits
135 <typename allocator_traits_type::pointer>::template
136 rebind_pointer<void>::type
137 void_pointer;
11fdf7f2 138 typedef typename dtl::list_node
7c673cae 139 <value_type, void_pointer> node_type;
11fdf7f2 140 typedef typename dtl::bi::make_list
7c673cae 141 < node_type
11fdf7f2
TL
142 , dtl::bi::base_hook<typename list_hook<void_pointer>::type>
143 , dtl::bi::constant_time_size<true>
144 , dtl::bi::size_type
7c673cae
FG
145 <typename allocator_traits_type::size_type>
146 >::type container_type;
147 typedef container_type type ;
148};
149
11fdf7f2 150} //namespace dtl {
7c673cae
FG
151#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
152
153//! A list is a doubly linked list. That is, it is a Sequence that supports both
154//! forward and backward traversal, and (amortized) constant time insertion and
155//! removal of elements at the beginning or the end, or in the middle. Lists have
156//! the important property that insertion and splicing do not invalidate iterators
157//! to list elements, and that even removal invalidates only the iterators that point
158//! to the elements that are removed. The ordering of iterators may be changed
159//! (that is, list<T>::iterator might have a different predecessor or successor
160//! after a list operation than it did before), but the iterators themselves will
161//! not be invalidated or made to point to different elements unless that invalidation
162//! or mutation is explicit.
163//!
164//! \tparam T The type of object that is stored in the list
92f5a8d4
TL
165//! \tparam Allocator The allocator used for all internal memory management, use void
166//! for the default allocator
7c673cae 167#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
92f5a8d4 168template <class T, class Allocator = void >
7c673cae
FG
169#else
170template <class T, class Allocator>
171#endif
172class list
11fdf7f2 173 : protected dtl::node_alloc_holder
92f5a8d4
TL
174 < typename real_allocator<T, Allocator>::type
175 , typename dtl::intrusive_list_type<typename real_allocator<T, Allocator>::type>::type>
7c673cae
FG
176{
177 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
92f5a8d4 178 typedef typename real_allocator<T, Allocator>::type ValueAllocator;
7c673cae 179 typedef typename
92f5a8d4
TL
180 dtl::intrusive_list_type<ValueAllocator>::type Icont;
181 typedef dtl::node_alloc_holder<ValueAllocator, Icont> AllocHolder;
7c673cae
FG
182 typedef typename AllocHolder::NodePtr NodePtr;
183 typedef typename AllocHolder::NodeAlloc NodeAlloc;
184 typedef typename AllocHolder::ValAlloc ValAlloc;
185 typedef typename AllocHolder::Node Node;
92f5a8d4 186 typedef dtl::allocator_destroyer<NodeAlloc> Destroyer;
7c673cae 187 typedef typename AllocHolder::alloc_version alloc_version;
92f5a8d4
TL
188 typedef boost::container::allocator_traits<ValueAllocator> allocator_traits_type;
189 typedef boost::container::equal_to_value
190 <typename allocator_traits_type::value_type> equal_to_value_type;
7c673cae
FG
191
192 BOOST_COPYABLE_AND_MOVABLE(list)
193
11fdf7f2
TL
194 typedef dtl::iterator_from_iiterator<typename Icont::iterator, false> iterator_impl;
195 typedef dtl::iterator_from_iiterator<typename Icont::iterator, true> const_iterator_impl;
7c673cae
FG
196 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
197
198 public:
199 //////////////////////////////////////////////
200 //
201 // types
202 //
203 //////////////////////////////////////////////
204
92f5a8d4
TL
205 typedef T value_type;
206 typedef typename ::boost::container::allocator_traits<ValueAllocator>::pointer pointer;
207 typedef typename ::boost::container::allocator_traits<ValueAllocator>::const_pointer const_pointer;
208 typedef typename ::boost::container::allocator_traits<ValueAllocator>::reference reference;
209 typedef typename ::boost::container::allocator_traits<ValueAllocator>::const_reference const_reference;
210 typedef typename ::boost::container::allocator_traits<ValueAllocator>::size_type size_type;
211 typedef typename ::boost::container::allocator_traits<ValueAllocator>::difference_type difference_type;
212 typedef ValueAllocator allocator_type;
213 typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type;
214 typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
215 typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
216 typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator;
217 typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
7c673cae
FG
218
219 //////////////////////////////////////////////
220 //
221 // construct/copy/destroy
222 //
223 //////////////////////////////////////////////
224
225 //! <b>Effects</b>: Default constructs a list.
226 //!
227 //! <b>Throws</b>: If allocator_type's default constructor throws.
228 //!
229 //! <b>Complexity</b>: Constant.
92f5a8d4 230 list() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<ValueAllocator>::value)
7c673cae
FG
231 : AllocHolder()
232 {}
233
234 //! <b>Effects</b>: Constructs a list taking the allocator as parameter.
235 //!
236 //! <b>Throws</b>: Nothing
237 //!
238 //! <b>Complexity</b>: Constant.
239 explicit list(const allocator_type &a) BOOST_NOEXCEPT_OR_NOTHROW
240 : AllocHolder(a)
241 {}
242
243 //! <b>Effects</b>: Constructs a list
244 //! and inserts n value-initialized value_types.
245 //!
246 //! <b>Throws</b>: If allocator_type's default constructor
247 //! throws or T's default or copy constructor throws.
248 //!
249 //! <b>Complexity</b>: Linear to n.
250 explicit list(size_type n)
92f5a8d4 251 : AllocHolder(ValueAllocator())
7c673cae
FG
252 { this->resize(n); }
253
254 //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
255 //! and inserts n copies of value.
256 //!
257 //! <b>Throws</b>: If allocator_type's default constructor
258 //! throws or T's default or copy constructor throws.
259 //!
260 //! <b>Complexity</b>: Linear to n.
261 list(size_type n, const allocator_type &a)
262 : AllocHolder(a)
263 { this->resize(n); }
264
265 //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
266 //! and inserts n copies of value.
267 //!
268 //! <b>Throws</b>: If allocator_type's default constructor
269 //! throws or T's default or copy constructor throws.
270 //!
271 //! <b>Complexity</b>: Linear to n.
92f5a8d4 272 list(size_type n, const T& value, const ValueAllocator& a = ValueAllocator())
7c673cae
FG
273 : AllocHolder(a)
274 { this->insert(this->cbegin(), n, value); }
275
276 //! <b>Effects</b>: Copy constructs a list.
277 //!
278 //! <b>Postcondition</b>: x == *this.
279 //!
280 //! <b>Throws</b>: If allocator_type's default constructor throws.
281 //!
282 //! <b>Complexity</b>: Linear to the elements x contains.
283 list(const list& x)
284 : AllocHolder(x)
285 { this->insert(this->cbegin(), x.begin(), x.end()); }
286
287 //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
288 //!
289 //! <b>Throws</b>: If allocator_type's copy constructor throws.
290 //!
291 //! <b>Complexity</b>: Constant.
292 list(BOOST_RV_REF(list) x) BOOST_NOEXCEPT_OR_NOTHROW
293 : AllocHolder(BOOST_MOVE_BASE(AllocHolder, x))
294 {}
295
296 //! <b>Effects</b>: Copy constructs a list using the specified allocator.
297 //!
298 //! <b>Postcondition</b>: x == *this.
299 //!
300 //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
301 //!
302 //! <b>Complexity</b>: Linear to the elements x contains.
303 list(const list& x, const allocator_type &a)
304 : AllocHolder(a)
305 { this->insert(this->cbegin(), x.begin(), x.end()); }
306
307 //! <b>Effects</b>: Move constructor sing the specified allocator.
308 //! Moves x's resources to *this.
309 //!
310 //! <b>Throws</b>: If allocation or value_type's copy constructor throws.
311 //!
312 //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
313 list(BOOST_RV_REF(list) x, const allocator_type &a)
314 : AllocHolder(a)
315 {
316 if(this->node_alloc() == x.node_alloc()){
317 this->icont().swap(x.icont());
318 }
319 else{
320 this->insert(this->cbegin(), boost::make_move_iterator(x.begin()), boost::make_move_iterator(x.end()));
321 }
322 }
323
324 //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
325 //! and inserts a copy of the range [first, last) in the list.
326 //!
327 //! <b>Throws</b>: If allocator_type's default constructor
328 //! throws or T's constructor taking a dereferenced InIt throws.
329 //!
330 //! <b>Complexity</b>: Linear to the range [first, last).
331 template <class InpIt>
92f5a8d4 332 list(InpIt first, InpIt last, const ValueAllocator &a = ValueAllocator())
7c673cae
FG
333 : AllocHolder(a)
334 { this->insert(this->cbegin(), first, last); }
335
336
337#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
338 //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
339 //! and inserts a copy of the range [il.begin(), il.end()) in the list.
340 //!
341 //! <b>Throws</b>: If allocator_type's default constructor
342 //! throws or T's constructor taking a dereferenced
343 //! std::initializer_list iterator throws.
344 //!
345 //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
92f5a8d4 346 list(std::initializer_list<value_type> il, const ValueAllocator &a = ValueAllocator())
7c673cae
FG
347 : AllocHolder(a)
348 { this->insert(this->cbegin(), il.begin(), il.end()); }
349#endif
350
351 //! <b>Effects</b>: Destroys the list. All stored values are destroyed
352 //! and used memory is deallocated.
353 //!
354 //! <b>Throws</b>: Nothing.
355 //!
356 //! <b>Complexity</b>: Linear to the number of elements.
20effc67 357 BOOST_CONTAINER_FORCEINLINE ~list() BOOST_NOEXCEPT_OR_NOTHROW
7c673cae
FG
358 {} //AllocHolder clears the list
359
360 //! <b>Effects</b>: Makes *this contain the same elements as x.
361 //!
362 //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
363 //! of each of x's elements.
364 //!
365 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
366 //!
367 //! <b>Complexity</b>: Linear to the number of elements in x.
368 list& operator=(BOOST_COPY_ASSIGN_REF(list) x)
369 {
92f5a8d4 370 if (BOOST_LIKELY(this != &x)) {
7c673cae
FG
371 NodeAlloc &this_alloc = this->node_alloc();
372 const NodeAlloc &x_alloc = x.node_alloc();
11fdf7f2 373 dtl::bool_<allocator_traits_type::
7c673cae
FG
374 propagate_on_container_copy_assignment::value> flag;
375 if(flag && this_alloc != x_alloc){
376 this->clear();
377 }
378 this->AllocHolder::copy_assign_alloc(x);
379 this->assign(x.begin(), x.end());
380 }
381 return *this;
382 }
383
384 //! <b>Effects</b>: Move assignment. All x's values are transferred to *this.
385 //!
386 //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
387 //! before the function.
388 //!
389 //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
390 //! is false and (allocation throws or value_type's move constructor throws)
391 //!
392 //! <b>Complexity</b>: Constant if allocator_traits_type::
393 //! propagate_on_container_move_assignment is true or
394 //! this->get>allocator() == x.get_allocator(). Linear otherwise.
395 list& operator=(BOOST_RV_REF(list) x)
396 BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
397 || allocator_traits_type::is_always_equal::value)
398 {
92f5a8d4
TL
399 if (BOOST_LIKELY(this != &x)) {
400 NodeAlloc &this_alloc = this->node_alloc();
401 NodeAlloc &x_alloc = x.node_alloc();
402 const bool propagate_alloc = allocator_traits_type::
403 propagate_on_container_move_assignment::value;
404 const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
405 //Resources can be transferred if both allocators are
406 //going to be equal after this function (either propagated or already equal)
407 if(propagate_alloc || allocators_equal){
408 //Destroy
409 this->clear();
410 //Move allocator if needed
411 this->AllocHolder::move_assign_alloc(x);
412 //Obtain resources
413 this->icont() = boost::move(x.icont());
414 }
415 //Else do a one by one move
416 else{
417 this->assign( boost::make_move_iterator(x.begin())
418 , boost::make_move_iterator(x.end()));
419 }
7c673cae
FG
420 }
421 return *this;
422 }
423
424#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
425 //! <b>Effects</b>: Makes *this contain the same elements as il.
426 //!
427 //! <b>Postcondition</b>: this->size() == il.size(). *this contains a copy
428 //! of each of x's elements.
429 //!
430 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
431 //!
432 //! <b>Complexity</b>: Linear to the number of elements in x.
20effc67 433 BOOST_CONTAINER_FORCEINLINE list& operator=(std::initializer_list<value_type> il)
7c673cae 434 {
20effc67 435 this->assign(il.begin(), il.end());
7c673cae
FG
436 return *this;
437 }
438#endif
439
440 //! <b>Effects</b>: Assigns the n copies of val to *this.
441 //!
442 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
443 //!
444 //! <b>Complexity</b>: Linear to n.
20effc67 445 BOOST_CONTAINER_FORCEINLINE void assign(size_type n, const T& val)
7c673cae
FG
446 {
447 typedef constant_iterator<value_type, difference_type> cvalue_iterator;
448 return this->assign(cvalue_iterator(val, n), cvalue_iterator());
449 }
450
451 //! <b>Effects</b>: Assigns the range [first, last) to *this.
452 //!
453 //! <b>Throws</b>: If memory allocation throws or
454 //! T's constructor from dereferencing InpIt throws.
455 //!
456 //! <b>Complexity</b>: Linear to n.
457 template <class InpIt>
458 void assign(InpIt first, InpIt last
459 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
11fdf7f2 460 , typename dtl::disable_if_convertible<InpIt, size_type>::type * = 0
7c673cae
FG
461 #endif
462 )
463 {
464 iterator first1 = this->begin();
465 const iterator last1 = this->end();
466 for ( ; first1 != last1 && first != last; ++first1, ++first)
467 *first1 = *first;
468 if (first == last)
469 this->erase(first1, last1);
470 else{
471 this->insert(last1, first, last);
472 }
473 }
474
475#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
476 //! <b>Effects</b>: Assigns the range [il.begin(), il.end()) to *this.
477 //!
478 //! <b>Throws</b>: If memory allocation throws or
479 //! T's constructor from dereferencing std::initializer_list iterator throws.
480 //!
481 //! <b>Complexity</b>: Linear to n.
20effc67
TL
482 BOOST_CONTAINER_FORCEINLINE void assign(std::initializer_list<value_type> il)
483 { this->assign(il.begin(), il.end()); }
7c673cae
FG
484#endif
485
486 //! <b>Effects</b>: Returns a copy of the internal allocator.
487 //!
488 //! <b>Throws</b>: If allocator's copy constructor throws.
489 //!
490 //! <b>Complexity</b>: Constant.
20effc67 491 BOOST_CONTAINER_FORCEINLINE allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
7c673cae
FG
492 { return allocator_type(this->node_alloc()); }
493
494 //! <b>Effects</b>: Returns a reference to the internal allocator.
495 //!
496 //! <b>Throws</b>: Nothing
497 //!
498 //! <b>Complexity</b>: Constant.
499 //!
500 //! <b>Note</b>: Non-standard extension.
20effc67 501 BOOST_CONTAINER_FORCEINLINE stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
7c673cae
FG
502 { return this->node_alloc(); }
503
504 //! <b>Effects</b>: Returns a reference to the internal allocator.
505 //!
506 //! <b>Throws</b>: Nothing
507 //!
508 //! <b>Complexity</b>: Constant.
509 //!
510 //! <b>Note</b>: Non-standard extension.
20effc67 511 BOOST_CONTAINER_FORCEINLINE const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
7c673cae
FG
512 { return this->node_alloc(); }
513
514 //////////////////////////////////////////////
515 //
516 // iterators
517 //
518 //////////////////////////////////////////////
519
520 //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
521 //!
522 //! <b>Throws</b>: Nothing.
523 //!
524 //! <b>Complexity</b>: Constant.
20effc67 525 BOOST_CONTAINER_FORCEINLINE iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
7c673cae
FG
526 { return iterator(this->icont().begin()); }
527
528 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
529 //!
530 //! <b>Throws</b>: Nothing.
531 //!
532 //! <b>Complexity</b>: Constant.
20effc67 533 BOOST_CONTAINER_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
7c673cae
FG
534 { return this->cbegin(); }
535
536 //! <b>Effects</b>: Returns an iterator to the end of the list.
537 //!
538 //! <b>Throws</b>: Nothing.
539 //!
540 //! <b>Complexity</b>: Constant.
20effc67 541 BOOST_CONTAINER_FORCEINLINE iterator end() BOOST_NOEXCEPT_OR_NOTHROW
7c673cae
FG
542 { return iterator(this->icont().end()); }
543
544 //! <b>Effects</b>: Returns a const_iterator to the end of the list.
545 //!
546 //! <b>Throws</b>: Nothing.
547 //!
548 //! <b>Complexity</b>: Constant.
20effc67 549 BOOST_CONTAINER_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
7c673cae
FG
550 { return this->cend(); }
551
552 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
553 //! of the reversed list.
554 //!
555 //! <b>Throws</b>: Nothing.
556 //!
557 //! <b>Complexity</b>: Constant.
20effc67 558 BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
7c673cae
FG
559 { return reverse_iterator(end()); }
560
561 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
562 //! of the reversed list.
563 //!
564 //! <b>Throws</b>: Nothing.
565 //!
566 //! <b>Complexity</b>: Constant.
20effc67 567 BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
7c673cae
FG
568 { return this->crbegin(); }
569
570 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
571 //! of the reversed list.
572 //!
573 //! <b>Throws</b>: Nothing.
574 //!
575 //! <b>Complexity</b>: Constant.
20effc67 576 BOOST_CONTAINER_FORCEINLINE reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
7c673cae
FG
577 { return reverse_iterator(begin()); }
578
579 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
580 //! of the reversed list.
581 //!
582 //! <b>Throws</b>: Nothing.
583 //!
584 //! <b>Complexity</b>: Constant.
20effc67 585 BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
7c673cae
FG
586 { return this->crend(); }
587
588 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
589 //!
590 //! <b>Throws</b>: Nothing.
591 //!
592 //! <b>Complexity</b>: Constant.
20effc67 593 BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
7c673cae
FG
594 { return const_iterator(this->non_const_icont().begin()); }
595
596 //! <b>Effects</b>: Returns a const_iterator to the end of the list.
597 //!
598 //! <b>Throws</b>: Nothing.
599 //!
600 //! <b>Complexity</b>: Constant.
20effc67 601 BOOST_CONTAINER_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
7c673cae
FG
602 { return const_iterator(this->non_const_icont().end()); }
603
604 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
605 //! of the reversed list.
606 //!
607 //! <b>Throws</b>: Nothing.
608 //!
609 //! <b>Complexity</b>: Constant.
20effc67 610 BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
7c673cae
FG
611 { return const_reverse_iterator(this->cend()); }
612
613 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
614 //! of the reversed list.
615 //!
616 //! <b>Throws</b>: Nothing.
617 //!
618 //! <b>Complexity</b>: Constant.
20effc67 619 BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
7c673cae
FG
620 { return const_reverse_iterator(this->cbegin()); }
621
622 //////////////////////////////////////////////
623 //
624 // capacity
625 //
626 //////////////////////////////////////////////
627
628 //! <b>Effects</b>: Returns true if the list contains no elements.
629 //!
630 //! <b>Throws</b>: Nothing.
631 //!
632 //! <b>Complexity</b>: Constant.
20effc67 633 BOOST_CONTAINER_FORCEINLINE bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
7c673cae
FG
634 { return !this->size(); }
635
636 //! <b>Effects</b>: Returns the number of the elements contained in the list.
637 //!
638 //! <b>Throws</b>: Nothing.
639 //!
640 //! <b>Complexity</b>: Constant.
20effc67 641 BOOST_CONTAINER_FORCEINLINE size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
7c673cae
FG
642 { return this->icont().size(); }
643
644 //! <b>Effects</b>: Returns the largest possible size of the list.
645 //!
646 //! <b>Throws</b>: Nothing.
647 //!
648 //! <b>Complexity</b>: Constant.
20effc67 649 BOOST_CONTAINER_FORCEINLINE size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
7c673cae
FG
650 { return AllocHolder::max_size(); }
651
652 //! <b>Effects</b>: Inserts or erases elements at the end such that
653 //! the size becomes n. New elements are value initialized.
654 //!
655 //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
656 //!
657 //! <b>Complexity</b>: Linear to the difference between size() and new_size.
658 void resize(size_type new_size)
659 {
660 if(!priv_try_shrink(new_size)){
661 typedef value_init_construct_iterator<value_type, difference_type> value_init_iterator;
662 this->insert(this->cend(), value_init_iterator(new_size - this->size()), value_init_iterator());
663 }
664 }
665
666 //! <b>Effects</b>: Inserts or erases elements at the end such that
667 //! the size becomes n. New elements are copy constructed from x.
668 //!
669 //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
670 //!
671 //! <b>Complexity</b>: Linear to the difference between size() and new_size.
672 void resize(size_type new_size, const T& x)
673 {
674 if(!priv_try_shrink(new_size)){
675 this->insert(this->cend(), new_size - this->size(), x);
676 }
677 }
678
679 //////////////////////////////////////////////
680 //
681 // element access
682 //
683 //////////////////////////////////////////////
684
685 //! <b>Requires</b>: !empty()
686 //!
687 //! <b>Effects</b>: Returns a reference to the first element
688 //! from the beginning of the container.
689 //!
690 //! <b>Throws</b>: Nothing.
691 //!
692 //! <b>Complexity</b>: Constant.
693 reference front() BOOST_NOEXCEPT_OR_NOTHROW
694 {
695 BOOST_ASSERT(!this->empty());
696 return *this->begin();
697 }
698
699 //! <b>Requires</b>: !empty()
700 //!
701 //! <b>Effects</b>: Returns a const reference to the first element
702 //! from the beginning of the container.
703 //!
704 //! <b>Throws</b>: Nothing.
705 //!
706 //! <b>Complexity</b>: Constant.
707 const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
708 {
709 BOOST_ASSERT(!this->empty());
710 return *this->begin();
711 }
712
713 //! <b>Requires</b>: !empty()
714 //!
715 //! <b>Effects</b>: Returns a reference to the first element
716 //! from the beginning of the container.
717 //!
718 //! <b>Throws</b>: Nothing.
719 //!
720 //! <b>Complexity</b>: Constant.
721 reference back() BOOST_NOEXCEPT_OR_NOTHROW
722 {
723 BOOST_ASSERT(!this->empty());
724 return *(--this->end());
725 }
726
727 //! <b>Requires</b>: !empty()
728 //!
729 //! <b>Effects</b>: Returns a const reference to the first element
730 //! from the beginning of the container.
731 //!
732 //! <b>Throws</b>: Nothing.
733 //!
734 //! <b>Complexity</b>: Constant.
735 const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
736 {
737 BOOST_ASSERT(!this->empty());
738 return *(--this->end());
739 }
740
741 //////////////////////////////////////////////
742 //
743 // modifiers
744 //
745 //////////////////////////////////////////////
746
747 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
748
749 //! <b>Effects</b>: Inserts an object of type T constructed with
750 //! std::forward<Args>(args)... in the end of the list.
751 //!
752 //! <b>Returns</b>: A reference to the created object.
753 //!
754 //! <b>Throws</b>: If memory allocation throws or
755 //! T's in-place constructor throws.
756 //!
757 //! <b>Complexity</b>: Constant
758 template <class... Args>
759 reference emplace_back(BOOST_FWD_REF(Args)... args)
760 { return *this->emplace(this->cend(), boost::forward<Args>(args)...); }
761
762 //! <b>Effects</b>: Inserts an object of type T constructed with
763 //! std::forward<Args>(args)... in the beginning of the list.
764 //!
765 //! <b>Returns</b>: A reference to the created object.
766 //!
767 //! <b>Throws</b>: If memory allocation throws or
768 //! T's in-place constructor throws.
769 //!
770 //! <b>Complexity</b>: Constant
771 template <class... Args>
772 reference emplace_front(BOOST_FWD_REF(Args)... args)
773 { return *this->emplace(this->cbegin(), boost::forward<Args>(args)...); }
774
775 //! <b>Effects</b>: Inserts an object of type T constructed with
776 //! std::forward<Args>(args)... before p.
777 //!
778 //! <b>Throws</b>: If memory allocation throws or
779 //! T's in-place constructor throws.
780 //!
781 //! <b>Complexity</b>: Constant
782 template <class... Args>
783 iterator emplace(const_iterator position, BOOST_FWD_REF(Args)... args)
784 {
785 BOOST_ASSERT((priv_is_linked)(position));
786 NodePtr pnode(AllocHolder::create_node(boost::forward<Args>(args)...));
787 return iterator(this->icont().insert(position.get(), *pnode));
788 }
789
790 #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
791
792 #define BOOST_CONTAINER_LIST_EMPLACE_CODE(N) \
793 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
794 reference emplace_back(BOOST_MOVE_UREF##N)\
795 { return *this->emplace(this->cend() BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
796 \
797 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
798 reference emplace_front(BOOST_MOVE_UREF##N)\
799 { return *this->emplace(this->cbegin() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);}\
800 \
801 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
802 iterator emplace(const_iterator position BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
803 {\
804 BOOST_ASSERT(position == this->cend() || (--(++position) == position) );\
805 NodePtr pnode (AllocHolder::create_node(BOOST_MOVE_FWD##N));\
806 return iterator(this->icont().insert(position.get(), *pnode));\
807 }\
808 //
809 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_LIST_EMPLACE_CODE)
810 #undef BOOST_CONTAINER_LIST_EMPLACE_CODE
811
812 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
813
814 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
815 //! <b>Effects</b>: Inserts a copy of x at the beginning of the list.
816 //!
817 //! <b>Throws</b>: If memory allocation throws or
818 //! T's copy constructor throws.
819 //!
820 //! <b>Complexity</b>: Amortized constant time.
821 void push_front(const T &x);
822
823 //! <b>Effects</b>: Constructs a new element in the beginning of the list
824 //! and moves the resources of x to this new element.
825 //!
826 //! <b>Throws</b>: If memory allocation throws.
827 //!
828 //! <b>Complexity</b>: Amortized constant time.
829 void push_front(T &&x);
830 #else
831 BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
832 #endif
833
834 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
835 //! <b>Effects</b>: Inserts a copy of x at the end of the list.
836 //!
837 //! <b>Throws</b>: If memory allocation throws or
838 //! T's copy constructor throws.
839 //!
840 //! <b>Complexity</b>: Amortized constant time.
841 void push_back(const T &x);
842
843 //! <b>Effects</b>: Constructs a new element in the end of the list
844 //! and moves the resources of x to this new element.
845 //!
846 //! <b>Throws</b>: If memory allocation throws.
847 //!
848 //! <b>Complexity</b>: Amortized constant time.
849 void push_back(T &&x);
850 #else
851 BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
852 #endif
853
854 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
855 //! <b>Requires</b>: p must be a valid iterator of *this.
856 //!
857 //! <b>Effects</b>: Insert a copy of x before p.
858 //!
859 //! <b>Returns</b>: an iterator to the inserted element.
860 //!
861 //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
862 //!
863 //! <b>Complexity</b>: Amortized constant time.
864 iterator insert(const_iterator p, const T &x);
865
866 //! <b>Requires</b>: p must be a valid iterator of *this.
867 //!
868 //! <b>Effects</b>: Insert a new element before p with x's resources.
869 //!
870 //! <b>Returns</b>: an iterator to the inserted element.
871 //!
872 //! <b>Throws</b>: If memory allocation throws.
873 //!
874 //! <b>Complexity</b>: Amortized constant time.
875 iterator insert(const_iterator p, T &&x);
876 #else
877 BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
878 #endif
879
880 //! <b>Requires</b>: p must be a valid iterator of *this.
881 //!
882 //! <b>Effects</b>: Inserts n copies of x before p.
883 //!
884 //! <b>Returns</b>: an iterator to the first inserted element or p if n is 0.
885 //!
886 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
887 //!
888 //! <b>Complexity</b>: Linear to n.
889 iterator insert(const_iterator position, size_type n, const T& x)
890 {
891 //range check is done by insert
892 typedef constant_iterator<value_type, difference_type> cvalue_iterator;
893 return this->insert(position, cvalue_iterator(x, n), cvalue_iterator());
894 }
895
896 //! <b>Requires</b>: p must be a valid iterator of *this.
897 //!
898 //! <b>Effects</b>: Insert a copy of the [first, last) range before p.
899 //!
900 //! <b>Returns</b>: an iterator to the first inserted element or p if first == last.
901 //!
902 //! <b>Throws</b>: If memory allocation throws, T's constructor from a
903 //! dereferenced InpIt throws.
904 //!
905 //! <b>Complexity</b>: Linear to distance [first, last).
906 template <class InpIt>
907 iterator insert(const_iterator p, InpIt first, InpIt last
908 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
11fdf7f2
TL
909 , typename dtl::enable_if_c
910 < !dtl::is_convertible<InpIt, size_type>::value
911 && (dtl::is_input_iterator<InpIt>::value
912 || dtl::is_same<alloc_version, version_1>::value
7c673cae
FG
913 )
914 >::type * = 0
915 #endif
916 )
917 {
918 BOOST_ASSERT((priv_is_linked)(p));
919 const typename Icont::iterator ipos(p.get());
920 iterator ret_it(ipos);
921 if(first != last){
922 ret_it = iterator(this->icont().insert(ipos, *this->create_node_from_it(first)));
923 ++first;
924 }
925 for (; first != last; ++first){
926 this->icont().insert(ipos, *this->create_node_from_it(first));
927 }
928 return ret_it;
929 }
930
931 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
932 template <class FwdIt>
933 iterator insert(const_iterator position, FwdIt first, FwdIt last
11fdf7f2
TL
934 , typename dtl::enable_if_c
935 < !dtl::is_convertible<FwdIt, size_type>::value
936 && !(dtl::is_input_iterator<FwdIt>::value
937 || dtl::is_same<alloc_version, version_1>::value
7c673cae
FG
938 )
939 >::type * = 0
940 )
941 {
942 BOOST_ASSERT((priv_is_linked)(position));
943 //Optimized allocation and construction
944 insertion_functor func(this->icont(), position.get());
945 iterator before_p(position.get());
946 --before_p;
947 this->allocate_many_and_construct(first, boost::container::iterator_distance(first, last), func);
948 return ++before_p;
949 }
950 #endif
951
952#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
953 //! <b>Requires</b>: p must be a valid iterator of *this.
954 //!
955 //! <b>Effects</b>: Insert a copy of the [il.begin(), il.end()) range before p.
956 //!
957 //! <b>Returns</b>: an iterator to the first inserted element or p if if.begin() == il.end().
958 //!
959 //! <b>Throws</b>: If memory allocation throws, T's constructor from a
960 //! dereferenced std::initializer_list iterator throws.
961 //!
962 //! <b>Complexity</b>: Linear to distance [il.begin(), il.end()).
963 iterator insert(const_iterator p, std::initializer_list<value_type> il)
964 {
965 //position range check is done by insert()
966 return insert(p, il.begin(), il.end());
967 }
968#endif
969
970 //! <b>Effects</b>: Removes the first element from the list.
971 //!
972 //! <b>Throws</b>: Nothing.
973 //!
974 //! <b>Complexity</b>: Amortized constant time.
975 void pop_front() BOOST_NOEXCEPT_OR_NOTHROW
976 {
977 BOOST_ASSERT(!this->empty());
978 this->erase(this->cbegin());
979 }
980
981 //! <b>Effects</b>: Removes the last element from the list.
982 //!
983 //! <b>Throws</b>: Nothing.
984 //!
985 //! <b>Complexity</b>: Amortized constant time.
986 void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
987 {
988 BOOST_ASSERT(!this->empty());
989 const_iterator tmp = this->cend();
990 this->erase(--tmp);
991 }
992
993 //! <b>Requires</b>: p must be a valid iterator of *this.
994 //!
995 //! <b>Effects</b>: Erases the element at p.
996 //!
997 //! <b>Throws</b>: Nothing.
998 //!
999 //! <b>Complexity</b>: Amortized constant time.
1000 iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
1001 {
1002 BOOST_ASSERT(p != this->cend() && (priv_is_linked)(p));
1003 return iterator(this->icont().erase_and_dispose(p.get(), Destroyer(this->node_alloc())));
1004 }
1005
1006 //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
1007 //!
1008 //! <b>Effects</b>: Erases the elements pointed by [first, last).
1009 //!
1010 //! <b>Throws</b>: Nothing.
1011 //!
1012 //! <b>Complexity</b>: Linear to the distance between first and last.
1013 iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
1014 {
1015 BOOST_ASSERT(first == last || (first != this->cend() && (priv_is_linked)(first)));
1016 BOOST_ASSERT(first == last || (priv_is_linked)(last));
1017 return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version()));
1018 }
1019
1020 //! <b>Effects</b>: Swaps the contents of *this and x.
1021 //!
1022 //! <b>Throws</b>: Nothing.
1023 //!
1024 //! <b>Complexity</b>: Constant.
1025 void swap(list& x)
1026 BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_swap::value
1027 || allocator_traits_type::is_always_equal::value)
1028 {
1029 BOOST_ASSERT(allocator_traits_type::propagate_on_container_swap::value ||
1030 allocator_traits_type::is_always_equal::value ||
1031 this->get_stored_allocator() == x.get_stored_allocator());
1032 AllocHolder::swap(x);
1033 }
1034
1035 //! <b>Effects</b>: Erases all the elements of the list.
1036 //!
1037 //! <b>Throws</b>: Nothing.
1038 //!
1039 //! <b>Complexity</b>: Linear to the number of elements in the list.
1040 void clear() BOOST_NOEXCEPT_OR_NOTHROW
1041 { AllocHolder::clear(alloc_version()); }
1042
1043 //////////////////////////////////////////////
1044 //
1045 // slist operations
1046 //
1047 //////////////////////////////////////////////
1048
1049 //! <b>Requires</b>: p must point to an element contained
1050 //! by the list. x != *this. this' allocator and x's allocator shall compare equal
1051 //!
1052 //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
1053 //! the element pointed by p. No destructors or copy constructors are called.
1054 //!
1055 //! <b>Throws</b>: Nothing
1056 //!
1057 //! <b>Complexity</b>: Constant.
1058 //!
1059 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
1060 //! this list. Iterators of this list and all the references are not invalidated.
1061 void splice(const_iterator p, list& x) BOOST_NOEXCEPT_OR_NOTHROW
1062 {
1063 BOOST_ASSERT((priv_is_linked)(p));
1064 BOOST_ASSERT(this != &x);
1065 BOOST_ASSERT(this->node_alloc() == x.node_alloc());
1066 this->icont().splice(p.get(), x.icont());
1067 }
1068
1069 //! <b>Requires</b>: p must point to an element contained
1070 //! by the list. x != *this. this' allocator and x's allocator shall compare equal
1071 //!
1072 //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
1073 //! the element pointed by p. No destructors or copy constructors are called.
1074 //!
1075 //! <b>Throws</b>: Nothing
1076 //!
1077 //! <b>Complexity</b>: Constant.
1078 //!
1079 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
1080 //! this list. Iterators of this list and all the references are not invalidated.
1081 void splice(const_iterator p, BOOST_RV_REF(list) x) BOOST_NOEXCEPT_OR_NOTHROW
1082 {
1083 //Checks done in splice
1084 this->splice(p, static_cast<list&>(x));
1085 }
1086
1087 //! <b>Requires</b>: p must point to an element contained
1088 //! by this list. i must point to an element contained in list x.
1089 //! this' allocator and x's allocator shall compare equal
1090 //!
1091 //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
1092 //! before the element pointed by p. No destructors or copy constructors are called.
1093 //! If p == i or p == ++i, this function is a null operation.
1094 //!
1095 //! <b>Throws</b>: Nothing
1096 //!
1097 //! <b>Complexity</b>: Constant.
1098 //!
1099 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
1100 //! list. Iterators of this list and all the references are not invalidated.
1101 void splice(const_iterator p, list &x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW
1102 {
1103 BOOST_ASSERT((priv_is_linked)(p));
1104 BOOST_ASSERT(this->node_alloc() == x.node_alloc());
1105 this->icont().splice(p.get(), x.icont(), i.get());
1106 }
1107
1108 //! <b>Requires</b>: p must point to an element contained
1109 //! by this list. i must point to an element contained in list x.
1110 //! this' allocator and x's allocator shall compare equal.
1111 //!
1112 //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
1113 //! before the element pointed by p. No destructors or copy constructors are called.
1114 //! If p == i or p == ++i, this function is a null operation.
1115 //!
1116 //! <b>Throws</b>: Nothing
1117 //!
1118 //! <b>Complexity</b>: Constant.
1119 //!
1120 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
1121 //! list. Iterators of this list and all the references are not invalidated.
1122 void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW
1123 {
1124 BOOST_ASSERT(this != &x);
1125 //Additional checks done in splice()
1126 this->splice(p, static_cast<list&>(x), i);
1127 }
1128
1129 //! <b>Requires</b>: p must point to an element contained
1130 //! by this list. first and last must point to elements contained in list x.
1131 //! this' allocator and x's allocator shall compare equal
1132 //!
1133 //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
1134 //! before the element pointed by p. No destructors or copy constructors are called.
1135 //!
1136 //! <b>Throws</b>: Nothing
1137 //!
1138 //! <b>Complexity</b>: Linear to the number of elements transferred.
1139 //!
1140 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
1141 //! list. Iterators of this list and all the references are not invalidated.
1142 void splice(const_iterator p, list &x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
1143 {
1144 BOOST_ASSERT((priv_is_linked)(p));
1145 BOOST_ASSERT(first == last || (first != x.cend() && x.priv_is_linked(first)));
1146 BOOST_ASSERT(first == last || x.priv_is_linked(last));
1147 BOOST_ASSERT(this->node_alloc() == x.node_alloc());
1148 this->icont().splice(p.get(), x.icont(), first.get(), last.get());
1149 }
1150
1151 //! <b>Requires</b>: p must point to an element contained
1152 //! by this list. first and last must point to elements contained in list x.
1153 //! this' allocator and x's allocator shall compare equal.
1154 //!
1155 //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
1156 //! before the element pointed by p. No destructors or copy constructors are called.
1157 //!
1158 //! <b>Throws</b>: Nothing
1159 //!
1160 //! <b>Complexity</b>: Linear to the number of elements transferred.
1161 //!
1162 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
1163 //! list. Iterators of this list and all the references are not invalidated.
1164 void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
1165 {
1166 BOOST_ASSERT(this != &x);
1167 //Additional checks done in splice()
1168 this->splice(p, static_cast<list&>(x), first, last);
1169 }
1170
1171 //! <b>Requires</b>: p must point to an element contained
1172 //! by this list. first and last must point to elements contained in list x.
1173 //! n == distance(first, last). this' allocator and x's allocator shall compare equal
1174 //!
1175 //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
1176 //! before the element pointed by p. No destructors or copy constructors are called.
1177 //!
1178 //! <b>Throws</b>: Nothing
1179 //!
1180 //! <b>Complexity</b>: Constant.
1181 //!
1182 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
1183 //! list. Iterators of this list and all the references are not invalidated.
1184 //!
1185 //! <b>Note</b>: Non-standard extension
1186 void splice(const_iterator p, list &x, const_iterator first, const_iterator last, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
1187 {
1188 BOOST_ASSERT(this->node_alloc() == x.node_alloc());
1189 this->icont().splice(p.get(), x.icont(), first.get(), last.get(), n);
1190 }
1191
1192 //! <b>Requires</b>: p must point to an element contained
1193 //! by this list. first and last must point to elements contained in list x.
1194 //! n == distance(first, last). this' allocator and x's allocator shall compare equal
1195 //!
1196 //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
1197 //! before the element pointed by p. No destructors or copy constructors are called.
1198 //!
1199 //! <b>Throws</b>: Nothing
1200 //!
1201 //! <b>Complexity</b>: Constant.
1202 //!
1203 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
1204 //! list. Iterators of this list and all the references are not invalidated.
1205 //!
1206 //! <b>Note</b>: Non-standard extension
1207 void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator first, const_iterator last, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
1208 { this->splice(p, static_cast<list&>(x), first, last, n); }
1209
1210 //! <b>Effects</b>: Removes all the elements that compare equal to value.
1211 //!
1212 //! <b>Throws</b>: If comparison throws.
1213 //!
1214 //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
1215 //!
1216 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1217 //! and iterators to elements that are not removed remain valid.
1218 void remove(const T& value)
1219 { this->remove_if(equal_to_value_type(value)); }
1220
1221 //! <b>Effects</b>: Removes all the elements for which a specified
1222 //! predicate is satisfied.
1223 //!
1224 //! <b>Throws</b>: If pred throws.
1225 //!
1226 //! <b>Complexity</b>: Linear time. It performs exactly size() calls to the predicate.
1227 //!
1228 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1229 //! and iterators to elements that are not removed remain valid.
1230 template <class Pred>
1231 void remove_if(Pred pred)
1232 {
1233 typedef value_to_node_compare<Node, Pred> value_to_node_compare_type;
1234 this->icont().remove_and_dispose_if(value_to_node_compare_type(pred), Destroyer(this->node_alloc()));
1235 }
1236
1237 //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
1238 //! elements that are equal from the list.
1239 //!
1240 //! <b>Throws</b>: If comparison throws.
1241 //!
1242 //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
1243 //!
1244 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1245 //! and iterators to elements that are not removed remain valid.
1246 void unique()
11fdf7f2 1247 { this->unique(value_equal_t()); }
7c673cae
FG
1248
1249 //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
1250 //! elements that satisfy some binary predicate from the list.
1251 //!
1252 //! <b>Throws</b>: If pred throws.
1253 //!
1254 //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
1255 //!
1256 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1257 //! and iterators to elements that are not removed remain valid.
1258 template <class BinaryPredicate>
1259 void unique(BinaryPredicate binary_pred)
1260 {
1261 typedef value_to_node_compare<Node, BinaryPredicate> value_to_node_compare_type;
1262 this->icont().unique_and_dispose(value_to_node_compare_type(binary_pred), Destroyer(this->node_alloc()));
1263 }
1264
1265 //! <b>Requires</b>: The lists x and *this must be distinct.
1266 //!
1267 //! <b>Effects</b>: This function removes all of x's elements and inserts them
1268 //! in order into *this according to std::less<value_type>. The merge is stable;
1269 //! that is, if an element from *this is equivalent to one from x, then the element
1270 //! from *this will precede the one from x.
1271 //!
1272 //! <b>Throws</b>: If comparison throws.
1273 //!
1274 //! <b>Complexity</b>: This function is linear time: it performs at most
1275 //! size() + x.size() - 1 comparisons.
1276 void merge(list &x)
11fdf7f2 1277 { this->merge(x, value_less_t()); }
7c673cae
FG
1278
1279 //! <b>Requires</b>: The lists x and *this must be distinct.
1280 //!
1281 //! <b>Effects</b>: This function removes all of x's elements and inserts them
1282 //! in order into *this according to std::less<value_type>. The merge is stable;
1283 //! that is, if an element from *this is equivalent to one from x, then the element
1284 //! from *this will precede the one from x.
1285 //!
1286 //! <b>Throws</b>: If comparison throws.
1287 //!
1288 //! <b>Complexity</b>: This function is linear time: it performs at most
1289 //! size() + x.size() - 1 comparisons.
1290 void merge(BOOST_RV_REF(list) x)
1291 { this->merge(static_cast<list&>(x)); }
1292
1293 //! <b>Requires</b>: p must be a comparison function that induces a strict weak
1294 //! ordering and both *this and x must be sorted according to that ordering
1295 //! The lists x and *this must be distinct.
1296 //!
1297 //! <b>Effects</b>: This function removes all of x's elements and inserts them
1298 //! in order into *this. The merge is stable; that is, if an element from *this is
1299 //! equivalent to one from x, then the element from *this will precede the one from x.
1300 //!
1301 //! <b>Throws</b>: If comp throws.
1302 //!
1303 //! <b>Complexity</b>: This function is linear time: it performs at most
1304 //! size() + x.size() - 1 comparisons.
1305 //!
1306 //! <b>Note</b>: Iterators and references to *this are not invalidated.
1307 template <class StrictWeakOrdering>
1308 void merge(list &x, const StrictWeakOrdering &comp)
1309 {
1310 BOOST_ASSERT(this->node_alloc() == x.node_alloc());
1311 typedef value_to_node_compare<Node, StrictWeakOrdering> value_to_node_compare_type;
1312 this->icont().merge(x.icont(), value_to_node_compare_type(comp));
1313 }
1314
1315 //! <b>Requires</b>: p must be a comparison function that induces a strict weak
1316 //! ordering and both *this and x must be sorted according to that ordering
1317 //! The lists x and *this must be distinct.
1318 //!
1319 //! <b>Effects</b>: This function removes all of x's elements and inserts them
1320 //! in order into *this. The merge is stable; that is, if an element from *this is
1321 //! equivalent to one from x, then the element from *this will precede the one from x.
1322 //!
1323 //! <b>Throws</b>: If comp throws.
1324 //!
1325 //! <b>Complexity</b>: This function is linear time: it performs at most
1326 //! size() + x.size() - 1 comparisons.
1327 //!
1328 //! <b>Note</b>: Iterators and references to *this are not invalidated.
1329 template <class StrictWeakOrdering>
1330 void merge(BOOST_RV_REF(list) x, StrictWeakOrdering comp)
1331 { this->merge(static_cast<list&>(x), comp); }
1332
1333 //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
1334 //! The sort is stable, that is, the relative order of equivalent elements is preserved.
1335 //!
1336 //! <b>Throws</b>: If comparison throws.
1337 //!
1338 //! <b>Notes</b>: Iterators and references are not invalidated.
1339 //!
1340 //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
1341 //! is the list's size.
1342 void sort()
11fdf7f2 1343 { this->sort(value_less_t()); }
7c673cae
FG
1344
1345 //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
1346 //! The sort is stable, that is, the relative order of equivalent elements is preserved.
1347 //!
1348 //! <b>Throws</b>: If comp throws.
1349 //!
1350 //! <b>Notes</b>: Iterators and references are not invalidated.
1351 //!
1352 //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
1353 //! is the list's size.
1354 template <class StrictWeakOrdering>
1355 void sort(StrictWeakOrdering comp)
1356 {
1357 // nothing if the list has length 0 or 1.
1358 if (this->size() < 2)
1359 return;
1360 typedef value_to_node_compare<Node, StrictWeakOrdering> value_to_node_compare_type;
1361 this->icont().sort(value_to_node_compare_type(comp));
1362 }
1363
1364 //! <b>Effects</b>: Reverses the order of elements in the list.
1365 //!
1366 //! <b>Throws</b>: Nothing.
1367 //!
1368 //! <b>Complexity</b>: This function is linear time.
1369 //!
1370 //! <b>Note</b>: Iterators and references are not invalidated
1371 void reverse() BOOST_NOEXCEPT_OR_NOTHROW
1372 { this->icont().reverse(); }
1373
1374 //! <b>Effects</b>: Returns true if x and y are equal
1375 //!
1376 //! <b>Complexity</b>: Linear to the number of elements in the container.
1377 friend bool operator==(const list& x, const list& y)
1378 { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
1379
1380 //! <b>Effects</b>: Returns true if x and y are unequal
1381 //!
1382 //! <b>Complexity</b>: Linear to the number of elements in the container.
1383 friend bool operator!=(const list& x, const list& y)
1384 { return !(x == y); }
1385
1386 //! <b>Effects</b>: Returns true if x is less than y
1387 //!
1388 //! <b>Complexity</b>: Linear to the number of elements in the container.
1389 friend bool operator<(const list& x, const list& y)
1390 { return boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
1391
1392 //! <b>Effects</b>: Returns true if x is greater than y
1393 //!
1394 //! <b>Complexity</b>: Linear to the number of elements in the container.
1395 friend bool operator>(const list& x, const list& y)
1396 { return y < x; }
1397
1398 //! <b>Effects</b>: Returns true if x is equal or less than y
1399 //!
1400 //! <b>Complexity</b>: Linear to the number of elements in the container.
1401 friend bool operator<=(const list& x, const list& y)
1402 { return !(y < x); }
1403
1404 //! <b>Effects</b>: Returns true if x is equal or greater than y
1405 //!
1406 //! <b>Complexity</b>: Linear to the number of elements in the container.
1407 friend bool operator>=(const list& x, const list& y)
1408 { return !(x < y); }
1409
1410 //! <b>Effects</b>: x.swap(y)
1411 //!
1412 //! <b>Complexity</b>: Constant.
1413 friend void swap(list& x, list& y)
1414 { x.swap(y); }
1415
1416 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1417 private:
1418
1419 static bool priv_is_linked(const_iterator const position)
1420 {
1421 const_iterator cur(position);
1422 //This list is circular including end nodes
1423 return (--(++cur)) == position && (++(--cur)) == position;
1424 }
1425
1426 bool priv_try_shrink(size_type new_size)
1427 {
1428 const size_type len = this->size();
1429 if(len > new_size){
1430 const const_iterator iend = this->cend();
1431 size_type to_erase = len - new_size;
1432 const_iterator ifirst;
1433 if(to_erase < len/2u){
1434 ifirst = iend;
1435 while(to_erase--){
1436 --ifirst;
1437 }
1438 }
1439 else{
1440 ifirst = this->cbegin();
1441 size_type to_skip = len - to_erase;
1442 while(to_skip--){
1443 ++ifirst;
1444 }
1445 }
1446 this->erase(ifirst, iend);
1447 return true;
1448 }
1449 else{
1450 return false;
1451 }
1452 }
1453
1454 iterator priv_insert(const_iterator p, const T &x)
1455 {
1456 BOOST_ASSERT((priv_is_linked)(p));
1457 NodePtr tmp = AllocHolder::create_node(x);
1458 return iterator(this->icont().insert(p.get(), *tmp));
1459 }
1460
1461 iterator priv_insert(const_iterator p, BOOST_RV_REF(T) x)
1462 {
1463 BOOST_ASSERT((priv_is_linked)(p));
1464 NodePtr tmp = AllocHolder::create_node(boost::move(x));
1465 return iterator(this->icont().insert(p.get(), *tmp));
1466 }
1467
1468 void priv_push_back (const T &x)
1469 { this->insert(this->cend(), x); }
1470
1471 void priv_push_back (BOOST_RV_REF(T) x)
1472 { this->insert(this->cend(), boost::move(x)); }
1473
1474 void priv_push_front (const T &x)
1475 { this->insert(this->cbegin(), x); }
1476
1477 void priv_push_front (BOOST_RV_REF(T) x)
1478 { this->insert(this->cbegin(), boost::move(x)); }
1479
1480 class insertion_functor;
1481 friend class insertion_functor;
1482
1483 class insertion_functor
1484 {
1485 Icont &icont_;
1486 typedef typename Icont::const_iterator iconst_iterator;
1487 const iconst_iterator pos_;
1488
1489 public:
1490 insertion_functor(Icont &icont, typename Icont::const_iterator pos)
1491 : icont_(icont), pos_(pos)
1492 {}
1493
1494 void operator()(Node &n)
1495 {
1496 this->icont_.insert(pos_, n);
1497 }
1498 };
1499
11fdf7f2
TL
1500 typedef value_less<value_type> value_less_t;
1501 typedef value_equal<value_type> value_equal_t;
7c673cae
FG
1502 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1503
1504};
1505
92f5a8d4
TL
1506#ifndef BOOST_CONTAINER_NO_CXX17_CTAD
1507template <typename InputIterator>
1508list(InputIterator, InputIterator) ->
1509 list<typename iterator_traits<InputIterator>::value_type>;
1510
1511template <typename InputIterator, typename ValueAllocator>
1512list(InputIterator, InputIterator, ValueAllocator const&) ->
1513 list<typename iterator_traits<InputIterator>::value_type, ValueAllocator>;
1514#endif
1515
7c673cae
FG
1516#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1517
1518} //namespace container {
1519
1520//!has_trivial_destructor_after_move<> == true_type
1521//!specialization for optimizations
1522template <class T, class Allocator>
1523struct has_trivial_destructor_after_move<boost::container::list<T, Allocator> >
1524{
92f5a8d4
TL
1525 typedef typename boost::container::list<T, Allocator>::allocator_type allocator_type;
1526 typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer;
1527 static const bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value &&
7c673cae
FG
1528 ::boost::has_trivial_destructor_after_move<pointer>::value;
1529};
1530
1531namespace container {
1532
1533#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1534
1535}}
1536
1537#include <boost/container/detail/config_end.hpp>
1538
1539#endif // BOOST_CONTAINER_LIST_HPP