]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Makefile.am: Add new header.
authorJonathan Wakely <jwakely@redhat.com>
Wed, 25 Jun 2014 20:54:46 +0000 (21:54 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 25 Jun 2014 20:54:46 +0000 (21:54 +0100)
* include/Makefile.am: Add new header.
* include/Makefile.in: Regenerate.
* include/bits/allocated_ptr.h (__allocated_ptr, __allocate_guarded):
New RAII utilities for working with allocators.
* include/bits/shared_ptr_base.h (_Sp_counted_deleter): Define
__allocator_type typedef and use new __allocated_ptr type.
(_Sp_counted_ptr_inplace): Likewise.
(__shared_count::__shared_count, __shared_ptr::__shared_ptr): Use
__allocate_guarded to to simplify exception handling.
* include/experimental/any (any::_Manager_alloc::_S_alloc): Likewise.
* include/std/future (_Result_alloc::_M_destroy): Likewise.
(_Result_alloc::_S_allocate_result): Likewise.
* testsuite/20_util/shared_ptr/cons/43820_neg.cc: Adjust line number.
* testsuite/20_util/shared_ptr/cons/void_neg.cc: Likewise.
* testsuite/20_util/shared_ptr/creation/no_rtti.cc: New.
* testsuite/20_util/shared_ptr/creation/alloc.cc: Test allocator
with fancy pointer.
* testsuite/30_threads/promise/cons/alloc.cc: Likewise.

From-SVN: r211996

12 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/include/Makefile.am
libstdc++-v3/include/Makefile.in
libstdc++-v3/include/bits/allocated_ptr.h [new file with mode: 0644]
libstdc++-v3/include/bits/shared_ptr_base.h
libstdc++-v3/include/experimental/any
libstdc++-v3/include/std/future
libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc
libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc
libstdc++-v3/testsuite/20_util/shared_ptr/creation/alloc.cc
libstdc++-v3/testsuite/20_util/shared_ptr/creation/no_rtti.cc [new file with mode: 0644]
libstdc++-v3/testsuite/30_threads/promise/cons/alloc.cc

index 2042b55eacc86d974321defc1b18585a17c752c3..31669e0cc3c4c308d2b6da46b3b5b8616e44c8d7 100644 (file)
@@ -6,6 +6,25 @@
        Likewise.
        * include/ext/alloc_traits.h: Fix comment.
 
+       * include/Makefile.am: Add new header.
+       * include/Makefile.in: Regenerate.
+       * include/bits/allocated_ptr.h (__allocated_ptr, __allocate_guarded):
+       New RAII utilities for working with allocators.
+       * include/bits/shared_ptr_base.h (_Sp_counted_deleter): Define
+       __allocator_type typedef and use new __allocated_ptr type.
+       (_Sp_counted_ptr_inplace): Likewise.
+       (__shared_count::__shared_count, __shared_ptr::__shared_ptr): Use
+       __allocate_guarded to to simplify exception handling.
+       * include/experimental/any (any::_Manager_alloc::_S_alloc): Likewise.
+       * include/std/future (_Result_alloc::_M_destroy): Likewise.
+       (_Result_alloc::_S_allocate_result): Likewise.
+       * testsuite/20_util/shared_ptr/cons/43820_neg.cc: Adjust line number.
+       * testsuite/20_util/shared_ptr/cons/void_neg.cc: Likewise.
+       * testsuite/20_util/shared_ptr/creation/no_rtti.cc: New.
+       * testsuite/20_util/shared_ptr/creation/alloc.cc: Test allocator
+       with fancy pointer.
+       * testsuite/30_threads/promise/cons/alloc.cc: Likewise.
+
 2014-06-24  Jonathan Wakely  <jwakely@redhat.com>
 
        * include/bits/functexcept.h (__throw_out_of_range_fmt): Change
index 8fe82daae2d975ddd180b06f4b04bbf5472a6ca8..e469586077d2659eef4ec9a71d8463aeb0f7d209 100644 (file)
@@ -80,6 +80,7 @@ bits_builddir = ./bits
 bits_headers = \
        ${bits_srcdir}/algorithmfwd.h \
        ${bits_srcdir}/alloc_traits.h \
+       ${bits_srcdir}/allocated_ptr.h \
        ${bits_srcdir}/allocator.h \
        ${bits_srcdir}/atomic_base.h \
        ${bits_srcdir}/basic_ios.h \
index 51fde97e605f9425c4f2daf0965b69a3793e9868..34ae1d17bd54e04224286dd451521ea41b287f80 100644 (file)
@@ -347,6 +347,7 @@ bits_builddir = ./bits
 bits_headers = \
        ${bits_srcdir}/algorithmfwd.h \
        ${bits_srcdir}/alloc_traits.h \
+       ${bits_srcdir}/allocated_ptr.h \
        ${bits_srcdir}/allocator.h \
        ${bits_srcdir}/atomic_base.h \
        ${bits_srcdir}/basic_ios.h \
diff --git a/libstdc++-v3/include/bits/allocated_ptr.h b/libstdc++-v3/include/bits/allocated_ptr.h
new file mode 100644 (file)
index 0000000..5cdce20
--- /dev/null
@@ -0,0 +1,104 @@
+// Guarded Allocation -*- C++ -*-
+
+// Copyright (C) 2014 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/allocated_ptr.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{memory}
+ */
+
+#ifndef _ALLOCATED_PTR_H
+#define _ALLOCATED_PTR_H 1
+
+#if __cplusplus < 201103L
+# include <bits/c++0xwarning.h>
+#else
+# include <type_traits>
+# include <bits/ptr_traits.h>
+# include <bits/alloc_traits.h>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /// Non-standard RAII type for managing pointers obtained from allocators.
+  template<typename _Alloc>
+    struct __allocated_ptr
+    {
+      using pointer = typename allocator_traits<_Alloc>::pointer;
+      using value_type = typename allocator_traits<_Alloc>::value_type;
+
+      /// Take ownership of __ptr
+      __allocated_ptr(_Alloc& __a, pointer __ptr) noexcept
+      : _M_alloc(&__a), _M_ptr(__ptr)
+      { }
+
+      /// Convert __ptr to allocator's pointer type and take ownership of it
+      template<typename _Ptr,
+              typename _Req = _Require<is_same<_Ptr, value_type*>>>
+      __allocated_ptr(_Alloc& __a, _Ptr __ptr)
+      : _M_alloc(&__a), _M_ptr(pointer_traits<pointer>::pointer_to(*__ptr))
+      { }
+
+      /// Transfer ownership of the owned pointer
+      __allocated_ptr(__allocated_ptr&& __gd) noexcept
+      : _M_alloc(__gd._M_alloc), _M_ptr(__gd._M_ptr)
+      { __gd._M_ptr = nullptr; }
+
+      /// Deallocate the owned pointer
+      ~__allocated_ptr()
+      {
+       if (_M_ptr != nullptr)
+         std::allocator_traits<_Alloc>::deallocate(*_M_alloc, _M_ptr, 1);
+      }
+
+      /// Release ownership of the owned pointer
+      __allocated_ptr& operator=(std::nullptr_t) noexcept { _M_ptr = nullptr; }
+
+      /// Get the address that the owned pointer refers to.
+      value_type* get() { return _S_raw_ptr(_M_ptr); }
+
+    private:
+      value_type* _S_raw_ptr(value_type* __ptr) { return __ptr; }
+
+      template<typename _Ptr>
+       auto _S_raw_ptr(_Ptr __ptr) -> decltype(_S_raw_ptr(__ptr.operator->()))
+       { return _S_raw_ptr(__ptr.operator->()); }
+
+      _Alloc* _M_alloc;
+      pointer _M_ptr;
+    };
+
+  /// Allocate space for a single object using __a
+  template<typename _Alloc>
+    __allocated_ptr<_Alloc>
+    __allocate_guarded(_Alloc& __a)
+    {
+      return { __a, std::allocator_traits<_Alloc>::allocate(__a, 1) };
+    }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif
+#endif
index c25157fe4bdce9ec6537af73e0de2c49493a1624..590a8d3cab7d255e39757262370d1ed021c68474 100644 (file)
@@ -49,6 +49,7 @@
 #ifndef _SHARED_PTR_BASE_H
 #define _SHARED_PTR_BASE_H 1
 
+#include <bits/allocated_ptr.h>
 #include <ext/aligned_buffer.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -448,6 +449,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       };
 
     public:
+      using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_deleter>;
+
       // __d(__p) must not throw.
       _Sp_counted_deleter(_Ptr __p, _Deleter __d) noexcept
       : _M_impl(__p, __d, _Alloc()) { }
@@ -465,11 +468,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       virtual void
       _M_destroy() noexcept
       {
-       typedef typename allocator_traits<_Alloc>::template
-         rebind_traits<_Sp_counted_deleter> _Alloc_traits;
-       typename _Alloc_traits::allocator_type __a(_M_impl._M_alloc());
-       _Alloc_traits::destroy(__a, this);
-       _Alloc_traits::deallocate(__a, this, 1);
+       __allocator_type __a(_M_impl._M_alloc());
+       __allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
+       this->~_Sp_counted_deleter();
       }
 
       virtual void*
@@ -506,6 +507,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       };
 
     public:
+      using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>;
+
       template<typename... _Args>
        _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
        : _M_impl(__a)
@@ -528,11 +531,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       virtual void
       _M_destroy() noexcept
       {
-       typedef typename allocator_traits<_Alloc>::template
-         rebind_traits<_Sp_counted_ptr_inplace> _Alloc_traits;
-       typename _Alloc_traits::allocator_type __a(_M_impl._M_alloc());
-       _Alloc_traits::destroy(__a, this);
-       _Alloc_traits::deallocate(__a, this, 1);
+       __allocator_type __a(_M_impl._M_alloc());
+       __allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
+       this->~_Sp_counted_ptr_inplace();
       }
 
       // Sneaky trick so __shared_ptr can get the managed pointer
@@ -584,22 +585,18 @@ _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 allocator_traits<_Alloc>::template
-           rebind_traits<_Sp_cd_type> _Alloc_traits;
-         typename _Alloc_traits::allocator_type __a2(__a);
-         _Sp_cd_type* __mem = 0;
          __try
            {
-             __mem = _Alloc_traits::allocate(__a2, 1);
-             _Alloc_traits::construct(__a2, __mem,
-                 __p, std::move(__d), std::move(__a));
+             typename _Sp_cd_type::__allocator_type __a2(__a);
+             auto __guard = std::__allocate_guarded(__a2);
+             _Sp_cd_type* __mem = __guard.get();
+             ::new (__mem) _Sp_cd_type(__p, std::move(__d), std::move(__a));
              _M_pi = __mem;
+             __guard = nullptr;
            }
          __catch(...)
            {
              __d(__p); // Call _Deleter on __p.
-             if (__mem)
-               _Alloc_traits::deallocate(__a2, __mem, 1);
              __throw_exception_again;
            }
        }
@@ -610,21 +607,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        : _M_pi(0)
        {
          typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type;
-         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
-           {
-             _Alloc_traits::construct(__a2, __mem, std::move(__a),
-                   std::forward<_Args>(__args)...);
-             _M_pi = __mem;
-           }
-         __catch(...)
-           {
-             _Alloc_traits::deallocate(__a2, __mem, 1);
-             __throw_exception_again;
-           }
+         typename _Sp_cp_type::__allocator_type __a2(__a);
+         auto __guard = std::__allocate_guarded(__a2);
+         _Sp_cp_type* __mem = __guard.get();
+         ::new (__mem) _Sp_cp_type(std::move(__a),
+                                   std::forward<_Args>(__args)...);
+         _M_pi = __mem;
+         __guard = nullptr;
        }
 
 #if _GLIBCXX_USE_DEPRECATED
@@ -1096,11 +1085,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       template<typename _Alloc>
         struct _Deleter
         {
-          void operator()(_Tp* __ptr)
+          void operator()(typename _Alloc::pointer __ptr)
           {
-           typedef allocator_traits<_Alloc> _Alloc_traits;
-           _Alloc_traits::destroy(_M_alloc, __ptr);
-           _Alloc_traits::deallocate(_M_alloc, __ptr, 1);
+           __allocated_ptr<_Alloc> __guard{ _M_alloc, __ptr };
+           allocator_traits<_Alloc>::destroy(_M_alloc, __guard.get());
           }
           _Alloc _M_alloc;
         };
@@ -1109,27 +1097,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
                     _Args&&... __args)
        : _M_ptr(), _M_refcount()
-        {
-         typedef typename _Alloc::template rebind<_Tp>::other _Alloc2;
-          _Deleter<_Alloc2> __del = { _Alloc2(__a) };
-         typedef allocator_traits<_Alloc2> __traits;
-          _M_ptr = __traits::allocate(__del._M_alloc, 1);
-         __try
-           {
-             // _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(...)
-           {
-             __traits::deallocate(__del._M_alloc, _M_ptr, 1);
-             __throw_exception_again;
-           }
-          __shared_count<_Lp> __count(_M_ptr, __del, __del._M_alloc);
-          _M_refcount._M_swap(__count);
+       {
+         typedef typename allocator_traits<_Alloc>::template
+           rebind_traits<_Tp> __traits;
+         _Deleter<typename __traits::allocator_type> __del = { __a };
+         auto __guard = std::__allocate_guarded(__del._M_alloc);
+         _M_ptr = __guard.get();
+         // _GLIBCXX_RESOLVE_LIB_DEFECTS
+         // 2070. allocate_shared should use allocator_traits<A>::construct
+         __traits::construct(__del._M_alloc, _M_ptr,
+                             std::forward<_Args>(__args)...);
+         __guard = nullptr;
+         __shared_count<_Lp> __count(_M_ptr, __del, __del._M_alloc);
+         _M_refcount._M_swap(__count);
          __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
-        }
+       }
 #endif
 
       template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
index 643fc23584884538774b6f5e071a78ea5932e15b..8f6e372c3b1e614ef602e02b700bf271f1f1e839 100644 (file)
@@ -116,8 +116,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     template<typename _Tp, typename _Alloc>
       struct _Manager_alloc; // creates contained object using an allocator
 
-    template<typename _Tp, typename _Alloc, typename _TpAlloc
-            = typename allocator_traits<_Alloc>::template rebind_alloc<_Tp>>
+    template<typename _Tp, typename _Alloc,
+            typename _TpAlloc = __alloc_rebind<_Alloc, _Tp>>
       using _ManagerAlloc = conditional_t<_Internal<_Tp>::value,
                                          _Manager_internal<_Tp>,
                                          _Manager_alloc<_Tp, _TpAlloc>>;
@@ -501,19 +501,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     _S_alloc(const _Alloc& __a, _Up&& __value)
     {
       typename _Traits::allocator_type __a2(__a);
-      auto __ptr = _Traits::allocate(__a2, 1);
-      __try
-       {
-         any::_Storage __storage;
-         __storage._M_ptr = std::__addressof(*__ptr);
-         ::new(__storage._M_ptr) _Data{__a, std::forward<_Up>(__value)};
-         return __storage;
-       }
-      __catch(...)
-       {
-         _Traits::deallocate(__a2, __ptr, 1);
-         __throw_exception_again;
-       }
+      auto __guard = std::__allocate_guarded(__a2);
+      any::_Storage __storage;
+      __storage._M_ptr = __guard.get();
+      ::new(__storage._M_ptr) _Data{__a, std::forward<_Up>(__value)};
+      __guard = nullptr;
+      return __storage;
     }
 #endif
 
@@ -591,11 +584,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        break;
       case _Op_destroy:
        {
-         using _PtrTr = pointer_traits<typename _Traits::pointer>;
-         typename _Traits::allocator_type __a(__ptr->_M_alloc());
-         auto __alloc_ptr = _PtrTr::pointer_to(*const_cast<_Data*>(__ptr));
+         using _Alloc2 = typename _Traits::allocator_type;
+         _Alloc2 __a(__ptr->_M_alloc());
+         __allocated_ptr<_Alloc2> __guard{__a, const_cast<_Data*>(__ptr)};
          __ptr->~_Data();
-         _Traits::deallocate(__a, __alloc_ptr, 1);
        }
        break;
       }
index 094914448c43475c34919033cf8b48fb4e6518eb..be2ed96f9729d289041743f1ba7d50d3554f3dec 100644 (file)
@@ -45,7 +45,7 @@
 #include <bits/unique_ptr.h>
 #include <bits/shared_ptr.h>
 #include <bits/uses_allocator.h>
-#include <bits/alloc_traits.h>
+#include <bits/allocated_ptr.h>
 #include <ext/aligned_buffer.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -251,42 +251,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     template<typename _Res, typename _Alloc>
       struct _Result_alloc final : _Result<_Res>, _Alloc
       {
-        typedef typename allocator_traits<_Alloc>::template
-          rebind_alloc<_Result_alloc> __allocator_type;
+       using __allocator_type = __alloc_rebind<_Alloc, _Result_alloc>;
 
         explicit
        _Result_alloc(const _Alloc& __a) : _Result<_Res>(), _Alloc(__a)
-        { }
+       { }
        
       private:
        void _M_destroy()
-        {
-         typedef allocator_traits<__allocator_type> __traits;
-          __allocator_type __a(*this);
-         __traits::destroy(__a, this);
-         __traits::deallocate(__a, this, 1);
-        }
+       {
+         __allocator_type __a(*this);
+         __allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
+         this->~_Result_alloc();
+       }
       };
 
     template<typename _Res, typename _Allocator>
       static _Ptr<_Result_alloc<_Res, _Allocator>>
       _S_allocate_result(const _Allocator& __a)
       {
-        typedef _Result_alloc<_Res, _Allocator>        __result_type;
-       typedef allocator_traits<typename __result_type::__allocator_type>
-         __traits;
-        typename __traits::allocator_type __a2(__a);
-        __result_type* __p = __traits::allocate(__a2, 1);
-        __try
-         {
-           __traits::construct(__a2, __p, __a);
-         }
-        __catch(...)
-         {
-           __traits::deallocate(__a2, __p, 1);
-           __throw_exception_again;
-         }
-        return _Ptr<__result_type>(__p);
+       using __result_type = _Result_alloc<_Res, _Allocator>;
+       typename __result_type::__allocator_type __a2(__a);
+       auto __guard = std::__allocate_guarded(__a2);
+       __result_type* __p = ::new((void*)__guard.get()) __result_type{__a};
+       __guard = nullptr;
+       return _Ptr<__result_type>(__p);
       }
 
     template<typename _Res, typename _Tp>
index fbd8ccde6201a97fb220f1553d03be53c86916ff..dff04028b15c32c73fa0b35ab63a67c4b568786b 100644 (file)
@@ -32,7 +32,7 @@ void test01()
 {
   X* px = 0;
   std::shared_ptr<X> p1(px);   // { dg-error "here" }
-  // { dg-error "incomplete" "" { target *-*-* } 875 }
+  // { dg-error "incomplete" "" { target *-*-* } 864 }
 
   std::shared_ptr<X> p9(ap());  // { dg-error "here" }
   // { dg-error "incomplete" "" { target *-*-* } 307 }
index 3f93a5e5249cd6dfe6d09e322e2645c92e165afd..1ea114c7085cc538649b9bda7bc57ea52109d9c3 100644 (file)
@@ -25,5 +25,5 @@
 void test01()
 {
   std::shared_ptr<void> p((void*)nullptr);   // { dg-error "here" }
-  // { dg-error "incomplete" "" { target *-*-* } 874 }
+  // { dg-error "incomplete" "" { target *-*-* } 863 }
 }
index cd2712a9d5576b6515d4ca65555a747022fd0c44..402c612f592b06c3466c0c55bd7fc55edf4a4d5a 100644 (file)
@@ -101,10 +101,25 @@ test02()
          == tracker_allocator_counter::get_deallocation_count() );
 }
 
+template<typename T>
+  struct Pointer : __gnu_test::PointerBase<Pointer<T>, T>
+  {
+    using __gnu_test::PointerBase<Pointer<T>, T>::PointerBase;
+  };
+
+void
+test03()
+{
+  __gnu_test::CustomPointerAlloc<Pointer<int>> alloc;
+  auto p = std::allocate_shared<int>(alloc, 1);
+  VERIFY( *p == 1 );
+}
+
 int
 main()
 {
   test01();
   test02();
+  test03();
   return 0;
 }
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/creation/no_rtti.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/creation/no_rtti.cc
new file mode 100644 (file)
index 0000000..127bafb
--- /dev/null
@@ -0,0 +1,41 @@
+// { dg-options "-std=gnu++11 -fno-rtti" }
+// { dg-do compile }
+
+// Copyright (C) 2014 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/>.
+
+// 20.8.2.2 Class template shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_allocator.h>
+
+struct X { };
+
+// 20.8.2.2.6 shared_ptr creation [util.smartptr.shared.create]
+
+// test allocate_shared with no RTTI
+
+template<typename T>
+  struct Pointer : __gnu_test::PointerBase<Pointer<T>, T>
+  {
+    using __gnu_test::PointerBase<Pointer<T>, T>::PointerBase;
+  };
+
+__gnu_test::CustomPointerAlloc<Pointer<int>> alloc;
+
+auto p = std::allocate_shared<X>(alloc);
+
index ac8fb1313c0e35044a5a374e0a55147a944a7769..c45e646aae0d2f973a5d518c731c0cfb6b5e7226 100644 (file)
 #include <testsuite_hooks.h>
 #include <testsuite_allocator.h>
 
+using std::promise;
+using std::allocator_arg;
+
 void test01()
 {
-  using std::promise;
-  using std::allocator_arg;
-  using __gnu_test::uneq_allocator;
+  __gnu_test::uneq_allocator<char> alloc(99);
+  promise<int> p1(allocator_arg, alloc);
+  p1.set_value(5);
+  VERIFY( p1.get_future().get() == 5 );
+}
 
-  uneq_allocator<char> alloc(99);
+template<typename T>
+  struct Pointer : __gnu_test::PointerBase<Pointer<T>, T>
+  {
+    using __gnu_test::PointerBase<Pointer<T>, T>::PointerBase;
+  };
 
+void
+test02()
+{
+  __gnu_test::CustomPointerAlloc<Pointer<int>> alloc;
   promise<int> p1(allocator_arg, alloc);
   p1.set_value(5);
   VERIFY( p1.get_future().get() == 5 );
@@ -43,5 +56,6 @@ void test01()
 int main()
 {
   test01();
+  test02();
   return 0;
 }