Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-15 08:29:44

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