[libc++] Fix PR22922 - Allocator support for std::function does not know how to rebind.

Summary:
This patch changes std::function to use allocator_traits to rebind the allocator instead of allocator itself.

It also changes most of the tests to use `bare_allocator` where possible instead of `test_allocator`.

Reviewers: mclow.lists

Reviewed By: mclow.lists

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D8391

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@232686 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eric Fiselier 2015-03-18 22:56:50 +00:00
parent 0b6f8ed1c7
commit 71aa376ede
6 changed files with 34 additions and 17 deletions

View File

@ -1367,7 +1367,14 @@ template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
__base<_Rp(_ArgTypes...)>* __base<_Rp(_ArgTypes...)>*
__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const
{ {
typedef typename _Alloc::template rebind<__func>::other _Ap; typedef allocator_traits<_Alloc> __alloc_traits;
typedef typename __alloc_traits::template
#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
rebind_alloc<__func>
#else
rebind_alloc<__func>::other
#endif
_Ap;
_Ap __a(__f_.second()); _Ap __a(__f_.second());
typedef __allocator_destructor<_Ap> _Dp; typedef __allocator_destructor<_Ap> _Dp;
unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
@ -1393,7 +1400,14 @@ template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
void void
__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT
{ {
typedef typename _Alloc::template rebind<__func>::other _Ap; typedef allocator_traits<_Alloc> __alloc_traits;
typedef typename __alloc_traits::template
#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
rebind_alloc<__func>
#else
rebind_alloc<__func>::other
#endif
_Ap;
_Ap __a(__f_.second()); _Ap __a(__f_.second());
__f_.~__compressed_pair<_Fp, _Alloc>(); __f_.~__compressed_pair<_Fp, _Alloc>();
__a.deallocate(this, 1); __a.deallocate(this, 1);

View File

@ -16,10 +16,12 @@
#include <functional> #include <functional>
#include <cassert> #include <cassert>
#include "test_allocator.h" #include "min_allocator.h"
int main() int main()
{ {
std::function<int(int)> f(std::allocator_arg, test_allocator<int>()); {
std::function<int(int)> f(std::allocator_arg, bare_allocator<int>());
assert(!f); assert(!f);
}
} }

View File

@ -16,7 +16,7 @@
#include <functional> #include <functional>
#include <cassert> #include <cassert>
#include "test_allocator.h" #include "min_allocator.h"
class A class A
{ {
@ -57,19 +57,19 @@ public:
int main() int main()
{ {
{ {
std::function<int(int)> f(std::allocator_arg, test_allocator<A>(), A()); std::function<int(int)> f(std::allocator_arg, bare_allocator<A>(), A());
assert(A::count == 1); assert(A::count == 1);
assert(f.target<A>()); assert(f.target<A>());
assert(f.target<int(*)(int)>() == 0); assert(f.target<int(*)(int)>() == 0);
} }
assert(A::count == 0); assert(A::count == 0);
{ {
std::function<int(int)> f(std::allocator_arg, test_allocator<int(*)(int)>(), g); std::function<int(int)> f(std::allocator_arg, bare_allocator<int(*)(int)>(), g);
assert(f.target<int(*)(int)>()); assert(f.target<int(*)(int)>());
assert(f.target<A>() == 0); assert(f.target<A>() == 0);
} }
{ {
std::function<int(int)> f(std::allocator_arg, test_allocator<int(*)(int)>(), std::function<int(int)> f(std::allocator_arg, bare_allocator<int(*)(int)>(),
(int (*)(int))0); (int (*)(int))0);
assert(!f); assert(!f);
assert(f.target<int(*)(int)>() == 0); assert(f.target<int(*)(int)>() == 0);
@ -77,7 +77,7 @@ int main()
} }
{ {
std::function<int(const A*, int)> f(std::allocator_arg, std::function<int(const A*, int)> f(std::allocator_arg,
test_allocator<int(A::*)(int)const>(), bare_allocator<int(A::*)(int)const>(),
&A::foo); &A::foo);
assert(f); assert(f);
assert(f.target<int (A::*)(int) const>() != 0); assert(f.target<int (A::*)(int) const>() != 0);
@ -91,7 +91,7 @@ int main()
#endif #endif
{ {
std::function<void(int)> fun(std::allocator_arg, std::function<void(int)> fun(std::allocator_arg,
test_allocator<int(*)(int)>(), bare_allocator<int(*)(int)>(),
&g); &g);
assert(fun); assert(fun);
assert(fun.target<int(*)(int)>() != 0); assert(fun.target<int(*)(int)>() != 0);

View File

@ -17,6 +17,7 @@
#include <functional> #include <functional>
#include <cassert> #include <cassert>
#include "min_allocator.h"
#include "test_allocator.h" #include "test_allocator.h"
#include "count_new.hpp" #include "count_new.hpp"
@ -58,7 +59,7 @@ int main()
assert(globalMemCounter.checkOutstandingNewEq(1)); assert(globalMemCounter.checkOutstandingNewEq(1));
assert(f.target<A>()); assert(f.target<A>());
assert(f.target<int(*)(int)>() == 0); assert(f.target<int(*)(int)>() == 0);
std::function<int(int)> f2(std::allocator_arg, test_allocator<A>(), f); std::function<int(int)> f2(std::allocator_arg, bare_allocator<A>(), f);
assert(A::count == 2); assert(A::count == 2);
assert(globalMemCounter.checkOutstandingNewEq(2)); assert(globalMemCounter.checkOutstandingNewEq(2));
assert(f2.target<A>()); assert(f2.target<A>());
@ -71,7 +72,7 @@ int main()
assert(globalMemCounter.checkOutstandingNewEq(0)); assert(globalMemCounter.checkOutstandingNewEq(0));
assert(f.target<int(*)(int)>()); assert(f.target<int(*)(int)>());
assert(f.target<A>() == 0); assert(f.target<A>() == 0);
std::function<int(int)> f2(std::allocator_arg, test_allocator<int(*)(int)>(), f); std::function<int(int)> f2(std::allocator_arg, bare_allocator<int(*)(int)>(), f);
assert(globalMemCounter.checkOutstandingNewEq(0)); assert(globalMemCounter.checkOutstandingNewEq(0));
assert(f2.target<int(*)(int)>()); assert(f2.target<int(*)(int)>());
assert(f2.target<A>() == 0); assert(f2.target<A>() == 0);
@ -91,7 +92,7 @@ int main()
assert(globalMemCounter.checkOutstandingNewEq(0)); assert(globalMemCounter.checkOutstandingNewEq(0));
assert(f.target<int(*)(int)>() == 0); assert(f.target<int(*)(int)>() == 0);
assert(f.target<A>() == 0); assert(f.target<A>() == 0);
std::function<int(int)> f2(std::allocator_arg, test_allocator<int>(), f); std::function<int(int)> f2(std::allocator_arg, bare_allocator<int>(), f);
assert(globalMemCounter.checkOutstandingNewEq(0)); assert(globalMemCounter.checkOutstandingNewEq(0));
assert(f2.target<int(*)(int)>() == 0); assert(f2.target<int(*)(int)>() == 0);
assert(f2.target<A>() == 0); assert(f2.target<A>() == 0);

View File

@ -16,10 +16,10 @@
#include <functional> #include <functional>
#include <cassert> #include <cassert>
#include "test_allocator.h" #include "min_allocator.h"
int main() int main()
{ {
std::function<int(int)> f(std::allocator_arg, test_allocator<int>(), nullptr); std::function<int(int)> f(std::allocator_arg, bare_allocator<int>(), nullptr);
assert(!f); assert(!f);
} }

View File

@ -16,7 +16,7 @@
#include <functional> #include <functional>
#include <cassert> #include <cassert>
#include "test_allocator.h" #include "min_allocator.h"
#include "count_new.hpp" #include "count_new.hpp"
class A class A
@ -56,7 +56,7 @@ int main()
assert(globalMemCounter.checkOutstandingNewEq(1)); assert(globalMemCounter.checkOutstandingNewEq(1));
assert(f.target<A>()); assert(f.target<A>());
assert(f.target<int(*)(int)>() == 0); assert(f.target<int(*)(int)>() == 0);
std::function<int(int)> f2(std::allocator_arg, test_allocator<A>(), std::move(f)); std::function<int(int)> f2(std::allocator_arg, bare_allocator<A>(), std::move(f));
assert(A::count == 1); assert(A::count == 1);
assert(globalMemCounter.checkOutstandingNewEq(1)); assert(globalMemCounter.checkOutstandingNewEq(1));
assert(f2.target<A>()); assert(f2.target<A>());