OSDN Git Service

* include/bits/shared_ptr_base.h (_Sp_counted_ptr): Make 'final'.
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 8 Nov 2011 16:45:54 +0000 (16:45 +0000)
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 8 Nov 2011 16:45:54 +0000 (16:45 +0000)
(_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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@181171 138bc75d-0d04-0410-961f-82ee72b054a4

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/shared_ptr_base.h
libstdc++-v3/include/std/future
libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc
libstdc++-v3/testsuite/20_util/shared_ptr/cons/alloc_min.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/creation/alloc_min.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/creation/private.cc [new file with mode: 0644]
libstdc++-v3/testsuite/30_threads/packaged_task/cons/alloc_min.cc [new file with mode: 0644]
libstdc++-v3/testsuite/30_threads/promise/cons/alloc_min.cc [new file with mode: 0644]

index 0fc92a0..24cc7b6 100644 (file)
@@ -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
index a06f5b9..fbbadd1 100644 (file)
@@ -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);
index 4591eb6..bfd1ff9 100644 (file)
@@ -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
index 42354d4..4276c40 100644 (file)
@@ -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 (file)
index 0000000..86f725d
--- /dev/null
@@ -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 (file)
index 0000000..7def5b1
--- /dev/null
@@ -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 (file)
index 0000000..c741fc5
--- /dev/null
@@ -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 (file)
index 0000000..aa8934d
--- /dev/null
@@ -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 (file)
index 0000000..ba7c553
--- /dev/null
@@ -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{} };