Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r80379 - trunk/boost/unordered/detail
From: dnljms_at_[hidden]
Date: 2012-09-03 16:02:11


Author: danieljames
Date: 2012-09-03 16:02:10 EDT (Mon, 03 Sep 2012)
New Revision: 80379
URL: http://svn.boost.org/trac/boost/changeset/80379

Log:
Unordered: Generic copy/move implementation.
Text files modified:
   trunk/boost/unordered/detail/equivalent.hpp | 72 +++------------------------------------
   trunk/boost/unordered/detail/table.hpp | 57 +++++++++++++++++++++++++++++--
   trunk/boost/unordered/detail/unique.hpp | 52 ++--------------------------
   3 files changed, 64 insertions(+), 117 deletions(-)

Modified: trunk/boost/unordered/detail/equivalent.hpp
==============================================================================
--- trunk/boost/unordered/detail/equivalent.hpp (original)
+++ trunk/boost/unordered/detail/equivalent.hpp 2012-09-03 16:02:10 EDT (Mon, 03 Sep 2012)
@@ -710,20 +710,12 @@
         }
 
         ////////////////////////////////////////////////////////////////////////
- // copy_buckets_to
- //
- // Basic exception safety. If an exception is thrown this will
- // leave dst partially filled and the buckets unset.
+ // fill_buckets
 
- static void copy_buckets_to(buckets const& src, buckets& dst)
+ template <class NodeCreator>
+ static void fill_buckets(iterator n, buckets& dst,
+ NodeCreator& creator)
         {
- BOOST_ASSERT(!dst.buckets_);
-
- dst.create_buckets(dst.bucket_count_);
-
- node_constructor a(dst.node_alloc());
-
- iterator n = src.get_start();
             previous_pointer prev = dst.get_previous_start();
 
             while (n.node_) {
@@ -733,10 +725,7 @@
                         static_cast<node_pointer>(n.node_->group_prev_)->next_
                     ));
 
- a.construct_node();
- a.construct_value2(*n);
-
- node_pointer first_node = a.release();
+ node_pointer first_node = creator.create(*n);
                 node_pointer end = first_node;
                 first_node->hash_ = key_hash;
                 prev->next_ = static_cast<link_pointer>(first_node);
@@ -744,56 +733,7 @@
 
                 for (++n; n != group_end; ++n)
                 {
- a.construct_node();
- a.construct_value2(*n);
- end = a.release();
- end->hash_ = key_hash;
- add_after_node(end, first_node);
- ++dst.size_;
- }
-
- prev = place_in_bucket(dst, prev, end);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- // move_buckets_to
- //
- // Basic exception safety. The source nodes are left in an unusable
- // state if an exception throws.
-
- static void move_buckets_to(buckets& src, buckets& dst)
- {
- BOOST_ASSERT(!dst.buckets_);
-
- dst.create_buckets(dst.bucket_count_);
-
- node_constructor a(dst.node_alloc());
-
- iterator n = src.get_start();
- previous_pointer prev = dst.get_previous_start();
-
- while (n.node_) {
- std::size_t key_hash = n.node_->hash_;
- iterator group_end(
- static_cast<node_pointer>(
- static_cast<node_pointer>(n.node_->group_prev_)->next_
- ));
-
- a.construct_node();
- a.construct_value2(boost::move(*n));
-
- node_pointer first_node = a.release();
- node_pointer end = first_node;
- first_node->hash_ = key_hash;
- prev->next_ = static_cast<link_pointer>(first_node);
- ++dst.size_;
-
- for(++n; n != group_end; ++n)
- {
- a.construct_node();
- a.construct_value2(boost::move(*n));
- end = a.release();
+ end = creator.create(*n);
                     end->hash_ = key_hash;
                     add_after_node(end, first_node);
                     ++dst.size_;

Modified: trunk/boost/unordered/detail/table.hpp
==============================================================================
--- trunk/boost/unordered/detail/table.hpp (original)
+++ trunk/boost/unordered/detail/table.hpp 2012-09-03 16:02:10 EDT (Mon, 03 Sep 2012)
@@ -54,6 +54,45 @@
         value_base& operator=(value_base const&);
     };
 
+ template <typename NodeAlloc>
+ struct copy_nodes
+ {
+ typedef boost::unordered::detail::allocator_traits<NodeAlloc>
+ node_allocator_traits;
+
+ node_constructor<NodeAlloc> constructor;
+
+ explicit copy_nodes(NodeAlloc& a) : constructor(a) {}
+
+ typename node_allocator_traits::pointer create(
+ typename node_allocator_traits::value_type::value_type const& v)
+ {
+ constructor.construct_node();
+ constructor.construct_value2(v);
+ return constructor.release();
+ }
+ };
+
+ template <typename NodeAlloc>
+ struct move_nodes
+ {
+ typedef boost::unordered::detail::allocator_traits<NodeAlloc>
+ node_allocator_traits;
+
+ node_constructor<NodeAlloc> constructor;
+
+ explicit move_nodes(NodeAlloc& a) : constructor(a) {}
+
+ typename node_allocator_traits::pointer create(
+ typename node_allocator_traits::value_type::value_type& v)
+ {
+ constructor.construct_node();
+ constructor.construct_value2(boost::move(v));
+ return constructor.release();
+ }
+ };
+
+
     template <typename Types>
     struct table :
         boost::unordered::detail::buckets<
@@ -173,7 +212,9 @@
             max_load_(0)
         {
             if(x.size_) {
- table_impl::copy_buckets_to(x, *this);
+ this->create_buckets(this->bucket_count_);
+ copy_nodes<node_allocator> copy(this->node_alloc());
+ table_impl::fill_buckets(x.get_start(), *this, copy);
                 this->max_load_ = calculate_max_load();
             }
         }
@@ -199,11 +240,15 @@
                 this->move_buckets_from(x);
             }
             else if(x.size_) {
- // Use a temporary table because move_buckets_to leaves the
+ // Use a temporary table because moving the nodes leaves the
                 // source container in a complete mess.
 
                 buckets tmp(x, m);
- table_impl::move_buckets_to(tmp, *this);
+
+ this->create_buckets(this->bucket_count_);
+ move_nodes<node_allocator> move(this->node_alloc());
+ table_impl::fill_buckets(tmp.get_start(), *this, move);
+
                 this->max_load_ = calculate_max_load();
             }
         }
@@ -271,7 +316,11 @@
                     buckets b(this->node_alloc(),
                         x.min_buckets_for_size(x.size_));
                     buckets tmp(x, move_tag());
- table_impl::move_buckets_to(tmp, b);
+
+ b.create_buckets(b.bucket_count_);
+ move_nodes<node_allocator> move(b.node_alloc());
+ table_impl::fill_buckets(tmp.get_start(), b, move);
+
                     b.swap(*this);
                 }
                 else {

Modified: trunk/boost/unordered/detail/unique.hpp
==============================================================================
--- trunk/boost/unordered/detail/unique.hpp (original)
+++ trunk/boost/unordered/detail/unique.hpp 2012-09-03 16:02:10 EDT (Mon, 03 Sep 2012)
@@ -617,58 +617,16 @@
         }
 
         ////////////////////////////////////////////////////////////////////////
- // copy_buckets_to
- //
- // Basic exception safety. If an exception is thrown this will
- // leave dst partially filled and the buckets unset.
+ // fill_buckets
 
- static void copy_buckets_to(buckets const& src, buckets& dst)
+ template <class NodeCreator>
+ static void fill_buckets(iterator n, buckets& dst,
+ NodeCreator& creator)
         {
- BOOST_ASSERT(!dst.buckets_);
-
- dst.create_buckets(dst.bucket_count_);
-
- node_constructor a(dst.node_alloc());
-
- iterator n = src.get_start();
- previous_pointer prev = dst.get_previous_start();
-
- while(n.node_) {
- a.construct_node();
- a.construct_value2(*n);
-
- node_pointer node = a.release();
- node->hash_ = n.node_->hash_;
- prev->next_ = static_cast<link_pointer>(node);
- ++dst.size_;
- ++n;
-
- prev = place_in_bucket(dst, prev);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- // move_buckets_to
- //
- // Basic exception safety. The source nodes are left in an unusable
- // state if an exception throws.
-
- static void move_buckets_to(buckets& src, buckets& dst)
- {
- BOOST_ASSERT(!dst.buckets_);
-
- dst.create_buckets(dst.bucket_count_);
-
- node_constructor a(dst.node_alloc());
-
- iterator n = src.get_start();
             previous_pointer prev = dst.get_previous_start();
 
             while (n.node_) {
- a.construct_node();
- a.construct_value2(boost::move(*n));
-
- node_pointer node = a.release();
+ node_pointer node = creator.create(*n);
                 node->hash_ = n.node_->hash_;
                 prev->next_ = static_cast<link_pointer>(node);
                 ++dst.size_;


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk