Back to home page

EIC code displayed by LXR

 
 

    


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

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