Update of /cvsroot/boost/boost/boost/interprocess/containers/detail
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv22035/containers/detail

Modified Files:
        tree.hpp 
Added Files:
        node_alloc_holder.hpp 
Log Message:
New Interprocess version

--- NEW FILE: node_alloc_holder.hpp ---
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////

#ifndef BOOST_INTERPROCESS_DETAIL_NODE_ALLOC_HPP_
#define BOOST_INTERPROCESS_DETAIL_NODE_ALLOC_HPP_

#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#  pragma once
#endif

#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>

#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/detail/version_type.hpp>
#include <boost/interprocess/detail/move.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/detail/algorithms.hpp>
#include <boost/interprocess/detail/mpl.hpp>

#include <utility>
#include <functional>


namespace boost {
namespace interprocess {
namespace detail {

template<class ValueCompare, class Node>
struct node_compare
   :  private ValueCompare
{
   typedef typename ValueCompare::key_type     key_type;
   typedef typename ValueCompare::value_type   value_type;
   typedef typename ValueCompare::key_of_value key_of_value;

   node_compare(const ValueCompare &pred)
      :  ValueCompare(pred)
   {}

   ValueCompare &value_comp()
   {  return static_cast<ValueCompare &>(*this);  }

   ValueCompare &value_comp() const
   {  return static_cast<const ValueCompare &>(*this);  }

   bool operator()(const Node &a, const Node &b) const
   {  return ValueCompare::operator()(a.m_data, b.m_data);  }
};

template<class A, class ICont>
struct node_alloc_holder
   :  public A::template rebind<typename ICont::value_type>::other
{
   typedef node_alloc_holder<A, ICont>                self_t;
   typedef typename A::value_type                     value_type;
   typedef typename ICont::value_type                 Node;
   typedef typename A::template rebind<Node>::other   NodeAlloc;
   typedef A                                          ValAlloc;
   typedef typename NodeAlloc::pointer                NodePtr;
   typedef detail::scoped_deallocator<NodeAlloc>      Deallocator;
   typedef typename NodeAlloc::size_type              size_type;
   typedef typename NodeAlloc::difference_type        difference_type;
   typedef detail::integral_constant<unsigned, 1>     allocator_v1;
   typedef detail::integral_constant<unsigned, 2>     allocator_v2;
   typedef detail::integral_constant<unsigned,
      boost::interprocess::detail::
         version<NodeAlloc>::value>                   alloc_version;

   node_alloc_holder(const ValAlloc &a) 
      : NodeAlloc(a)
   {}

   #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
   node_alloc_holder(const detail::moved_object<ValAlloc> &a) 
      : NodeAlloc(a.get())
   {}
   #else
   node_alloc_holder(ValAlloc &&a) 
      : NodeAlloc(a)
   {}
   #endif

   node_alloc_holder(const node_alloc_holder &other)
      : NodeAlloc(other)
   {}

   #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
   node_alloc_holder(const detail::moved_object<node_alloc_holder> &other)
      : NodeAlloc(move((NodeAlloc&)other.get()))
   {  this->swap(other.get());  }
   #else
   node_alloc_holder(node_alloc_holder &&other)
      : NodeAlloc(move((NodeAlloc&)other))
   {  this->swap(other);  }
   #endif

   template<class Pred>
   node_alloc_holder(const ValAlloc &a, const Pred &c) 
      : NodeAlloc(a), m_icont(typename ICont::value_compare(c))
   {}

   #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
   template<class Pred>
   node_alloc_holder(const detail::moved_object<ValAlloc> &a, const Pred &c) 
      : NodeAlloc(a.get()), m_icont(typename ICont::value_compare(c))
   {}
   #else
   template<class Pred>
   node_alloc_holder(ValAlloc &&a, const Pred &c) 
      : NodeAlloc(a), m_icont(typename ICont::value_compare(c))
   {}
   #endif

   template<class Pred>
   node_alloc_holder(const node_alloc_holder &other, const Pred &c)
      : NodeAlloc(other), m_icont(typename ICont::value_compare(c))
   {}

   #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
   template<class Pred>
   node_alloc_holder
      (const detail::moved_object<node_alloc_holder> &other, const Pred &c)
      : NodeAlloc(move((NodeAlloc&)other.get())), m_icont(typename 
ICont::value_compare(c))
   {  this->swap(other.get());  }
   #else
   template<class Pred>
   node_alloc_holder(node_alloc_holder &&other, const Pred &c)
      : NodeAlloc(move((NodeAlloc&)other)), m_icont(typename 
ICont::value_compare(c))
   {  this->swap(other);  }
   #endif

   ~node_alloc_holder()
   {}

   size_type max_size() const
   {  return NodeAlloc::max_size();  }

   NodePtr allocate_one()
   {  return this->allocate_one(alloc_version());   }

   NodePtr allocate_one(allocator_v1)
   {  return NodeAlloc::allocate(1);   }

   NodePtr allocate_one(allocator_v2)
   {  return NodeAlloc::allocate_one();   }

   void deallocate_one(NodePtr p)
   {  return this->deallocate_one(p, alloc_version());   }

   void deallocate_one(NodePtr p, allocator_v1)
   {  NodeAlloc::deallocate(p, 1);   }

   void deallocate_one(NodePtr p, allocator_v2)
   {  NodeAlloc::deallocate_one(p);   }

   #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
   template<class Convertible>
   static void construct(const NodePtr &ptr, const Convertible &value)
   {  new(detail::get_pointer(ptr)) Node(value);  }
   #else
   template<class Convertible>
   static void construct(const NodePtr &ptr, Convertible &&value)
   {  new(detail::get_pointer(ptr)) Node(forward<Convertible>(value));  }
   #endif

   static void construct(const NodePtr &ptr)
   {  new(detail::get_pointer(ptr)) Node();  }

   #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
   template<class Convertible1, class Convertible2>
   static void construct(const NodePtr &ptr, 
                         const detail::moved_object<std::pair<Convertible1, 
Convertible2> > &value)
   {
      typedef typename Node::hook_type                hook_type;
      typedef typename Node::value_type::first_type   first_type;
      typedef typename Node::value_type::second_type  second_type;
      Node *nodeptr = detail::get_pointer(ptr);

      //Hook constructor does not throw
      new(static_cast<hook_type*>(nodeptr))hook_type();
      //Now construct pair members
      value_type *valueptr = &nodeptr->m_data;
      new((void*)&valueptr->first) first_type(move(value.get().first));
      BOOST_TRY{
         new((void*)&valueptr->second) second_type(move(value.get().second));
      }
      BOOST_CATCH(...){
         valueptr->first.~first_type();
         static_cast<hook_type*>(nodeptr)->~hook_type();
         throw;
      }
      BOOST_CATCH_END
   }
   #else
   template<class Convertible1, class Convertible2>
   static void construct(const NodePtr &ptr, 
                         std::pair<Convertible1, Convertible2> &&value)
   {  
      typedef typename Node::hook_type                hook_type;
      typedef typename Node::value_type::first_type   first_type;
      typedef typename Node::value_type::second_type  second_type;
      Node *nodeptr = detail::get_pointer(ptr);

      //Hook constructor does not throw
      new(static_cast<hook_type*>(nodeptr))hook_type();
      //Now construct pair members
      value_type *valueptr = &nodeptr->m_data;
      new((void*)&valueptr->first) first_type(move(value.first));
      BOOST_TRY{
         new((void*)&valueptr->second) second_type(move(value.second));
      }
      BOOST_CATCH(...){
         valueptr->first.~first_type();
         static_cast<hook_type*>(nodeptr)->~hook_type();
         throw;
      }
      BOOST_CATCH_END
   }
   #endif

   static void destroy(const NodePtr &ptr)
   {  detail::get_pointer(ptr)->~Node();  }

   #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
   template<class Convertible>
   NodePtr create_node(const Convertible& x)
   {
      NodePtr p = this->allocate_one();
      Deallocator node_deallocator(p, *this);
      self_t::construct(p, x);
      node_deallocator.release();
      return (p);
   }
   #else
   template<class Convertible>
   NodePtr create_node(Convertible &&x)
   {
      NodePtr p = this->allocate_one();
      Deallocator node_deallocator(p, *this);
      self_t::construct(p, forward<Convertible>(x));
      node_deallocator.release();
      return (p);
   }
   #endif

   template<class It>
   NodePtr create_node_from_it(It it)
   {
      NodePtr p = this->allocate_one();
      Deallocator node_deallocator(p, *this);
      ::boost::interprocess::construct_in_place(detail::get_pointer(p), it);
      node_deallocator.release();
      return (p);
   }

   NodePtr create_node()
   {
      NodePtr p = this->allocate_one();
      Deallocator node_deallocator(p, *this);
      self_t::construct(p);
      node_deallocator.release();
      return (p);
   }

   void destroy_node(NodePtr node)
   {
      self_t::destroy(node);
      this->deallocate_one(node);
   }

   void swap(node_alloc_holder &x)
   {
      NodeAlloc& this_alloc   = static_cast<NodeAlloc&>(*this);
      NodeAlloc& other_alloc  = static_cast<NodeAlloc&>(x);

      if (this_alloc != other_alloc){
         detail::do_swap(this_alloc, other_alloc);
      }

      this->m_icont.swap(x.m_icont);
   }

   template<class FwdIterator, class MultiAllocator>
   FwdIterator allocate_many_and_construct
      (FwdIterator beg, difference_type n, MultiAllocator &multi_beg, size_type 
&constructed)
   {
      typedef typename NodeAlloc::multiallocation_iterator 
multiallocation_iterator;

      //Try to allocate memory in a single chunk
      MultiAllocator itbeg = NodeAlloc::allocate_individual(1, n, constructed), 
itend, it;

      //Prepare exception-safety machinery
      detail::multiallocation_deallocator<NodeAlloc> multi_deallocator(itbeg, 
*this);

      //Initialize all the data (this can throw)
      FwdIterator next = 
         boost::interprocess::n_uninitialized_copy_n(beg, constructed, itbeg);

      //Exception-unsafe zone passed. Disable auto-deallocation
      multi_deallocator.release();
      multi_beg = itbeg;
      return next;
   }

   protected:
   struct cloner
   {
      cloner(node_alloc_holder &holder)
         :  m_holder(holder)
      {}

      NodePtr operator()(const Node &other) const
      {  return m_holder.create_node(other.m_data);  }

      node_alloc_holder &m_holder;
   };

   struct destroyer
   {
      destroyer(node_alloc_holder &holder)
         :  m_holder(holder)
      {}

      void operator()(NodePtr n) const
      {  m_holder.destroy_node(n);  }

      node_alloc_holder &m_holder;
   };

   //The intrusive container
   ICont m_icont;

   ICont &non_const_icont() const
   {  return const_cast<ICont&>(this->m_icont);   }
};

}  //namespace detail {
}  //namespace interprocess {
}  //namespace boost {

#include <boost/interprocess/detail/config_end.hpp>

#endif // BOOST_INTERPROCESS_DETAIL_NODE_ALLOC_HPP_

Index: tree.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/interprocess/containers/detail/tree.hpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- tree.hpp    23 Jun 2007 12:53:54 -0000      1.4
+++ tree.hpp    22 Jul 2007 14:05:56 -0000      1.5
@@ -47,14 +47,18 @@
 
 #include <boost/interprocess/detail/move.hpp>
 #include <boost/interprocess/detail/utilities.hpp>
+#include <boost/interprocess/detail/algorithms.hpp>
 #include <boost/type_traits/has_trivial_destructor.hpp>
 #include <boost/detail/no_exceptions_support.hpp>
+#include <boost/interprocess/containers/detail/node_alloc_holder.hpp>
 #include <boost/intrusive/rbtree.hpp>
 
 #include <iterator>
 #include <algorithm>
 
-namespace boost { namespace interprocess { namespace detail {
+namespace boost {
+namespace interprocess {
+namespace detail {
 
 template<class Key, class Value, class KeyCompare, class KeyOfValue>
 struct value_compare_impl
@@ -90,10 +94,12 @@
    typedef boost::intrusive::set_base_hook
          < boost::intrusive::tag
          , boost::intrusive::safe_link
-         , VoidPointer>   IrbtreeData;
+         , VoidPointer>   hook_type;
 
    typedef T value_type;
 
+   typedef rbtree_node<T, VoidPointer> node_type;
+
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    template<class Convertible>
    rbtree_node(const Convertible &conv)
@@ -120,208 +126,122 @@
    template<class V>
    void do_assign(const V &v)
    {  m_data = v; }
-};
-
-template<class A, class ValueCompare>
-struct rbtree_alloc
-   :  public A::template rebind<rbtree_node
-            < typename A::value_type
-            , typename detail::pointer_to_other<typename A::pointer, 
void>::type>
-            >::other
-{
-   typedef rbtree_alloc<A, ValueCompare> self_t;
-   typedef typename A::value_type                     value_type;
-   typedef rbtree_node
-      <typename A::value_type
-      ,typename detail::pointer_to_other
-         <typename A::pointer, void>::type>           Node;
-   typedef typename A::template rebind<Node>::other   NodeAlloc;
-   typedef typename detail::pointer_to_other
-         <typename A::pointer, void>::type            VoidPointer;
-   typedef A                                          ValAlloc;
-   typedef typename NodeAlloc::pointer                NodePtr;
-   typedef detail::scoped_deallocator<NodeAlloc>      Deallocator;
-
-   struct node_compare
-      :  private ValueCompare
-   {
-      typedef typename ValueCompare::key_type     key_type;
-      typedef typename ValueCompare::value_type   value_type;
-      typedef typename ValueCompare::key_of_value key_of_value;
-
-      node_compare(ValueCompare pred)
-         :  ValueCompare(pred)
-      {}
-
-      ValueCompare &value_comp()
-      {  return static_cast<ValueCompare &>(*this);  }
-
-      ValueCompare &value_comp() const
-      {  return static_cast<const ValueCompare &>(*this);  }
-
-      bool operator()(const Node &a, const Node &b) const
-      {  return ValueCompare::operator()(a.m_data, b.m_data);  }
-   };
-
-   //The intrusive rbtree
-   typedef typename boost::intrusive::rbtree
-      <typename Node::IrbtreeData::template value_traits<Node>
-      ,node_compare
-      ,boost::intrusive::safe_link
-      ,typename A::size_type> Irbtree;
-
-   rbtree_alloc(const ValAlloc &a, const ValueCompare &c) 
-      : NodeAlloc(a), m_irbtree(node_compare(c))
-   {}
-
-   #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
-   rbtree_alloc(const detail::moved_object<ValAlloc> &a, const ValueCompare 
&c) 
-      : NodeAlloc(a.get()), m_irbtree(node_compare(c))
-   {}
-   #else
-   rbtree_alloc(ValAlloc &&a, const ValueCompare &c) 
-      : NodeAlloc(a), m_irbtree(node_compare(c))
-   {}
-   #endif
-
-   rbtree_alloc(const rbtree_alloc &other, const ValueCompare &c)
-      : NodeAlloc(other), m_irbtree(node_compare(c))
-   {}
-
-   #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
-   rbtree_alloc
-      (const detail::moved_object<rbtree_alloc> &other, const ValueCompare &c)
-      : NodeAlloc(move((NodeAlloc&)other.get())), m_irbtree(node_compare(c))
-   {  this->swap(other.get());  }
-   #else
-   rbtree_alloc(rbtree_alloc &&other, const ValueCompare &c)
-      : NodeAlloc(move((NodeAlloc&)other)), m_irbtree(node_compare(c))
-   {  this->swap(other);  }
-   #endif
-
-   ~rbtree_alloc()
-   {}
-
-   typename NodeAlloc::size_type max_size() const
-   {  return NodeAlloc::max_size();  }
 
+   public:
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    template<class Convertible>
-   static void construct(const NodePtr &ptr, const Convertible &value)
-   {  new(detail::get_pointer(ptr)) Node(value);  }
+   static void construct(node_type *ptr, const Convertible &value)
+   {  new(ptr) node_type(value);  }
    #else
    template<class Convertible>
-   static void construct(const NodePtr &ptr, Convertible &&value)
-   {  new(detail::get_pointer(ptr)) Node(forward<Convertible>(value));  }
+   static void construct(node_type *ptr, Convertible &&value)
+   {  new(ptr) node_type(forward<Convertible>(value));  }
    #endif
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    template<class Convertible1, class Convertible2>
-   static void construct(const NodePtr &ptr, 
+   static void construct(node_type *ptr, 
                          const detail::moved_object<std::pair<Convertible1, 
Convertible2> > &value)
    {  
       //std::pair is not movable so we define our own type and overwrite it
-      typedef detail::pair<typename Node::value_type::first_type
-                          ,typename Node::value_type::second_type> hack_pair_t;
+      typedef detail::pair<typename node_type::value_type::first_type
+                          ,typename node_type::value_type::second_type> 
hack_pair_t;
 
       typedef rbtree_node<hack_pair_t, VoidPointer>  hack_node_t;
 
-      new((void*)detail::get_pointer(ptr)) hack_node_t(value);  
+      new((void*)ptr) hack_node_t(value);  
    }
    #else
    template<class Convertible1, class Convertible2>
-   static void construct(const NodePtr &ptr, 
+   static void construct(node_type *ptr, 
                          std::pair<Convertible1, Convertible2> &&value)
    {  
       //std::pair is not movable so we define our own type and overwrite it
-      typedef detail::pair<typename Node::value_type::first_type
-                          ,typename Node::value_type::second_type> hack_pair_t;
+      typedef detail::pair<typename node_type::value_type::first_type
+                          ,typename node_type::value_type::second_type> 
hack_pair_t;
 
       typedef rbtree_node<hack_pair_t, VoidPointer>  hack_node_t;
 
-      new((void*)detail::get_pointer(ptr)) hack_node_t(value);  
-   }
-   #endif
-
-   static void destroy(const NodePtr &ptr)
-   {  detail::get_pointer(ptr)->~Node();  }
-
-   #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
-   template<class Convertible>
-   NodePtr create_node(const Convertible& x)
-   {
-      NodePtr p = NodeAlloc::allocate(1);
-      Deallocator node_deallocator(p, *this);
-      self_t::construct(p, x);
-      node_deallocator.release();
-      return (p);
-   }
-   #else
-   template<class Convertible>
-   NodePtr create_node(Convertible &&x)
-   {
-      NodePtr p = NodeAlloc::allocate(1);
-      Deallocator node_deallocator(p, *this);
-      self_t::construct(p, forward<Convertible>(x));
-      node_deallocator.release();
-      return (p);
+      new((void*)ptr) hack_node_t(value);  
    }
    #endif
+};
 
-   void destroy_node(NodePtr node)
-   {
-      self_t::destroy(node);
-      NodeAlloc::deallocate(node, 1);
-   }
-
-   void swap(rbtree_alloc &x)
-   {
-      NodeAlloc& this_alloc   = static_cast<NodeAlloc&>(*this);
-      NodeAlloc& other_alloc  = static_cast<NodeAlloc&>(x);
-
-      if (this_alloc != other_alloc){
-         detail::do_swap(this_alloc, other_alloc);
-      }
-
-      this->m_irbtree.swap(x.m_irbtree);
-   }
+template<class A, class ValueCompare>
+struct intrusive_rbtree_type
+{
+   typedef typename A::value_type                  value_type;
+   typedef typename detail::pointer_to_other
+      <typename A::pointer, void>::type            void_pointer;
+   typedef typename detail::rbtree_node
+         <value_type, void_pointer>                node_type;
+   typedef node_compare<ValueCompare, node_type>   node_compare_type;
 
-   protected:
-   struct cloner
-   {
-      cloner(rbtree_alloc &holder)
-         :  m_holder(holder)
-      {}
+   typedef typename boost::intrusive::rbtree
+      <typename node_type::hook_type::
+            template value_traits<node_type>
+      ,node_compare_type
+      ,boost::intrusive::safe_link
+      ,typename A::size_type>                      container_type;
 
-      NodePtr operator()(const Node &other) const
-      {  return m_holder.create_node(other.m_data);  }
+   typedef container_type                          type ;
+};
 
-      rbtree_alloc &m_holder;
-   };
+}  //namespace detail {
 
-   struct destroyer
-   {
-      destroyer(rbtree_alloc &holder)
-         :  m_holder(holder)
-      {}
+//This specialization is necessary since std::pair is not movable.
+//We need to hack the constructor to add move semantics
+//to rbtrees
+template<class T, class VoidPointer, class InpIt>
+inline void construct_in_place(detail::rbtree_node<T, VoidPointer>* dest, 
InpIt source)
+{
+   detail::rbtree_node<T, VoidPointer>::construct(dest, *source);
+}
 
-      void operator()(NodePtr n) const
-      {  m_holder.destroy_node(n);  }
+namespace detail {
 
-      rbtree_alloc &m_holder;
-   };
+template <class Key, class Value, class KeyOfValue, 
+          class KeyCompare, class A>
+class rbtree
+   : protected detail::node_alloc_holder
+      <A, typename detail::intrusive_rbtree_type
+         <A, value_compare_impl<Key, Value, KeyCompare, KeyOfValue>  
+         >::type
+      >
+{
+   typedef typename detail::intrusive_rbtree_type
+         <A, value_compare_impl
+            <Key, Value, KeyCompare, KeyOfValue>
+         >::type                                      Icont;
+   typedef detail::node_alloc_holder<A, Icont>        AllocHolder;
+   typedef typename AllocHolder::NodePtr              NodePtr;
+   typedef rbtree < Key, Value, KeyOfValue
+                  , KeyCompare, A>                    ThisType;
+   typedef typename AllocHolder::NodeAlloc            NodeAlloc;
+   typedef typename AllocHolder::ValAlloc             ValAlloc;
+   typedef typename AllocHolder::Node                 Node;
+   typedef typename Icont::iterator                   iiterator;
+   typedef typename Icont::const_iterator             iconst_iterator;
+   typedef detail::allocator_destroyer<NodeAlloc>     Destroyer;
+   typedef typename AllocHolder::allocator_v1         allocator_v1;
+   typedef typename AllocHolder::allocator_v2         allocator_v2;
+   typedef typename AllocHolder::alloc_version        alloc_version;
 
-   struct recycling_cloner
+   class RecyclingCloner;
+   friend class RecyclingCloner;
+   
+   class RecyclingCloner
    {
-      recycling_cloner(rbtree_alloc &holder, Irbtree &irbtree)
-         :  m_holder(holder), m_irbtree(irbtree)
+      public:
+      RecyclingCloner(AllocHolder &holder, Icont &irbtree)
+         :  m_holder(holder), m_icont(irbtree)
       {}
 
       NodePtr operator()(const Node &other) const
       {
-         if(!m_irbtree.empty()){
+         if(!m_icont.empty()){
             //First recycle a node (this can't throw)
-            NodePtr p = m_irbtree.unlink_leftmost_without_rebalance();
+            NodePtr p = m_icont.unlink_leftmost_without_rebalance();
             try{
                //This can throw
                *p = other;
@@ -330,7 +250,7 @@
             catch(...){
                //If there is an exception destroy the whole source
                m_holder.destroy_node(p);
-               while((p = m_irbtree.unlink_leftmost_without_rebalance())){
+               while((p = m_icont.unlink_leftmost_without_rebalance())){
                   m_holder.destroy_node(p);
                }
                throw;
@@ -341,37 +261,10 @@
          }
       }
 
-      rbtree_alloc &m_holder;
-      Irbtree &m_irbtree;
+      AllocHolder &m_holder;
+      Icont &m_icont;
    };
 
-   Irbtree m_irbtree;
-
-   Irbtree &non_const_irbtree() const
-   {  return const_cast<Irbtree&>(this->m_irbtree);   }
-};
-
-template <class Key, class Value, class KeyOfValue, 
-          class KeyCompare, class A>
-class rbtree
-   : protected detail::rbtree_alloc
-      <A, value_compare_impl<Key, Value, KeyCompare, KeyOfValue> >
-{
-   typedef detail::rbtree_alloc
-      < A, value_compare_impl<Key, Value
-      , KeyCompare, KeyOfValue> >                        AllocHolder;
-   typedef typename AllocHolder::NodePtr                 NodePtr;
-   typedef rbtree < Key, Value, KeyOfValue
-                  , KeyCompare, A>                       ThisType;
-   typedef typename AllocHolder::NodeAlloc               NodeAlloc;
-   typedef typename AllocHolder::ValAlloc                ValAlloc;
-   typedef typename AllocHolder::Node                    Node;
-   typedef typename AllocHolder::Irbtree                 Irbtree;
-   typedef typename Irbtree::iterator                    iiterator;
-   typedef typename Irbtree::const_iterator              iconst_iterator;
-   typedef typename AllocHolder::destroyer               Destroyer;
-   typedef typename AllocHolder::recycling_cloner        RecyclingCloner;
-
    public:
    typedef Key                                        key_type;
    typedef Value                                      value_type;
@@ -390,6 +283,7 @@
    typedef const_pointer                              rbtree_const_pointer;
    typedef reference                                  rbtree_reference;
    typedef const_reference                            rbtree_const_reference;
+   typedef NodeAlloc                                  stored_allocator_type;
 
    private:
 
@@ -421,7 +315,7 @@
          , rbtree_const_pointer  , rbtree_const_reference>
    {
       protected:
-      typedef typename Irbtree::iterator  iiterator;
+      typedef typename Icont::iterator  iiterator;
       iiterator m_it;
       explicit const_iterator(iiterator it)  : m_it(it){}
       void prot_incr() { ++m_it; }
@@ -518,24 +412,15 @@
           const allocator_type& a, bool unique_insertion)
       : AllocHolder(a, comp)
    {
-      iterator end_it(this->end());
-      if(unique_insertion){
-         for(; first != last; ++first){
-            this->insert_unique(end_it, *first);
-         }
-      }
-      else{
-         for(; first != last; ++first){
-            this->insert_equal(end_it, *first);
-         }
-      }
+      typedef typename std::iterator_traits<InputIterator>::iterator_category 
ItCat;
+      priv_create_and_insert_nodes(first, last, unique_insertion, 
alloc_version(), ItCat());
    }
 
    rbtree(const rbtree& x) 
       :  AllocHolder(x, x.key_comp())
    {
-      this->m_irbtree.clone_from
-         (x.m_irbtree, typename AllocHolder::cloner(*this), Destroyer(*this));
+      this->m_icont.clone_from
+         (x.m_icont, typename AllocHolder::cloner(*this), Destroyer(*this));
    }
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
@@ -557,12 +442,12 @@
          //Transfer all the nodes to a temporary tree
          //If anything goes wrong, all the nodes will be destroyed
          //automatically
-         Irbtree other_tree(this->m_irbtree.value_comp());
-         other_tree.swap(this->m_irbtree);
+         Icont other_tree(this->m_icont.value_comp());
+         other_tree.swap(this->m_icont);
 
          //Now recreate the source tree reusing nodes stored by other_tree
-         this->m_irbtree.clone_from
-            (x.m_irbtree, RecyclingCloner(*this, other_tree), 
Destroyer(*this));
+         this->m_icont.clone_from
+            (x.m_icont, RecyclingCloner(*this, other_tree), Destroyer(*this));
 
          //If there are remaining nodes, destroy them
          NodePtr p;
@@ -584,25 +469,31 @@
    public:    
    // accessors:
    value_compare value_comp() const 
-   {  return this->m_irbtree.value_comp().value_comp(); }
+   {  return this->m_icont.value_comp().value_comp(); }
 
    key_compare key_comp() const 
-   {  return this->m_irbtree.value_comp().value_comp().key_comp(); }
+   {  return this->m_icont.value_comp().value_comp().key_comp(); }
 
    allocator_type get_allocator() const 
    {  return allocator_type(*this); }
 
+   const stored_allocator_type &get_stored_allocator() const 
+   {  return static_cast<const stored_allocator_type &>(*this); }
+
+   stored_allocator_type &get_stored_allocator()
+   {  return static_cast<stored_allocator_type&>(*this); }
+
    iterator begin()
-   { return iterator(this->m_irbtree.begin()); }
+   { return iterator(this->m_icont.begin()); }
 
    const_iterator begin() const
-   {  return const_iterator(this->non_const_irbtree().begin());   }
+   {  return const_iterator(this->non_const_icont().begin());   }
 
    iterator end()
-   {  return iterator(this->m_irbtree.end());  }
+   {  return iterator(this->m_icont.end());  }
 
    const_iterator end() const
-   {  return const_iterator(this->non_const_irbtree().end());  }
+   {  return const_iterator(this->non_const_icont().end());  }
 
    reverse_iterator rbegin()
    {  return reverse_iterator(end());  }
@@ -620,7 +511,7 @@
    {  return !this->size();  }
 
    size_type size() const 
-   {  return this->m_irbtree.size();   }
+   {  return this->m_icont.size();   }
 
    size_type max_size() const 
    {  return AllocHolder::max_size();  }
@@ -638,14 +529,14 @@
 
    public:
 
-   typedef typename Irbtree::insert_commit_data insert_commit_data;
+   typedef typename Icont::insert_commit_data insert_commit_data;
 
    // insert/erase
    std::pair<iterator,bool> insert_unique_check
       (const key_type& key, insert_commit_data &data)
    {
       std::pair<iiterator, bool> ret = 
-         this->m_irbtree.insert_unique_check(key, 
KeyNodeCompare(value_comp()), data);
+         this->m_icont.insert_unique_check(key, KeyNodeCompare(value_comp()), 
data);
       return std::pair<iterator, bool>(iterator(ret.first), ret.second);
    }
 
@@ -653,14 +544,14 @@
       (const_iterator hint, const key_type& key, insert_commit_data &data)
    {
       std::pair<iiterator, bool> ret = 
-         this->m_irbtree.insert_unique_check(hint.get(), key, 
KeyNodeCompare(value_comp()), data);
+         this->m_icont.insert_unique_check(hint.get(), key, 
KeyNodeCompare(value_comp()), data);
       return std::pair<iterator, bool>(iterator(ret.first), ret.second);
    }
 
    iterator insert_unique_commit(const value_type& v, insert_commit_data &data)
    {
       NodePtr tmp = AllocHolder::create_node(v);
-      iiterator it(this->m_irbtree.insert_unique_commit(*tmp, data));
+      iiterator it(this->m_icont.insert_unique_commit(*tmp, data));
       return iterator(it);
    }
 
@@ -670,7 +561,7 @@
       (const detail::moved_object<MovableConvertible>& mv, insert_commit_data 
&data)
    {
       NodePtr tmp = AllocHolder::create_node(mv);
-      iiterator it(this->m_irbtree.insert_unique_commit(*tmp, data));
+      iiterator it(this->m_icont.insert_unique_commit(*tmp, data));
       return iterator(it);
    }
    #else
@@ -679,7 +570,7 @@
       (MovableConvertible && mv, insert_commit_data &data)
    {
       NodePtr tmp = AllocHolder::create_node(forward<MovableConvertible>(mv));
-      iiterator it(this->m_irbtree.insert_unique_commit(*tmp, data));
+      iiterator it(this->m_icont.insert_unique_commit(*tmp, data));
       return iterator(it);
    }
    #endif
@@ -777,7 +668,7 @@
    iterator insert_equal(const value_type& v)
    {
       NodePtr p(AllocHolder::create_node(v));
-      return iterator(this->m_irbtree.insert_equal_upper_bound(*p));
+      return iterator(this->m_icont.insert_equal_upper_bound(*p));
    }
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
@@ -785,21 +676,21 @@
    iterator insert_equal(const detail::moved_object<MovableConvertible> &mv)
    {
       NodePtr p(AllocHolder::create_node(mv));
-      return iterator(this->m_irbtree.insert_equal_upper_bound(*p));
+      return iterator(this->m_icont.insert_equal_upper_bound(*p));
    }
    #else
    template<class MovableConvertible>
    iterator insert_equal(MovableConvertible &&mv)
    {
       NodePtr p(AllocHolder::create_node(forward<MovableConvertible>(mv)));
-      return iterator(this->m_irbtree.insert_equal_upper_bound(*p));
+      return iterator(this->m_icont.insert_equal_upper_bound(*p));
    }
    #endif
 
    iterator insert_equal(const_iterator hint, const value_type& v)
    {
       NodePtr p(AllocHolder::create_node(v));
-      return iterator(this->m_irbtree.insert_equal(hint.get(), *p));
+      return iterator(this->m_icont.insert_equal(hint.get(), *p));
    }
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
@@ -807,14 +698,14 @@
    iterator insert_equal(const_iterator hint, const 
detail::moved_object<MovableConvertible> &mv)
    {
       NodePtr p(AllocHolder::create_node(mv));
-      return iterator(this->m_irbtree.insert_equal(hint.get(), *p));
+      return iterator(this->m_icont.insert_equal(hint.get(), *p));
    }
    #else
    template<class MovableConvertible>
    iterator insert_equal(const_iterator hint, MovableConvertible &&mv)
    {
       NodePtr p(AllocHolder::create_node(move(mv)));
-      return iterator(this->m_irbtree.insert_equal(hint.get(), *p));
+      return iterator(this->m_icont.insert_equal(hint.get(), *p));
    }
    #endif
 
@@ -835,53 +726,122 @@
    }
 
    iterator erase(const_iterator position)
-   {  return iterator(this->m_irbtree.erase_and_dispose(position.get(), 
Destroyer(*this))); }
+   {  return iterator(this->m_icont.erase_and_dispose(position.get(), 
Destroyer(*this))); }
 
    size_type erase(const key_type& k)
-   {  return this->m_irbtree.erase_and_dispose(k, 
KeyNodeCompare(value_comp()), Destroyer(*this)); }
+   {  return this->m_icont.erase_and_dispose(k, KeyNodeCompare(value_comp()), 
Destroyer(*this)); }
 
    iterator erase(const_iterator first, const_iterator last)
-   {  return iterator(this->m_irbtree.erase_and_dispose(first.get(), 
last.get(), Destroyer(*this))); }
+   {  return iterator(this->m_icont.erase_and_dispose(first.get(), last.get(), 
Destroyer(*this))); }
 
    void clear() 
-   {  this->m_irbtree.clear_and_dispose(Destroyer(*this)); }
+   {  this->m_icont.clear_and_dispose(Destroyer(*this)); }
 
    // set operations:
    iterator find(const key_type& k)
-   {  return iterator(this->m_irbtree.find(k, KeyNodeCompare(value_comp())));  
}
+   {  return iterator(this->m_icont.find(k, KeyNodeCompare(value_comp())));  }
 
    const_iterator find(const key_type& k) const
-   {  return const_iterator(this->non_const_irbtree().find(k, 
KeyNodeCompare(value_comp())));  }
+   {  return const_iterator(this->non_const_icont().find(k, 
KeyNodeCompare(value_comp())));  }
 
    size_type count(const key_type& k) const
-   {  return size_type(this->m_irbtree.count(k, 
KeyNodeCompare(value_comp()))); }
+   {  return size_type(this->m_icont.count(k, KeyNodeCompare(value_comp()))); }
 
    iterator lower_bound(const key_type& k)
-   {  return iterator(this->m_irbtree.lower_bound(k, 
KeyNodeCompare(value_comp())));  }
+   {  return iterator(this->m_icont.lower_bound(k, 
KeyNodeCompare(value_comp())));  }
 
    const_iterator lower_bound(const key_type& k) const
-   {  return const_iterator(this->non_const_irbtree().lower_bound(k, 
KeyNodeCompare(value_comp())));  }
+   {  return const_iterator(this->non_const_icont().lower_bound(k, 
KeyNodeCompare(value_comp())));  }
 
    iterator upper_bound(const key_type& k)
-   {  return iterator(this->m_irbtree.upper_bound(k, 
KeyNodeCompare(value_comp())));   }
+   {  return iterator(this->m_icont.upper_bound(k, 
KeyNodeCompare(value_comp())));   }
 
    const_iterator upper_bound(const key_type& k) const
-   {  return const_iterator(this->non_const_irbtree().upper_bound(k, 
KeyNodeCompare(value_comp())));  }
+   {  return const_iterator(this->non_const_icont().upper_bound(k, 
KeyNodeCompare(value_comp())));  }
 
    std::pair<iterator,iterator> equal_range(const key_type& k)
    {  
       std::pair<iiterator, iiterator> ret =
-         this->m_irbtree.equal_range(k, KeyNodeCompare(value_comp()));
+         this->m_icont.equal_range(k, KeyNodeCompare(value_comp()));
       return std::pair<iterator,iterator>(iterator(ret.first), 
iterator(ret.second));
    }
 
    std::pair<const_iterator, const_iterator> equal_range(const key_type& k) 
const
    {  
       std::pair<iiterator, iiterator> ret =
-         this->non_const_irbtree().equal_range(k, 
KeyNodeCompare(value_comp()));
+         this->non_const_icont().equal_range(k, KeyNodeCompare(value_comp()));
       return std::pair<const_iterator,const_iterator>
          (const_iterator(ret.first), const_iterator(ret.second));
    }
+
+   private:
+   //Iterator range version
+   template<class InpIterator>
+   void priv_create_and_insert_nodes
+      (InpIterator beg, InpIterator end, bool unique)
+   {
+      typedef typename std::iterator_traits<InpIterator>::iterator_category 
ItCat;
+      priv_create_and_insert_nodes(beg, end, unique, alloc_version(), ItCat());
+   }
+
+   template<class InpIterator>
+   void priv_create_and_insert_nodes
+      (InpIterator beg, InpIterator end, bool unique, allocator_v1, 
std::input_iterator_tag)
+   {
+      if(unique){
+         for (; beg != end; ++beg){
+            this->insert_unique(*beg);
+         }
+      }
+      else{
+         for (; beg != end; ++beg){
+            this->insert_equal(*beg);
+         }
+      }
+   }
+
+   template<class InpIterator>
+   void priv_create_and_insert_nodes
+      (InpIterator beg, InpIterator end, bool unique, allocator_v2, 
std::input_iterator_tag)
+   {  //Just forward to the default one
+      priv_create_and_insert_nodes(beg, end, unique, allocator_v1(), 
std::input_iterator_tag());
+   }
+
+   template<class FwdIterator>
+   void priv_create_and_insert_nodes
+      (FwdIterator beg, FwdIterator end, bool unique, allocator_v2, 
std::forward_iterator_tag)
+   {
+      if(unique){
+         priv_create_and_insert_nodes(beg, end, unique, allocator_v2(), 
std::input_iterator_tag());
+      }
+      else{
+         //Optimize memory allocation obtaining the distance between iterators
+         size_type n = std::distance(beg, end);
+
+         //Allocate and construct as many nodes as possible with
+         //the one-shot allocation
+         typedef typename NodeAlloc::multiallocation_iterator 
multiallocation_iterator;
+         multiallocation_iterator many_beg, itend, it;
+         size_type received_array;
+         FwdIterator next = this->allocate_many_and_construct
+            (beg, n, many_beg, received_array);
+
+         detail::multiallocation_destroy_dealloc<NodeAlloc>
+            multi_destroy_dealloc(many_beg, *this);
+
+         //Insert constructed nodes (this does not throw)
+         for (it = many_beg; it != itend; ++it){
+            this->m_icont.insert_equal_upper_bound(*it);
+            multi_destroy_dealloc.next();
+         }
+
+         //Insert remaining nodes using individual allocation
+         //(this can throw, but there is no leak)
+         for (size_type i = received_array; i < n; ++i, ++next){
+            this->insert_equal(*next);
+         }
+      }
+   }
 };
 
 template <class Key, class Value, class KeyOfValue, 
@@ -948,27 +908,28 @@
 
 } //namespace detail {
 
-/*!This class is movable*/
+//!This class is movable
 template <class T, class V, class K, class C, class A>
 struct is_movable<detail::rbtree<T, V, K, C, A> >
 {
    enum {   value = true };
 };
 
-/*!This class is movable*/
+//!This class is movable
 template <class T, class VoidPointer>
 struct is_movable<detail::rbtree_node<T, VoidPointer> >
 {
    enum {   value = true };
 };
 
-/*!This class is movable*/
+//!This class is movable
+/*
 template <class A, class C>
 struct is_movable<detail::rbtree_alloc<A, C> >
 {
    enum {   value = true };
 };
-
+*/
 
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
Boost-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/boost-cvs

Reply via email to