|
Boost-Commit : |
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);
}
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