From a58a38b32c7ed8b4843e8d2b2658323204fa96ed Mon Sep 17 00:00:00 2001 From: Jonathan Wakely <jwakely.gcc@gmail.com> Date: Tue, 8 Nov 2011 16:45:54 +0000 Subject: [PATCH] shared_ptr_base.h (_Sp_counted_ptr): Make 'final'. * include/bits/shared_ptr_base.h (_Sp_counted_ptr): Make 'final'. (_Sp_counted_deleter): Make 'final'. Use allocator_traits. (_Sp_counted_ptr_inplace): Make 'final'. Use allocator_traits. Derive from _Sp_counted_ptr instead of _Sp_counted_deleter to use EBO for the allocator. (__shared_count, __shared_ptr): Use allocator_traits. * include/std/future (__future_base::_Result_alloc): Make 'final'. Use allocator traits. (__future_base::_Task_state): Make 'final'. (__future_base::_Deferred_state): Likewise. (__future_base::_Async_state): Likewise. * testsuite/20_util/shared_ptr/cons/alloc_min.cc: New. * testsuite/20_util/shared_ptr/creation/alloc_min.cc: New. * testsuite/20_util/shared_ptr/creation/private.cc: New. * testsuite/20_util/shared_ptr/cons/43820_neg.cc: Adjust line numbers. * testsuite/30_threads/packaged_task/cons/alloc_min.cc: New. * testsuite/30_threads/promise/cons/alloc_min.cc: New. From-SVN: r181171 --- libstdc++-v3/ChangeLog | 20 +++ libstdc++-v3/include/bits/shared_ptr_base.h | 138 +++++++++--------- libstdc++-v3/include/std/future | 29 ++-- .../20_util/shared_ptr/cons/43820_neg.cc | 4 +- .../20_util/shared_ptr/cons/alloc_min.cc | 35 +++++ .../20_util/shared_ptr/creation/alloc_min.cc | 34 +++++ .../20_util/shared_ptr/creation/private.cc | 52 +++++++ .../packaged_task/cons/alloc_min.cc | 34 +++++ .../30_threads/promise/cons/alloc_min.cc | 40 +++++ 9 files changed, 307 insertions(+), 79 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/shared_ptr/cons/alloc_min.cc create mode 100644 libstdc++-v3/testsuite/20_util/shared_ptr/creation/alloc_min.cc create mode 100644 libstdc++-v3/testsuite/20_util/shared_ptr/creation/private.cc create mode 100644 libstdc++-v3/testsuite/30_threads/packaged_task/cons/alloc_min.cc create mode 100644 libstdc++-v3/testsuite/30_threads/promise/cons/alloc_min.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 0fc92a0e5ed8..24cc7b67b625 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,23 @@ +2011-11-08 Jonathan Wakely <jwakely.gcc@gmail.com> + + * include/bits/shared_ptr_base.h (_Sp_counted_ptr): Make 'final'. + (_Sp_counted_deleter): Make 'final'. Use allocator_traits. + (_Sp_counted_ptr_inplace): Make 'final'. Use allocator_traits. + Derive from _Sp_counted_ptr instead of _Sp_counted_deleter to use EBO + for the allocator. + (__shared_count, __shared_ptr): Use allocator_traits. + * include/std/future (__future_base::_Result_alloc): Make 'final'. Use + allocator traits. + (__future_base::_Task_state): Make 'final'. + (__future_base::_Deferred_state): Likewise. + (__future_base::_Async_state): Likewise. + * testsuite/20_util/shared_ptr/cons/alloc_min.cc: New. + * testsuite/20_util/shared_ptr/creation/alloc_min.cc: New. + * testsuite/20_util/shared_ptr/creation/private.cc: New. + * testsuite/20_util/shared_ptr/cons/43820_neg.cc: Adjust line numbers. + * testsuite/30_threads/packaged_task/cons/alloc_min.cc: New. + * testsuite/30_threads/promise/cons/alloc_min.cc: New. + 2011-11-08 Paolo Carlini <paolo.carlini@oracle.com> * acinclude.m4 ([GLIBCXX_ENABLE_VISIBILITY]): Rename to diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index a06f5b99f182..fbbadd1aaaac 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -281,7 +281,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Counted ptr with no deleter or allocator support template<typename _Ptr, _Lock_policy _Lp> - class _Sp_counted_ptr : public _Sp_counted_base<_Lp> + class _Sp_counted_ptr final : public _Sp_counted_base<_Lp> { public: explicit @@ -321,20 +321,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Support for custom deleter and/or allocator template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp> - class _Sp_counted_deleter : public _Sp_counted_base<_Lp> + class _Sp_counted_deleter final : public _Sp_counted_base<_Lp> { - typedef typename _Alloc::template - rebind<_Sp_counted_deleter>::other _My_alloc_type; - // Helper class that stores the Deleter and also acts as an allocator. // Used to dispose of the owned pointer and the internal refcount // Requires that copies of _Alloc can free each other's memory. struct _My_Deleter - : public _My_alloc_type // copy constructor must not throw + : public _Alloc // copy constructor must not throw { - _Deleter _M_del; // copy constructor must not throw + _Deleter _M_del; // copy constructor must not throw _My_Deleter(_Deleter __d, const _Alloc& __a) - : _My_alloc_type(__a), _M_del(__d) { } + : _Alloc(__a), _M_del(__d) { } }; public: @@ -353,9 +350,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION virtual void _M_destroy() noexcept { - _My_alloc_type __a(_M_del); - this->~_Sp_counted_deleter(); - __a.deallocate(this, 1); + typedef typename allocator_traits<_Alloc>::template + rebind_traits<_Sp_counted_deleter> _Alloc_traits; + typename _Alloc_traits::allocator_type __a(_M_del); + _Alloc_traits::destroy(__a, this); + _Alloc_traits::deallocate(__a, this, 1); } virtual void* @@ -375,51 +374,46 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // helpers for make_shared / allocate_shared - template<typename _Tp> - struct _Sp_destroy_inplace - { - void operator()(_Tp* __p) const { if (__p) __p->~_Tp(); } - }; - struct _Sp_make_shared_tag { }; template<typename _Tp, typename _Alloc, _Lock_policy _Lp> - class _Sp_counted_ptr_inplace - : public _Sp_counted_deleter<_Tp*, _Sp_destroy_inplace<_Tp>, _Alloc, _Lp> + class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp> { - typedef _Sp_counted_deleter<_Tp*, _Sp_destroy_inplace<_Tp>, _Alloc, _Lp> - _Base_type; - - public: - explicit - _Sp_counted_ptr_inplace(_Alloc __a) - : _Base_type(static_cast<_Tp*>(0), _Sp_destroy_inplace<_Tp>(), __a) - , _M_storage() + // Helper class that stores the pointer and also acts as an allocator. + // Used to dispose of the owned pointer and the internal refcount + // Requires that copies of _Alloc can free each other's memory. + struct _Impl + : public _Alloc // copy constructor must not throw { - void* __p = &_M_storage; - ::new (__p) _Tp(); // might throw - _Base_type::_M_ptr = static_cast<_Tp*>(__p); - } + _Impl(_Alloc __a) : _Alloc(__a), _M_ptr() { } + _Tp* _M_ptr; + }; + public: template<typename... _Args> _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args) - : _Base_type(static_cast<_Tp*>(0), _Sp_destroy_inplace<_Tp>(), __a) - , _M_storage() + : _M_impl(__a), _M_storage() { - void* __p = &_M_storage; - ::new (__p) _Tp(std::forward<_Args>(__args)...); // might throw - _Base_type::_M_ptr = static_cast<_Tp*>(__p); + _M_impl._M_ptr = static_cast<_Tp*>(static_cast<void*>(&_M_storage)); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2070. allocate_shared should use allocator_traits<A>::construct + allocator_traits<_Alloc>::construct(__a, _M_impl._M_ptr, + std::forward<_Args>(__args)...); // might throw } + virtual void + _M_dispose() noexcept + { allocator_traits<_Alloc>::destroy(_M_impl, _M_impl._M_ptr); } + // Override because the allocator needs to know the dynamic type virtual void _M_destroy() noexcept { - typedef typename _Alloc::template - rebind<_Sp_counted_ptr_inplace>::other _My_alloc_type; - _My_alloc_type __a(_Base_type::_M_del); - this->~_Sp_counted_ptr_inplace(); - __a.deallocate(this, 1); + typedef typename allocator_traits<_Alloc>::template + rebind_traits<_Sp_counted_ptr_inplace> _Alloc_traits; + typename _Alloc_traits::allocator_type __a(_M_impl); + _Alloc_traits::destroy(__a, this); + _Alloc_traits::deallocate(__a, this, 1); } // Sneaky trick so __shared_ptr can get the managed pointer @@ -429,13 +423,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #ifdef __GXX_RTTI return __ti == typeid(_Sp_make_shared_tag) ? static_cast<void*>(&_M_storage) - : _Base_type::_M_get_deleter(__ti); + : 0; #else return 0; #endif } private: + _Impl _M_impl; typename aligned_storage<sizeof(_Tp), alignment_of<_Tp>::value>::type _M_storage; }; @@ -468,18 +463,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // The allocator's value_type doesn't matter, will rebind it anyway. typedef std::allocator<int> _Alloc; typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type; - typedef std::allocator<_Sp_cd_type> _Alloc2; - _Alloc2 __a2; + typedef typename allocator_traits<_Alloc>::template + rebind_traits<_Sp_cd_type> _Alloc_traits; + typename _Alloc_traits::allocator_type __a; + _Sp_cd_type* __mem = 0; __try { - _M_pi = __a2.allocate(1); - ::new(static_cast<void*>(_M_pi)) _Sp_cd_type(__p, __d); + __mem = _Alloc_traits::allocate(__a, 1); + _Alloc_traits::construct(__a, __mem, __p, std::move(__d)); + _M_pi = __mem; } __catch(...) { __d(__p); // Call _Deleter on __p. - if (_M_pi) - __a2.deallocate(static_cast<_Sp_cd_type*>(_M_pi), 1); + if (__mem) + _Alloc_traits::deallocate(__a, __mem, 1); __throw_exception_again; } } @@ -488,18 +486,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0) { typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type; - typedef typename _Alloc::template rebind<_Sp_cd_type>::other _Alloc2; - _Alloc2 __a2(__a); + typedef typename allocator_traits<_Alloc>::template + rebind_traits<_Sp_cd_type> _Alloc_traits; + typename _Alloc_traits::allocator_type __a2(__a); + _Sp_cd_type* __mem = 0; __try { - _M_pi = __a2.allocate(1); - ::new(static_cast<void*>(_M_pi)) _Sp_cd_type(__p, __d, __a); + __mem = _Alloc_traits::allocate(__a2, 1); + _Alloc_traits::construct(__a2, __mem, + __p, std::move(__d), std::move(__a)); + _M_pi = __mem; } __catch(...) { __d(__p); // Call _Deleter on __p. - if (_M_pi) - __a2.deallocate(static_cast<_Sp_cd_type*>(_M_pi), 1); + if (__mem) + _Alloc_traits::deallocate(__a2, __mem, 1); __throw_exception_again; } } @@ -510,18 +512,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _M_pi(0) { typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type; - typedef typename _Alloc::template rebind<_Sp_cp_type>::other _Alloc2; - _Alloc2 __a2(__a); + typedef typename allocator_traits<_Alloc>::template + rebind_traits<_Sp_cp_type> _Alloc_traits; + typename _Alloc_traits::allocator_type __a2(__a); + _Sp_cp_type* __mem = _Alloc_traits::allocate(__a2, 1); __try { - _M_pi = __a2.allocate(1); - ::new(static_cast<void*>(_M_pi)) _Sp_cp_type(__a, + _Alloc_traits::construct(__a2, __mem, std::move(__a), std::forward<_Args>(__args)...); + _M_pi = __mem; } __catch(...) { - if (_M_pi) - __a2.deallocate(static_cast<_Sp_cp_type*>(_M_pi), 1); + _Alloc_traits::deallocate(__a2, __mem, 1); __throw_exception_again; } } @@ -1001,8 +1004,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { void operator()(_Tp* __ptr) { - _M_alloc.destroy(__ptr); - _M_alloc.deallocate(__ptr, 1); + typedef allocator_traits<_Alloc> _Alloc_traits; + _Alloc_traits::destroy(_M_alloc, __ptr); + _Alloc_traits::deallocate(_M_alloc, __ptr, 1); } _Alloc _M_alloc; }; @@ -1014,14 +1018,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { typedef typename _Alloc::template rebind<_Tp>::other _Alloc2; _Deleter<_Alloc2> __del = { _Alloc2(__a) }; - _M_ptr = __del._M_alloc.allocate(1); + typedef allocator_traits<_Alloc2> __traits; + _M_ptr = __traits::allocate(__del._M_alloc, 1); __try { - __del._M_alloc.construct(_M_ptr, std::forward<_Args>(__args)...); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2070. allocate_shared should use allocator_traits<A>::construct + __traits::construct(__del._M_alloc, _M_ptr, + std::forward<_Args>(__args)...); } __catch(...) { - __del._M_alloc.deallocate(_M_ptr, 1); + __traits::deallocate(__del._M_alloc, _M_ptr, 1); __throw_exception_again; } __shared_count<_Lp> __count(_M_ptr, __del, __del._M_alloc); diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future index 4591eb67c98f..bfd1ff9e9bb0 100644 --- a/libstdc++-v3/include/std/future +++ b/libstdc++-v3/include/std/future @@ -264,10 +264,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Result_alloc. template<typename _Res, typename _Alloc> - struct _Result_alloc : _Result<_Res>, _Alloc + struct _Result_alloc final : _Result<_Res>, _Alloc { - typedef typename _Alloc::template rebind<_Result_alloc>::other - __allocator_type; + typedef typename allocator_traits<_Alloc>::template + rebind_alloc<_Result_alloc> __allocator_type; explicit _Result_alloc(const _Alloc& __a) : _Result<_Res>(), _Alloc(__a) @@ -276,9 +276,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION private: void _M_destroy() { + typedef allocator_traits<__allocator_type> __traits; __allocator_type __a(*this); - __a.destroy(this); - __a.deallocate(this, 1); + __traits::destroy(__a, this); + __traits::deallocate(__a, this, 1); } }; @@ -287,15 +288,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _S_allocate_result(const _Allocator& __a) { typedef _Result_alloc<_Res, _Allocator> __result_type; - typename __result_type::__allocator_type __a2(__a); - __result_type* __p = __a2.allocate(1); + typedef allocator_traits<typename __result_type::__allocator_type> + __traits; + typename __traits::allocator_type __a2(__a); + __result_type* __p = __traits::allocate(__a2, 1); __try { - __a2.construct(__p, __a); + __traits::construct(__a2, __p, __a); } __catch(...) { - __a2.deallocate(__p, 1); + __traits::deallocate(__a2, __p, 1); __throw_exception_again; } return _Ptr<__result_type>(__p); @@ -1239,7 +1242,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; template<typename _Res, typename... _Args> - struct __future_base::_Task_state<_Res(_Args...)> + struct __future_base::_Task_state<_Res(_Args...)> final : __future_base::_State_base { typedef _Res _Res_type; @@ -1393,7 +1396,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _BoundFn, typename _Res> - class __future_base::_Deferred_state : public __future_base::_State_base + class __future_base::_Deferred_state final + : public __future_base::_State_base { public: explicit @@ -1415,7 +1419,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; template<typename _BoundFn, typename _Res> - class __future_base::_Async_state : public __future_base::_State_base + class __future_base::_Async_state final + : public __future_base::_State_base { public: explicit diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc index 42354d4999d5..4276c406269e 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc @@ -32,9 +32,9 @@ void test01() { X* px = 0; std::shared_ptr<X> p1(px); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 768 } + // { dg-error "incomplete" "" { target *-*-* } 771 } std::shared_ptr<X> p9(ap()); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 862 } + // { dg-error "incomplete" "" { target *-*-* } 865 } } diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/alloc_min.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/alloc_min.cc new file mode 100644 index 000000000000..86f725d53902 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/alloc_min.cc @@ -0,0 +1,35 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2011 Free Software Foundation +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// 20.7.2.2 Class template shared_ptr [util.smartptr.shared] + +#include <memory> +#include <testsuite_allocator.h> + +struct X { }; + +// 20.7.2.2.1 shared_ptr constructors [util.smartptr.shared.const] + +// test shared_ptr with minimal allocator + +__gnu_test::SimpleAllocator<X> alloc; +auto deleter = [](X* p) { delete p; }; +std::shared_ptr<X> p(new X, deleter, alloc); + diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/creation/alloc_min.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/creation/alloc_min.cc new file mode 100644 index 000000000000..7def5b1c7bcc --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/creation/alloc_min.cc @@ -0,0 +1,34 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2011 Free Software Foundation +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// 20.7.2.2 Class template shared_ptr [util.smartptr.shared] + +#include <memory> +#include <testsuite_allocator.h> + +struct X { }; + +// 20.7.2.2.6 shared_ptr creation [util.smartptr.shared.create] + +// test shared_ptr with minimal allocator + +__gnu_test::SimpleAllocator<X> alloc; +auto p = std::allocate_shared<X>(alloc); + diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/creation/private.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/creation/private.cc new file mode 100644 index 000000000000..c741fc5f74ca --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/creation/private.cc @@ -0,0 +1,52 @@ +// { dg-options "-std=gnu++0x" } + +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <memory> +#include <new> + +// The behaviour tested here relies on the resolution of LWG issue 2070 + +template<typename T> struct MyAlloc; + +class Private +{ + Private() = default; + Private(const Private&) = default; + ~Private() = default; + + friend class MyAlloc<Private>; + +public: + int get() const { return 0; } +}; + +template<typename T> +struct MyAlloc : std::allocator<Private> +{ + void construct(T* p) { ::new((void*)p) T(); } + void destroy(T* p) { p->~T(); } +}; + +int main() +{ + MyAlloc<Private> a; + auto p = std::allocate_shared<Private>(a); + return p->get(); +} + diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/alloc_min.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/alloc_min.cc new file mode 100644 index 000000000000..aa8934d47e60 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/alloc_min.cc @@ -0,0 +1,34 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } +// { dg-require-gthreads "" } +// { dg-require-atomic-builtins "" } + +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// Test that packaged_task can use a minimal C++11 allocator +// and doesn't rely on C++98 allocator interface. + +#include <future> +#include <testsuite_allocator.h> + +using std::packaged_task; +using std::allocator_arg; + +__gnu_test::SimpleAllocator<int> a; +packaged_task<int()> p(allocator_arg, a, []() { return 1; }); diff --git a/libstdc++-v3/testsuite/30_threads/promise/cons/alloc_min.cc b/libstdc++-v3/testsuite/30_threads/promise/cons/alloc_min.cc new file mode 100644 index 000000000000..ba7c55334f05 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/promise/cons/alloc_min.cc @@ -0,0 +1,40 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } +// { dg-require-gthreads "" } +// { dg-require-atomic-builtins "" } + +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// Test that promise can use a minimal C++11 allocator +// and doesn't rely on C++98 allocator interface. + +#include <future> +#include <testsuite_allocator.h> + +using std::promise; +using std::allocator_arg; +using std::tuple; + +typedef promise<int> p; +typedef promise<int&> pr; +typedef promise<void> pv; +__gnu_test::SimpleAllocator<p> a; + +tuple<p, pr, pv> t1{ allocator_arg, a }; +tuple<p, pr, pv> t2{ allocator_arg, a, p{}, pr{}, pv{} }; -- GitLab