]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/container/detail/node_alloc_holder.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / container / detail / node_alloc_holder.hpp
index ad7b713d6e27c2d1791664b0395a1664adf134a6..a103e63c9a6cb948e710f94a277b3c013051efab 100644 (file)
@@ -52,26 +52,49 @@ namespace boost {
 namespace container {
 namespace dtl {
 
-BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_compare)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(key_compare)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(key_equal)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(hasher)
 BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(predicate_type)
 
 template<class Allocator, class ICont>
 struct node_alloc_holder
+   : public allocator_traits<Allocator>::template
+            portable_rebind_alloc<typename ICont::value_type>::type   //NodeAlloc
 {
    //If the intrusive container is an associative container, obtain the predicate, which will
-   //be of type node_compare<>. If not an associative container value_compare will be a "nat" type.
+   //be of type node_compare<>. If not an associative container val_compare will be a "nat" type.
    typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
       ( boost::container::dtl::
-      , ICont, value_compare, dtl::nat)              intrusive_value_compare;
+      , ICont, key_compare, dtl::nat)                 intrusive_val_compare;
    //In that case obtain the value predicate from the node predicate via predicate_type
-   //if intrusive_value_compare is node_compare<>, nat otherwise
+   //if intrusive_val_compare is node_compare<>, nat otherwise
    typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
       ( boost::container::dtl::
-      , intrusive_value_compare
-      , predicate_type, dtl::nat)                    value_compare;
+      , intrusive_val_compare
+      , predicate_type, dtl::nat)                    val_compare;
+
+   //If the intrusive container is a hash container, obtain the predicate, which will
+   //be of type node_compare<>. If not an associative container val_equal will be a "nat" type.
+   typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
+      (boost::container::dtl::
+         , ICont, key_equal, dtl::nat2)              intrusive_val_equal;
+   typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
+   (boost::container::dtl::
+      , ICont, hasher, dtl::nat3)                     intrusive_val_hasher;
+   //In that case obtain the value predicate from the node predicate via predicate_type
+   //if intrusive_val_compare is node_compare<>, nat otherwise
+   typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
+   (boost::container::dtl::
+      , intrusive_val_equal
+      , predicate_type, dtl::nat2)                    val_equal;
+   typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
+   (boost::container::dtl::
+      , intrusive_val_hasher
+      , predicate_type, dtl::nat3)                    val_hasher;
 
    typedef allocator_traits<Allocator>                            allocator_traits_type;
-   typedef typename allocator_traits_type::value_type             value_type;
+   typedef typename allocator_traits_type::value_type             val_type;
    typedef ICont                                                  intrusive_container;
    typedef typename ICont::value_type                             Node;
    typedef typename allocator_traits_type::template
@@ -99,51 +122,91 @@ struct node_alloc_holder
 
    //Constructors for sequence containers
    node_alloc_holder()
-      : members_()
    {}
 
    explicit node_alloc_holder(const ValAlloc &a)
-      : members_(a)
+      : NodeAlloc(a)
    {}
 
    //Constructors for associative containers
-   node_alloc_holder(const value_compare &c, const ValAlloc &a)
-      : members_(a, c)
+   node_alloc_holder(const val_compare &c, const ValAlloc &a)
+      : NodeAlloc(a), m_icont(typename ICont::key_compare(c))
+   {}
+
+   node_alloc_holder(const val_hasher &hf, const val_equal &eql, const ValAlloc &a)
+      : NodeAlloc(a)
+      , m_icont(typename ICont::bucket_traits()
+         , typename ICont::hasher(hf)
+         , typename ICont::key_equal(eql))
+   {}
+
+   node_alloc_holder(const val_hasher &hf, const ValAlloc &a)
+      : NodeAlloc(a)
+      , m_icont(typename ICont::bucket_traits()
+         , typename ICont::hasher(hf)
+         , typename ICont::key_equal())
+   {}
+
+   node_alloc_holder(const val_hasher &hf)
+      : m_icont(typename ICont::bucket_traits()
+         , typename ICont::hasher(hf)
+         , typename ICont::key_equal())
    {}
 
    explicit node_alloc_holder(const node_alloc_holder &x)
-      : members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()))
+      : NodeAlloc(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()))
    {}
 
-   node_alloc_holder(const node_alloc_holder &x, const value_compare &c)
-      : members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()), c)
+   node_alloc_holder(const node_alloc_holder &x, const val_compare &c)
+      : NodeAlloc(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()))
+      , m_icont(typename ICont::key_compare(c))
+   {}
+
+   node_alloc_holder(const node_alloc_holder &x, const val_hasher &hf, const val_equal &eql)
+      : NodeAlloc(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()))
+      , m_icont( typename ICont::bucket_traits()
+               , typename ICont::hasher(hf)
+               , typename ICont::key_equal(eql))
+   {}
+
+   node_alloc_holder(const val_hasher &hf, const val_equal &eql)
+      : m_icont(typename ICont::bucket_traits()
+         , typename ICont::hasher(hf)
+         , typename ICont::key_equal(eql))
    {}
 
    explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x)
-      : members_(boost::move(x.node_alloc()))
+      : NodeAlloc(boost::move(x.node_alloc()))
    {  this->icont().swap(x.icont());  }
 
-   explicit node_alloc_holder(const value_compare &c)
-      : members_(c)
+   explicit node_alloc_holder(const val_compare &c)
+      : m_icont(typename ICont::key_compare(c))
    {}
 
    //helpers for move assignments
-   explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const value_compare &c)
-      : members_(boost::move(x.node_alloc()), c)
+   explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const val_compare &c)
+      : NodeAlloc(boost::move(x.node_alloc())), m_icont(typename ICont::key_compare(c))
    {  this->icont().swap(x.icont());  }
 
+   explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const val_hasher &hf, const val_equal &eql)
+      : NodeAlloc(boost::move(x.node_alloc()))
+      , m_icont( typename ICont::bucket_traits()
+               , typename ICont::hasher(hf)
+               , typename ICont::key_equal(eql))
+   {  this->icont().swap(x.icont());   }
+
    void copy_assign_alloc(const node_alloc_holder &x)
    {
       dtl::bool_<allocator_traits_type::propagate_on_container_copy_assignment::value> flag;
-      dtl::assign_alloc( static_cast<NodeAlloc &>(this->members_)
-                                    , static_cast<const NodeAlloc &>(x.members_), flag);
+      dtl::assign_alloc( static_cast<NodeAlloc &>(*this)
+                       , static_cast<const NodeAlloc &>(x), flag);
    }
 
    void move_assign_alloc( node_alloc_holder &x)
    {
       dtl::bool_<allocator_traits_type::propagate_on_container_move_assignment::value> flag;
-      dtl::move_alloc( static_cast<NodeAlloc &>(this->members_)
-                                  , static_cast<NodeAlloc &>(x.members_), flag);
+      dtl::move_alloc( static_cast<NodeAlloc &>(*this)
+                     , static_cast<NodeAlloc &>(x), flag);
    }
 
    ~node_alloc_holder()
@@ -164,14 +227,18 @@ struct node_alloc_holder
    NodePtr create_node(Args &&...args)
    {
       NodePtr p = this->allocate_one();
-      Deallocator node_deallocator(p, this->node_alloc());
-      allocator_traits<NodeAlloc>::construct
-         ( this->node_alloc()
-         , dtl::addressof(p->m_data), boost::forward<Args>(args)...);
-      node_deallocator.release();
-      //This does not throw
-      typedef typename Node::hook_type hook_type;
-      ::new(static_cast<hook_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type;
+      BOOST_TRY{
+         ::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) Node;
+         allocator_traits<NodeAlloc>::construct
+            (this->node_alloc()
+            , p->get_real_data_ptr(), boost::forward<Args>(args)...);
+      }
+      BOOST_CATCH(...) {
+         p->destroy_header();
+         this->node_alloc().deallocate(p, 1);
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
       return (p);
    }
 
@@ -182,14 +249,19 @@ struct node_alloc_holder
    NodePtr create_node(BOOST_MOVE_UREF##N)\
    {\
       NodePtr p = this->allocate_one();\
-      Deallocator node_deallocator(p, this->node_alloc());\
-      allocator_traits<NodeAlloc>::construct\
-         ( this->node_alloc()\
-         , dtl::addressof(p->m_data)\
-          BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
-      node_deallocator.release();\
-      typedef typename Node::hook_type hook_type;\
-      ::new(static_cast<hook_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type;\
+      BOOST_TRY{\
+         ::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) Node;\
+         allocator_traits<NodeAlloc>::construct\
+            ( this->node_alloc()\
+            , p->get_real_data_ptr()\
+             BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+      }\
+      BOOST_CATCH(...) {\
+         p->destroy_header();\
+         this->node_alloc().deallocate(p, 1);\
+         BOOST_RETHROW\
+      }\
+      BOOST_CATCH_END\
       return (p);\
    }\
    //
@@ -202,12 +274,16 @@ struct node_alloc_holder
    NodePtr create_node_from_it(const It &it)
    {
       NodePtr p = this->allocate_one();
-      Deallocator node_deallocator(p, this->node_alloc());
-      ::boost::container::construct_in_place(this->node_alloc(), dtl::addressof(p->m_data), it);
-      node_deallocator.release();
-      //This does not throw
-      typedef typename Node::hook_type hook_type;
-      ::new(static_cast<hook_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type;
+      BOOST_TRY{
+         ::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) Node;
+         ::boost::container::construct_in_place(this->node_alloc(), p->get_real_data_ptr(), it);
+      }
+      BOOST_CATCH(...) {
+         p->destroy_header();
+         this->node_alloc().deallocate(p, 1);
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
       return (p);
    }
 
@@ -215,22 +291,26 @@ struct node_alloc_holder
    NodePtr create_node_from_key(BOOST_FWD_REF(KeyConvertible) key)
    {
       NodePtr p = this->allocate_one();
-      NodeAlloc &na = this->node_alloc();
-      Deallocator node_deallocator(p, this->node_alloc());
-      node_allocator_traits_type::construct
-         (na, dtl::addressof(p->m_data.first), boost::forward<KeyConvertible>(key));
       BOOST_TRY{
-         node_allocator_traits_type::construct(na, dtl::addressof(p->m_data.second));
+         ::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) Node;
+         NodeAlloc &na = this->node_alloc();
+         node_allocator_traits_type::construct
+            (na, dtl::addressof(p->get_real_data().first), boost::forward<KeyConvertible>(key));
+         BOOST_TRY{
+            node_allocator_traits_type::construct(na, dtl::addressof(p->get_real_data().second));
+         }
+         BOOST_CATCH(...){
+            node_allocator_traits_type::destroy(na, dtl::addressof(p->get_real_data().first));
+            BOOST_RETHROW;
+         }
+         BOOST_CATCH_END
       }
-      BOOST_CATCH(...){
-         node_allocator_traits_type::destroy(na, dtl::addressof(p->m_data.first));
-         BOOST_RETHROW;
+      BOOST_CATCH(...) {
+         p->destroy_header();
+         this->node_alloc().deallocate(p, 1);
+         BOOST_RETHROW
       }
       BOOST_CATCH_END
-      node_deallocator.release();
-      //This does not throw
-      typedef typename Node::hook_type hook_type;
-      ::new(static_cast<hook_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type;
       return (p);
    }
 
@@ -252,30 +332,32 @@ struct node_alloc_holder
       (FwdIterator beg, difference_type n, Inserter inserter)
    {
       if(n){
-         typedef typename node_allocator_version_traits_type::multiallocation_chain multiallocation_chain;
+         typedef typename node_allocator_version_traits_type::multiallocation_chain multiallocation_chain_t;
 
          //Try to allocate memory in a single block
-         typedef typename multiallocation_chain::iterator multialloc_iterator;
-         multiallocation_chain mem;
+         typedef typename multiallocation_chain_t::iterator multialloc_iterator_t;
+         multiallocation_chain_t chain;
          NodeAlloc &nalloc = this->node_alloc();
-         node_allocator_version_traits_type::allocate_individual(nalloc, n, mem);
-         multialloc_iterator itbeg(mem.begin()), itlast(mem.last());
-         mem.clear();
+         node_allocator_version_traits_type::allocate_individual(nalloc, n, chain);
+         multialloc_iterator_t itbeg  = chain.begin();
+         multialloc_iterator_t itlast = chain.last();
+         chain.clear();
+
          Node *p = 0;
-         BOOST_TRY{
+            BOOST_TRY{
             Deallocator node_deallocator(NodePtr(), nalloc);
             dtl::scoped_destructor<NodeAlloc> sdestructor(nalloc, 0);
-            while(n--){
+            while(n){
+               --n;
                p = boost::movelib::iterator_to_raw_pointer(itbeg);
+               ++itbeg; //Increment iterator before overwriting pointed memory
+               //This does not throw
+               p = ::new(p, boost_container_new_t()) Node;
                node_deallocator.set(p);
-               ++itbeg;
                //This can throw
-               boost::container::construct_in_place(nalloc, dtl::addressof(p->m_data), beg);
+               boost::container::construct_in_place(nalloc, p->get_real_data_ptr(), beg);
                sdestructor.set(p);
                ++beg;
-               //This does not throw
-               typedef typename Node::hook_type hook_type;
-               ::new(static_cast<hook_type*>(p), boost_container_new_t()) hook_type;
                //This can throw in some containers (predicate might throw).
                //(sdestructor will destruct the node and node_deallocator will deallocate it in case of exception)
                inserter(*p);
@@ -285,8 +367,9 @@ struct node_alloc_holder
             node_deallocator.release();
          }
          BOOST_CATCH(...){
-            mem.incorporate_after(mem.last(), &*itbeg, &*itlast, n);
-            node_allocator_version_traits_type::deallocate_individual(this->node_alloc(), mem);
+            p->destroy_header();
+            chain.incorporate_after(chain.last(), &*itbeg, &*itlast, n);
+            node_allocator_version_traits_type::deallocate_individual(this->node_alloc(), chain);
             BOOST_RETHROW
          }
          BOOST_CATCH_END
@@ -339,7 +422,7 @@ struct node_alloc_holder
       {}
 
       NodePtr operator()(const Node &other) const
-      {  return m_holder.create_node(other.m_data);  }
+      {  return m_holder.create_node(other.get_real_data());  }
 
       node_alloc_holder &m_holder;
    };
@@ -351,63 +434,32 @@ struct node_alloc_holder
       {}
 
       NodePtr operator()(Node &other)
-      {  //Use m_data instead of get_data to allow moving const key in [multi]map
-         return m_holder.create_node(::boost::move(other.m_data));
+      {  //Use get_real_data() instead of get_real_data to allow moving const key in [multi]map
+         return m_holder.create_node(::boost::move(other.get_real_data()));
       }
 
       node_alloc_holder &m_holder;
    };
 
-   struct members_holder
-      :  public NodeAlloc
-   {
-      private:
-      members_holder(const members_holder&);
-      members_holder & operator=(const members_holder&);
-
-      public:
-      members_holder()
-         : NodeAlloc(), m_icont()
-      {}
-
-      template<class ConvertibleToAlloc>
-      explicit members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc)
-         :  NodeAlloc(boost::forward<ConvertibleToAlloc>(c2alloc))
-         , m_icont()
-      {}
-
-      template<class ConvertibleToAlloc>
-      members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc, const value_compare &c)
-         :  NodeAlloc(boost::forward<ConvertibleToAlloc>(c2alloc))
-         , m_icont(typename ICont::key_compare(c))
-      {}
-
-      explicit members_holder(const value_compare &c)
-         : NodeAlloc()
-         , m_icont(typename ICont::key_compare(c))
-      {}
-
-      //The intrusive container
-      ICont m_icont;
-   };
-
    ICont &non_const_icont() const
-   {  return const_cast<ICont&>(this->members_.m_icont);   }
+   {  return const_cast<ICont&>(this->m_icont);   }
 
    NodeAlloc &node_alloc()
-   {  return static_cast<NodeAlloc &>(this->members_);   }
+   {  return static_cast<NodeAlloc &>(*this);   }
 
    const NodeAlloc &node_alloc() const
-   {  return static_cast<const NodeAlloc &>(this->members_);   }
-
-   members_holder members_;
+   {  return static_cast<const NodeAlloc &>(*this);   }
 
    public:
    ICont &icont()
-   {  return this->members_.m_icont;   }
+   {  return this->m_icont;   }
 
    const ICont &icont() const
-   {  return this->members_.m_icont;   }
+   {  return this->m_icont;   }
+
+   private:
+   //The intrusive container
+   ICont m_icont;
 };
 
 }  //namespace dtl {