$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: daniel_james_at_[hidden]
Date: 2008-04-16 13:36:07
Author: danieljames
Date: 2008-04-16 13:36:06 EDT (Wed, 16 Apr 2008)
New Revision: 44468
URL: http://svn.boost.org/trac/boost/changeset/44468
Log:
Add a C++-0x node_constructor.
Text files modified: 
   branches/unordered/trunk/boost/unordered/detail/hash_table_impl.hpp |   102 +++++++++++++++++++++++++++++++++++++++ 
   1 files changed, 100 insertions(+), 2 deletions(-)
Modified: branches/unordered/trunk/boost/unordered/detail/hash_table_impl.hpp
==============================================================================
--- branches/unordered/trunk/boost/unordered/detail/hash_table_impl.hpp	(original)
+++ branches/unordered/trunk/boost/unordered/detail/hash_table_impl.hpp	2008-04-16 13:36:06 EDT (Wed, 16 Apr 2008)
@@ -113,10 +113,103 @@
                 value_type value_;
             };
 
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+
+            // allocators
+            //
+            // Stores all the allocators that we're going to need.
+
+            struct allocators
+            {
+                node_allocator node_alloc_;
+                bucket_allocator bucket_alloc_;
+
+                allocators(value_allocator const& a)
+                    : node_alloc_(a), bucket_alloc_(a)
+                {}
+
+                void destroy(link_ptr ptr)
+                {
+                    node_ptr n(node_alloc_.address(*static_cast<node*>(&*ptr)));
+                    node_alloc_.destroy(n);
+                    node_alloc_.deallocate(n, 1);
+                }
+
+                void swap(allocators& x)
+                {
+                    unordered_detail::hash_swap(node_alloc_, x.node_alloc_);
+                    unordered_detail::hash_swap(bucket_alloc_, x.bucket_alloc_);
+                }
+
+                bool operator==(allocators const& x)
+                {
+                    return node_alloc_ == x.node_alloc_;
+                }
+            };
+
             // node_constructor
             //
             // Used to construct nodes in an exception safe manner.
 
+            class node_constructor
+            {
+                allocators& allocators_;
+
+                node_ptr node_;
+                bool node_constructed_;
+
+            public:
+
+                node_constructor(allocators& a)
+                    : allocators_(a),
+                    node_(), node_constructed_(false)
+                {
+                }
+
+                ~node_constructor()
+                {
+                    if (node_) {
+                        if (node_constructed_)
+                            allocators_.node_alloc_.destroy(node_);
+                        allocators_.node_alloc_.deallocate(node_, 1);
+                    }
+                }
+
+                template <typename... Args>
+                void construct(Args&&... args)
+                {
+                    BOOST_ASSERT(!node_);
+                    node_constructed_ = false;
+
+                    node_ = allocators_.node_alloc_.allocate(1);
+                    allocators_.node_alloc_.construct(node_, std::forward<Args>(args)...);
+                    node_constructed_ = true;
+                }
+
+                node_ptr get() const
+                {
+                    BOOST_ASSERT(node_);
+                    return node_;
+                }
+
+                // no throw
+                link_ptr release()
+                {
+                    node_ptr p = node_;
+                    unordered_detail::reset(node_);
+                    return link_ptr(allocators_.bucket_alloc_.address(*p));
+                }
+
+            private:
+                node_constructor(node_constructor const&);
+                node_constructor& operator=(node_constructor const&);
+            };
+#else
+
+            // allocators
+            //
+            // Stores all the allocators that we're going to need.
+
             struct allocators
             {
                 node_allocator node_alloc_;
@@ -151,6 +244,10 @@
                 }
             };
 
+            // node_constructor
+            //
+            // Used to construct nodes in an exception safe manner.
+
             class node_constructor
             {
                 allocators& allocators_;
@@ -219,6 +316,7 @@
                 node_constructor(node_constructor const&);
                 node_constructor& operator=(node_constructor const&);
             };
+#endif
 
             // Methods for navigating groups of elements with equal keys.
 
@@ -1232,9 +1330,9 @@
             // accessors
 
             // no throw
-            value_allocator get_allocator() const
+            node_allocator get_allocator() const
             {
-                return data_.allocators_.value_alloc_;
+                return data_.allocators_.node_alloc_;
             }
 
             // no throw