Use nothrow move construction for function objects, when available.

[SVN r84277]
This commit is contained in:
Daniel James
2013-05-13 23:13:04 +00:00
parent a422b40041
commit d603e75d03
2 changed files with 31 additions and 9 deletions

View File

@ -678,10 +678,17 @@ namespace boost { namespace unordered { namespace detail {
template <class H, class P> template <class H, class P>
class functions 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<H>::value &&
boost::is_nothrow_move_assignable<P>::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&); functions& operator=(functions const&);
typedef compressed<H, P> function_pair; typedef compressed<H, P> function_pair;
@ -713,6 +720,12 @@ namespace boost { namespace unordered { namespace detail {
new((void*) &funcs_[which]) function_pair(f); 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) void destroy(bool which)
{ {
boost::unordered::detail::destroy((function_pair*)(&funcs_[which])); boost::unordered::detail::destroy((function_pair*)(&funcs_[which]));
@ -721,9 +734,7 @@ namespace boost { namespace unordered { namespace detail {
public: public:
typedef boost::unordered::detail::set_hash_functions<H, P, typedef boost::unordered::detail::set_hash_functions<H, P,
boost::is_nothrow_move_assignable<H>::value && nothrow_move_assignable> set_hash_functions;
boost::is_nothrow_move_assignable<P>::value
> set_hash_functions;
functions(H const& hf, P const& eq) functions(H const& hf, P const& eq)
: current_(false) : current_(false)
@ -737,6 +748,17 @@ namespace boost { namespace unordered { namespace detail {
construct(current_, bf.current()); 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() { ~functions() {
this->destroy(current_); this->destroy(current_);
} }

View File

@ -364,7 +364,7 @@ namespace boost { namespace unordered { namespace detail {
{} {}
table(table& x, boost::unordered::detail::move_tag m) : table(table& x, boost::unordered::detail::move_tag m) :
functions(x), functions(x, m),
allocators_(x.allocators_, m), allocators_(x.allocators_, m),
bucket_count_(x.bucket_count_), bucket_count_(x.bucket_count_),
size_(x.size_), size_(x.size_),
@ -378,8 +378,8 @@ namespace boost { namespace unordered { namespace detail {
} }
table(table& x, node_allocator const& a, table(table& x, node_allocator const& a,
boost::unordered::detail::move_tag) : boost::unordered::detail::move_tag m) :
functions(x), functions(x, m),
allocators_(a, a), allocators_(a, a),
bucket_count_(x.bucket_count_), bucket_count_(x.bucket_count_),
size_(0), size_(0),