Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r73805 - trunk/boost/unordered/detail
From: dnljms_at_[hidden]
Date: 2011-08-15 17:34:02


Author: danieljames
Date: 2011-08-15 17:34:01 EDT (Mon, 15 Aug 2011)
New Revision: 73805
URL: http://svn.boost.org/trac/boost/changeset/73805

Log:
Unordered: Support moving allocators.
Text files modified:
   trunk/boost/unordered/detail/buckets.hpp | 14 ++---
   trunk/boost/unordered/detail/table.hpp | 4
   trunk/boost/unordered/detail/util.hpp | 99 +++++++++++++++++++++++++++++++++++++++
   3 files changed, 106 insertions(+), 11 deletions(-)

Modified: trunk/boost/unordered/detail/buckets.hpp
==============================================================================
--- trunk/boost/unordered/detail/buckets.hpp (original)
+++ trunk/boost/unordered/detail/buckets.hpp 2011-08-15 17:34:01 EDT (Mon, 15 Aug 2011)
@@ -65,7 +65,7 @@
         bucket_ptr buckets_;
         std::size_t bucket_count_;
         std::size_t size_;
- ::boost::compressed_pair<bucket_allocator, node_allocator> allocators_;
+ compressed_pair<bucket_allocator, node_allocator> allocators_;
         
         // Data access
 
@@ -106,22 +106,20 @@
         {
         }
 
- // TODO: Need to move allocators_, not copy. But compressed_pair
- // doesn't support move parameters.
- buckets(buckets& b, move_tag)
+ buckets(buckets& b, move_tag m)
           : buckets_(),
             bucket_count_(b.bucket_count_),
             size_(),
- allocators_(b.allocators_)
+ allocators_(b.allocators_, m)
         {
             swap(b);
         }
 
         template <typename T>
- buckets(table<T>& x, move_tag)
+ buckets(table<T>& x, move_tag m)
           : buckets_(),
             bucket_count_(x.bucket_count_),
- allocators_(x.allocators_)
+ allocators_(x.allocators_, m)
         {
             swap(x);
             x.size_ = 0;
@@ -424,7 +422,7 @@
         friend class set_hash_functions<H, P>;
         functions& operator=(functions const&);
 
- typedef ::boost::compressed_pair<H, P> function_pair;
+ typedef compressed_pair<H, P> function_pair;
         typedef BOOST_DEDUCED_TYPENAME ::boost::aligned_storage<
             sizeof(function_pair),
             ::boost::alignment_of<function_pair>::value>::type aligned_function;

Modified: trunk/boost/unordered/detail/table.hpp
==============================================================================
--- trunk/boost/unordered/detail/table.hpp (original)
+++ trunk/boost/unordered/detail/table.hpp 2011-08-15 17:34:01 EDT (Mon, 15 Aug 2011)
@@ -245,7 +245,7 @@
             // aren't deleted with the wrong allocator.
             if(this->buckets_) this->delete_buckets();
             // TODO: Can allocator assignment throw?
- this->allocators_ = x.allocators_;
+ this->allocators_.assign(x.allocators_);
             this->swap(tmp, false_type());
         }
 
@@ -259,7 +259,7 @@
         void move_assign(table& x, true_type)
         {
             if(this->buckets_) this->delete_buckets();
- this->allocators_ = x.allocators_; // TODO: Move allocators, not copy.
+ this->allocators_.move_assign(x.allocators_);
             move_assign_no_alloc(x);
         }
 

Modified: trunk/boost/unordered/detail/util.hpp
==============================================================================
--- trunk/boost/unordered/detail/util.hpp (original)
+++ trunk/boost/unordered/detail/util.hpp 2011-08-15 17:34:01 EDT (Mon, 15 Aug 2011)
@@ -19,16 +19,17 @@
 #include <boost/assert.hpp>
 #include <boost/iterator.hpp>
 #include <boost/iterator/iterator_categories.hpp>
-#include <boost/compressed_pair.hpp>
 #include <boost/type_traits/aligned_storage.hpp>
 #include <boost/type_traits/alignment_of.hpp>
 #include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/is_empty.hpp>
 #include <boost/throw_exception.hpp>
 #include <boost/unordered/detail/allocator_helpers.hpp>
 #include <boost/preprocessor/seq/size.hpp>
 #include <boost/preprocessor/seq/enum.hpp>
 #include <boost/preprocessor/repetition/enum.hpp>
 #include <boost/move/move.hpp>
+#include <boost/swap.hpp>
 
 // Template parameters:
 //
@@ -253,6 +254,102 @@
         return (std::max)(static_cast<std::size_t>(insert_size(i, j)) + 1,
             num_buckets);
     }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // compressed_pair
+
+ template <typename T, int Index>
+ struct compressed_base : private T
+ {
+ compressed_base(T const& x) : T(x) {}
+ compressed_base(T& x, move_tag) : T(boost::move(x)) {}
+
+ T& get() { return *this; }
+ T const& get() const { return *this; }
+ };
+
+ template <typename T, int Index>
+ struct uncompressed_base
+ {
+ uncompressed_base(T const& x) : value_(x) {}
+ uncompressed_base(T& x, move_tag) : value_(boost::move(x)) {}
+
+ T& get() { return value_; }
+ T const& get() const { return value_; }
+ private:
+ T value_;
+ };
+
+ template <typename T, int Index>
+ struct generate_base
+ : boost::detail::if_true<
+ boost::is_empty<T>::value
+ >:: BOOST_NESTED_TEMPLATE then<
+ compressed_base<T, Index>,
+ uncompressed_base<T, Index>
+ >
+ {};
+
+ template <typename T1, typename T2>
+ struct compressed_pair
+ : private generate_base<T1, 1>::type,
+ private generate_base<T2, 2>::type
+ {
+ typedef BOOST_DEDUCED_TYPENAME generate_base<T1, 1>::type base1;
+ typedef BOOST_DEDUCED_TYPENAME generate_base<T2, 2>::type base2;
+
+ typedef T1 first_type;
+ typedef T2 second_type;
+
+ first_type& first() {
+ return static_cast<base1*>(this)->get();
+ }
+
+ first_type const& first() const {
+ return static_cast<base1 const*>(this)->get();
+ }
+
+ second_type& second() {
+ return static_cast<base2*>(this)->get();
+ }
+
+ second_type const& second() const {
+ return static_cast<base2 const*>(this)->get();
+ }
+
+ template <typename First, typename Second>
+ compressed_pair(First const& x1, Second const& x2)
+ : base1(x1), base2(x2) {}
+
+ compressed_pair(compressed_pair const& x)
+ : base1(x.first()), base2(x.second()) {}
+
+ compressed_pair(compressed_pair& x, move_tag m)
+ : base1(x.first(), m), base2(x.second(), m) {}
+
+ void assign(compressed_pair const& x)
+ {
+ first() = x.first();
+ second() = x.second();
+ }
+
+ void move_assign(compressed_pair& x)
+ {
+ first() = boost::move(x.first());
+ second() = boost::move(x.second());
+ }
+
+ void swap(compressed_pair& x)
+ {
+ boost::swap(first(), x.first());
+ boost::swap(second(), x.second());
+ }
+
+ private:
+ // Prevent assignment just to make use of assign or
+ // move_assign explicit.
+ compressed_pair& operator=(compressed_pair const&);
+ };
 }}}
 
 #endif


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