diff DEPENDENCIES/generic/include/boost/intrusive/list.hpp @ 101:c530137014c0

Update Boost headers (1.58.0)
author Chris Cannam
date Mon, 07 Sep 2015 11:12:49 +0100
parents 2665513ce2d3
children
line wrap: on
line diff
--- a/DEPENDENCIES/generic/include/boost/intrusive/list.hpp	Fri Sep 04 12:01:02 2015 +0100
+++ b/DEPENDENCIES/generic/include/boost/intrusive/list.hpp	Mon Sep 07 11:12:49 2015 +0100
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga  2006-2013
+// (C) Copyright Ion Gaztanaga  2006-2014
 //
 // Distributed under the Boost Software License, Version 1.0.
 //    (See accompanying file LICENSE_1_0.txt or copy at
@@ -15,34 +15,55 @@
 #define BOOST_INTRUSIVE_LIST_HPP
 
 #include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/intrusive/intrusive_fwd.hpp>
 #include <boost/intrusive/detail/assert.hpp>
-#include <boost/intrusive/intrusive_fwd.hpp>
 #include <boost/intrusive/list_hook.hpp>
 #include <boost/intrusive/circular_list_algorithms.hpp>
 #include <boost/intrusive/pointer_traits.hpp>
-#include <boost/intrusive/detail/clear_on_destructor_base.hpp>
 #include <boost/intrusive/detail/mpl.hpp>
 #include <boost/intrusive/link_mode.hpp>
+#include <boost/intrusive/detail/get_value_traits.hpp>
+#include <boost/intrusive/detail/is_stateful_value_traits.hpp>
+#include <boost/intrusive/detail/default_header_holder.hpp>
+#include <boost/intrusive/detail/reverse_iterator.hpp>
+#include <boost/intrusive/detail/uncast.hpp>
+#include <boost/intrusive/detail/list_iterator.hpp>
+#include <boost/intrusive/detail/array_initializer.hpp>
+#include <boost/intrusive/detail/exception_disposer.hpp>
+#include <boost/intrusive/detail/equal_to_value.hpp>
+#include <boost/intrusive/detail/key_nodeptr_comp.hpp>
+#include <boost/intrusive/detail/simple_disposers.hpp>
+#include <boost/intrusive/detail/size_holder.hpp>
+#include <boost/intrusive/detail/algorithm.hpp>
+
+#include <boost/move/utility_core.hpp>
 #include <boost/static_assert.hpp>
-#include <boost/intrusive/options.hpp>
-#include <boost/intrusive/pointer_traits.hpp>
-#include <boost/intrusive/detail/utilities.hpp>
-#include <iterator>
-#include <algorithm>
-#include <functional>
-#include <cstddef>
-#include <boost/move/move.hpp>
+
+#include <boost/intrusive/detail/minimal_less_equal_header.hpp>//std::less
+#include <cstddef>   //std::size_t, etc.
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
 
 namespace boost {
 namespace intrusive {
 
 /// @cond
 
+struct default_list_hook_applier
+{  template <class T> struct apply{ typedef typename T::default_list_hook type;  };  };
+
+template<>
+struct is_default_hook_tag<default_list_hook_applier>
+{  static const bool value = true;  };
+
 struct list_defaults
 {
-   typedef detail::default_list_hook proto_value_traits;
+   typedef default_list_hook_applier proto_value_traits;
    static const bool constant_time_size = true;
    typedef std::size_t size_type;
+   typedef void header_holder_type;
 };
 
 /// @endcond
@@ -60,42 +81,36 @@
 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize>
+template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
 #endif
 class list_impl
-   :  private detail::clear_on_destructor_base
-         < list_impl<ValueTraits, SizeType, ConstantTimeSize>
-         , is_safe_autounlink<detail::get_real_value_traits<ValueTraits>::type::link_mode>::value
-         >
 {
-   template<class C, bool> friend class detail::clear_on_destructor_base;
    //Public typedefs
    public:
-   typedef ValueTraits value_traits;
-   /// @cond
-   static const bool external_value_traits =
-      detail::external_value_traits_bool_is_true<value_traits>::value;
-   typedef typename detail::get_real_value_traits<ValueTraits>::type real_value_traits;
-   /// @endcond
-   typedef typename real_value_traits::pointer                       pointer;
-   typedef typename real_value_traits::const_pointer                 const_pointer;
+   typedef ValueTraits                                               value_traits;
+   typedef typename value_traits::pointer                            pointer;
+   typedef typename value_traits::const_pointer                      const_pointer;
    typedef typename pointer_traits<pointer>::element_type            value_type;
    typedef typename pointer_traits<pointer>::reference               reference;
    typedef typename pointer_traits<const_pointer>::reference         const_reference;
    typedef typename pointer_traits<pointer>::difference_type         difference_type;
    typedef SizeType                                                  size_type;
-   typedef list_iterator<real_value_traits, false>                   iterator;
-   typedef list_iterator<real_value_traits, true>                    const_iterator;
-   typedef boost::intrusive::detail::reverse_iterator<iterator>      reverse_iterator;
-   typedef boost::intrusive::detail::reverse_iterator<const_iterator>const_reverse_iterator;
-   typedef typename real_value_traits::node_traits                   node_traits;
+   typedef list_iterator<value_traits, false>                        iterator;
+   typedef list_iterator<value_traits, true>                         const_iterator;
+   typedef boost::intrusive::reverse_iterator<iterator>              reverse_iterator;
+   typedef boost::intrusive::reverse_iterator<const_iterator>        const_reverse_iterator;
+   typedef typename value_traits::node_traits                        node_traits;
    typedef typename node_traits::node                                node;
    typedef typename node_traits::node_ptr                            node_ptr;
    typedef typename node_traits::const_node_ptr                      const_node_ptr;
    typedef circular_list_algorithms<node_traits>                     node_algorithms;
+   typedef typename detail::get_header_holder_type
+      < value_traits, HeaderHolder >::type                           header_holder_type;
 
    static const bool constant_time_size = ConstantTimeSize;
-   static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
+   static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value;
+   static const bool has_container_from_iterator =
+        detail::is_same< header_holder_type, detail::default_header_holder< node_traits > >::value;
 
    /// @cond
 
@@ -105,22 +120,22 @@
    //noncopyable
    BOOST_MOVABLE_BUT_NOT_COPYABLE(list_impl)
 
-   static const bool safemode_or_autounlink = is_safe_autounlink<real_value_traits::link_mode>::value;
+   static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
 
    //Constant-time size is incompatible with auto-unlink hooks!
    BOOST_STATIC_ASSERT(!(constant_time_size &&
-                        ((int)real_value_traits::link_mode == (int)auto_unlink)
+                        ((int)value_traits::link_mode == (int)auto_unlink)
                       ));
 
    node_ptr get_root_node()
-   {  return pointer_traits<node_ptr>::pointer_to(data_.root_plus_size_.root_);  }
+   { return data_.root_plus_size_.m_header.get_node(); }
 
    const_node_ptr get_root_node() const
-   {  return pointer_traits<const_node_ptr>::pointer_to(data_.root_plus_size_.root_);  }
+   { return data_.root_plus_size_.m_header.get_node(); }
 
    struct root_plus_size : public size_traits
    {
-      node root_;
+      header_holder_type m_header;
    };
 
    struct data_t : public value_traits
@@ -139,54 +154,27 @@
    const size_traits &priv_size_traits() const
    {  return data_.root_plus_size_;  }
 
-   const real_value_traits &get_real_value_traits(detail::bool_<false>) const
-   {  return data_;  }
-
-   const real_value_traits &get_real_value_traits(detail::bool_<true>) const
-   {  return data_.get_value_traits(*this);  }
-
-   real_value_traits &get_real_value_traits(detail::bool_<false>)
-   {  return data_;  }
-
-   real_value_traits &get_real_value_traits(detail::bool_<true>)
-   {  return data_.get_value_traits(*this);  }
-
    const value_traits &priv_value_traits() const
    {  return data_;  }
 
    value_traits &priv_value_traits()
    {  return data_;  }
 
-   protected:
-   node &prot_root_node()
-   {  return data_.root_plus_size_.root_; }
+   typedef typename boost::intrusive::value_traits_pointers
+      <ValueTraits>::const_value_traits_ptr const_value_traits_ptr;
 
-   node const &prot_root_node() const
-   {  return data_.root_plus_size_.root_; }
-
-   void prot_set_size(size_type s)
-   {  data_.root_plus_size_.set_size(s);  }
+   const_value_traits_ptr priv_value_traits_ptr() const
+   {  return pointer_traits<const_value_traits_ptr>::pointer_to(this->priv_value_traits());  }
 
    /// @endcond
 
    public:
 
-   const real_value_traits &get_real_value_traits() const
-   {  return this->get_real_value_traits(detail::bool_<external_value_traits>());  }
-
-   real_value_traits &get_real_value_traits()
-   {  return this->get_real_value_traits(detail::bool_<external_value_traits>());  }
-
-   typedef typename pointer_traits<node_ptr>::template rebind_pointer<real_value_traits const>::type const_real_value_traits_ptr;
-
-   const_real_value_traits_ptr real_value_traits_ptr() const
-   {  return pointer_traits<const_real_value_traits_ptr>::pointer_to(this->get_real_value_traits());  }
-
    //! <b>Effects</b>: constructs an empty list.
    //!
    //! <b>Complexity</b>: Constant
    //!
-   //! <b>Throws</b>: If real_value_traits::node_traits::node
+   //! <b>Throws</b>: If value_traits::node_traits::node
    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks).
    explicit list_impl(const value_traits &v_traits = value_traits())
       :  data_(v_traits)
@@ -199,16 +187,18 @@
    //!
    //! <b>Effects</b>: Constructs a list equal to the range [first,last).
    //!
-   //! <b>Complexity</b>: Linear in std::distance(b, e). No copy constructors are called.
+   //! <b>Complexity</b>: Linear in distance(b, e). No copy constructors are called.
    //!
-   //! <b>Throws</b>: If real_value_traits::node_traits::node
+   //! <b>Throws</b>: If value_traits::node_traits::node
    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks).
    template<class Iterator>
    list_impl(Iterator b, Iterator e, const value_traits &v_traits = value_traits())
       :  data_(v_traits)
    {
+      //nothrow, no need to rollback to release elements on exception
       this->priv_size_traits().set_size(size_type(0));
       node_algorithms::init_header(this->get_root_node());
+      //nothrow, no need to rollback to release elements on exception
       this->insert(this->cend(), b, e);
    }
 
@@ -219,6 +209,7 @@
    {
       this->priv_size_traits().set_size(size_type(0));
       node_algorithms::init_header(this->get_root_node());
+      //nothrow, no need to rollback to release elements on exception
       this->swap(x);
    }
 
@@ -227,7 +218,6 @@
    list_impl& operator=(BOOST_RV_REF(list_impl) x)
    {  this->swap(x); return *this;  }
 
-   #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
    //! <b>Effects</b>: If it's not a safe-mode or an auto-unlink value_type
    //!   the destructor does nothing
    //!   (ie. no code is generated). Otherwise it detaches all elements from this.
@@ -238,8 +228,12 @@
    //! <b>Complexity</b>: Linear to the number of elements in the list, if
    //!   it's a safe-mode or auto-unlink value . Otherwise constant.
    ~list_impl()
-   {}
-   #endif
+   {
+      if(is_safe_autounlink<ValueTraits::link_mode>::value){
+         this->clear();
+         node_algorithms::init(this->get_root_node());
+      }
+   }
 
    //! <b>Requires</b>: value must be an lvalue.
    //!
@@ -253,7 +247,7 @@
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    void push_back(reference value)
    {
-      node_ptr to_insert = get_real_value_traits().to_node_ptr(value);
+      node_ptr to_insert = priv_value_traits().to_node_ptr(value);
       if(safemode_or_autounlink)
          BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
       node_algorithms::link_before(this->get_root_node(), to_insert);
@@ -272,7 +266,7 @@
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    void push_front(reference value)
    {
-      node_ptr to_insert = get_real_value_traits().to_node_ptr(value);
+      node_ptr to_insert = priv_value_traits().to_node_ptr(value);
       if(safemode_or_autounlink)
          BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
       node_algorithms::link_before(node_traits::get_next(this->get_root_node()), to_insert);
@@ -309,7 +303,7 @@
       this->priv_size_traits().decrement();
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
-      disposer(get_real_value_traits().to_value_ptr(to_erase));
+      disposer(priv_value_traits().to_value_ptr(to_erase));
    }
 
    //! <b>Effects</b>: Erases the first element of the list.
@@ -342,7 +336,7 @@
       this->priv_size_traits().decrement();
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
-      disposer(get_real_value_traits().to_value_ptr(to_erase));
+      disposer(priv_value_traits().to_value_ptr(to_erase));
    }
 
    //! <b>Effects</b>: Returns a reference to the first element of the list.
@@ -351,7 +345,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    reference front()
-   { return *get_real_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); }
+   { return *priv_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); }
 
    //! <b>Effects</b>: Returns a const_reference to the first element of the list.
    //!
@@ -359,7 +353,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_reference front() const
-   { return *get_real_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); }
+   { return *priv_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); }
 
    //! <b>Effects</b>: Returns a reference to the last element of the list.
    //!
@@ -367,7 +361,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    reference back()
-   { return *get_real_value_traits().to_value_ptr(node_traits::get_previous(this->get_root_node())); }
+   { return *priv_value_traits().to_value_ptr(node_traits::get_previous(this->get_root_node())); }
 
    //! <b>Effects</b>: Returns a const_reference to the last element of the list.
    //!
@@ -375,7 +369,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_reference back() const
-   { return *get_real_value_traits().to_value_ptr(detail::uncast(node_traits::get_previous(this->get_root_node()))); }
+   { return *priv_value_traits().to_value_ptr(detail::uncast(node_traits::get_previous(this->get_root_node()))); }
 
    //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
    //!
@@ -383,7 +377,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    iterator begin()
-   { return iterator(node_traits::get_next(this->get_root_node()), real_value_traits_ptr()); }
+   { return iterator(node_traits::get_next(this->get_root_node()), this->priv_value_traits_ptr()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
    //!
@@ -399,7 +393,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator cbegin() const
-   { return const_iterator(node_traits::get_next(this->get_root_node()), real_value_traits_ptr()); }
+   { return const_iterator(node_traits::get_next(this->get_root_node()), this->priv_value_traits_ptr()); }
 
    //! <b>Effects</b>: Returns an iterator to the end of the list.
    //!
@@ -407,7 +401,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    iterator end()
-   { return iterator(this->get_root_node(), real_value_traits_ptr()); }
+   { return iterator(this->get_root_node(), this->priv_value_traits_ptr()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the list.
    //!
@@ -423,7 +417,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator cend() const
-   { return const_iterator(detail::uncast(this->get_root_node()), real_value_traits_ptr()); }
+   { return const_iterator(detail::uncast(this->get_root_node()), this->priv_value_traits_ptr()); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
    //! of the reversed list.
@@ -610,7 +604,7 @@
    }
 
    //! <b>Requires</b>: b and e must be valid iterators to elements in *this.
-   //!   n must be std::distance(b, e).
+   //!   n must be distance(b, e).
    //!
    //! <b>Effects</b>: Erases the element range pointed by b and e
    //! No destructors are called.
@@ -625,9 +619,9 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references) to the
    //!   erased elements.
-   iterator erase(const_iterator b, const_iterator e, difference_type n)
+   iterator erase(const_iterator b, const_iterator e, size_type n)
    {
-      BOOST_INTRUSIVE_INVARIANT_ASSERT(std::distance(b, e) == difference_type(n));
+      BOOST_INTRUSIVE_INVARIANT_ASSERT(node_algorithms::distance(b.pointed_node(), e.pointed_node()) == n);
       if(safemode_or_autounlink || constant_time_size){
          return this->erase_and_dispose(b, e, detail::null_disposer());
       }
@@ -663,7 +657,7 @@
       this->priv_size_traits().decrement();
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
-      disposer(this->get_real_value_traits().to_value_ptr(to_erase));
+      disposer(this->priv_value_traits().to_value_ptr(to_erase));
       return i.unconst();
    }
 
@@ -697,7 +691,7 @@
          bp = node_traits::get_next(bp);
          if(safemode_or_autounlink)
             node_algorithms::init(to_erase);
-         disposer(get_real_value_traits().to_value_ptr(to_erase));
+         disposer(priv_value_traits().to_value_ptr(to_erase));
          this->priv_size_traits().decrement();
       }
       return e.unconst();
@@ -743,7 +737,7 @@
          ++it;
          if(safemode_or_autounlink)
             node_algorithms::init(to_erase);
-         disposer(get_real_value_traits().to_value_ptr(to_erase));
+         disposer(priv_value_traits().to_value_ptr(to_erase));
       }
       node_algorithms::init_header(this->get_root_node());
       this->priv_size_traits().set_size(0);
@@ -789,12 +783,12 @@
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    iterator insert(const_iterator p, reference value)
    {
-      node_ptr to_insert = this->get_real_value_traits().to_node_ptr(value);
+      node_ptr to_insert = this->priv_value_traits().to_node_ptr(value);
       if(safemode_or_autounlink)
          BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
       node_algorithms::link_before(p.pointed_node(), to_insert);
       this->priv_size_traits().increment();
-      return iterator(to_insert, real_value_traits_ptr());
+      return iterator(to_insert, this->priv_value_traits_ptr());
    }
 
    //! <b>Requires</b>: Dereferencing iterator must yield
@@ -887,7 +881,7 @@
    //!   new_ele must point to an element contained in list x.
    //!
    //! <b>Effects</b>: Transfers the value pointed by new_ele, from list x to this list,
-   //!   before the the element pointed by p. No destructors or copy constructors are called.
+   //!   before the element pointed by p. No destructors or copy constructors are called.
    //!   If p == new_ele or p == ++new_ele, this function is a null operation.
    //!
    //! <b>Throws</b>: Nothing.
@@ -907,7 +901,7 @@
    //!   f and e must point to elements contained in list x.
    //!
    //! <b>Effects</b>: Transfers the range pointed by f and e from list x to this list,
-   //!   before the the element pointed by p. No destructors or copy constructors are called.
+   //!   before the element pointed by p. No destructors or copy constructors are called.
    //!
    //! <b>Throws</b>: Nothing.
    //!
@@ -919,17 +913,17 @@
    void splice(const_iterator p, list_impl&x, const_iterator f, const_iterator e)
    {
       if(constant_time_size)
-         this->splice(p, x, f, e, std::distance(f, e));
+         this->splice(p, x, f, e, node_algorithms::distance(f.pointed_node(), e.pointed_node()));
       else
-         this->splice(p, x, f, e, 1);//distance is a dummy value
+         this->splice(p, x, f, e, 1);//intrusive::iterator_distance is a dummy value
    }
 
    //! <b>Requires</b>: p must be a valid iterator of *this.
    //!   f and e must point to elements contained in list x.
-   //!   n == std::distance(f, e)
+   //!   n == distance(f, e)
    //!
    //! <b>Effects</b>: Transfers the range pointed by f and e from list x to this list,
-   //!   before the the element pointed by p. No destructors or copy constructors are called.
+   //!   before the element pointed by p. No destructors or copy constructors are called.
    //!
    //! <b>Throws</b>: Nothing.
    //!
@@ -937,11 +931,11 @@
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //!   list. Iterators of this list and all the references are not invalidated.
-   void splice(const_iterator p, list_impl&x, const_iterator f, const_iterator e, difference_type n)
+   void splice(const_iterator p, list_impl&x, const_iterator f, const_iterator e, size_type n)
    {
       if(n){
          if(constant_time_size){
-            BOOST_INTRUSIVE_INVARIANT_ASSERT(n == std::distance(f, e));
+            BOOST_INTRUSIVE_INVARIANT_ASSERT(n == node_algorithms::distance(f.pointed_node(), e.pointed_node()));
             node_algorithms::transfer(p.pointed_node(), f.pointed_node(), e.pointed_node());
             size_traits &thist = this->priv_size_traits();
             size_traits &xt = x.priv_size_traits();
@@ -957,7 +951,7 @@
    //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
    //!   The sort is stable, that is, the relative order of equivalent elements is preserved.
    //!
-   //! <b>Throws</b>: If real_value_traits::node_traits::node
+   //! <b>Throws</b>: If value_traits::node_traits::node
    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
    //!   or std::less<value_type> throws. Basic guarantee.
    //!
@@ -973,7 +967,7 @@
    //! <b>Effects</b>: This function sorts the list *this according to p. The sort is
    //!   stable, that is, the relative order of equivalent elements is preserved.
    //!
-   //! <b>Throws</b>: If real_value_traits::node_traits::node
+   //! <b>Throws</b>: If value_traits::node_traits::node
    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
    //!   or the predicate throws. Basic guarantee.
    //!
@@ -1109,7 +1103,17 @@
    //!   and iterators to elements that are not removed remain valid.
    template<class Pred>
    void remove_if(Pred pred)
-   {  this->remove_and_dispose_if(pred, detail::null_disposer());   }
+   {
+      const node_ptr root_node = this->get_root_node();
+      typename node_algorithms::stable_partition_info info;
+      node_algorithms::stable_partition
+         (node_traits::get_next(root_node), root_node, detail::key_nodeptr_comp<Pred, value_traits>(pred, &this->priv_value_traits()), info);
+      //Invariants preserved by stable_partition so erase can be safely called
+      //The first element might have changed so calculate it again
+      this->erase( const_iterator(node_traits::get_next(root_node), this->priv_value_traits_ptr())
+                 , const_iterator(info.beg_2st_partition, this->priv_value_traits_ptr())
+                 , info.num_1st_partition);
+   }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
@@ -1126,16 +1130,15 @@
    template<class Pred, class Disposer>
    void remove_and_dispose_if(Pred pred, Disposer disposer)
    {
-      const_iterator cur(this->cbegin());
-      const_iterator last(this->cend());
-      while(cur != last) {
-         if(pred(*cur)){
-            cur = this->erase_and_dispose(cur, disposer);
-         }
-         else{
-            ++cur;
-         }
-      }
+      const node_ptr root_node = this->get_root_node();
+      typename node_algorithms::stable_partition_info info;
+      node_algorithms::stable_partition
+         (node_traits::get_next(root_node), root_node, detail::key_nodeptr_comp<Pred, value_traits>(pred, &this->priv_value_traits()), info);
+      //Invariants preserved by stable_partition so erase can be safely called
+      //The first element might have changed so calculate it again
+      this->erase_and_dispose( const_iterator(node_traits::get_next(root_node), this->priv_value_traits_ptr())
+                             , const_iterator(info.beg_2st_partition, this->priv_value_traits_ptr())
+                             , disposer);
    }
 
    //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
@@ -1227,8 +1230,8 @@
    static iterator s_iterator_to(reference value)
    {
       BOOST_STATIC_ASSERT((!stateful_value_traits));
-      BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(value)));
-      return iterator(real_value_traits::to_node_ptr(value), const_real_value_traits_ptr());
+      BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(value_traits::to_node_ptr(value)));
+      return iterator(value_traits::to_node_ptr(value), const_value_traits_ptr());
    }
 
    //! <b>Requires</b>: value must be a const reference to a value inserted in a list.
@@ -1245,8 +1248,9 @@
    static const_iterator s_iterator_to(const_reference value)
    {
       BOOST_STATIC_ASSERT((!stateful_value_traits));
-      BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(const_cast<reference> (value))));
-      return const_iterator(real_value_traits::to_node_ptr(const_cast<reference> (value)), const_real_value_traits_ptr());
+      reference r =*detail::uncast(pointer_traits<const_pointer>::pointer_to(value));
+      BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(value_traits::to_node_ptr(r)));
+      return const_iterator(value_traits::to_node_ptr(r), const_value_traits_ptr());
    }
 
    //! <b>Requires</b>: value must be a reference to a value inserted in a list.
@@ -1260,8 +1264,8 @@
    //! <b>Note</b>: Iterators and references are not invalidated.
    iterator iterator_to(reference value)
    {
-      BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(value)));
-      return iterator(real_value_traits::to_node_ptr(value), real_value_traits_ptr());
+      BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(this->priv_value_traits().to_node_ptr(value)));
+      return iterator(this->priv_value_traits().to_node_ptr(value), this->priv_value_traits_ptr());
    }
 
    //! <b>Requires</b>: value must be a const reference to a value inserted in a list.
@@ -1275,8 +1279,45 @@
    //! <b>Note</b>: Iterators and references are not invalidated.
    const_iterator iterator_to(const_reference value) const
    {
-      BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(const_cast<reference> (value))));
-      return const_iterator(real_value_traits::to_node_ptr(const_cast<reference> (value)), real_value_traits_ptr());
+      reference r = *detail::uncast(pointer_traits<const_pointer>::pointer_to(value));
+      BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(this->priv_value_traits().to_node_ptr(r)));
+      return const_iterator(this->priv_value_traits().to_node_ptr(r), this->priv_value_traits_ptr());
+   }
+
+   //! <b>Effects</b>: Asserts the integrity of the container.
+   //!
+   //! <b>Complexity</b>: Linear time.
+   //!
+   //! <b>Note</b>: The method has no effect when asserts are turned off (e.g., with NDEBUG).
+   //!   Experimental function, interface might change in future versions.
+   void check() const
+   {
+      const_node_ptr header_ptr = get_root_node();
+      // header's next and prev are never null
+      BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_next(header_ptr));
+      BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_previous(header_ptr));
+      // header's next and prev either both point to header (empty list) or neither does
+      BOOST_INTRUSIVE_INVARIANT_ASSERT((node_traits::get_next(header_ptr) == header_ptr)
+         == (node_traits::get_previous(header_ptr) == header_ptr));
+      if (node_traits::get_next(header_ptr) == header_ptr)
+      {
+         if (constant_time_size)
+            BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == 0);
+         return;
+      }
+      size_t node_count = 0;
+      const_node_ptr p = header_ptr;
+      while (true)
+      {
+         const_node_ptr next_p = node_traits::get_next(p);
+         BOOST_INTRUSIVE_INVARIANT_ASSERT(next_p);
+         BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_previous(next_p) == p);
+         p = next_p;
+         if (p == header_ptr) break;
+         ++node_count;
+      }
+      if (constant_time_size)
+         BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == node_count);
    }
 
    /// @cond
@@ -1284,8 +1325,11 @@
    private:
    static list_impl &priv_container_from_end_iterator(const const_iterator &end_iterator)
    {
-      root_plus_size *r = detail::parent_from_member<root_plus_size, node>
-         ( boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()), &root_plus_size::root_);
+      BOOST_STATIC_ASSERT((has_container_from_iterator));
+      node_ptr p = end_iterator.pointed_node();
+      header_holder_type* h = header_holder_type::get_holder(p);
+      root_plus_size* r = detail::parent_from_member
+         < root_plus_size, header_holder_type>(h, &root_plus_size::m_header);
       data_t *d = detail::parent_from_member<data_t, root_plus_size>
          ( r, &data_t::root_plus_size_);
       list_impl *s  = detail::parent_from_member<list_impl, data_t>(d, &list_impl::data_);
@@ -1297,117 +1341,98 @@
 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize>
+template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
 #endif
 inline bool operator<
 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
 #else
-(const list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
+(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
 #endif
-{  return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
+{  return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
 
 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize>
+template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
 #endif
 bool operator==
 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
 #else
-(const list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
+(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
 #endif
 {
-   typedef list_impl<ValueTraits, SizeType, ConstantTimeSize> list_type;
-   typedef typename list_type::const_iterator const_iterator;
+   typedef list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> list_type;
    const bool C = list_type::constant_time_size;
    if(C && x.size() != y.size()){
       return false;
    }
-   const_iterator end1 = x.end();
-
-   const_iterator i1 = x.begin();
-   const_iterator i2 = y.begin();
-   if(C){
-      while (i1 != end1 && *i1 == *i2) {
-         ++i1;
-         ++i2;
-      }
-      return i1 == end1;
-   }
-   else{
-      const_iterator end2 = y.end();
-      while (i1 != end1 && i2 != end2 && *i1 == *i2) {
-         ++i1;
-         ++i2;
-      }
-      return i1 == end1 && i2 == end2;
-   }
+   return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
 }
 
 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize>
+template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
 #endif
 inline bool operator!=
 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
 #else
-(const list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
+(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
 #endif
 {  return !(x == y); }
 
 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize>
+template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
 #endif
 inline bool operator>
 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
 #else
-(const list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
+(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
 #endif
 {  return y < x;  }
 
 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize>
+template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
 #endif
 inline bool operator<=
 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
 #else
-(const list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
+(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
 #endif
 {  return !(y < x);  }
 
 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize>
+template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
 #endif
 inline bool operator>=
 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
 #else
-(const list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
+(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
 #endif
 {  return !(x < y);  }
 
 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize>
+template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
 #endif
 inline void swap
 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (list_impl<T, Options...> &x, list_impl<T, Options...> &y)
 #else
-(list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
+(list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
 #endif
 {  x.swap(y);  }
 
@@ -1416,7 +1441,7 @@
 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class ...Options>
 #else
-template<class T, class O1 = void, class O2 = void, class O3 = void>
+template<class T, class O1 = void, class O2 = void, class O3 = void, class O4 = void>
 #endif
 struct make_list
 {
@@ -1424,7 +1449,7 @@
    typedef typename pack_options
       < list_defaults,
          #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-         O1, O2, O3
+         O1, O2, O3, O4
          #else
          Options...
          #endif
@@ -1432,12 +1457,12 @@
 
    typedef typename detail::get_value_traits
       <T, typename packed_options::proto_value_traits>::type value_traits;
-
    typedef list_impl
       <
          value_traits,
          typename packed_options::size_type,
-         packed_options::constant_time_size
+         packed_options::constant_time_size,
+         typename packed_options::header_holder_type
       > implementation_defined;
    /// @endcond
    typedef implementation_defined type;
@@ -1447,14 +1472,14 @@
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
 
 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3>
+template<class T, class O1, class O2, class O3, class O4>
 #else
 template<class T, class ...Options>
 #endif
 class list
    :  public make_list<T,
       #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-      O1, O2, O3
+      O1, O2, O3, O4
       #else
       Options...
       #endif
@@ -1463,14 +1488,13 @@
    typedef typename make_list
       <T,
       #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-      O1, O2, O3
+      O1, O2, O3, O4
       #else
       Options...
       #endif
       >::type      Base;
-   typedef typename Base::real_value_traits     real_value_traits;
    //Assert if passed value traits are compatible with the type
-   BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
+   BOOST_STATIC_ASSERT((detail::is_same<typename Base::value_traits::value_type, T>::value));
    BOOST_MOVABLE_BUT_NOT_COPYABLE(list)
 
    public:
@@ -1488,11 +1512,11 @@
    {}
 
    list(BOOST_RV_REF(list) x)
-      :  Base(::boost::move(static_cast<Base&>(x)))
+      :  Base(BOOST_MOVE_BASE(Base, x))
    {}
 
    list& operator=(BOOST_RV_REF(list) x)
-   {  return static_cast<list &>(this->Base::operator=(::boost::move(static_cast<Base&>(x))));  }
+   {  return static_cast<list &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x)));  }
 
    static list &container_from_end_iterator(iterator end_iterator)
    {  return static_cast<list &>(Base::container_from_end_iterator(end_iterator));   }