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>
class functions
{
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,
boost::is_nothrow_move_assignable<H>::value &&
boost::is_nothrow_move_assignable<P>::value
>;
nothrow_move_assignable>;
functions& operator=(functions const&);
typedef compressed<H, P> function_pair;
@ -713,6 +720,12 @@ namespace boost { namespace unordered { namespace detail {
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]));
@ -721,9 +734,7 @@ namespace boost { namespace unordered { namespace detail {
public:
typedef boost::unordered::detail::set_hash_functions<H, P,
boost::is_nothrow_move_assignable<H>::value &&
boost::is_nothrow_move_assignable<P>::value
> set_hash_functions;
nothrow_move_assignable> set_hash_functions;
functions(H const& hf, P const& eq)
: current_(false)
@ -737,6 +748,17 @@ namespace boost { namespace unordered { namespace detail {
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_);
}

View File

@ -364,7 +364,7 @@ namespace boost { namespace unordered { namespace detail {
{}
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_),
@ -378,8 +378,8 @@ namespace boost { namespace unordered { namespace detail {
}
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),