Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:14:33

0001 /////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Olaf Krzikalla 2004-2006.
0004 // (C) Copyright Ion Gaztanaga  2006-2014
0005 //
0006 // Distributed under the Boost Software License, Version 1.0.
0007 //    (See accompanying file LICENSE_1_0.txt or copy at
0008 //          http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 // See http://www.boost.org/libs/intrusive for documentation.
0011 //
0012 /////////////////////////////////////////////////////////////////////////////
0013 
0014 #ifndef BOOST_INTRUSIVE_LIST_HPP
0015 #define BOOST_INTRUSIVE_LIST_HPP
0016 
0017 #include <boost/intrusive/detail/config_begin.hpp>
0018 #include <boost/intrusive/intrusive_fwd.hpp>
0019 #include <boost/intrusive/detail/assert.hpp>
0020 #include <boost/intrusive/list_hook.hpp>
0021 #include <boost/intrusive/circular_list_algorithms.hpp>
0022 #include <boost/intrusive/pointer_traits.hpp>
0023 #include <boost/intrusive/detail/mpl.hpp>
0024 #include <boost/intrusive/link_mode.hpp>
0025 #include <boost/intrusive/detail/get_value_traits.hpp>
0026 #include <boost/intrusive/detail/is_stateful_value_traits.hpp>
0027 #include <boost/intrusive/detail/default_header_holder.hpp>
0028 #include <boost/intrusive/detail/reverse_iterator.hpp>
0029 #include <boost/intrusive/detail/uncast.hpp>
0030 #include <boost/intrusive/detail/list_iterator.hpp>
0031 #include <boost/intrusive/detail/array_initializer.hpp>
0032 #include <boost/intrusive/detail/exception_disposer.hpp>
0033 #include <boost/intrusive/detail/equal_to_value.hpp>
0034 #include <boost/intrusive/detail/key_nodeptr_comp.hpp>
0035 #include <boost/intrusive/detail/simple_disposers.hpp>
0036 #include <boost/intrusive/detail/size_holder.hpp>
0037 #include <boost/intrusive/detail/algorithm.hpp>
0038 
0039 #include <boost/move/utility_core.hpp>
0040 #include <boost/static_assert.hpp>
0041 
0042 #include <boost/intrusive/detail/value_functors.hpp>
0043 #include <cstddef>   //std::size_t, etc.
0044 
0045 #if defined(BOOST_HAS_PRAGMA_ONCE)
0046 #  pragma once
0047 #endif
0048 
0049 namespace boost {
0050 namespace intrusive {
0051 
0052 /// @cond
0053 
0054 struct default_list_hook_applier
0055 {  template <class T> struct apply{ typedef typename T::default_list_hook type;  };  };
0056 
0057 template<>
0058 struct is_default_hook_tag<default_list_hook_applier>
0059 {  static const bool value = true;  };
0060 
0061 struct list_defaults
0062 {
0063    typedef default_list_hook_applier proto_value_traits;
0064    static const bool constant_time_size = true;
0065    typedef std::size_t size_type;
0066    typedef void header_holder_type;
0067 };
0068 
0069 /// @endcond
0070 
0071 //! The class template list is an intrusive container that mimics most of the
0072 //! interface of std::list as described in the C++ standard.
0073 //!
0074 //! The template parameter \c T is the type to be managed by the container.
0075 //! The user can specify additional options and if no options are provided
0076 //! default options are used.
0077 //!
0078 //! The container supports the following options:
0079 //! \c base_hook<>/member_hook<>/value_traits<>,
0080 //! \c constant_time_size<> and \c size_type<>.
0081 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
0082 template<class T, class ...Options>
0083 #else
0084 template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
0085 #endif
0086 class list_impl
0087 {
0088    //Public typedefs
0089    public:
0090    typedef ValueTraits                                               value_traits;
0091    typedef typename value_traits::pointer                            pointer;
0092    typedef typename value_traits::const_pointer                      const_pointer;
0093    typedef typename pointer_traits<pointer>::element_type            value_type;
0094    typedef typename pointer_traits<pointer>::reference               reference;
0095    typedef typename pointer_traits<const_pointer>::reference         const_reference;
0096    typedef typename pointer_traits<pointer>::difference_type         difference_type;
0097    typedef SizeType                                                  size_type;
0098    typedef list_iterator<value_traits, false>                        iterator;
0099    typedef list_iterator<value_traits, true>                         const_iterator;
0100    typedef boost::intrusive::reverse_iterator<iterator>              reverse_iterator;
0101    typedef boost::intrusive::reverse_iterator<const_iterator>        const_reverse_iterator;
0102    typedef typename value_traits::node_traits                        node_traits;
0103    typedef typename node_traits::node                                node;
0104    typedef typename node_traits::node_ptr                            node_ptr;
0105    typedef typename node_traits::const_node_ptr                      const_node_ptr;
0106    typedef circular_list_algorithms<node_traits>                     node_algorithms;
0107    typedef typename detail::get_header_holder_type
0108       < value_traits, HeaderHolder >::type                           header_holder_type;
0109 
0110    static const bool constant_time_size = ConstantTimeSize;
0111    static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value;
0112    static const bool has_container_from_iterator =
0113         detail::is_same< header_holder_type, detail::default_header_holder< node_traits > >::value;
0114 
0115    /// @cond
0116 
0117    private:
0118    typedef detail::size_holder<constant_time_size, size_type>          size_traits;
0119 
0120    //noncopyable
0121    BOOST_MOVABLE_BUT_NOT_COPYABLE(list_impl)
0122 
0123    static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
0124 
0125    //Constant-time size is incompatible with auto-unlink hooks!
0126    BOOST_STATIC_ASSERT(!(constant_time_size &&
0127                         ((int)value_traits::link_mode == (int)auto_unlink)
0128                       ));
0129 
0130    BOOST_INTRUSIVE_FORCEINLINE node_ptr get_root_node()
0131    { return data_.root_plus_size_.m_header.get_node(); }
0132 
0133    BOOST_INTRUSIVE_FORCEINLINE const_node_ptr get_root_node() const
0134    { return data_.root_plus_size_.m_header.get_node(); }
0135 
0136    struct root_plus_size : public size_traits
0137    {
0138       header_holder_type m_header;
0139    };
0140 
0141    struct data_t : public value_traits
0142    {
0143       typedef typename list_impl::value_traits value_traits;
0144       BOOST_INTRUSIVE_FORCEINLINE explicit data_t(const value_traits &val_traits)
0145          :  value_traits(val_traits)
0146       {}
0147 
0148       root_plus_size root_plus_size_;
0149    } data_;
0150 
0151    BOOST_INTRUSIVE_FORCEINLINE size_traits &priv_size_traits() BOOST_NOEXCEPT
0152    {  return data_.root_plus_size_;  }
0153 
0154    BOOST_INTRUSIVE_FORCEINLINE const size_traits &priv_size_traits() const BOOST_NOEXCEPT
0155    {  return data_.root_plus_size_;  }
0156 
0157    BOOST_INTRUSIVE_FORCEINLINE const value_traits &priv_value_traits() const BOOST_NOEXCEPT
0158    {  return data_;  }
0159 
0160    BOOST_INTRUSIVE_FORCEINLINE value_traits &priv_value_traits() BOOST_NOEXCEPT
0161    {  return data_;  }
0162 
0163    typedef typename boost::intrusive::value_traits_pointers
0164       <ValueTraits>::const_value_traits_ptr const_value_traits_ptr;
0165 
0166    BOOST_INTRUSIVE_FORCEINLINE const_value_traits_ptr priv_value_traits_ptr() const BOOST_NOEXCEPT
0167    {  return pointer_traits<const_value_traits_ptr>::pointer_to(this->priv_value_traits());  }
0168 
0169    /// @endcond
0170 
0171    public:
0172 
0173    //! <b>Effects</b>: constructs an empty list.
0174    //!
0175    //! <b>Complexity</b>: Constant
0176    //!
0177    //! <b>Throws</b>: If value_traits::node_traits::node
0178    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks).
0179    list_impl()
0180       :  data_(value_traits())
0181    {
0182       this->priv_size_traits().set_size(size_type(0));
0183       node_algorithms::init_header(this->get_root_node());
0184    }
0185 
0186    //! <b>Effects</b>: constructs an empty list.
0187    //!
0188    //! <b>Complexity</b>: Constant
0189    //!
0190    //! <b>Throws</b>: If value_traits::node_traits::node
0191    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks).
0192    explicit list_impl(const value_traits &v_traits)
0193       :  data_(v_traits)
0194    {
0195       this->priv_size_traits().set_size(size_type(0));
0196       node_algorithms::init_header(this->get_root_node());
0197    }
0198 
0199    //! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type.
0200    //!
0201    //! <b>Effects</b>: Constructs a list equal to the range [first,last).
0202    //!
0203    //! <b>Complexity</b>: Linear in distance(b, e). No copy constructors are called.
0204    //!
0205    //! <b>Throws</b>: If value_traits::node_traits::node
0206    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks).
0207    template<class Iterator>
0208    list_impl(Iterator b, Iterator e, const value_traits &v_traits = value_traits())
0209       :  data_(v_traits)
0210    {
0211       //nothrow, no need to rollback to release elements on exception
0212       this->priv_size_traits().set_size(size_type(0));
0213       node_algorithms::init_header(this->get_root_node());
0214       //nothrow, no need to rollback to release elements on exception
0215       this->insert(this->cend(), b, e);
0216    }
0217 
0218    //! <b>Effects</b>: Constructs a container moving resources from another container.
0219    //!   Internal value traits are move constructed and
0220    //!   nodes belonging to x (except the node representing the "end") are linked to *this.
0221    //!
0222    //! <b>Complexity</b>: Constant.
0223    //!
0224    //! <b>Throws</b>: If value_traits::node_traits::node's
0225    //!   move constructor throws (this does not happen with predefined Boost.Intrusive hooks)
0226    //!   or the move constructor of value traits throws.
0227    list_impl(BOOST_RV_REF(list_impl) x)
0228       : data_(::boost::move(x.priv_value_traits()))
0229    {
0230       this->priv_size_traits().set_size(size_type(0));
0231       node_algorithms::init_header(this->get_root_node());
0232       //nothrow, no need to rollback to release elements on exception
0233       this->swap(x);
0234    }
0235 
0236    //! <b>Effects</b>: Equivalent to swap
0237    //!
0238    list_impl& operator=(BOOST_RV_REF(list_impl) x)
0239    {  this->swap(x); return *this;  }
0240 
0241    //! <b>Effects</b>: If it's not a safe-mode or an auto-unlink value_type
0242    //!   the destructor does nothing
0243    //!   (ie. no code is generated). Otherwise it detaches all elements from this.
0244    //!   In this case the objects in the list are not deleted (i.e. no destructors
0245    //!   are called), but the hooks according to the ValueTraits template parameter
0246    //!   are set to their default value.
0247    //!
0248    //! <b>Throws</b>: Nothing.
0249    //! 
0250    //! <b>Complexity</b>: Linear to the number of elements in the list, if
0251    //!   it's a safe-mode or auto-unlink value . Otherwise constant.
0252    ~list_impl()
0253    {
0254       BOOST_IF_CONSTEXPR(is_safe_autounlink<ValueTraits::link_mode>::value){
0255          this->clear();
0256          node_algorithms::init(this->get_root_node());
0257       }
0258    }
0259 
0260    //! <b>Requires</b>: value must be an lvalue.
0261    //!
0262    //! <b>Effects</b>: Inserts the value in the back of the list.
0263    //!   No copy constructors are called.
0264    //!
0265    //! <b>Throws</b>: Nothing.
0266    //!
0267    //! <b>Complexity</b>: Constant.
0268    //!
0269    //! <b>Note</b>: Does not affect the validity of iterators and references.
0270    void push_back(reference value) BOOST_NOEXCEPT
0271    {
0272       node_ptr to_insert = priv_value_traits().to_node_ptr(value);
0273       BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(to_insert));
0274       node_algorithms::link_before(this->get_root_node(), to_insert);
0275       this->priv_size_traits().increment();
0276    }
0277 
0278    //! <b>Requires</b>: value must be an lvalue.
0279    //!
0280    //! <b>Effects</b>: Inserts the value in the front of the list.
0281    //!   No copy constructors are called.
0282    //!
0283    //! <b>Throws</b>: Nothing.
0284    //!
0285    //! <b>Complexity</b>: Constant.
0286    //!
0287    //! <b>Note</b>: Does not affect the validity of iterators and references.
0288    void push_front(reference value) BOOST_NOEXCEPT
0289    {
0290       node_ptr to_insert = priv_value_traits().to_node_ptr(value);
0291       BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(to_insert));
0292       node_algorithms::link_before(node_traits::get_next(this->get_root_node()), to_insert);
0293       this->priv_size_traits().increment();
0294    }
0295 
0296    //! <b>Effects</b>: Erases the last element of the list.
0297    //!   No destructors are called.
0298    //!
0299    //! <b>Throws</b>: Nothing.
0300    //!
0301    //! <b>Complexity</b>: Constant.
0302    //!
0303    //! <b>Note</b>: Invalidates the iterators (but not the references) to the erased element.
0304    void pop_back() BOOST_NOEXCEPT
0305    {  return this->pop_back_and_dispose(detail::null_disposer());   }
0306 
0307    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
0308    //!
0309    //! <b>Effects</b>: Erases the last element of the list.
0310    //!   No destructors are called.
0311    //!   Disposer::operator()(pointer) is called for the removed element.
0312    //!
0313    //! <b>Throws</b>: Nothing.
0314    //!
0315    //! <b>Complexity</b>: Constant.
0316    //!
0317    //! <b>Note</b>: Invalidates the iterators to the erased element.
0318    template<class Disposer>
0319    void pop_back_and_dispose(Disposer disposer) BOOST_NOEXCEPT
0320    {
0321       node_ptr to_erase = node_traits::get_previous(this->get_root_node());
0322       node_algorithms::unlink(to_erase);
0323       this->priv_size_traits().decrement();
0324       BOOST_IF_CONSTEXPR(safemode_or_autounlink)
0325          node_algorithms::init(to_erase);
0326       disposer(priv_value_traits().to_value_ptr(to_erase));
0327    }
0328 
0329    //! <b>Effects</b>: Erases the first element of the list.
0330    //!   No destructors are called.
0331    //!
0332    //! <b>Throws</b>: Nothing.
0333    //!
0334    //! <b>Complexity</b>: Constant.
0335    //!
0336    //! <b>Note</b>: Invalidates the iterators (but not the references) to the erased element.
0337    void pop_front() BOOST_NOEXCEPT
0338    {  return this->pop_front_and_dispose(detail::null_disposer());   }
0339 
0340    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
0341    //!
0342    //! <b>Effects</b>: Erases the first element of the list.
0343    //!   No destructors are called.
0344    //!   Disposer::operator()(pointer) is called for the removed element.
0345    //!
0346    //! <b>Throws</b>: Nothing.
0347    //!
0348    //! <b>Complexity</b>: Constant.
0349    //!
0350    //! <b>Note</b>: Invalidates the iterators to the erased element.
0351    template<class Disposer>
0352    void pop_front_and_dispose(Disposer disposer) BOOST_NOEXCEPT
0353    {
0354       node_ptr to_erase = node_traits::get_next(this->get_root_node());
0355       node_algorithms::unlink(to_erase);
0356       this->priv_size_traits().decrement();
0357       BOOST_IF_CONSTEXPR(safemode_or_autounlink)
0358          node_algorithms::init(to_erase);
0359       disposer(priv_value_traits().to_value_ptr(to_erase));
0360    }
0361 
0362    //! <b>Effects</b>: Returns a reference to the first element of the list.
0363    //!
0364    //! <b>Throws</b>: Nothing.
0365    //!
0366    //! <b>Complexity</b>: Constant.
0367    BOOST_INTRUSIVE_FORCEINLINE reference front() BOOST_NOEXCEPT
0368    { return *priv_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); }
0369 
0370    //! <b>Effects</b>: Returns a const_reference to the first element of the list.
0371    //!
0372    //! <b>Throws</b>: Nothing.
0373    //!
0374    //! <b>Complexity</b>: Constant.
0375    BOOST_INTRUSIVE_FORCEINLINE const_reference front() const BOOST_NOEXCEPT
0376    { return *priv_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); }
0377 
0378    //! <b>Effects</b>: Returns a reference to the last element of the list.
0379    //!
0380    //! <b>Throws</b>: Nothing.
0381    //!
0382    //! <b>Complexity</b>: Constant.
0383    BOOST_INTRUSIVE_FORCEINLINE reference back() BOOST_NOEXCEPT
0384    { return *priv_value_traits().to_value_ptr(node_traits::get_previous(this->get_root_node())); }
0385 
0386    //! <b>Effects</b>: Returns a const_reference to the last element of the list.
0387    //!
0388    //! <b>Throws</b>: Nothing.
0389    //!
0390    //! <b>Complexity</b>: Constant.
0391    BOOST_INTRUSIVE_FORCEINLINE const_reference back() const BOOST_NOEXCEPT
0392    { return *priv_value_traits().to_value_ptr(detail::uncast(node_traits::get_previous(this->get_root_node()))); }
0393 
0394    //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
0395    //!
0396    //! <b>Throws</b>: Nothing.
0397    //!
0398    //! <b>Complexity</b>: Constant.
0399    BOOST_INTRUSIVE_FORCEINLINE iterator begin() BOOST_NOEXCEPT
0400    { return iterator(node_traits::get_next(this->get_root_node()), this->priv_value_traits_ptr()); }
0401 
0402    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
0403    //!
0404    //! <b>Throws</b>: Nothing.
0405    //!
0406    //! <b>Complexity</b>: Constant.
0407    BOOST_INTRUSIVE_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT
0408    { return this->cbegin(); }
0409 
0410    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
0411    //!
0412    //! <b>Throws</b>: Nothing.
0413    //!
0414    //! <b>Complexity</b>: Constant.
0415    BOOST_INTRUSIVE_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT
0416    { return const_iterator(node_traits::get_next(this->get_root_node()), this->priv_value_traits_ptr()); }
0417 
0418    //! <b>Effects</b>: Returns an iterator to the end of the list.
0419    //!
0420    //! <b>Throws</b>: Nothing.
0421    //!
0422    //! <b>Complexity</b>: Constant.
0423    BOOST_INTRUSIVE_FORCEINLINE iterator end() BOOST_NOEXCEPT
0424    { return iterator(this->get_root_node(), this->priv_value_traits_ptr()); }
0425 
0426    //! <b>Effects</b>: Returns a const_iterator to the end of the list.
0427    //!
0428    //! <b>Throws</b>: Nothing.
0429    //!
0430    //! <b>Complexity</b>: Constant.
0431    BOOST_INTRUSIVE_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT
0432    { return this->cend(); }
0433 
0434    //! <b>Effects</b>: Returns a constant iterator to the end of the list.
0435    //!
0436    //! <b>Throws</b>: Nothing.
0437    //!
0438    //! <b>Complexity</b>: Constant.
0439    BOOST_INTRUSIVE_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT
0440    { return const_iterator(detail::uncast(this->get_root_node()), this->priv_value_traits_ptr()); }
0441 
0442    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
0443    //! of the reversed list.
0444    //!
0445    //! <b>Throws</b>: Nothing.
0446    //!
0447    //! <b>Complexity</b>: Constant.
0448    BOOST_INTRUSIVE_FORCEINLINE reverse_iterator rbegin() BOOST_NOEXCEPT
0449    { return reverse_iterator(this->end()); }
0450 
0451    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
0452    //! of the reversed list.
0453    //!
0454    //! <b>Throws</b>: Nothing.
0455    //!
0456    //! <b>Complexity</b>: Constant.
0457    BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator rbegin() const BOOST_NOEXCEPT
0458    { return this->crbegin(); }
0459 
0460    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
0461    //! of the reversed list.
0462    //!
0463    //! <b>Throws</b>: Nothing.
0464    //!
0465    //! <b>Complexity</b>: Constant.
0466    BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator crbegin() const BOOST_NOEXCEPT
0467    { return const_reverse_iterator(end()); }
0468 
0469    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
0470    //! of the reversed list.
0471    //!
0472    //! <b>Throws</b>: Nothing.
0473    //!
0474    //! <b>Complexity</b>: Constant.
0475    BOOST_INTRUSIVE_FORCEINLINE reverse_iterator rend() BOOST_NOEXCEPT
0476    { return reverse_iterator(begin()); }
0477 
0478    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
0479    //! of the reversed list.
0480    //!
0481    //! <b>Throws</b>: Nothing.
0482    //!
0483    //! <b>Complexity</b>: Constant.
0484    BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator rend() const BOOST_NOEXCEPT
0485    { return this->crend(); }
0486 
0487    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
0488    //! of the reversed list.
0489    //!
0490    //! <b>Throws</b>: Nothing.
0491    //!
0492    //! <b>Complexity</b>: Constant.
0493    BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator crend() const BOOST_NOEXCEPT
0494    { return const_reverse_iterator(this->begin()); }
0495 
0496    //! <b>Precondition</b>: end_iterator must be a valid end iterator
0497    //!   of list.
0498    //!
0499    //! <b>Effects</b>: Returns a const reference to the list associated to the end iterator
0500    //!
0501    //! <b>Throws</b>: Nothing.
0502    //!
0503    //! <b>Complexity</b>: Constant.
0504    BOOST_INTRUSIVE_FORCEINLINE static list_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
0505    {  return list_impl::priv_container_from_end_iterator(end_iterator);   }
0506 
0507    //! <b>Precondition</b>: end_iterator must be a valid end const_iterator
0508    //!   of list.
0509    //!
0510    //! <b>Effects</b>: Returns a const reference to the list associated to the end iterator
0511    //!
0512    //! <b>Throws</b>: Nothing.
0513    //!
0514    //! <b>Complexity</b>: Constant.
0515    BOOST_INTRUSIVE_FORCEINLINE static const list_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
0516    {  return list_impl::priv_container_from_end_iterator(end_iterator);   }
0517 
0518    //! <b>Effects</b>: Returns the number of the elements contained in the list.
0519    //!
0520    //! <b>Throws</b>: Nothing.
0521    //!
0522    //! <b>Complexity</b>: Linear to the number of elements contained in the list.
0523    //!   if constant-time size option is disabled. Constant time otherwise.
0524    //!
0525    //! <b>Note</b>: Does not affect the validity of iterators and references.
0526    BOOST_INTRUSIVE_FORCEINLINE size_type size() const BOOST_NOEXCEPT
0527    {
0528       BOOST_IF_CONSTEXPR(constant_time_size)
0529          return this->priv_size_traits().get_size();
0530       else
0531          return node_algorithms::count(this->get_root_node()) - 1;
0532    }
0533 
0534    //! <b>Effects</b>: Returns true if the list contains no elements.
0535    //!
0536    //! <b>Throws</b>: Nothing.
0537    //!
0538    //! <b>Complexity</b>: Constant.
0539    //!
0540    //! <b>Note</b>: Does not affect the validity of iterators and references.
0541    BOOST_INTRUSIVE_FORCEINLINE bool empty() const BOOST_NOEXCEPT
0542    {  return node_algorithms::unique(this->get_root_node());   }
0543 
0544    //! <b>Effects</b>: Swaps the elements of x and *this.
0545    //!
0546    //! <b>Throws</b>: Nothing.
0547    //!
0548    //! <b>Complexity</b>: Constant.
0549    //!
0550    //! <b>Note</b>: Does not affect the validity of iterators and references.
0551    void swap(list_impl& other) BOOST_NOEXCEPT
0552    {
0553       node_algorithms::swap_nodes(this->get_root_node(), other.get_root_node());
0554       this->priv_size_traits().swap(other.priv_size_traits());
0555    }
0556 
0557    //! <b>Effects</b>: Moves backwards all the elements, so that the first
0558    //!   element becomes the second, the second becomes the third...
0559    //!   the last element becomes the first one.
0560    //!
0561    //! <b>Throws</b>: Nothing.
0562    //!
0563    //! <b>Complexity</b>: Linear to the number of shifts.
0564    //!
0565    //! <b>Note</b>: Does not affect the validity of iterators and references.
0566    BOOST_INTRUSIVE_FORCEINLINE void shift_backwards(size_type n = 1) BOOST_NOEXCEPT
0567    {  node_algorithms::move_forward(this->get_root_node(), n);  }
0568 
0569    //! <b>Effects</b>: Moves forward all the elements, so that the second
0570    //!   element becomes the first, the third becomes the second...
0571    //!   the first element becomes the last one.
0572    //!
0573    //! <b>Throws</b>: Nothing.
0574    //!
0575    //! <b>Complexity</b>: Linear to the number of shifts.
0576    //!
0577    //! <b>Note</b>: Does not affect the validity of iterators and references.
0578    BOOST_INTRUSIVE_FORCEINLINE void shift_forward(size_type n = 1) BOOST_NOEXCEPT
0579    {  node_algorithms::move_backwards(this->get_root_node(), n);  }
0580 
0581    //! <b>Effects</b>: Erases the element pointed by i of the list.
0582    //!   No destructors are called.
0583    //!
0584    //! <b>Returns</b>: the first element remaining beyond the removed element,
0585    //!   or end() if no such element exists.
0586    //!
0587    //! <b>Throws</b>: Nothing.
0588    //!
0589    //! <b>Complexity</b>: Constant.
0590    //!
0591    //! <b>Note</b>: Invalidates the iterators (but not the references) to the
0592    //!   erased element.
0593    BOOST_INTRUSIVE_FORCEINLINE iterator erase(const_iterator i) BOOST_NOEXCEPT
0594    {  return this->erase_and_dispose(i, detail::null_disposer());  }
0595 
0596    //! <b>Requires</b>: b and e must be valid iterators to elements in *this.
0597    //!
0598    //! <b>Effects</b>: Erases the element range pointed by b and e
0599    //! No destructors are called.
0600    //!
0601    //! <b>Returns</b>: the first element remaining beyond the removed elements,
0602    //!   or end() if no such element exists.
0603    //!
0604    //! <b>Throws</b>: Nothing.
0605    //!
0606    //! <b>Complexity</b>: Linear to the number of erased elements if it's a safe-mode
0607    //!   or auto-unlink value, or constant-time size is enabled. Constant-time otherwise.
0608    //!
0609    //! <b>Note</b>: Invalidates the iterators (but not the references) to the
0610    //!   erased elements.
0611    BOOST_INTRUSIVE_FORCEINLINE iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT
0612    {
0613       BOOST_IF_CONSTEXPR(safemode_or_autounlink || constant_time_size){
0614          return this->erase_and_dispose(b, e, detail::null_disposer());
0615       }
0616       else{
0617          node_algorithms::unlink(b.pointed_node(), e.pointed_node());
0618          return e.unconst();
0619       }
0620    }
0621 
0622    //! <b>Requires</b>: b and e must be valid iterators to elements in *this.
0623    //!   n must be distance(b, e).
0624    //!
0625    //! <b>Effects</b>: Erases the element range pointed by b and e
0626    //! No destructors are called.
0627    //!
0628    //! <b>Returns</b>: the first element remaining beyond the removed elements,
0629    //!   or end() if no such element exists.
0630    //!
0631    //! <b>Throws</b>: Nothing.
0632    //!
0633    //! <b>Complexity</b>: Linear to the number of erased elements if it's a safe-mode
0634    //!   or auto-unlink value is enabled. Constant-time otherwise.
0635    //!
0636    //! <b>Note</b>: Invalidates the iterators (but not the references) to the
0637    //!   erased elements.
0638    iterator erase(const_iterator b, const_iterator e, size_type n) BOOST_NOEXCEPT
0639    {
0640       BOOST_INTRUSIVE_INVARIANT_ASSERT(node_algorithms::distance(b.pointed_node(), e.pointed_node()) == n);
0641       (void)n;
0642       BOOST_IF_CONSTEXPR(safemode_or_autounlink){
0643          return this->erase_and_dispose(b, e, detail::null_disposer());
0644       }
0645       else{
0646          BOOST_IF_CONSTEXPR(constant_time_size){
0647             this->priv_size_traits().decrease(n);
0648          }
0649          node_algorithms::unlink(b.pointed_node(), e.pointed_node());
0650          return e.unconst();
0651       }
0652    }
0653 
0654    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
0655    //!
0656    //! <b>Effects</b>: Erases the element pointed by i of the list.
0657    //!   No destructors are called.
0658    //!   Disposer::operator()(pointer) is called for the removed element.
0659    //!
0660    //! <b>Returns</b>: the first element remaining beyond the removed element,
0661    //!   or end() if no such element exists.
0662    //!
0663    //! <b>Throws</b>: Nothing.
0664    //!
0665    //! <b>Complexity</b>: Constant.
0666    //!
0667    //! <b>Note</b>: Invalidates the iterators to the erased element.
0668    template <class Disposer>
0669    iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT
0670    {
0671       node_ptr to_erase(i.pointed_node());
0672       ++i;
0673       node_algorithms::unlink(to_erase);
0674       this->priv_size_traits().decrement();
0675       BOOST_IF_CONSTEXPR(safemode_or_autounlink)
0676          node_algorithms::init(to_erase);
0677       disposer(this->priv_value_traits().to_value_ptr(to_erase));
0678       return i.unconst();
0679    }
0680 
0681    #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
0682    template<class Disposer>
0683    iterator erase_and_dispose(iterator i, Disposer disposer) BOOST_NOEXCEPT
0684    {  return this->erase_and_dispose(const_iterator(i), disposer);   }
0685    #endif
0686 
0687    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
0688    //!
0689    //! <b>Effects</b>: Erases the element range pointed by b and e
0690    //!   No destructors are called.
0691    //!   Disposer::operator()(pointer) is called for the removed elements.
0692    //!
0693    //! <b>Returns</b>: the first element remaining beyond the removed elements,
0694    //!   or end() if no such element exists.
0695    //!
0696    //! <b>Throws</b>: Nothing.
0697    //!
0698    //! <b>Complexity</b>: Linear to the number of elements erased.
0699    //!
0700    //! <b>Note</b>: Invalidates the iterators to the erased elements.
0701    template <class Disposer>
0702    iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT
0703    {
0704       node_ptr bp(b.pointed_node()), ep(e.pointed_node());
0705       node_algorithms::unlink(bp, ep);
0706       while(bp != ep){
0707          node_ptr to_erase(bp);
0708          bp = node_traits::get_next(bp);
0709          BOOST_IF_CONSTEXPR(safemode_or_autounlink)
0710             node_algorithms::init(to_erase);
0711          disposer(priv_value_traits().to_value_ptr(to_erase));
0712          this->priv_size_traits().decrement();
0713       }
0714       return e.unconst();
0715    }
0716 
0717    //! <b>Effects</b>: Erases all the elements of the container.
0718    //!   No destructors are called.
0719    //!
0720    //! <b>Throws</b>: Nothing.
0721    //!
0722    //! <b>Complexity</b>: Linear to the number of elements of the list.
0723    //!   if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
0724    //!
0725    //! <b>Note</b>: Invalidates the iterators (but not the references) to the erased elements.
0726    void clear() BOOST_NOEXCEPT
0727    {
0728       BOOST_IF_CONSTEXPR(safemode_or_autounlink){
0729          this->clear_and_dispose(detail::null_disposer());
0730       }
0731       else{
0732          node_algorithms::init_header(this->get_root_node());
0733          this->priv_size_traits().set_size(size_type(0));
0734       }
0735    }
0736 
0737    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
0738    //!
0739    //! <b>Effects</b>: Erases all the elements of the container.
0740    //!   No destructors are called.
0741    //!   Disposer::operator()(pointer) is called for the removed elements.
0742    //!
0743    //! <b>Throws</b>: Nothing.
0744    //!
0745    //! <b>Complexity</b>: Linear to the number of elements of the list.
0746    //!
0747    //! <b>Note</b>: Invalidates the iterators to the erased elements.
0748    template <class Disposer>
0749    void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT
0750    {
0751       const_iterator it(this->begin()), itend(this->end());
0752       while(it != itend){
0753          node_ptr to_erase(it.pointed_node());
0754          ++it;
0755          BOOST_IF_CONSTEXPR(safemode_or_autounlink)
0756             node_algorithms::init(to_erase);
0757          disposer(priv_value_traits().to_value_ptr(to_erase));
0758       }
0759       node_algorithms::init_header(this->get_root_node());
0760       this->priv_size_traits().set_size(0);
0761    }
0762 
0763    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
0764    //!   Cloner should yield to nodes equivalent to the original nodes.
0765    //!
0766    //! <b>Effects</b>: Erases all the elements from *this
0767    //!   calling Disposer::operator()(pointer), clones all the
0768    //!   elements from src calling Cloner::operator()(const_reference )
0769    //!   and inserts them on *this.
0770    //!
0771    //!   If cloner throws, all cloned elements are unlinked and disposed
0772    //!   calling Disposer::operator()(pointer).
0773    //!
0774    //! <b>Complexity</b>: Linear to erased plus inserted elements.
0775    //!
0776    //! <b>Throws</b>: If cloner throws. Basic guarantee.
0777    template <class Cloner, class Disposer>
0778    void clone_from(const list_impl &src, Cloner cloner, Disposer disposer)
0779    {
0780       this->clear_and_dispose(disposer);
0781       detail::exception_disposer<list_impl, Disposer>
0782          rollback(*this, disposer);
0783       const_iterator b(src.begin()), e(src.end());
0784       for(; b != e; ++b){
0785          this->push_back(*cloner(*b));
0786       }
0787       rollback.release();
0788    }
0789 
0790    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
0791    //!   Cloner should yield to nodes equivalent to the original nodes.
0792    //!
0793    //! <b>Effects</b>: Erases all the elements from *this
0794    //!   calling Disposer::operator()(pointer), clones all the
0795    //!   elements from src calling Cloner::operator()(reference)
0796    //!   and inserts them on *this.
0797    //!
0798    //!   If cloner throws, all cloned elements are unlinked and disposed
0799    //!   calling Disposer::operator()(pointer).
0800    //!
0801    //! <b>Complexity</b>: Linear to erased plus inserted elements.
0802    //!
0803    //! <b>Throws</b>: If cloner throws. Basic guarantee.
0804    template <class Cloner, class Disposer>
0805    void clone_from(BOOST_RV_REF(list_impl) src, Cloner cloner, Disposer disposer)
0806    {
0807       this->clear_and_dispose(disposer);
0808       detail::exception_disposer<list_impl, Disposer>
0809          rollback(*this, disposer);
0810       iterator b(src.begin()), e(src.end());
0811       for(; b != e; ++b){
0812          this->push_back(*cloner(*b));
0813       }
0814       rollback.release();
0815    }
0816 
0817    //! <b>Requires</b>: value must be an lvalue and p must be a valid iterator of *this.
0818    //!
0819    //! <b>Effects</b>: Inserts the value before the position pointed by p.
0820    //!
0821    //! <b>Returns</b>: An iterator to the inserted element.
0822    //!
0823    //! <b>Throws</b>: Nothing.
0824    //!
0825    //! <b>Complexity</b>: Constant time. No copy constructors are called.
0826    //!
0827    //! <b>Note</b>: Does not affect the validity of iterators and references.
0828    iterator insert(const_iterator p, reference value) BOOST_NOEXCEPT
0829    {
0830       node_ptr to_insert = this->priv_value_traits().to_node_ptr(value);
0831       BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(to_insert));
0832       node_algorithms::link_before(p.pointed_node(), to_insert);
0833       this->priv_size_traits().increment();
0834       return iterator(to_insert, this->priv_value_traits_ptr());
0835    }
0836 
0837    //! <b>Requires</b>: Dereferencing iterator must yield
0838    //!   an lvalue of type value_type and p must be a valid iterator of *this.
0839    //!
0840    //! <b>Effects</b>: Inserts the range pointed by b and e before the position p.
0841    //!   No copy constructors are called.
0842    //!
0843    //! <b>Throws</b>: Nothing.
0844    //!
0845    //! <b>Complexity</b>: Linear to the number of elements inserted.
0846    //!
0847    //! <b>Note</b>: Does not affect the validity of iterators and references.
0848    template<class Iterator>
0849    void insert(const_iterator p, Iterator b, Iterator e) BOOST_NOEXCEPT
0850    {
0851       for (; b != e; ++b)
0852          this->insert(p, *b);
0853    }
0854 
0855    //! <b>Requires</b>: Dereferencing iterator must yield
0856    //!   an lvalue of type value_type.
0857    //!
0858    //! <b>Effects</b>: Clears the list and inserts the range pointed by b and e.
0859    //!   No destructors or copy constructors are called.
0860    //!
0861    //! <b>Throws</b>: Nothing.
0862    //!
0863    //! <b>Complexity</b>: Linear to the number of elements inserted plus
0864    //!   linear to the elements contained in the list if it's a safe-mode
0865    //!   or auto-unlink value.
0866    //!   Linear to the number of elements inserted in the list otherwise.
0867    //!
0868    //! <b>Note</b>: Invalidates the iterators (but not the references)
0869    //!   to the erased elements.
0870    template<class Iterator>
0871    void assign(Iterator b, Iterator e) BOOST_NOEXCEPT
0872    {
0873       this->clear();
0874       this->insert(this->cend(), b, e);
0875    }
0876 
0877    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
0878    //!
0879    //! <b>Requires</b>: Dereferencing iterator must yield
0880    //!   an lvalue of type value_type.
0881    //!
0882    //! <b>Effects</b>: Clears the list and inserts the range pointed by b and e.
0883    //!   No destructors or copy constructors are called.
0884    //!   Disposer::operator()(pointer) is called for the removed elements.
0885    //!
0886    //! <b>Throws</b>: Nothing.
0887    //!
0888    //! <b>Complexity</b>: Linear to the number of elements inserted plus
0889    //!   linear to the elements contained in the list.
0890    //!
0891    //! <b>Note</b>: Invalidates the iterators (but not the references)
0892    //!   to the erased elements.
0893    template<class Iterator, class Disposer>
0894    void dispose_and_assign(Disposer disposer, Iterator b, Iterator e) BOOST_NOEXCEPT
0895    {
0896       this->clear_and_dispose(disposer);
0897       this->insert(this->cend(), b, e);
0898    }
0899 
0900    //! <b>Requires</b>: p must be a valid iterator of *this.
0901    //!
0902    //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
0903    //!   the element pointed by p. No destructors or copy constructors are called.
0904    //!
0905    //! <b>Throws</b>: Nothing.
0906    //!
0907    //! <b>Complexity</b>: Constant.
0908    //!
0909    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
0910    //!    this list. Iterators of this list and all the references are not invalidated.
0911    void splice(const_iterator p, list_impl& x) BOOST_NOEXCEPT
0912    {
0913       if(!x.empty()){
0914          node_algorithms::transfer
0915             (p.pointed_node(), x.begin().pointed_node(), x.end().pointed_node());
0916          size_traits &thist = this->priv_size_traits();
0917          size_traits &xt = x.priv_size_traits();
0918          thist.increase(xt.get_size());
0919          xt.set_size(size_type(0));
0920       }
0921    }
0922 
0923    //! <b>Requires</b>: p must be a valid iterator of *this.
0924    //!   new_ele must point to an element contained in list x.
0925    //!
0926    //! <b>Effects</b>: Transfers the value pointed by new_ele, from list x to this list,
0927    //!   before the element pointed by p. No destructors or copy constructors are called.
0928    //!   If p == new_ele or p == ++new_ele, this function is a null operation.
0929    //!
0930    //! <b>Throws</b>: Nothing.
0931    //!
0932    //! <b>Complexity</b>: Constant.
0933    //!
0934    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
0935    //!   list. Iterators of this list and all the references are not invalidated.
0936    void splice(const_iterator p, list_impl&x, const_iterator new_ele) BOOST_NOEXCEPT
0937    {
0938       node_algorithms::transfer(p.pointed_node(), new_ele.pointed_node());
0939       x.priv_size_traits().decrement();
0940       this->priv_size_traits().increment();
0941    }
0942 
0943    //! <b>Requires</b>: p must be a valid iterator of *this.
0944    //!   f and e must point to elements contained in list x.
0945    //!
0946    //! <b>Effects</b>: Transfers the range pointed by f and e from list x to this list,
0947    //!   before the element pointed by p. No destructors or copy constructors are called.
0948    //!
0949    //! <b>Throws</b>: Nothing.
0950    //!
0951    //! <b>Complexity</b>: Linear to the number of elements transferred
0952    //!   if constant-time size option is enabled. Constant-time otherwise.
0953    //!
0954    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
0955    //!   list. Iterators of this list and all the references are not invalidated.
0956    void splice(const_iterator p, list_impl&x, const_iterator f, const_iterator e) BOOST_NOEXCEPT
0957    {
0958       BOOST_IF_CONSTEXPR(constant_time_size)
0959          this->splice(p, x, f, e, node_algorithms::distance(f.pointed_node(), e.pointed_node()));
0960       else
0961          this->splice(p, x, f, e, 1);//intrusive::iterator_distance is a dummy value
0962    }
0963 
0964    //! <b>Requires</b>: p must be a valid iterator of *this.
0965    //!   f and e must point to elements contained in list x.
0966    //!   n == distance(f, e)
0967    //!
0968    //! <b>Effects</b>: Transfers the range pointed by f and e from list x to this list,
0969    //!   before the element pointed by p. No destructors or copy constructors are called.
0970    //!
0971    //! <b>Throws</b>: Nothing.
0972    //!
0973    //! <b>Complexity</b>: Constant.
0974    //!
0975    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
0976    //!   list. Iterators of this list and all the references are not invalidated.
0977    void splice(const_iterator p, list_impl&x, const_iterator f, const_iterator e, size_type n) BOOST_NOEXCEPT
0978    {
0979       if(n){
0980          BOOST_IF_CONSTEXPR(constant_time_size){
0981             BOOST_INTRUSIVE_INVARIANT_ASSERT(n == node_algorithms::distance(f.pointed_node(), e.pointed_node()));
0982             node_algorithms::transfer(p.pointed_node(), f.pointed_node(), e.pointed_node());
0983             size_traits &thist = this->priv_size_traits();
0984             size_traits &xt = x.priv_size_traits();
0985             thist.increase(n);
0986             xt.decrease(n);
0987          }
0988          else{
0989             node_algorithms::transfer(p.pointed_node(), f.pointed_node(), e.pointed_node());
0990          }
0991       }
0992    }
0993 
0994    //! <b>Effects</b>: This function sorts the list *this according to operator <.
0995    //!   The sort is stable, that is, the relative order of equivalent elements is preserved.
0996    //!
0997    //! <b>Throws</b>: If value_traits::node_traits::node
0998    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
0999    //!   or operator < throws. Basic guarantee.
1000    //!
1001    //! <b>Notes</b>: Iterators and references are not invalidated.
1002    //!
1003    //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
1004    //!   is the list's size.
1005    void sort()
1006    {  this->sort(value_less<value_type>());  }
1007 
1008    //! <b>Requires</b>: p must be a comparison function that induces a strict weak ordering
1009    //!
1010    //! <b>Effects</b>: This function sorts the list *this according to p. The sort is
1011    //!   stable, that is, the relative order of equivalent elements is preserved.
1012    //!
1013    //! <b>Throws</b>: If value_traits::node_traits::node
1014    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
1015    //!   or the predicate throws. Basic guarantee.
1016    //!
1017    //! <b>Notes</b>: This won't throw if list_base_hook<> or
1018    //!   list_member_hook are used.
1019    //!   Iterators and references are not invalidated.
1020    //!
1021    //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
1022    //!   is the list's size.
1023    template<class Predicate>
1024    void sort(Predicate p)
1025    {
1026       if(node_traits::get_next(this->get_root_node())
1027          != node_traits::get_previous(this->get_root_node())){
1028          list_impl carry(this->priv_value_traits());
1029          detail::array_initializer<list_impl, 64> counter(this->priv_value_traits());
1030          int fill = 0;
1031          while(!this->empty()){
1032             carry.splice(carry.cbegin(), *this, this->cbegin());
1033             int i = 0;
1034             while(i < fill && !counter[i].empty()) {
1035                counter[i].merge(carry, p);
1036                carry.swap(counter[i++]);
1037             }
1038             carry.swap(counter[i]);
1039             if(i == fill)
1040                ++fill;
1041          }
1042          for (int i = 1; i < fill; ++i)
1043             counter[i].merge(counter[i-1], p);
1044          this->swap(counter[fill-1]);
1045       }
1046    }
1047 
1048    //! <b>Effects</b>: This function removes all of x's elements and inserts them
1049    //!   in order into *this according to operator <. The merge is stable;
1050    //!   that is, if an element from *this is equivalent to one from x, then the element
1051    //!   from *this will precede the one from x.
1052    //!
1053    //! <b>Throws</b>: If operator < throws. Basic guarantee.
1054    //!
1055    //! <b>Complexity</b>: This function is linear time: it performs at most
1056    //!   size() + x.size() - 1 comparisons.
1057    //!
1058    //! <b>Note</b>: Iterators and references are not invalidated
1059    void merge(list_impl& x)
1060    { this->merge(x, value_less<value_type>()); }
1061 
1062    //! <b>Requires</b>: p must be a comparison function that induces a strict weak
1063    //!   ordering and both *this and x must be sorted according to that ordering
1064    //!   The lists x and *this must be distinct.
1065    //!
1066    //! <b>Effects</b>: This function removes all of x's elements and inserts them
1067    //!   in order into *this. The merge is stable; that is, if an element from *this is
1068    //!   equivalent to one from x, then the element from *this will precede the one from x.
1069    //!
1070    //! <b>Throws</b>: If the predicate throws. Basic guarantee.
1071    //!
1072    //! <b>Complexity</b>: This function is linear time: it performs at most
1073    //!   size() + x.size() - 1 comparisons.
1074    //!
1075    //! <b>Note</b>: Iterators and references are not invalidated.
1076    template<class Predicate>
1077    void merge(list_impl& x, Predicate p)
1078    {
1079       const_iterator e(this->cend()), ex(x.cend());
1080       const_iterator b(this->cbegin());
1081       while(!x.empty()){
1082          const_iterator ix(x.cbegin());
1083          while (b != e && !p(*ix, *b)){
1084             ++b;
1085          }
1086          if(b == e){
1087             //Now transfer the rest to the end of the container
1088             this->splice(e, x);
1089             break;
1090          }
1091          else{
1092             size_type n(0);
1093             do{
1094                ++ix; ++n;
1095             } while(ix != ex && p(*ix, *b));
1096             this->splice(b, x, x.begin(), ix, n);
1097          }
1098       }
1099    }
1100 
1101    //! <b>Effects</b>: Reverses the order of elements in the list.
1102    //!
1103    //! <b>Throws</b>: Nothing.
1104    //!
1105    //! <b>Complexity</b>: This function is linear time.
1106    //!
1107    //! <b>Note</b>: Iterators and references are not invalidated
1108    void reverse() BOOST_NOEXCEPT
1109    {  node_algorithms::reverse(this->get_root_node());   }
1110 
1111    //! <b>Effects</b>: Removes all the elements that compare equal to value.
1112    //!   No destructors are called.
1113    //!
1114    //! <b>Throws</b>: If operator == throws. Basic guarantee.
1115    //!
1116    //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
1117    //!
1118    //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1119    //!   and iterators to elements that are not removed remain valid.
1120    void remove(const_reference value) BOOST_NOEXCEPT
1121    {  this->remove_if(detail::equal_to_value<const_reference>(value));  }
1122 
1123    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1124    //!
1125    //! <b>Effects</b>: Removes all the elements that compare equal to value.
1126    //!   Disposer::operator()(pointer) is called for every removed element.
1127    //!
1128    //! <b>Throws</b>: If operator == throws. Basic guarantee.
1129    //!
1130    //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
1131    //!
1132    //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1133    //!   and iterators to elements that are not removed remain valid.
1134    template<class Disposer>
1135    void remove_and_dispose(const_reference value, Disposer disposer) BOOST_NOEXCEPT
1136    {  this->remove_and_dispose_if(detail::equal_to_value<const_reference>(value), disposer);  }
1137 
1138    //! <b>Effects</b>: Removes all the elements for which a specified
1139    //!   predicate is satisfied. No destructors are called.
1140    //!
1141    //! <b>Throws</b>: If pred throws. Basic guarantee.
1142    //!
1143    //! <b>Complexity</b>: Linear time. It performs exactly size() calls to the predicate.
1144    //!
1145    //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1146    //!   and iterators to elements that are not removed remain valid.
1147    template<class Pred>
1148    void remove_if(Pred pred)
1149    {
1150       const node_ptr root_node = this->get_root_node();
1151       typename node_algorithms::stable_partition_info info;
1152       node_algorithms::stable_partition
1153          (node_traits::get_next(root_node), root_node, detail::key_nodeptr_comp<Pred, value_traits>(pred, &this->priv_value_traits()), info);
1154       //Invariants preserved by stable_partition so erase can be safely called
1155       //The first element might have changed so calculate it again
1156       this->erase( const_iterator(node_traits::get_next(root_node), this->priv_value_traits_ptr())
1157                  , const_iterator(info.beg_2st_partition, this->priv_value_traits_ptr())
1158                  , info.num_1st_partition);
1159    }
1160 
1161    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1162    //!
1163    //! <b>Effects</b>: Removes all the elements for which a specified
1164    //!   predicate is satisfied.
1165    //!   Disposer::operator()(pointer) is called for every removed element.
1166    //!
1167    //! <b>Throws</b>: If pred throws. Basic guarantee.
1168    //!
1169    //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
1170    //!
1171    //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1172    //!   and iterators to elements that are not removed remain valid.
1173    template<class Pred, class Disposer>
1174    void remove_and_dispose_if(Pred pred, Disposer disposer)
1175    {
1176       const node_ptr root_node = this->get_root_node();
1177       typename node_algorithms::stable_partition_info info;
1178       node_algorithms::stable_partition
1179          (node_traits::get_next(root_node), root_node, detail::key_nodeptr_comp<Pred, value_traits>(pred, &this->priv_value_traits()), info);
1180       //Invariants preserved by stable_partition so erase can be safely called
1181       //The first element might have changed so calculate it again
1182       this->erase_and_dispose( const_iterator(node_traits::get_next(root_node), this->priv_value_traits_ptr())
1183                              , const_iterator(info.beg_2st_partition, this->priv_value_traits_ptr())
1184                              , disposer);
1185    }
1186 
1187    //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
1188    //!   elements that are equal from the list. No destructors are called.
1189    //!
1190    //! <b>Throws</b>: If std::equal_to<value_type throws. Basic guarantee.
1191    //!
1192    //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
1193    //!
1194    //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1195    //!   and iterators to elements that are not removed remain valid.
1196    void unique()
1197    {  this->unique_and_dispose(std::equal_to<value_type>(), detail::null_disposer());  }
1198 
1199    //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
1200    //!   elements that satisfy some binary predicate from the list.
1201    //!   No destructors are called.
1202    //!
1203    //! <b>Throws</b>: If pred throws. Basic guarantee.
1204    //!
1205    //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
1206    //!
1207    //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1208    //!   and iterators to elements that are not removed remain valid.
1209    template<class BinaryPredicate>
1210    void unique(BinaryPredicate pred)
1211    {  this->unique_and_dispose(pred, detail::null_disposer());  }
1212 
1213    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1214    //!
1215    //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
1216    //!   elements that are equal from the list.
1217    //!   Disposer::operator()(pointer) is called for every removed element.
1218    //!
1219    //! <b>Throws</b>: If std::equal_to<value_type throws. Basic guarantee.
1220    //!
1221    //! <b>Complexity</b>: Linear time (size()-1) comparisons equality comparisons.
1222    //!
1223    //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1224    //!   and iterators to elements that are not removed remain valid.
1225    template<class Disposer>
1226    void unique_and_dispose(Disposer disposer)
1227    {  this->unique_and_dispose(std::equal_to<value_type>(), disposer);  }
1228 
1229    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1230    //!
1231    //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
1232    //!   elements that satisfy some binary predicate from the list.
1233    //!   Disposer::operator()(pointer) is called for every removed element.
1234    //!
1235    //! <b>Throws</b>: If pred throws. Basic guarantee.
1236    //!
1237    //! <b>Complexity</b>: Linear time (size()-1) comparisons equality comparisons.
1238    //!
1239    //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1240    //!   and iterators to elements that are not removed remain valid.
1241    template<class BinaryPredicate, class Disposer>
1242    void unique_and_dispose(BinaryPredicate pred, Disposer disposer)
1243    {
1244       const_iterator itend(this->cend());
1245       const_iterator cur(this->cbegin());
1246 
1247       if(cur != itend){
1248          const_iterator after(cur);
1249          ++after;
1250          while(after != itend){
1251             if(pred(*cur, *after)){
1252                after = this->erase_and_dispose(after, disposer);
1253             }
1254             else{
1255                cur = after;
1256                ++after;
1257             }
1258          }
1259       }
1260    }
1261 
1262    //! <b>Requires</b>: value must be a reference to a value inserted in a list.
1263    //!
1264    //! <b>Effects</b>: This function returns a const_iterator pointing to the element
1265    //!
1266    //! <b>Throws</b>: Nothing.
1267    //!
1268    //! <b>Complexity</b>: Constant time.
1269    //!
1270    //! <b>Note</b>: Iterators and references are not invalidated.
1271    //!   This static function is available only if the <i>value traits</i>
1272    //!   is stateless.
1273    static iterator s_iterator_to(reference value) BOOST_NOEXCEPT
1274    {
1275       BOOST_STATIC_ASSERT((!stateful_value_traits));
1276       BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(value_traits::to_node_ptr(value)));
1277       return iterator(value_traits::to_node_ptr(value), const_value_traits_ptr());
1278    }
1279 
1280    //! <b>Requires</b>: value must be a const reference to a value inserted in a list.
1281    //!
1282    //! <b>Effects</b>: This function returns an iterator pointing to the element.
1283    //!
1284    //! <b>Throws</b>: Nothing.
1285    //!
1286    //! <b>Complexity</b>: Constant time.
1287    //!
1288    //! <b>Note</b>: Iterators and references are not invalidated.
1289    //!   This static function is available only if the <i>value traits</i>
1290    //!   is stateless.
1291    static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT
1292    {
1293       BOOST_STATIC_ASSERT((!stateful_value_traits));
1294       reference r =*detail::uncast(pointer_traits<const_pointer>::pointer_to(value));
1295       BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(value_traits::to_node_ptr(r)));
1296       return const_iterator(value_traits::to_node_ptr(r), const_value_traits_ptr());
1297    }
1298 
1299    //! <b>Requires</b>: value must be a reference to a value inserted in a list.
1300    //!
1301    //! <b>Effects</b>: This function returns a const_iterator pointing to the element
1302    //!
1303    //! <b>Throws</b>: Nothing.
1304    //!
1305    //! <b>Complexity</b>: Constant time.
1306    //!
1307    //! <b>Note</b>: Iterators and references are not invalidated.
1308    iterator iterator_to(reference value) BOOST_NOEXCEPT
1309    {
1310       BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(this->priv_value_traits().to_node_ptr(value)));
1311       return iterator(this->priv_value_traits().to_node_ptr(value), this->priv_value_traits_ptr());
1312    }
1313 
1314    //! <b>Requires</b>: value must be a const reference to a value inserted in a list.
1315    //!
1316    //! <b>Effects</b>: This function returns an iterator pointing to the element.
1317    //!
1318    //! <b>Throws</b>: Nothing.
1319    //!
1320    //! <b>Complexity</b>: Constant time.
1321    //!
1322    //! <b>Note</b>: Iterators and references are not invalidated.
1323    const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT
1324    {
1325       reference r = *detail::uncast(pointer_traits<const_pointer>::pointer_to(value));
1326       BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(this->priv_value_traits().to_node_ptr(r)));
1327       return const_iterator(this->priv_value_traits().to_node_ptr(r), this->priv_value_traits_ptr());
1328    }
1329 
1330    //! <b>Effects</b>: Asserts the integrity of the container.
1331    //!
1332    //! <b>Complexity</b>: Linear time.
1333    //!
1334    //! <b>Note</b>: The method has no effect when asserts are turned off (e.g., with NDEBUG).
1335    //!   Experimental function, interface might change in future versions.
1336    void check() const
1337    {
1338       const_node_ptr header_ptr = get_root_node();
1339       // header's next and prev are never null
1340       BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_next(header_ptr));
1341       BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_previous(header_ptr));
1342       // header's next and prev either both point to header (empty list) or neither does
1343       BOOST_INTRUSIVE_INVARIANT_ASSERT((node_traits::get_next(header_ptr) == header_ptr)
1344          == (node_traits::get_previous(header_ptr) == header_ptr));
1345       if (node_traits::get_next(header_ptr) == header_ptr)
1346       {
1347          BOOST_IF_CONSTEXPR(constant_time_size)
1348             BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == 0);
1349          return;
1350       }
1351       size_t node_count = 0; (void)node_count;
1352       const_node_ptr p = header_ptr;
1353       while (true)
1354       {
1355          const_node_ptr next_p = node_traits::get_next(p);
1356          BOOST_INTRUSIVE_INVARIANT_ASSERT(next_p);
1357          BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_previous(next_p) == p);
1358          p = next_p;
1359          if (p == header_ptr) break;
1360          ++node_count;
1361       }
1362       BOOST_IF_CONSTEXPR(constant_time_size)
1363          BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == node_count);
1364    }
1365 
1366    friend bool operator==(const list_impl &x, const list_impl &y)
1367    {
1368       if(constant_time_size && x.size() != y.size()){
1369          return false;
1370       }
1371       return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
1372    }
1373 
1374    BOOST_INTRUSIVE_FORCEINLINE friend bool operator!=(const list_impl &x, const list_impl &y)
1375    {  return !(x == y); }
1376 
1377    BOOST_INTRUSIVE_FORCEINLINE friend bool operator<(const list_impl &x, const list_impl &y)
1378    {  return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
1379 
1380    BOOST_INTRUSIVE_FORCEINLINE friend bool operator>(const list_impl &x, const list_impl &y)
1381    {  return y < x;  }
1382 
1383    BOOST_INTRUSIVE_FORCEINLINE friend bool operator<=(const list_impl &x, const list_impl &y)
1384    {  return !(y < x);  }
1385 
1386    BOOST_INTRUSIVE_FORCEINLINE friend bool operator>=(const list_impl &x, const list_impl &y)
1387    {  return !(x < y);  }
1388 
1389    BOOST_INTRUSIVE_FORCEINLINE friend void swap(list_impl &x, list_impl &y) BOOST_NOEXCEPT
1390    {  x.swap(y);  }
1391 
1392    /// @cond
1393 
1394    private:
1395    static list_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) BOOST_NOEXCEPT
1396    {
1397       BOOST_STATIC_ASSERT((has_container_from_iterator));
1398       node_ptr p = end_iterator.pointed_node();
1399       header_holder_type* h = header_holder_type::get_holder(p);
1400       root_plus_size* r = detail::parent_from_member
1401          < root_plus_size, header_holder_type>(h, &root_plus_size::m_header);
1402       data_t *d = detail::parent_from_member<data_t, root_plus_size>
1403          ( r, &data_t::root_plus_size_);
1404       list_impl *s  = detail::parent_from_member<list_impl, data_t>(d, &list_impl::data_);
1405       return *s;
1406    }
1407    /// @endcond
1408 };
1409 
1410 
1411 //! Helper metafunction to define a \c list that yields to the same type when the
1412 //! same options (either explicitly or implicitly) are used.
1413 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1414 template<class T, class ...Options>
1415 #else
1416 template<class T, class O1 = void, class O2 = void, class O3 = void, class O4 = void>
1417 #endif
1418 struct make_list
1419 {
1420    /// @cond
1421    typedef typename pack_options
1422       < list_defaults,
1423          #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1424          O1, O2, O3, O4
1425          #else
1426          Options...
1427          #endif
1428       >::type packed_options;
1429 
1430    typedef typename detail::get_value_traits
1431       <T, typename packed_options::proto_value_traits>::type value_traits;
1432    typedef list_impl
1433       <
1434          value_traits,
1435          typename packed_options::size_type,
1436          packed_options::constant_time_size,
1437          typename packed_options::header_holder_type
1438       > implementation_defined;
1439    /// @endcond
1440    typedef implementation_defined type;
1441 };
1442 
1443 
1444 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
1445 
1446 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1447 template<class T, class O1, class O2, class O3, class O4>
1448 #else
1449 template<class T, class ...Options>
1450 #endif
1451 class list
1452    :  public make_list<T,
1453       #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1454       O1, O2, O3, O4
1455       #else
1456       Options...
1457       #endif
1458    >::type
1459 {
1460    typedef typename make_list
1461       <T,
1462       #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1463       O1, O2, O3, O4
1464       #else
1465       Options...
1466       #endif
1467       >::type      Base;
1468    //Assert if passed value traits are compatible with the type
1469    BOOST_STATIC_ASSERT((detail::is_same<typename Base::value_traits::value_type, T>::value));
1470    BOOST_MOVABLE_BUT_NOT_COPYABLE(list)
1471 
1472    public:
1473    typedef typename Base::value_traits          value_traits;
1474    typedef typename Base::iterator              iterator;
1475    typedef typename Base::const_iterator        const_iterator;
1476 
1477    BOOST_INTRUSIVE_FORCEINLINE list()
1478       :  Base()
1479    {}
1480 
1481    BOOST_INTRUSIVE_FORCEINLINE explicit list(const value_traits &v_traits)
1482       :  Base(v_traits)
1483    {}
1484 
1485    template<class Iterator>
1486    BOOST_INTRUSIVE_FORCEINLINE list(Iterator b, Iterator e, const value_traits &v_traits = value_traits())
1487       :  Base(b, e, v_traits)
1488    {}
1489 
1490    BOOST_INTRUSIVE_FORCEINLINE list(BOOST_RV_REF(list) x)
1491       :  Base(BOOST_MOVE_BASE(Base, x))
1492    {}
1493 
1494    BOOST_INTRUSIVE_FORCEINLINE list& operator=(BOOST_RV_REF(list) x)
1495    {  return static_cast<list &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x)));  }
1496 
1497    template <class Cloner, class Disposer>
1498    BOOST_INTRUSIVE_FORCEINLINE void clone_from(const list &src, Cloner cloner, Disposer disposer)
1499    {  Base::clone_from(src, cloner, disposer);  }
1500 
1501    template <class Cloner, class Disposer>
1502    BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(list) src, Cloner cloner, Disposer disposer)
1503    {  Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer);  }
1504 
1505    BOOST_INTRUSIVE_FORCEINLINE static list &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
1506    {  return static_cast<list &>(Base::container_from_end_iterator(end_iterator));   }
1507 
1508    BOOST_INTRUSIVE_FORCEINLINE static const list &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
1509    {  return static_cast<const list &>(Base::container_from_end_iterator(end_iterator));   }
1510 };
1511 
1512 #endif
1513 
1514 } //namespace intrusive
1515 } //namespace boost
1516 
1517 #include <boost/intrusive/detail/config_end.hpp>
1518 
1519 #endif //BOOST_INTRUSIVE_LIST_HPP