Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:18

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2005-2015. Distributed under the Boost
0004 // Software License, Version 1.0. (See accompanying file
0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // See http://www.boost.org/libs/container for documentation.
0008 //
0009 //////////////////////////////////////////////////////////////////////////////
0010 #ifndef BOOST_CONTAINER_LIST_HPP
0011 #define BOOST_CONTAINER_LIST_HPP
0012 
0013 #ifndef BOOST_CONFIG_HPP
0014 #  include <boost/config.hpp>
0015 #endif
0016 
0017 #if defined(BOOST_HAS_PRAGMA_ONCE)
0018 #  pragma once
0019 #endif
0020 
0021 #include <boost/container/detail/config_begin.hpp>
0022 #include <boost/container/detail/workaround.hpp>
0023 
0024 // container
0025 #include <boost/container/container_fwd.hpp>
0026 #include <boost/container/new_allocator.hpp> //new_allocator
0027 #include <boost/container/throw_exception.hpp>
0028 // container/detail
0029 #include <boost/container/detail/algorithm.hpp>
0030 #include <boost/container/detail/compare_functors.hpp>
0031 #include <boost/container/detail/iterator.hpp>
0032 #include <boost/container/detail/iterators.hpp>
0033 #include <boost/container/detail/mpl.hpp>
0034 #include <boost/container/detail/node_alloc_holder.hpp>
0035 #include <boost/container/detail/version_type.hpp>
0036 #include <boost/container/detail/value_functors.hpp>
0037 // move
0038 #include <boost/move/utility_core.hpp>
0039 #include <boost/move/iterator.hpp>
0040 #include <boost/move/traits.hpp>
0041 // move/detail
0042 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0043 #  include <boost/move/detail/fwd_macros.hpp>
0044 #endif
0045 #include <boost/move/detail/move_helpers.hpp>
0046 #include <boost/move/detail/force_ptr.hpp>
0047 
0048 // intrusive
0049 #include <boost/intrusive/pointer_traits.hpp>
0050 #include <boost/intrusive/list.hpp>
0051 // other
0052 #include <boost/assert.hpp>
0053 // std
0054 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0055 #include <initializer_list>
0056 #endif
0057 
0058 namespace boost {
0059 namespace container {
0060 
0061 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0062 namespace dtl {
0063 
0064 template<class VoidPointer>
0065 struct list_hook
0066 {
0067    typedef typename dtl::bi::make_list_base_hook
0068       <dtl::bi::void_pointer<VoidPointer>, dtl::bi::link_mode<dtl::bi::normal_link> >::type type;
0069 };
0070 
0071 template <class T, class VoidPointer>
0072 struct iiterator_node_value_type< base_node<T, list_hook<VoidPointer> > >
0073 {
0074   typedef T type;
0075 };
0076 
0077 template<class Allocator>
0078 struct intrusive_list_type
0079 {
0080    typedef boost::container::allocator_traits<Allocator>   allocator_traits_type;
0081    typedef typename allocator_traits_type::value_type value_type;
0082    typedef typename boost::intrusive::pointer_traits
0083       <typename allocator_traits_type::pointer>::template
0084          rebind_pointer<void>::type
0085             void_pointer;
0086    typedef base_node<value_type, list_hook<void_pointer> > node_type;
0087    typedef typename dtl::bi::make_list
0088       < node_type
0089       , dtl::bi::base_hook<typename list_hook<void_pointer>::type>
0090       , dtl::bi::constant_time_size<true>
0091       , dtl::bi::size_type
0092          <typename allocator_traits_type::size_type>
0093       >::type                                   container_type;
0094    typedef container_type                       type ;
0095 };
0096 
0097 }  //namespace dtl {
0098 #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0099 
0100 //! A list is a doubly linked list. That is, it is a Sequence that supports both
0101 //! forward and backward traversal, and (amortized) constant time insertion and
0102 //! removal of elements at the beginning or the end, or in the middle. Lists have
0103 //! the important property that insertion and splicing do not invalidate iterators
0104 //! to list elements, and that even removal invalidates only the iterators that point
0105 //! to the elements that are removed. The ordering of iterators may be changed
0106 //! (that is, list<T>::iterator might have a different predecessor or successor
0107 //! after a list operation than it did before), but the iterators themselves will
0108 //! not be invalidated or made to point to different elements unless that invalidation
0109 //! or mutation is explicit.
0110 //!
0111 //! \tparam T The type of object that is stored in the list
0112 //! \tparam Allocator The allocator used for all internal memory management, use void
0113 //!   for the default allocator
0114 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
0115 template <class T, class Allocator = void >
0116 #else
0117 template <class T, class Allocator>
0118 #endif
0119 class list
0120    : protected dtl::node_alloc_holder
0121       < typename real_allocator<T, Allocator>::type
0122       , typename dtl::intrusive_list_type<typename real_allocator<T, Allocator>::type>::type>
0123 {
0124    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0125    typedef typename real_allocator<T, Allocator>::type            ValueAllocator;
0126    typedef typename
0127       dtl::intrusive_list_type<ValueAllocator>::type Icont;
0128    typedef dtl::node_alloc_holder<ValueAllocator, Icont>          AllocHolder;
0129    typedef typename AllocHolder::NodePtr                          NodePtr;
0130    typedef typename AllocHolder::NodeAlloc                        NodeAlloc;
0131    typedef typename AllocHolder::ValAlloc                         ValAlloc;
0132    typedef typename AllocHolder::Node                             Node;
0133    typedef dtl::allocator_node_destroyer<NodeAlloc>                    Destroyer;
0134    typedef typename AllocHolder::alloc_version                    alloc_version;
0135    typedef boost::container::allocator_traits<ValueAllocator>     allocator_traits_type;
0136    typedef boost::container::equal_to_value
0137       <typename allocator_traits_type::value_type>                equal_to_value_type;
0138 
0139    BOOST_COPYABLE_AND_MOVABLE(list)
0140 
0141    typedef dtl::iterator_from_iiterator<typename Icont::iterator, false>  iterator_impl;
0142    typedef dtl::iterator_from_iiterator<typename Icont::iterator, true>   const_iterator_impl;
0143    #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0144 
0145    public:
0146    //////////////////////////////////////////////
0147    //
0148    //                    types
0149    //
0150    //////////////////////////////////////////////
0151 
0152    typedef T                                                                              value_type;
0153    typedef typename ::boost::container::allocator_traits<ValueAllocator>::pointer         pointer;
0154    typedef typename ::boost::container::allocator_traits<ValueAllocator>::const_pointer   const_pointer;
0155    typedef typename ::boost::container::allocator_traits<ValueAllocator>::reference       reference;
0156    typedef typename ::boost::container::allocator_traits<ValueAllocator>::const_reference const_reference;
0157    typedef typename ::boost::container::allocator_traits<ValueAllocator>::size_type       size_type;
0158    typedef typename ::boost::container::allocator_traits<ValueAllocator>::difference_type difference_type;
0159    typedef ValueAllocator                                                                 allocator_type;
0160    typedef BOOST_CONTAINER_IMPDEF(NodeAlloc)                                              stored_allocator_type;
0161    typedef BOOST_CONTAINER_IMPDEF(iterator_impl)                                          iterator;
0162    typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl)                                    const_iterator;
0163    typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>)           reverse_iterator;
0164    typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>)     const_reverse_iterator;
0165 
0166    //////////////////////////////////////////////
0167    //
0168    //          construct/copy/destroy
0169    //
0170    //////////////////////////////////////////////
0171 
0172    //! <b>Effects</b>: Default constructs a list.
0173    //!
0174    //! <b>Throws</b>: If allocator_type's default constructor throws.
0175    //!
0176    //! <b>Complexity</b>: Constant.
0177    list() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<ValueAllocator>::value)
0178       : AllocHolder()
0179    {}
0180 
0181    //! <b>Effects</b>: Constructs a list taking the allocator as parameter.
0182    //!
0183    //! <b>Throws</b>: Nothing
0184    //!
0185    //! <b>Complexity</b>: Constant.
0186    explicit list(const allocator_type &a) BOOST_NOEXCEPT_OR_NOTHROW
0187       : AllocHolder(a)
0188    {}
0189 
0190    //! <b>Effects</b>: Constructs a list
0191    //!   and inserts n value-initialized value_types.
0192    //!
0193    //! <b>Throws</b>: If allocator_type's default constructor
0194    //!   throws or T's default or copy constructor throws.
0195    //!
0196    //! <b>Complexity</b>: Linear to n.
0197    explicit list(size_type n)
0198       : AllocHolder(ValueAllocator())
0199    {  this->resize(n);  }
0200 
0201    //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
0202    //!   and inserts n copies of value.
0203    //!
0204    //! <b>Throws</b>: If allocator_type's default constructor
0205    //!   throws or T's default or copy constructor throws.
0206    //!
0207    //! <b>Complexity</b>: Linear to n.
0208    list(size_type n, const allocator_type &a)
0209       : AllocHolder(a)
0210    {  this->resize(n);  }
0211 
0212    //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
0213    //!   and inserts n copies of value.
0214    //!
0215    //! <b>Throws</b>: If allocator_type's default constructor
0216    //!   throws or T's default or copy constructor throws.
0217    //!
0218    //! <b>Complexity</b>: Linear to n.
0219    list(size_type n, const T& value, const ValueAllocator& a = ValueAllocator())
0220       : AllocHolder(a)
0221    {  this->insert(this->cbegin(), n, value);  }
0222 
0223    //! <b>Effects</b>: Copy constructs a list.
0224    //!
0225    //! <b>Postcondition</b>: x == *this.
0226    //!
0227    //! <b>Throws</b>: If allocator_type's default constructor throws.
0228    //!
0229    //! <b>Complexity</b>: Linear to the elements x contains.
0230    list(const list& x)
0231       : AllocHolder(x)
0232    {  this->insert(this->cbegin(), x.begin(), x.end());   }
0233 
0234    //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
0235    //!
0236    //! <b>Throws</b>: If allocator_type's copy constructor throws.
0237    //!
0238    //! <b>Complexity</b>: Constant.
0239    list(BOOST_RV_REF(list) x) BOOST_NOEXCEPT_OR_NOTHROW
0240       : AllocHolder(BOOST_MOVE_BASE(AllocHolder, x))
0241    {}
0242 
0243    //! <b>Effects</b>: Copy constructs a list using the specified allocator.
0244    //!
0245    //! <b>Postcondition</b>: x == *this.
0246    //!
0247    //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
0248    //!
0249    //! <b>Complexity</b>: Linear to the elements x contains.
0250    list(const list& x, const allocator_type &a)
0251       : AllocHolder(a)
0252    {  this->insert(this->cbegin(), x.begin(), x.end());   }
0253 
0254    //! <b>Effects</b>: Move constructor sing the specified allocator.
0255    //!                 Moves x's resources to *this.
0256    //!
0257    //! <b>Throws</b>: If allocation or value_type's copy constructor throws.
0258    //!
0259    //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
0260    list(BOOST_RV_REF(list) x, const allocator_type &a)
0261       : AllocHolder(a)
0262    {
0263       if(this->node_alloc() == x.node_alloc()){
0264          this->icont().swap(x.icont());
0265       }
0266       else{
0267          this->insert(this->cbegin(), boost::make_move_iterator(x.begin()), boost::make_move_iterator(x.end()));
0268       }
0269    }
0270 
0271    //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
0272    //!   and inserts a copy of the range [first, last) in the list.
0273    //!
0274    //! <b>Throws</b>: If allocator_type's default constructor
0275    //!   throws or T's constructor taking a dereferenced InIt throws.
0276    //!
0277    //! <b>Complexity</b>: Linear to the range [first, last).
0278    template <class InpIt>
0279    list(InpIt first, InpIt last, const ValueAllocator &a = ValueAllocator())
0280       : AllocHolder(a)
0281    {  this->insert(this->cbegin(), first, last);  }
0282 
0283 
0284 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0285    //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
0286    //!   and inserts a copy of the range [il.begin(), il.end()) in the list.
0287    //!
0288    //! <b>Throws</b>: If allocator_type's default constructor
0289    //!   throws or T's constructor taking a dereferenced
0290    //!   std::initializer_list iterator throws.
0291    //!
0292    //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
0293    list(std::initializer_list<value_type> il, const ValueAllocator &a = ValueAllocator())
0294       : AllocHolder(a)
0295    {  this->insert(this->cbegin(), il.begin(), il.end()); }
0296 #endif
0297 
0298    //! <b>Effects</b>: Destroys the list. All stored values are destroyed
0299    //!   and used memory is deallocated.
0300    //!
0301    //! <b>Throws</b>: Nothing.
0302    //!
0303    //! <b>Complexity</b>: Linear to the number of elements.
0304    BOOST_CONTAINER_FORCEINLINE ~list() BOOST_NOEXCEPT_OR_NOTHROW
0305    {} //AllocHolder clears the list
0306 
0307    //! <b>Effects</b>: Makes *this contain the same elements as x.
0308    //!
0309    //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
0310    //! of each of x's elements.
0311    //!
0312    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
0313    //!
0314    //! <b>Complexity</b>: Linear to the number of elements in x.
0315    list& operator=(BOOST_COPY_ASSIGN_REF(list) x)
0316    {
0317       if (BOOST_LIKELY(this != &x)) {
0318          NodeAlloc &this_alloc     = this->node_alloc();
0319          const NodeAlloc &x_alloc  = x.node_alloc();
0320          dtl::bool_<allocator_traits_type::
0321             propagate_on_container_copy_assignment::value> flag;
0322          if(flag && this_alloc != x_alloc){
0323             this->clear();
0324          }
0325          this->AllocHolder::copy_assign_alloc(x);
0326          this->assign(x.begin(), x.end());
0327       }
0328       return *this;
0329    }
0330 
0331    //! <b>Effects</b>: Move assignment. All x's values are transferred to *this.
0332    //!
0333    //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
0334    //!   before the function.
0335    //!
0336    //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
0337    //!   is false and (allocation throws or value_type's move constructor throws)
0338    //!
0339    //! <b>Complexity</b>: Constant if allocator_traits_type::
0340    //!   propagate_on_container_move_assignment is true or
0341    //!   this->get>allocator() == x.get_allocator(). Linear otherwise.
0342    list& operator=(BOOST_RV_REF(list) x)
0343       BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
0344                                   || allocator_traits_type::is_always_equal::value)
0345    {
0346       if (BOOST_LIKELY(this != &x)) {
0347          NodeAlloc &this_alloc = this->node_alloc();
0348          NodeAlloc &x_alloc    = x.node_alloc();
0349          const bool propagate_alloc = allocator_traits_type::
0350                propagate_on_container_move_assignment::value;
0351          const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
0352          //Resources can be transferred if both allocators are
0353          //going to be equal after this function (either propagated or already equal)
0354          if(propagate_alloc || allocators_equal){
0355             //Destroy
0356             this->clear();
0357             //Move allocator if needed
0358             this->AllocHolder::move_assign_alloc(x);
0359             //Obtain resources
0360             this->icont() = boost::move(x.icont());
0361          }
0362          //Else do a one by one move
0363          else{
0364             this->assign( boost::make_move_iterator(x.begin())
0365                         , boost::make_move_iterator(x.end()));
0366          }
0367       }
0368       return *this;
0369    }
0370 
0371 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0372    //! <b>Effects</b>: Makes *this contain the same elements as il.
0373    //!
0374    //! <b>Postcondition</b>: this->size() == il.size(). *this contains a copy
0375    //! of each of x's elements.
0376    //!
0377    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
0378    //!
0379    //! <b>Complexity</b>: Linear to the number of elements in x.
0380    BOOST_CONTAINER_FORCEINLINE list& operator=(std::initializer_list<value_type> il)
0381    {
0382       this->assign(il.begin(), il.end());
0383       return *this;
0384    }
0385 #endif
0386 
0387    //! <b>Effects</b>: Assigns the n copies of val to *this.
0388    //!
0389    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
0390    //!
0391    //! <b>Complexity</b>: Linear to n.
0392    BOOST_CONTAINER_FORCEINLINE void assign(size_type n, const T& val)
0393    {
0394       typedef constant_iterator<value_type> cvalue_iterator;
0395       return this->assign(cvalue_iterator(val, n), cvalue_iterator());
0396    }
0397 
0398    //! <b>Effects</b>: Assigns the range [first, last) to *this.
0399    //!
0400    //! <b>Throws</b>: If memory allocation throws or
0401    //!   T's constructor from dereferencing InpIt throws.
0402    //!
0403    //! <b>Complexity</b>: Linear to n.
0404    template <class InpIt>
0405    void assign(InpIt first, InpIt last
0406       #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0407       , typename dtl::disable_if_convertible<InpIt, size_type>::type * = 0
0408       #endif
0409       )
0410    {
0411       iterator first1      = this->begin();
0412       const iterator last1 = this->end();
0413       for ( ; first1 != last1 && first != last; ++first1, ++first)
0414          *first1 = *first;
0415       if (first == last)
0416          this->erase(first1, last1);
0417       else{
0418          this->insert(last1, first, last);
0419       }
0420    }
0421 
0422 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0423    //! <b>Effects</b>: Assigns the range [il.begin(), il.end()) to *this.
0424    //!
0425    //! <b>Throws</b>: If memory allocation throws or
0426    //!   T's constructor from dereferencing std::initializer_list iterator throws.
0427    //!
0428    //! <b>Complexity</b>: Linear to n.
0429    BOOST_CONTAINER_FORCEINLINE void assign(std::initializer_list<value_type> il)
0430    { this->assign(il.begin(), il.end()); }
0431 #endif
0432 
0433    //! <b>Effects</b>: Returns a copy of the internal allocator.
0434    //!
0435    //! <b>Throws</b>: If allocator's copy constructor throws.
0436    //!
0437    //! <b>Complexity</b>: Constant.
0438    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0439       allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
0440    {  return allocator_type(this->node_alloc()); }
0441 
0442    //! <b>Effects</b>: Returns a reference to the internal allocator.
0443    //!
0444    //! <b>Throws</b>: Nothing
0445    //!
0446    //! <b>Complexity</b>: Constant.
0447    //!
0448    //! <b>Note</b>: Non-standard extension.
0449    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0450       stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
0451    {  return this->node_alloc(); }
0452 
0453    //! <b>Effects</b>: Returns a reference to the internal allocator.
0454    //!
0455    //! <b>Throws</b>: Nothing
0456    //!
0457    //! <b>Complexity</b>: Constant.
0458    //!
0459    //! <b>Note</b>: Non-standard extension.
0460    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0461       const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
0462    {  return this->node_alloc(); }
0463 
0464    //////////////////////////////////////////////
0465    //
0466    //                iterators
0467    //
0468    //////////////////////////////////////////////
0469 
0470    //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
0471    //!
0472    //! <b>Throws</b>: Nothing.
0473    //!
0474    //! <b>Complexity</b>: Constant.
0475    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0476       iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
0477    { return iterator(this->icont().begin()); }
0478 
0479    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
0480    //!
0481    //! <b>Throws</b>: Nothing.
0482    //!
0483    //! <b>Complexity</b>: Constant.
0484    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0485       const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
0486    {  return this->cbegin();   }
0487 
0488    //! <b>Effects</b>: Returns an iterator to the end of the list.
0489    //!
0490    //! <b>Throws</b>: Nothing.
0491    //!
0492    //! <b>Complexity</b>: Constant.
0493    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0494       iterator end() BOOST_NOEXCEPT_OR_NOTHROW
0495    {  return iterator(this->icont().end());  }
0496 
0497    //! <b>Effects</b>: Returns a const_iterator to the end of the list.
0498    //!
0499    //! <b>Throws</b>: Nothing.
0500    //!
0501    //! <b>Complexity</b>: Constant.
0502    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0503       const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
0504    {  return this->cend();  }
0505 
0506    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
0507    //! of the reversed list.
0508    //!
0509    //! <b>Throws</b>: Nothing.
0510    //!
0511    //! <b>Complexity</b>: Constant.
0512    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0513       reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
0514    {  return reverse_iterator(end());  }
0515 
0516    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
0517    //! of the reversed list.
0518    //!
0519    //! <b>Throws</b>: Nothing.
0520    //!
0521    //! <b>Complexity</b>: Constant.
0522    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0523       const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
0524    {  return this->crbegin();  }
0525 
0526    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
0527    //! of the reversed list.
0528    //!
0529    //! <b>Throws</b>: Nothing.
0530    //!
0531    //! <b>Complexity</b>: Constant.
0532    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0533       reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
0534    {  return reverse_iterator(begin());   }
0535 
0536    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
0537    //! of the reversed list.
0538    //!
0539    //! <b>Throws</b>: Nothing.
0540    //!
0541    //! <b>Complexity</b>: Constant.
0542    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0543       const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
0544    {  return this->crend();   }
0545 
0546    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
0547    //!
0548    //! <b>Throws</b>: Nothing.
0549    //!
0550    //! <b>Complexity</b>: Constant.
0551    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0552       const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
0553    {  return const_iterator(this->non_const_icont().begin());   }
0554 
0555    //! <b>Effects</b>: Returns a const_iterator to the end of the list.
0556    //!
0557    //! <b>Throws</b>: Nothing.
0558    //!
0559    //! <b>Complexity</b>: Constant.
0560    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0561       const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
0562    {  return const_iterator(this->non_const_icont().end());  }
0563 
0564    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
0565    //! of the reversed list.
0566    //!
0567    //! <b>Throws</b>: Nothing.
0568    //!
0569    //! <b>Complexity</b>: Constant.
0570    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0571       const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
0572    {  return const_reverse_iterator(this->cend());  }
0573 
0574    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
0575    //! of the reversed list.
0576    //!
0577    //! <b>Throws</b>: Nothing.
0578    //!
0579    //! <b>Complexity</b>: Constant.
0580    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0581       const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
0582    {  return const_reverse_iterator(this->cbegin());   }
0583 
0584    //////////////////////////////////////////////
0585    //
0586    //                capacity
0587    //
0588    //////////////////////////////////////////////
0589 
0590    //! <b>Effects</b>: Returns true if the list contains no elements.
0591    //!
0592    //! <b>Throws</b>: Nothing.
0593    //!
0594    //! <b>Complexity</b>: Constant.
0595    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0596       bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
0597    {  return !this->size();  }
0598 
0599    //! <b>Effects</b>: Returns the number of the elements contained in the list.
0600    //!
0601    //! <b>Throws</b>: Nothing.
0602    //!
0603    //! <b>Complexity</b>: Constant.
0604    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0605       size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
0606    {   return this->icont().size();   }
0607 
0608    //! <b>Effects</b>: Returns the largest possible size of the list.
0609    //!
0610    //! <b>Throws</b>: Nothing.
0611    //!
0612    //! <b>Complexity</b>: Constant.
0613    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0614       size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
0615    {  return AllocHolder::max_size();  }
0616 
0617    //! <b>Effects</b>: Inserts or erases elements at the end such that
0618    //!   the size becomes n. New elements are value initialized.
0619    //!
0620    //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
0621    //!
0622    //! <b>Complexity</b>: Linear to the difference between size() and new_size.
0623    void resize(size_type new_size)
0624    {
0625       if(!priv_try_shrink(new_size)){
0626          typedef value_init_construct_iterator<value_type> value_init_iterator;
0627          this->insert(this->cend(), value_init_iterator(new_size - this->size()), value_init_iterator());
0628       }
0629    }
0630 
0631    //! <b>Effects</b>: Inserts or erases elements at the end such that
0632    //!   the size becomes n. New elements are copy constructed from x.
0633    //!
0634    //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
0635    //!
0636    //! <b>Complexity</b>: Linear to the difference between size() and new_size.
0637    void resize(size_type new_size, const T& x)
0638    {
0639       if(!priv_try_shrink(new_size)){
0640          this->insert(this->cend(), new_size - this->size(), x);
0641       }
0642    }
0643 
0644    //////////////////////////////////////////////
0645    //
0646    //               element access
0647    //
0648    //////////////////////////////////////////////
0649 
0650    //! <b>Requires</b>: !empty()
0651    //!
0652    //! <b>Effects</b>: Returns a reference to the first element
0653    //!   from the beginning of the container.
0654    //!
0655    //! <b>Throws</b>: Nothing.
0656    //!
0657    //! <b>Complexity</b>: Constant.
0658    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0659       reference front() BOOST_NOEXCEPT_OR_NOTHROW
0660    {
0661       BOOST_ASSERT(!this->empty());
0662       return *this->begin();
0663    }
0664 
0665    //! <b>Requires</b>: !empty()
0666    //!
0667    //! <b>Effects</b>: Returns a const reference to the first element
0668    //!   from the beginning of the container.
0669    //!
0670    //! <b>Throws</b>: Nothing.
0671    //!
0672    //! <b>Complexity</b>: Constant.
0673    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0674       const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
0675    {
0676       BOOST_ASSERT(!this->empty());
0677       return *this->begin();
0678    }
0679 
0680    //! <b>Requires</b>: !empty()
0681    //!
0682    //! <b>Effects</b>: Returns a reference to the first element
0683    //!   from the beginning of the container.
0684    //!
0685    //! <b>Throws</b>: Nothing.
0686    //!
0687    //! <b>Complexity</b>: Constant.
0688    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0689       reference back() BOOST_NOEXCEPT_OR_NOTHROW
0690    {
0691       BOOST_ASSERT(!this->empty());
0692       return *(--this->end());
0693    }
0694 
0695    //! <b>Requires</b>: !empty()
0696    //!
0697    //! <b>Effects</b>: Returns a const reference to the first element
0698    //!   from the beginning of the container.
0699    //!
0700    //! <b>Throws</b>: Nothing.
0701    //!
0702    //! <b>Complexity</b>: Constant.
0703    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0704       const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
0705    {
0706       BOOST_ASSERT(!this->empty());
0707       return *(--this->end());
0708    }
0709 
0710    //////////////////////////////////////////////
0711    //
0712    //                modifiers
0713    //
0714    //////////////////////////////////////////////
0715 
0716    #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0717 
0718    //! <b>Effects</b>: Inserts an object of type T constructed with
0719    //!   std::forward<Args>(args)... in the end of the list.
0720    //!
0721    //! <b>Returns</b>: A reference to the created object.
0722    //!
0723    //! <b>Throws</b>: If memory allocation throws or
0724    //!   T's in-place constructor throws.
0725    //!
0726    //! <b>Complexity</b>: Constant
0727    template <class... Args>
0728    reference emplace_back(BOOST_FWD_REF(Args)... args)
0729    {  return *this->emplace(this->cend(), boost::forward<Args>(args)...); }
0730 
0731    //! <b>Effects</b>: Inserts an object of type T constructed with
0732    //!   std::forward<Args>(args)... in the beginning of the list.
0733    //!
0734    //! <b>Returns</b>: A reference to the created object.
0735    //!
0736    //! <b>Throws</b>: If memory allocation throws or
0737    //!   T's in-place constructor throws.
0738    //!
0739    //! <b>Complexity</b>: Constant
0740    template <class... Args>
0741    reference emplace_front(BOOST_FWD_REF(Args)... args)
0742    {  return *this->emplace(this->cbegin(), boost::forward<Args>(args)...);  }
0743 
0744    //! <b>Effects</b>: Inserts an object of type T constructed with
0745    //!   std::forward<Args>(args)... before p.
0746    //!
0747    //! <b>Throws</b>: If memory allocation throws or
0748    //!   T's in-place constructor throws.
0749    //!
0750    //! <b>Complexity</b>: Constant
0751    template <class... Args>
0752    iterator emplace(const_iterator position, BOOST_FWD_REF(Args)... args)
0753    {
0754       BOOST_ASSERT((priv_is_linked)(position));
0755       NodePtr pnode(AllocHolder::create_node(boost::forward<Args>(args)...));
0756       return iterator(this->icont().insert(position.get(), *pnode));
0757    }
0758 
0759    #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0760 
0761    #define BOOST_CONTAINER_LIST_EMPLACE_CODE(N) \
0762    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
0763    reference emplace_back(BOOST_MOVE_UREF##N)\
0764    {  return *this->emplace(this->cend() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);  }\
0765    \
0766    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
0767    reference emplace_front(BOOST_MOVE_UREF##N)\
0768    {  return *this->emplace(this->cbegin() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);}\
0769    \
0770    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
0771    iterator emplace(const_iterator position BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
0772    {\
0773       BOOST_ASSERT(position == this->cend() || (--(++position) == position) );\
0774       NodePtr pnode (AllocHolder::create_node(BOOST_MOVE_FWD##N));\
0775       return iterator(this->icont().insert(position.get(), *pnode));\
0776    }\
0777    //
0778    BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_LIST_EMPLACE_CODE)
0779    #undef BOOST_CONTAINER_LIST_EMPLACE_CODE
0780 
0781    #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0782 
0783    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0784    //! <b>Effects</b>: Inserts a copy of x at the beginning of the list.
0785    //!
0786    //! <b>Throws</b>: If memory allocation throws or
0787    //!   T's copy constructor throws.
0788    //!
0789    //! <b>Complexity</b>: Amortized constant time.
0790    void push_front(const T &x);
0791 
0792    //! <b>Effects</b>: Constructs a new element in the beginning of the list
0793    //!   and moves the resources of x to this new element.
0794    //!
0795    //! <b>Throws</b>: If memory allocation throws.
0796    //!
0797    //! <b>Complexity</b>: Amortized constant time.
0798    void push_front(T &&x);
0799    #else
0800    BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
0801    #endif
0802 
0803    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0804    //! <b>Effects</b>: Inserts a copy of x at the end of the list.
0805    //!
0806    //! <b>Throws</b>: If memory allocation throws or
0807    //!   T's copy constructor throws.
0808    //!
0809    //! <b>Complexity</b>: Amortized constant time.
0810    void push_back(const T &x);
0811 
0812    //! <b>Effects</b>: Constructs a new element in the end of the list
0813    //!   and moves the resources of x to this new element.
0814    //!
0815    //! <b>Throws</b>: If memory allocation throws.
0816    //!
0817    //! <b>Complexity</b>: Amortized constant time.
0818    void push_back(T &&x);
0819    #else
0820    BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
0821    #endif
0822 
0823    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0824    //! <b>Requires</b>: p must be a valid iterator of *this.
0825    //!
0826    //! <b>Effects</b>: Insert a copy of x before p.
0827    //!
0828    //! <b>Returns</b>: an iterator to the inserted element.
0829    //!
0830    //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
0831    //!
0832    //! <b>Complexity</b>: Amortized constant time.
0833    iterator insert(const_iterator p, const T &x);
0834 
0835    //! <b>Requires</b>: p must be a valid iterator of *this.
0836    //!
0837    //! <b>Effects</b>: Insert a new element before p with x's resources.
0838    //!
0839    //! <b>Returns</b>: an iterator to the inserted element.
0840    //!
0841    //! <b>Throws</b>: If memory allocation throws.
0842    //!
0843    //! <b>Complexity</b>: Amortized constant time.
0844    iterator insert(const_iterator p, T &&x);
0845    #else
0846    BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
0847    #endif
0848 
0849    //! <b>Requires</b>: p must be a valid iterator of *this.
0850    //!
0851    //! <b>Effects</b>: Inserts n copies of x before p.
0852    //!
0853    //! <b>Returns</b>: an iterator to the first inserted element or p if n is 0.
0854    //!
0855    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
0856    //!
0857    //! <b>Complexity</b>: Linear to n.
0858    iterator insert(const_iterator position, size_type n, const T& x)
0859    {
0860       //range check is done by insert
0861       typedef constant_iterator<value_type> cvalue_iterator;
0862       return this->insert(position, cvalue_iterator(x, n), cvalue_iterator());
0863    }
0864 
0865    //! <b>Requires</b>: p must be a valid iterator of *this.
0866    //!
0867    //! <b>Effects</b>: Insert a copy of the [first, last) range before p.
0868    //!
0869    //! <b>Returns</b>: an iterator to the first inserted element or p if first == last.
0870    //!
0871    //! <b>Throws</b>: If memory allocation throws, T's constructor from a
0872    //!   dereferenced InpIt throws.
0873    //!
0874    //! <b>Complexity</b>: Linear to distance [first, last).
0875    template <class InpIt>
0876    iterator insert(const_iterator p, InpIt first, InpIt last
0877       #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0878       , typename dtl::enable_if_c
0879          < !dtl::is_convertible<InpIt, size_type>::value
0880             && (dtl::is_input_iterator<InpIt>::value
0881                 || dtl::is_same<alloc_version, version_1>::value
0882                )
0883          >::type * = 0
0884       #endif
0885       )
0886    {
0887       BOOST_ASSERT((priv_is_linked)(p));
0888       const typename Icont::iterator ipos(p.get());
0889       iterator ret_it(ipos);
0890       if(first != last){
0891          ret_it = iterator(this->icont().insert(ipos, *this->create_node_from_it(first)));
0892          ++first;
0893       }
0894       for (; first != last; ++first){
0895          this->icont().insert(ipos, *this->create_node_from_it(first));
0896       }
0897       return ret_it;
0898    }
0899 
0900    #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0901    template <class FwdIt>
0902    iterator insert(const_iterator position, FwdIt first, FwdIt last
0903       , typename dtl::enable_if_c
0904          < !dtl::is_convertible<FwdIt, size_type>::value
0905             && !(dtl::is_input_iterator<FwdIt>::value
0906                 || dtl::is_same<alloc_version, version_1>::value
0907                )
0908          >::type * = 0
0909       )
0910    {
0911       BOOST_ASSERT((priv_is_linked)(position));
0912       //Optimized allocation and construction
0913       insertion_functor func(this->icont(), position.get());
0914       iterator before_p(position.get());
0915       --before_p;
0916       this->allocate_many_and_construct(first, boost::container::iterator_udistance(first, last), func);
0917       return ++before_p;
0918    }
0919    #endif
0920 
0921 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0922    //! <b>Requires</b>: p must be a valid iterator of *this.
0923    //!
0924    //! <b>Effects</b>: Insert a copy of the [il.begin(), il.end()) range before p.
0925    //!
0926    //! <b>Returns</b>: an iterator to the first inserted element or p if if.begin() == il.end().
0927    //!
0928    //! <b>Throws</b>: If memory allocation throws, T's constructor from a
0929    //!   dereferenced std::initializer_list iterator throws.
0930    //!
0931    //! <b>Complexity</b>: Linear to distance [il.begin(), il.end()).
0932    iterator insert(const_iterator p, std::initializer_list<value_type> il)
0933    {
0934       //position range check is done by insert()
0935       return insert(p, il.begin(), il.end());
0936    }
0937 #endif
0938 
0939    //! <b>Effects</b>: Removes the first element from the list.
0940    //!
0941    //! <b>Throws</b>: Nothing.
0942    //!
0943    //! <b>Complexity</b>: Amortized constant time.
0944    void pop_front() BOOST_NOEXCEPT_OR_NOTHROW
0945    {
0946       BOOST_ASSERT(!this->empty());
0947       this->erase(this->cbegin());
0948    }
0949 
0950    //! <b>Effects</b>: Removes the last element from the list.
0951    //!
0952    //! <b>Throws</b>: Nothing.
0953    //!
0954    //! <b>Complexity</b>: Amortized constant time.
0955    void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
0956    {
0957       BOOST_ASSERT(!this->empty());
0958       const_iterator tmp = this->cend();
0959       this->erase(--tmp);
0960    }
0961 
0962    //! <b>Requires</b>: p must be a valid iterator of *this.
0963    //!
0964    //! <b>Effects</b>: Erases the element at p.
0965    //!
0966    //! <b>Throws</b>: Nothing.
0967    //!
0968    //! <b>Complexity</b>: Amortized constant time.
0969    iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
0970    {
0971       BOOST_ASSERT(p != this->cend() && (priv_is_linked)(p));
0972       return iterator(this->icont().erase_and_dispose(p.get(), Destroyer(this->node_alloc())));
0973    }
0974 
0975    //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
0976    //!
0977    //! <b>Effects</b>: Erases the elements pointed by [first, last).
0978    //!
0979    //! <b>Throws</b>: Nothing.
0980    //!
0981    //! <b>Complexity</b>: Linear to the distance between first and last.
0982    iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
0983    {
0984       BOOST_ASSERT(first == last || (first != this->cend() && (priv_is_linked)(first)));
0985       BOOST_ASSERT(first == last || (priv_is_linked)(last));
0986       return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version()));
0987    }
0988 
0989    //! <b>Effects</b>: Swaps the contents of *this and x.
0990    //!
0991    //! <b>Throws</b>: Nothing.
0992    //!
0993    //! <b>Complexity</b>: Constant.
0994    void swap(list& x)
0995       BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_swap::value
0996                                || allocator_traits_type::is_always_equal::value)
0997    {
0998       BOOST_ASSERT(allocator_traits_type::propagate_on_container_swap::value ||
0999                    allocator_traits_type::is_always_equal::value ||
1000                    this->get_stored_allocator() == x.get_stored_allocator());
1001       AllocHolder::swap(x);
1002    }
1003 
1004    //! <b>Effects</b>: Erases all the elements of the list.
1005    //!
1006    //! <b>Throws</b>: Nothing.
1007    //!
1008    //! <b>Complexity</b>: Linear to the number of elements in the list.
1009    void clear() BOOST_NOEXCEPT_OR_NOTHROW
1010    {  AllocHolder::clear(alloc_version());  }
1011 
1012    //////////////////////////////////////////////
1013    //
1014    //              slist operations
1015    //
1016    //////////////////////////////////////////////
1017 
1018    //! <b>Requires</b>: p must point to an element contained
1019    //!   by the list. x != *this. this' allocator and x's allocator shall compare equal
1020    //!
1021    //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
1022    //!   the element pointed by p. No destructors or copy constructors are called.
1023    //!
1024    //! <b>Throws</b>: Nothing
1025    //!
1026    //! <b>Complexity</b>: Constant.
1027    //!
1028    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
1029    //!    this list. Iterators of this list and all the references are not invalidated.
1030    void splice(const_iterator p, list& x) BOOST_NOEXCEPT_OR_NOTHROW
1031    {
1032       BOOST_ASSERT((priv_is_linked)(p));
1033       BOOST_ASSERT(this != &x);
1034       BOOST_ASSERT(this->node_alloc() == x.node_alloc());
1035       this->icont().splice(p.get(), x.icont());
1036    }
1037 
1038    //! <b>Requires</b>: p must point to an element contained
1039    //!   by the list. x != *this. this' allocator and x's allocator shall compare equal
1040    //!
1041    //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
1042    //!   the element pointed by p. No destructors or copy constructors are called.
1043    //!
1044    //! <b>Throws</b>: Nothing
1045    //!
1046    //! <b>Complexity</b>: Constant.
1047    //!
1048    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
1049    //!    this list. Iterators of this list and all the references are not invalidated.
1050    void splice(const_iterator p, BOOST_RV_REF(list) x) BOOST_NOEXCEPT_OR_NOTHROW
1051    {
1052       //Checks done in splice
1053       this->splice(p, static_cast<list&>(x));
1054    }
1055 
1056    //! <b>Requires</b>: p must point to an element contained
1057    //!   by this list. i must point to an element contained in list x.
1058    //!   this' allocator and x's allocator shall compare equal
1059    //!
1060    //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
1061    //!   before the element pointed by p. No destructors or copy constructors are called.
1062    //!   If p == i or p == ++i, this function is a null operation.
1063    //!
1064    //! <b>Throws</b>: Nothing
1065    //!
1066    //! <b>Complexity</b>: Constant.
1067    //!
1068    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
1069    //!   list. Iterators of this list and all the references are not invalidated.
1070    void splice(const_iterator p, list &x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW
1071    {
1072       BOOST_ASSERT((priv_is_linked)(p));
1073       BOOST_ASSERT(this->node_alloc() == x.node_alloc());
1074       this->icont().splice(p.get(), x.icont(), i.get());
1075    }
1076 
1077    //! <b>Requires</b>: p must point to an element contained
1078    //!   by this list. i must point to an element contained in list x.
1079    //!   this' allocator and x's allocator shall compare equal.
1080    //!
1081    //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
1082    //!   before the element pointed by p. No destructors or copy constructors are called.
1083    //!   If p == i or p == ++i, this function is a null operation.
1084    //!
1085    //! <b>Throws</b>: Nothing
1086    //!
1087    //! <b>Complexity</b>: Constant.
1088    //!
1089    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
1090    //!   list. Iterators of this list and all the references are not invalidated.
1091    void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW
1092    {
1093       BOOST_ASSERT(this != &x);
1094       //Additional checks done in splice()
1095       this->splice(p, static_cast<list&>(x), i);
1096    }
1097 
1098    //! <b>Requires</b>: p must point to an element contained
1099    //!   by this list. first and last must point to elements contained in list x.
1100    //!   this' allocator and x's allocator shall compare equal
1101    //!
1102    //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
1103    //!   before the element pointed by p. No destructors or copy constructors are called.
1104    //!
1105    //! <b>Throws</b>: Nothing
1106    //!
1107    //! <b>Complexity</b>: Linear to the number of elements transferred.
1108    //!
1109    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
1110    //!   list. Iterators of this list and all the references are not invalidated.
1111    void splice(const_iterator p, list &x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
1112    {
1113       BOOST_ASSERT((priv_is_linked)(p));
1114       BOOST_ASSERT(first == last || (first != x.cend() && x.priv_is_linked(first)));
1115       BOOST_ASSERT(first == last || x.priv_is_linked(last));
1116       BOOST_ASSERT(this->node_alloc() == x.node_alloc());
1117       this->icont().splice(p.get(), x.icont(), first.get(), last.get());
1118    }
1119 
1120    //! <b>Requires</b>: p must point to an element contained
1121    //!   by this list. first and last must point to elements contained in list x.
1122    //!   this' allocator and x's allocator shall compare equal.
1123    //!
1124    //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
1125    //!   before the element pointed by p. No destructors or copy constructors are called.
1126    //!
1127    //! <b>Throws</b>: Nothing
1128    //!
1129    //! <b>Complexity</b>: Linear to the number of elements transferred.
1130    //!
1131    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
1132    //!   list. Iterators of this list and all the references are not invalidated.
1133    void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
1134    {
1135       BOOST_ASSERT(this != &x);
1136       //Additional checks done in splice()
1137       this->splice(p, static_cast<list&>(x), first, last);
1138    }
1139 
1140    //! <b>Requires</b>: p must point to an element contained
1141    //!   by this list. first and last must point to elements contained in list x.
1142    //!   n == distance(first, last). this' allocator and x's allocator shall compare equal
1143    //!
1144    //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
1145    //!   before the element pointed by p. No destructors or copy constructors are called.
1146    //!
1147    //! <b>Throws</b>:  Nothing
1148    //!
1149    //! <b>Complexity</b>: Constant.
1150    //!
1151    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
1152    //!   list. Iterators of this list and all the references are not invalidated.
1153    //!
1154    //! <b>Note</b>: Non-standard extension
1155    void splice(const_iterator p, list &x, const_iterator first, const_iterator last, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
1156    {
1157       BOOST_ASSERT(this->node_alloc() == x.node_alloc());
1158       this->icont().splice(p.get(), x.icont(), first.get(), last.get(), n);
1159    }
1160 
1161    //! <b>Requires</b>: p must point to an element contained
1162    //!   by this list. first and last must point to elements contained in list x.
1163    //!   n == distance(first, last). this' allocator and x's allocator shall compare equal
1164    //!
1165    //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
1166    //!   before the element pointed by p. No destructors or copy constructors are called.
1167    //!
1168    //! <b>Throws</b>: Nothing
1169    //!
1170    //! <b>Complexity</b>: Constant.
1171    //!
1172    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
1173    //!   list. Iterators of this list and all the references are not invalidated.
1174    //!
1175    //! <b>Note</b>: Non-standard extension
1176    void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator first, const_iterator last, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
1177    {  this->splice(p, static_cast<list&>(x), first, last, n);  }
1178 
1179    //! <b>Effects</b>: Removes all the elements that compare equal to value.
1180    //!
1181    //! <b>Throws</b>: If comparison throws.
1182    //!
1183    //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
1184    //!
1185    //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1186    //!   and iterators to elements that are not removed remain valid.
1187    void remove(const T& value)
1188    {  this->remove_if(equal_to_value_type(value));  }
1189 
1190    //! <b>Effects</b>: Removes all the elements for which a specified
1191    //!   predicate is satisfied.
1192    //!
1193    //! <b>Throws</b>: If pred throws.
1194    //!
1195    //! <b>Complexity</b>: Linear time. It performs exactly size() calls to the predicate.
1196    //!
1197    //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1198    //!   and iterators to elements that are not removed remain valid.
1199    template <class Pred>
1200    void remove_if(Pred pred)
1201    {
1202       typedef value_to_node_compare<Node, Pred> value_to_node_compare_type;
1203       this->icont().remove_and_dispose_if(value_to_node_compare_type(pred), Destroyer(this->node_alloc()));
1204    }
1205 
1206    //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
1207    //!   elements that are equal from the list.
1208    //!
1209    //! <b>Throws</b>: If comparison throws.
1210    //!
1211    //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
1212    //!
1213    //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1214    //!   and iterators to elements that are not removed remain valid.
1215    void unique()
1216    {  this->unique(value_equal_t());  }
1217 
1218    //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
1219    //!   elements that satisfy some binary predicate from the list.
1220    //!
1221    //! <b>Throws</b>: If pred throws.
1222    //!
1223    //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
1224    //!
1225    //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1226    //!   and iterators to elements that are not removed remain valid.
1227    template <class BinaryPredicate>
1228    void unique(BinaryPredicate binary_pred)
1229    {
1230       typedef value_to_node_compare<Node, BinaryPredicate> value_to_node_compare_type;
1231       this->icont().unique_and_dispose(value_to_node_compare_type(binary_pred), Destroyer(this->node_alloc()));
1232    }
1233 
1234    //! <b>Requires</b>: The lists x and *this must be distinct.
1235    //!
1236    //! <b>Effects</b>: This function removes all of x's elements and inserts them
1237    //!   in order into *this according to std::less<value_type>. The merge is stable;
1238    //!   that is, if an element from *this is equivalent to one from x, then the element
1239    //!   from *this will precede the one from x.
1240    //!
1241    //! <b>Throws</b>: If comparison throws.
1242    //!
1243    //! <b>Complexity</b>: This function is linear time: it performs at most
1244    //!   size() + x.size() - 1 comparisons.
1245    void merge(list &x)
1246    {  this->merge(x, value_less_t());  }
1247 
1248    //! <b>Requires</b>: The lists x and *this must be distinct.
1249    //!
1250    //! <b>Effects</b>: This function removes all of x's elements and inserts them
1251    //!   in order into *this according to std::less<value_type>. The merge is stable;
1252    //!   that is, if an element from *this is equivalent to one from x, then the element
1253    //!   from *this will precede the one from x.
1254    //!
1255    //! <b>Throws</b>: If comparison throws.
1256    //!
1257    //! <b>Complexity</b>: This function is linear time: it performs at most
1258    //!   size() + x.size() - 1 comparisons.
1259    void merge(BOOST_RV_REF(list) x)
1260    {  this->merge(static_cast<list&>(x)); }
1261 
1262    //! <b>Requires</b>: p must be a comparison function that induces a strict weak
1263    //!   ordering and both *this and x must be sorted according to that ordering
1264    //!   The lists x and *this must be distinct.
1265    //!
1266    //! <b>Effects</b>: This function removes all of x's elements and inserts them
1267    //!   in order into *this. The merge is stable; that is, if an element from *this is
1268    //!   equivalent to one from x, then the element from *this will precede the one from x.
1269    //!
1270    //! <b>Throws</b>: If comp throws.
1271    //!
1272    //! <b>Complexity</b>: This function is linear time: it performs at most
1273    //!   size() + x.size() - 1 comparisons.
1274    //!
1275    //! <b>Note</b>: Iterators and references to *this are not invalidated.
1276    template <class StrictWeakOrdering>
1277    void merge(list &x, const StrictWeakOrdering &comp)
1278    {
1279       BOOST_ASSERT(this->node_alloc() == x.node_alloc());
1280       typedef value_to_node_compare<Node, StrictWeakOrdering> value_to_node_compare_type;
1281       this->icont().merge(x.icont(), value_to_node_compare_type(comp));
1282    }
1283 
1284    //! <b>Requires</b>: p must be a comparison function that induces a strict weak
1285    //!   ordering and both *this and x must be sorted according to that ordering
1286    //!   The lists x and *this must be distinct.
1287    //!
1288    //! <b>Effects</b>: This function removes all of x's elements and inserts them
1289    //!   in order into *this. The merge is stable; that is, if an element from *this is
1290    //!   equivalent to one from x, then the element from *this will precede the one from x.
1291    //!
1292    //! <b>Throws</b>: If comp throws.
1293    //!
1294    //! <b>Complexity</b>: This function is linear time: it performs at most
1295    //!   size() + x.size() - 1 comparisons.
1296    //!
1297    //! <b>Note</b>: Iterators and references to *this are not invalidated.
1298    template <class StrictWeakOrdering>
1299    void merge(BOOST_RV_REF(list) x, StrictWeakOrdering comp)
1300    {  this->merge(static_cast<list&>(x), comp); }
1301 
1302    //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
1303    //!   The sort is stable, that is, the relative order of equivalent elements is preserved.
1304    //!
1305    //! <b>Throws</b>: If comparison throws.
1306    //!
1307    //! <b>Notes</b>: Iterators and references are not invalidated.
1308    //!
1309    //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
1310    //!   is the list's size.
1311    void sort()
1312    {  this->sort(value_less_t());  }
1313 
1314    //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
1315    //!   The sort is stable, that is, the relative order of equivalent elements is preserved.
1316    //!
1317    //! <b>Throws</b>: If comp throws.
1318    //!
1319    //! <b>Notes</b>: Iterators and references are not invalidated.
1320    //!
1321    //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
1322    //!   is the list's size.
1323    template <class StrictWeakOrdering>
1324    void sort(StrictWeakOrdering comp)
1325    {
1326       // nothing if the list has length 0 or 1.
1327       if (this->size() < 2)
1328          return;
1329       typedef value_to_node_compare<Node, StrictWeakOrdering> value_to_node_compare_type;
1330       this->icont().sort(value_to_node_compare_type(comp));
1331    }
1332 
1333    //! <b>Effects</b>: Reverses the order of elements in the list.
1334    //!
1335    //! <b>Throws</b>: Nothing.
1336    //!
1337    //! <b>Complexity</b>: This function is linear time.
1338    //!
1339    //! <b>Note</b>: Iterators and references are not invalidated
1340    void reverse() BOOST_NOEXCEPT_OR_NOTHROW
1341    {  this->icont().reverse(); }
1342 
1343    //! <b>Effects</b>: Returns true if x and y are equal
1344    //!
1345    //! <b>Complexity</b>: Linear to the number of elements in the container.
1346    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1347       friend bool operator==(const list& x, const list& y)
1348    {  return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin());  }
1349 
1350    //! <b>Effects</b>: Returns true if x and y are unequal
1351    //!
1352    //! <b>Complexity</b>: Linear to the number of elements in the container.
1353    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1354       friend bool operator!=(const list& x, const list& y)
1355    {  return !(x == y); }
1356 
1357    //! <b>Effects</b>: Returns true if x is less than y
1358    //!
1359    //! <b>Complexity</b>: Linear to the number of elements in the container.
1360    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1361       friend bool operator<(const list& x, const list& y)
1362    {  return boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
1363 
1364    //! <b>Effects</b>: Returns true if x is greater than y
1365    //!
1366    //! <b>Complexity</b>: Linear to the number of elements in the container.
1367    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1368       friend bool operator>(const list& x, const list& y)
1369    {  return y < x;  }
1370 
1371    //! <b>Effects</b>: Returns true if x is equal or less than y
1372    //!
1373    //! <b>Complexity</b>: Linear to the number of elements in the container.
1374    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1375       friend bool operator<=(const list& x, const list& y)
1376    {  return !(y < x);  }
1377 
1378    //! <b>Effects</b>: Returns true if x is equal or greater than y
1379    //!
1380    //! <b>Complexity</b>: Linear to the number of elements in the container.
1381    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1382       friend bool operator>=(const list& x, const list& y)
1383    {  return !(x < y);  }
1384 
1385    //! <b>Effects</b>: x.swap(y)
1386    //!
1387    //! <b>Complexity</b>: Constant.
1388    BOOST_CONTAINER_FORCEINLINE friend void swap(list& x, list& y)
1389        BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y)))
1390    {  x.swap(y);  }
1391 
1392    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1393    private:
1394 
1395    static bool priv_is_linked(const_iterator const position)
1396    {
1397       const_iterator cur(position);
1398       //This list is circular including end nodes
1399       return (--(++cur)) == position && (++(--cur)) == position;
1400    }
1401 
1402    bool priv_try_shrink(size_type new_size)
1403    {
1404       const size_type len = this->size();
1405       if(len > new_size){
1406          const const_iterator iend = this->cend();
1407          size_type to_erase = len - new_size;
1408          const_iterator ifirst;
1409          if(to_erase < len/2u){
1410             ifirst = iend;
1411             while(to_erase--){
1412                --ifirst;
1413             }
1414          }
1415          else{
1416             ifirst = this->cbegin();
1417             size_type to_skip = len - to_erase;
1418             while(to_skip--){
1419                ++ifirst;
1420             }
1421          }
1422          this->erase(ifirst, iend);
1423          return true;
1424       }
1425       else{
1426          return false;
1427       }
1428    }
1429 
1430    iterator priv_insert(const_iterator p, const T &x)
1431    {
1432       BOOST_ASSERT((priv_is_linked)(p));
1433       NodePtr tmp = AllocHolder::create_node(x);
1434       return iterator(this->icont().insert(p.get(), *tmp));
1435    }
1436 
1437    iterator priv_insert(const_iterator p, BOOST_RV_REF(T) x)
1438    {
1439       BOOST_ASSERT((priv_is_linked)(p));
1440       NodePtr tmp = AllocHolder::create_node(boost::move(x));
1441       return iterator(this->icont().insert(p.get(), *tmp));
1442    }
1443 
1444    template<class U>
1445    void priv_push_back(BOOST_FWD_REF(U) x)
1446    {  this->icont().push_back(*this->create_node(::boost::forward<U>(x))); }
1447 
1448    template<class U>
1449    void priv_push_front(BOOST_FWD_REF(U) x)
1450    {  this->icont().push_front(*this->create_node(::boost::forward<U>(x))); }
1451 
1452    class insertion_functor;
1453    friend class insertion_functor;
1454 
1455    class insertion_functor
1456    {
1457       Icont &icont_;
1458       typedef typename Icont::const_iterator iconst_iterator;
1459       const iconst_iterator pos_;
1460 
1461       public:
1462       insertion_functor(Icont &icont, typename Icont::const_iterator pos)
1463          :  icont_(icont), pos_(pos)
1464       {}
1465 
1466       void operator()(Node &n)
1467       {
1468          this->icont_.insert(pos_, n);
1469       }
1470    };
1471 
1472    typedef value_less<value_type>   value_less_t;
1473    typedef value_equal<value_type>  value_equal_t;
1474    #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1475 
1476 };
1477 
1478 #ifndef BOOST_CONTAINER_NO_CXX17_CTAD
1479 template <typename InputIterator>
1480 list(InputIterator, InputIterator) ->
1481    list<typename iterator_traits<InputIterator>::value_type>;
1482 
1483 template <typename InputIterator, typename ValueAllocator>
1484 list(InputIterator, InputIterator, ValueAllocator const&) ->
1485    list<typename iterator_traits<InputIterator>::value_type, ValueAllocator>;
1486 #endif
1487 
1488 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1489 
1490 }  //namespace container {
1491 
1492 //!has_trivial_destructor_after_move<> == true_type
1493 //!specialization for optimizations
1494 template <class T, class Allocator>
1495 struct has_trivial_destructor_after_move<boost::container::list<T, Allocator> >
1496 {
1497    typedef typename boost::container::list<T, Allocator>::allocator_type allocator_type;
1498    typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer;
1499    static const bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value &&
1500                              ::boost::has_trivial_destructor_after_move<pointer>::value;
1501 };
1502 
1503 namespace container {
1504 
1505 #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1506 
1507 }}
1508 
1509 #include <boost/container/detail/config_end.hpp>
1510 
1511 #endif // BOOST_CONTAINER_LIST_HPP