From 6d370568c3239568f9ba375f521ea84315abace7 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Wed, 18 Mar 2015 22:56:50 +0000 Subject: [PATCH] [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 llvm-svn: 232686 --- libcxx/include/functional | 18 ++++++++++++++++-- .../func.wrap.func/func.wrap.func.con/alloc.pass.cpp | 6 ++++-- .../func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp | 12 ++++++------ .../func.wrap.func.con/alloc_function.pass.cpp | 7 ++++--- .../func.wrap.func.con/alloc_nullptr.pass.cpp | 4 ++-- .../func.wrap.func.con/alloc_rfunction.pass.cpp | 4 ++-- 6 files changed, 34 insertions(+), 17 deletions(-) diff --git a/libcxx/include/functional b/libcxx/include/functional index 070347a..35e661b 100644 --- a/libcxx/include/functional +++ b/libcxx/include/functional @@ -1367,7 +1367,14 @@ template __base<_Rp(_ArgTypes...)>* __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()); typedef __allocator_destructor<_Ap> _Dp; unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); @@ -1393,7 +1400,14 @@ template void __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()); __f_.~__compressed_pair<_Fp, _Alloc>(); __a.deallocate(this, 1); diff --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp index 4feac30..f97e34d 100644 --- a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp @@ -16,10 +16,12 @@ #include #include -#include "test_allocator.h" +#include "min_allocator.h" int main() { - std::function f(std::allocator_arg, test_allocator()); + { + std::function f(std::allocator_arg, bare_allocator()); assert(!f); + } } diff --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp index 28e44a6..741a3b9 100644 --- a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp @@ -16,7 +16,7 @@ #include #include -#include "test_allocator.h" +#include "min_allocator.h" class A { @@ -57,19 +57,19 @@ public: int main() { { - std::function f(std::allocator_arg, test_allocator(), A()); + std::function f(std::allocator_arg, bare_allocator(), A()); assert(A::count == 1); assert(f.target()); assert(f.target() == 0); } assert(A::count == 0); { - std::function f(std::allocator_arg, test_allocator(), g); + std::function f(std::allocator_arg, bare_allocator(), g); assert(f.target()); assert(f.target() == 0); } { - std::function f(std::allocator_arg, test_allocator(), + std::function f(std::allocator_arg, bare_allocator(), (int (*)(int))0); assert(!f); assert(f.target() == 0); @@ -77,7 +77,7 @@ int main() } { std::function f(std::allocator_arg, - test_allocator(), + bare_allocator(), &A::foo); assert(f); assert(f.target() != 0); @@ -91,7 +91,7 @@ int main() #endif { std::function fun(std::allocator_arg, - test_allocator(), + bare_allocator(), &g); assert(fun); assert(fun.target() != 0); diff --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp index bb8feff..e89636a 100644 --- a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp @@ -17,6 +17,7 @@ #include #include +#include "min_allocator.h" #include "test_allocator.h" #include "count_new.hpp" @@ -58,7 +59,7 @@ int main() assert(globalMemCounter.checkOutstandingNewEq(1)); assert(f.target()); assert(f.target() == 0); - std::function f2(std::allocator_arg, test_allocator(), f); + std::function f2(std::allocator_arg, bare_allocator(), f); assert(A::count == 2); assert(globalMemCounter.checkOutstandingNewEq(2)); assert(f2.target()); @@ -71,7 +72,7 @@ int main() assert(globalMemCounter.checkOutstandingNewEq(0)); assert(f.target()); assert(f.target() == 0); - std::function f2(std::allocator_arg, test_allocator(), f); + std::function f2(std::allocator_arg, bare_allocator(), f); assert(globalMemCounter.checkOutstandingNewEq(0)); assert(f2.target()); assert(f2.target() == 0); @@ -91,7 +92,7 @@ int main() assert(globalMemCounter.checkOutstandingNewEq(0)); assert(f.target() == 0); assert(f.target() == 0); - std::function f2(std::allocator_arg, test_allocator(), f); + std::function f2(std::allocator_arg, bare_allocator(), f); assert(globalMemCounter.checkOutstandingNewEq(0)); assert(f2.target() == 0); assert(f2.target() == 0); diff --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp index 956136b..2350f92 100644 --- a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp @@ -16,10 +16,10 @@ #include #include -#include "test_allocator.h" +#include "min_allocator.h" int main() { - std::function f(std::allocator_arg, test_allocator(), nullptr); + std::function f(std::allocator_arg, bare_allocator(), nullptr); assert(!f); } diff --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp index 15b7c8b..aa6b743 100644 --- a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp @@ -16,7 +16,7 @@ #include #include -#include "test_allocator.h" +#include "min_allocator.h" #include "count_new.hpp" class A @@ -56,7 +56,7 @@ int main() assert(globalMemCounter.checkOutstandingNewEq(1)); assert(f.target()); assert(f.target() == 0); - std::function f2(std::allocator_arg, test_allocator(), std::move(f)); + std::function f2(std::allocator_arg, bare_allocator(), std::move(f)); assert(A::count == 1); assert(globalMemCounter.checkOutstandingNewEq(1)); assert(f2.target()); -- 2.7.4