$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r84304 - in branches/release/boost/unordered: . detail
From: dnljms_at_[hidden]
Date: 2013-05-16 18:15:42
Author: danieljames
Date: 2013-05-16 18:15:42 EDT (Thu, 16 May 2013)
New Revision: 84304
URL: http://svn.boost.org/trac/boost/changeset/84304
Log:
Merge initial unordered use of noexcept + friends.
Still more to come, hopefully in time for the release.
Properties modified: 
   branches/release/boost/unordered/   (props changed)
Text files modified: 
   branches/release/boost/unordered/detail/buckets.hpp |    85 ++++++++++++++++++++++++++++++++++++--- 
   branches/release/boost/unordered/detail/table.hpp   |    25 ++++-------                             
   branches/release/boost/unordered/unordered_map.hpp  |    72 ++++++++++++++++----------------        
   branches/release/boost/unordered/unordered_set.hpp  |    72 ++++++++++++++++----------------        
   4 files changed, 160 insertions(+), 94 deletions(-)
Modified: branches/release/boost/unordered/detail/buckets.hpp
==============================================================================
--- branches/release/boost/unordered/detail/buckets.hpp	(original)
+++ branches/release/boost/unordered/detail/buckets.hpp	2013-05-16 18:15:42 EDT (Thu, 16 May 2013)
@@ -15,6 +15,8 @@
 #include <boost/unordered/detail/allocate.hpp>
 #include <boost/type_traits/aligned_storage.hpp>
 #include <boost/type_traits/alignment_of.hpp>
+#include <boost/type_traits/is_nothrow_move_constructible.hpp>
+#include <boost/type_traits/is_nothrow_move_assignable.hpp>
 #include <boost/swap.hpp>
 #include <boost/assert.hpp>
 #include <boost/limits.hpp>
@@ -670,12 +672,23 @@
     // atomically assigns the new function objects in a strongly
     // exception safe manner.
 
-    template <class H, class P> class set_hash_functions;
+    template <class H, class P, bool NoThrowMoveAssign>
+    class set_hash_functions;
 
     template <class H, class P>
     class functions
     {
-        friend class boost::unordered::detail::set_hash_functions<H, P>;
+    public:
+        static const bool nothrow_move_assignable =
+                boost::is_nothrow_move_assignable<H>::value &&
+                boost::is_nothrow_move_assignable<P>::value;
+        static const bool nothrow_move_constructible =
+                boost::is_nothrow_move_constructible<H>::value &&
+                boost::is_nothrow_move_constructible<P>::value;
+
+    private:
+        friend class boost::unordered::detail::set_hash_functions<H, P,
+               nothrow_move_assignable>;
         functions& operator=(functions const&);
 
         typedef compressed<H, P> function_pair;
@@ -692,6 +705,11 @@
                 static_cast<void const*>(&funcs_[current_]));
         }
 
+        function_pair& current() {
+            return *static_cast<function_pair*>(
+                static_cast<void*>(&funcs_[current_]));
+        }
+
         void construct(bool which, H const& hf, P const& eq)
         {
             new((void*) &funcs_[which]) function_pair(hf, eq);
@@ -702,6 +720,12 @@
             new((void*) &funcs_[which]) function_pair(f);
         }
         
+        void construct(bool which, function_pair& f,
+                boost::unordered::detail::move_tag m)
+        {
+            new((void*) &funcs_[which]) function_pair(f, m);
+        }
+
         void destroy(bool which)
         {
             boost::unordered::detail::destroy((function_pair*)(&funcs_[which]));
@@ -709,6 +733,9 @@
         
     public:
 
+        typedef boost::unordered::detail::set_hash_functions<H, P,
+                nothrow_move_assignable> set_hash_functions;
+
         functions(H const& hf, P const& eq)
             : current_(false)
         {
@@ -721,6 +748,17 @@
             construct(current_, bf.current());
         }
 
+        functions(functions& bf, boost::unordered::detail::move_tag m)
+            : current_(false)
+        {
+            if (nothrow_move_constructible) {
+                construct(current_, bf.current(), m);
+            }
+            else {
+                construct(current_, bf.current());
+            }
+        }
+
         ~functions() {
             this->destroy(current_);
         }
@@ -733,26 +771,28 @@
             return current().second();
         }
     };
-    
+
     template <class H, class P>
-    class set_hash_functions
+    class set_hash_functions<H, P, false>
     {
         set_hash_functions(set_hash_functions const&);
         set_hash_functions& operator=(set_hash_functions const&);
+
+        typedef functions<H, P> functions_type;
     
-        functions<H,P>& functions_;
+        functions_type& functions_;
         bool tmp_functions_;
 
     public:
 
-        set_hash_functions(functions<H,P>& f, H const& h, P const& p)
+        set_hash_functions(functions_type& f, H const& h, P const& p)
           : functions_(f),
             tmp_functions_(!f.current_)
         {
             f.construct(tmp_functions_, h, p);
         }
 
-        set_hash_functions(functions<H,P>& f, functions<H,P> const& other)
+        set_hash_functions(functions_type& f, functions_type const& other)
           : functions_(f),
             tmp_functions_(!f.current_)
         {
@@ -771,6 +811,37 @@
         }
     };
 
+    template <class H, class P>
+    class set_hash_functions<H, P, true>
+    {
+        set_hash_functions(set_hash_functions const&);
+        set_hash_functions& operator=(set_hash_functions const&);
+
+        typedef functions<H, P> functions_type;
+
+        functions_type& functions_;
+        H hash_;
+        P pred_;
+    
+    public:
+
+        set_hash_functions(functions_type& f, H const& h, P const& p) :
+            functions_(f),
+            hash_(h),
+            pred_(p) {}
+
+        set_hash_functions(functions_type& f, functions_type const& other) :
+            functions_(f),
+            hash_(other.hash_function()),
+            pred_(other.key_eq()) {}
+
+        void commit()
+        {
+            functions_.current().first() = boost::move(hash_);
+            functions_.current().second() = boost::move(pred_);
+        }
+    };
+    
     ////////////////////////////////////////////////////////////////////////////
     // rvalue parameters when type can't be a BOOST_RV_REF(T) parameter
     // e.g. for int
Modified: branches/release/boost/unordered/detail/table.hpp
==============================================================================
--- branches/release/boost/unordered/detail/table.hpp	(original)
+++ branches/release/boost/unordered/detail/table.hpp	2013-05-16 18:15:42 EDT (Thu, 16 May 2013)
@@ -159,6 +159,7 @@
         typedef boost::unordered::detail::functions<
             typename Types::hasher,
             typename Types::key_equal> functions;
+        typedef typename functions::set_hash_functions set_hash_functions;
 
         typedef typename Types::allocator allocator;
         typedef typename boost::unordered::detail::
@@ -363,7 +364,7 @@
         {}
 
         table(table& x, boost::unordered::detail::move_tag m) :
-            functions(x),
+            functions(x, m),
             allocators_(x.allocators_, m),
             bucket_count_(x.bucket_count_),
             size_(x.size_),
@@ -377,8 +378,8 @@
         }
 
         table(table& x, node_allocator const& a,
-                boost::unordered::detail::move_tag) :
-            functions(x),
+                boost::unordered::detail::move_tag m) :
+            functions(x, m),
             allocators_(a, a),
             bucket_count_(x.bucket_count_),
             size_(0),
@@ -469,10 +470,8 @@
         // Only swaps the allocators if propagate_on_container_swap
         void swap(table& x)
         {
-            boost::unordered::detail::set_hash_functions<hasher, key_equal>
-                op1(*this, x);
-            boost::unordered::detail::set_hash_functions<hasher, key_equal>
-                op2(x, *this);
+            set_hash_functions op1(*this, x);
+            set_hash_functions op2(x, *this);
 
             // I think swap can throw if Propagate::value,
             // since the allocators' swap can throw. Not sure though.
@@ -637,8 +636,7 @@
         void assign(table const& x, false_type)
         {
             // Strong exception safety.
-            boost::unordered::detail::set_hash_functions<hasher, key_equal>
-                new_func_this(*this, x);
+            set_hash_functions new_func_this(*this, x);
             new_func_this.commit();
             mlf_ = x.mlf_;
             recalculate_max_load();
@@ -666,8 +664,7 @@
                 assign(x, false_type());
             }
             else {
-                boost::unordered::detail::set_hash_functions<hasher, key_equal>
-                    new_func_this(*this, x);
+                set_hash_functions new_func_this(*this, x);
 
                 // Delete everything with current allocators before assigning
                 // the new ones.
@@ -714,8 +711,7 @@
                 move_assign_no_alloc(x);
             }
             else {
-                boost::unordered::detail::set_hash_functions<hasher, key_equal>
-                    new_func_this(*this, x);
+                set_hash_functions new_func_this(*this, x);
                 new_func_this.commit();
                 mlf_ = x.mlf_;
                 recalculate_max_load();
@@ -740,8 +736,7 @@
         
         void move_assign_no_alloc(table& x)
         {
-            boost::unordered::detail::set_hash_functions<hasher, key_equal>
-                new_func_this(*this, x);
+            set_hash_functions new_func_this(*this, x);
             // No throw from here.
             mlf_ = x.mlf_;
             max_load_ = x.max_load_;
Modified: branches/release/boost/unordered/unordered_map.hpp
==============================================================================
--- branches/release/boost/unordered/unordered_map.hpp	(original)
+++ branches/release/boost/unordered/unordered_map.hpp	2013-05-16 18:15:42 EDT (Thu, 16 May 2013)
@@ -178,53 +178,53 @@
         unordered_map& operator=(std::initializer_list<value_type>);
 #endif
 
-        allocator_type get_allocator() const
+        allocator_type get_allocator() const BOOST_NOEXCEPT
         {
             return table_.node_alloc();
         }
 
         // size and capacity
 
-        bool empty() const
+        bool empty() const BOOST_NOEXCEPT
         {
             return table_.size_ == 0;
         }
 
-        size_type size() const
+        size_type size() const BOOST_NOEXCEPT
         {
             return table_.size_;
         }
 
-        size_type max_size() const;
+        size_type max_size() const BOOST_NOEXCEPT;
 
         // iterators
 
-        iterator begin()
+        iterator begin() BOOST_NOEXCEPT
         {
             return table_.begin();
         }
 
-        const_iterator begin() const
+        const_iterator begin() const BOOST_NOEXCEPT
         {
             return table_.begin();
         }
 
-        iterator end()
+        iterator end() BOOST_NOEXCEPT
         {
             return iterator();
         }
 
-        const_iterator end() const
+        const_iterator end() const BOOST_NOEXCEPT
         {
             return const_iterator();
         }
 
-        const_iterator cbegin() const
+        const_iterator cbegin() const BOOST_NOEXCEPT
         {
             return table_.begin();
         }
 
-        const_iterator cend() const
+        const_iterator cend() const BOOST_NOEXCEPT
         {
             return const_iterator();
         }
@@ -449,12 +449,12 @@
 
         // bucket interface
 
-        size_type bucket_count() const
+        size_type bucket_count() const BOOST_NOEXCEPT
         {
             return table_.bucket_count_;
         }
 
-        size_type max_bucket_count() const
+        size_type max_bucket_count() const BOOST_NOEXCEPT
         {
             return table_.max_bucket_count();
         }
@@ -501,13 +501,13 @@
 
         // hash policy
 
-        float max_load_factor() const
+        float max_load_factor() const BOOST_NOEXCEPT
         {
             return table_.mlf_;
         }
 
-        float load_factor() const;
-        void max_load_factor(float);
+        float load_factor() const BOOST_NOEXCEPT;
+        void max_load_factor(float) BOOST_NOEXCEPT;
         void rehash(size_type);
         void reserve(size_type);
 
@@ -660,53 +660,53 @@
         unordered_multimap& operator=(std::initializer_list<value_type>);
 #endif
 
-        allocator_type get_allocator() const
+        allocator_type get_allocator() const BOOST_NOEXCEPT
         {
             return table_.node_alloc();
         }
 
         // size and capacity
 
-        bool empty() const
+        bool empty() const BOOST_NOEXCEPT
         {
             return table_.size_ == 0;
         }
 
-        size_type size() const
+        size_type size() const BOOST_NOEXCEPT
         {
             return table_.size_;
         }
 
-        size_type max_size() const;
+        size_type max_size() const BOOST_NOEXCEPT;
 
         // iterators
 
-        iterator begin()
+        iterator begin() BOOST_NOEXCEPT
         {
             return table_.begin();
         }
 
-        const_iterator begin() const
+        const_iterator begin() const BOOST_NOEXCEPT
         {
             return table_.begin();
         }
 
-        iterator end()
+        iterator end() BOOST_NOEXCEPT
         {
             return iterator();
         }
 
-        const_iterator end() const
+        const_iterator end() const BOOST_NOEXCEPT
         {
             return const_iterator();
         }
 
-        const_iterator cbegin() const
+        const_iterator cbegin() const BOOST_NOEXCEPT
         {
             return table_.begin();
         }
 
-        const_iterator cend() const
+        const_iterator cend() const BOOST_NOEXCEPT
         {
             return const_iterator();
         }
@@ -927,12 +927,12 @@
 
         // bucket interface
 
-        size_type bucket_count() const
+        size_type bucket_count() const BOOST_NOEXCEPT
         {
             return table_.bucket_count_;
         }
 
-        size_type max_bucket_count() const
+        size_type max_bucket_count() const BOOST_NOEXCEPT
         {
             return table_.max_bucket_count();
         }
@@ -979,13 +979,13 @@
 
         // hash policy
 
-        float max_load_factor() const
+        float max_load_factor() const BOOST_NOEXCEPT
         {
             return table_.mlf_;
         }
 
-        float load_factor() const;
-        void max_load_factor(float);
+        float load_factor() const BOOST_NOEXCEPT;
+        void max_load_factor(float) BOOST_NOEXCEPT;
         void rehash(size_type);
         void reserve(size_type);
 
@@ -1105,7 +1105,7 @@
     // size and capacity
 
     template <class K, class T, class H, class P, class A>
-    std::size_t unordered_map<K,T,H,P,A>::max_size() const
+    std::size_t unordered_map<K,T,H,P,A>::max_size() const BOOST_NOEXCEPT
     {
         return table_.max_size();
     }
@@ -1274,13 +1274,13 @@
     // hash policy
 
     template <class K, class T, class H, class P, class A>
-    float unordered_map<K,T,H,P,A>::load_factor() const
+    float unordered_map<K,T,H,P,A>::load_factor() const BOOST_NOEXCEPT
     {
         return table_.load_factor();
     }
 
     template <class K, class T, class H, class P, class A>
-    void unordered_map<K,T,H,P,A>::max_load_factor(float m)
+    void unordered_map<K,T,H,P,A>::max_load_factor(float m) BOOST_NOEXCEPT
     {
         table_.max_load_factor(m);
     }
@@ -1438,7 +1438,7 @@
     // size and capacity
 
     template <class K, class T, class H, class P, class A>
-    std::size_t unordered_multimap<K,T,H,P,A>::max_size() const
+    std::size_t unordered_multimap<K,T,H,P,A>::max_size() const BOOST_NOEXCEPT
     {
         return table_.max_size();
     }
@@ -1586,13 +1586,13 @@
     // hash policy
 
     template <class K, class T, class H, class P, class A>
-    float unordered_multimap<K,T,H,P,A>::load_factor() const
+    float unordered_multimap<K,T,H,P,A>::load_factor() const BOOST_NOEXCEPT
     {
         return table_.load_factor();
     }
 
     template <class K, class T, class H, class P, class A>
-    void unordered_multimap<K,T,H,P,A>::max_load_factor(float m)
+    void unordered_multimap<K,T,H,P,A>::max_load_factor(float m) BOOST_NOEXCEPT
     {
         table_.max_load_factor(m);
     }
Modified: branches/release/boost/unordered/unordered_set.hpp
==============================================================================
--- branches/release/boost/unordered/unordered_set.hpp	(original)
+++ branches/release/boost/unordered/unordered_set.hpp	2013-05-16 18:15:42 EDT (Thu, 16 May 2013)
@@ -176,53 +176,53 @@
         unordered_set& operator=(std::initializer_list<value_type>);
 #endif
 
-        allocator_type get_allocator() const
+        allocator_type get_allocator() const BOOST_NOEXCEPT
         {
             return table_.node_alloc();
         }
 
         // size and capacity
 
-        bool empty() const
+        bool empty() const BOOST_NOEXCEPT
         {
             return table_.size_ == 0;
         }
 
-        size_type size() const
+        size_type size() const BOOST_NOEXCEPT
         {
             return table_.size_;
         }
 
-        size_type max_size() const;
+        size_type max_size() const BOOST_NOEXCEPT;
 
         // iterators
 
-        iterator begin()
+        iterator begin() BOOST_NOEXCEPT
         {
             return table_.begin();
         }
 
-        const_iterator begin() const
+        const_iterator begin() const BOOST_NOEXCEPT
         {
             return table_.begin();
         }
 
-        iterator end()
+        iterator end() BOOST_NOEXCEPT
         {
             return iterator();
         }
 
-        const_iterator end() const
+        const_iterator end() const BOOST_NOEXCEPT
         {
             return const_iterator();
         }
 
-        const_iterator cbegin() const
+        const_iterator cbegin() const BOOST_NOEXCEPT
         {
             return table_.begin();
         }
 
-        const_iterator cend() const
+        const_iterator cend() const BOOST_NOEXCEPT
         {
             return const_iterator();
         }
@@ -434,12 +434,12 @@
 
         // bucket interface
 
-        size_type bucket_count() const
+        size_type bucket_count() const BOOST_NOEXCEPT
         {
             return table_.bucket_count_;
         }
 
-        size_type max_bucket_count() const
+        size_type max_bucket_count() const BOOST_NOEXCEPT
         {
             return table_.max_bucket_count();
         }
@@ -486,13 +486,13 @@
 
         // hash policy
 
-        float max_load_factor() const
+        float max_load_factor() const BOOST_NOEXCEPT
         {
             return table_.mlf_;
         }
 
-        float load_factor() const;
-        void max_load_factor(float);
+        float load_factor() const BOOST_NOEXCEPT;
+        void max_load_factor(float) BOOST_NOEXCEPT;
         void rehash(size_type);
         void reserve(size_type);
 
@@ -644,53 +644,53 @@
         unordered_multiset& operator=(std::initializer_list<value_type>);
 #endif
 
-        allocator_type get_allocator() const
+        allocator_type get_allocator() const BOOST_NOEXCEPT
         {
             return table_.node_alloc();
         }
 
         // size and capacity
 
-        bool empty() const
+        bool empty() const BOOST_NOEXCEPT
         {
             return table_.size_ == 0;
         }
 
-        size_type size() const
+        size_type size() const BOOST_NOEXCEPT
         {
             return table_.size_;
         }
 
-        size_type max_size() const;
+        size_type max_size() const BOOST_NOEXCEPT;
 
         // iterators
 
-        iterator begin()
+        iterator begin() BOOST_NOEXCEPT
         {
             return iterator(table_.begin());
         }
 
-        const_iterator begin() const
+        const_iterator begin() const BOOST_NOEXCEPT
         {
             return const_iterator(table_.begin());
         }
 
-        iterator end()
+        iterator end() BOOST_NOEXCEPT
         {
             return iterator();
         }
 
-        const_iterator end() const
+        const_iterator end() const BOOST_NOEXCEPT
         {
             return const_iterator();
         }
 
-        const_iterator cbegin() const
+        const_iterator cbegin() const BOOST_NOEXCEPT
         {
             return const_iterator(table_.begin());
         }
 
-        const_iterator cend() const
+        const_iterator cend() const BOOST_NOEXCEPT
         {
             return const_iterator();
         }
@@ -902,12 +902,12 @@
 
         // bucket interface
 
-        size_type bucket_count() const
+        size_type bucket_count() const BOOST_NOEXCEPT
         {
             return table_.bucket_count_;
         }
 
-        size_type max_bucket_count() const
+        size_type max_bucket_count() const BOOST_NOEXCEPT
         {
             return table_.max_bucket_count();
         }
@@ -954,13 +954,13 @@
 
         // hash policy
 
-        float max_load_factor() const
+        float max_load_factor() const BOOST_NOEXCEPT
         {
             return table_.mlf_;
         }
 
-        float load_factor() const;
-        void max_load_factor(float);
+        float load_factor() const BOOST_NOEXCEPT;
+        void max_load_factor(float) BOOST_NOEXCEPT;
         void rehash(size_type);
         void reserve(size_type);
 
@@ -1080,7 +1080,7 @@
     // size and capacity
 
     template <class T, class H, class P, class A>
-    std::size_t unordered_set<T,H,P,A>::max_size() const
+    std::size_t unordered_set<T,H,P,A>::max_size() const BOOST_NOEXCEPT
     {
         return table_.max_size();
     }
@@ -1200,13 +1200,13 @@
     // hash policy
 
     template <class T, class H, class P, class A>
-    float unordered_set<T,H,P,A>::load_factor() const
+    float unordered_set<T,H,P,A>::load_factor() const BOOST_NOEXCEPT
     {
         return table_.load_factor();
     }
 
     template <class T, class H, class P, class A>
-    void unordered_set<T,H,P,A>::max_load_factor(float m)
+    void unordered_set<T,H,P,A>::max_load_factor(float m) BOOST_NOEXCEPT
     {
         table_.max_load_factor(m);
     }
@@ -1364,7 +1364,7 @@
     // size and capacity
 
     template <class T, class H, class P, class A>
-    std::size_t unordered_multiset<T,H,P,A>::max_size() const
+    std::size_t unordered_multiset<T,H,P,A>::max_size() const BOOST_NOEXCEPT
     {
         return table_.max_size();
     }
@@ -1484,13 +1484,13 @@
     // hash policy
 
     template <class T, class H, class P, class A>
-    float unordered_multiset<T,H,P,A>::load_factor() const
+    float unordered_multiset<T,H,P,A>::load_factor() const BOOST_NOEXCEPT
     {
         return table_.load_factor();
     }
 
     template <class T, class H, class P, class A>
-    void unordered_multiset<T,H,P,A>::max_load_factor(float m)
+    void unordered_multiset<T,H,P,A>::max_load_factor(float m) BOOST_NOEXCEPT
     {
         table_.max_load_factor(m);
     }