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