}
template<typename _Ptr, typename _Deleter>
- __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
- {
- // 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 typename allocator_traits<_Alloc>::template
- rebind_traits<_Sp_cd_type> _Alloc_traits;
- typename _Alloc_traits::allocator_type __a;
- _Sp_cd_type* __mem = 0;
- __try
- {
- __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 (__mem)
- _Alloc_traits::deallocate(__a, __mem, 1);
- __throw_exception_again;
- }
- }
+ __shared_count(_Ptr __p, _Deleter __d)
+ : __shared_count(__p, std::move(__d), allocator<void>())
+ { }
template<typename _Ptr, typename _Deleter, typename _Alloc>
__shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0)
// Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee.
template<typename _Tp, typename _Del>
explicit
- __shared_count(std::unique_ptr<_Tp, _Del>&& __r)
- : _M_pi(_S_create_from_up(std::move(__r)))
- { __r.release(); }
+ __shared_count(std::unique_ptr<_Tp, _Del>&& __r) : _M_pi(0)
+ {
+ using _Ptr = typename unique_ptr<_Tp, _Del>::pointer;
+ using _Del2 = typename conditional<is_reference<_Del>::value,
+ reference_wrapper<typename remove_reference<_Del>::type>,
+ _Del>::type;
+ using _Sp_cd_type
+ = _Sp_counted_deleter<_Ptr, _Del2, allocator<void>, _Lp>;
+ using _Alloc = allocator<_Sp_cd_type>;
+ using _Alloc_traits = allocator_traits<_Alloc>;
+ _Alloc __a;
+ _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1);
+ _Alloc_traits::construct(__a, __mem, __r.release(),
+ __r.get_deleter()); // non-throwing
+ _M_pi = __mem;
+ }
// Throw bad_weak_ptr when __r._M_get_use_count() == 0.
explicit __shared_count(const __weak_count<_Lp>& __r);
~__shared_count() noexcept
{
- if (_M_pi != 0)
+ if (_M_pi != nullptr)
_M_pi->_M_release();
}
private:
friend class __weak_count<_Lp>;
- template<typename _Tp, typename _Del>
- static _Sp_counted_base<_Lp>*
- _S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r,
- typename std::enable_if<!std::is_reference<_Del>::value>::type* = 0)
- {
- typedef typename unique_ptr<_Tp, _Del>::pointer _Ptr;
- return new _Sp_counted_deleter<_Ptr, _Del, std::allocator<void>,
- _Lp>(__r.get(), __r.get_deleter());
- }
-
- template<typename _Tp, typename _Del>
- static _Sp_counted_base<_Lp>*
- _S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r,
- typename std::enable_if<std::is_reference<_Del>::value>::type* = 0)
- {
- typedef typename unique_ptr<_Tp, _Del>::pointer _Ptr;
- typedef typename std::remove_reference<_Del>::type _Del1;
- typedef std::reference_wrapper<_Del1> _Del2;
- return new _Sp_counted_deleter<_Ptr, _Del2, std::allocator<void>,
- _Lp>(__r.get(), std::ref(__r.get_deleter()));
- }
-
_Sp_counted_base<_Lp>* _M_pi;
};
--- /dev/null
+// { dg-options "-std=gnu++11" }
+
+// Copyright (C) 2013 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 <testsuite_hooks.h>
+
+struct X { };
+
+using spcd = std::_Sp_counted_deleter<X*, std::default_delete<X>,
+std::allocator<void>, std::__default_lock_policy>;
+
+namespace std
+{
+ template<>
+ struct allocator<spcd>
+ {
+ using value_type = spcd;
+
+ allocator() = default;
+
+ template<typename U>
+ allocator(const allocator<U>&) { }
+
+ value_type* allocate(size_t n)
+ {
+ if (n != 1)
+ throw bad_alloc();
+ allocated = true;
+ return static_cast<value_type*>((void*)(storage));
+ }
+
+ void deallocate(value_type* p, size_t n)
+ {
+ if (n != 1 || p != (void*)storage || !allocated)
+ abort();
+ allocated = false;
+ }
+
+ static char storage[sizeof(spcd)];
+ static bool allocated;
+ };
+
+ char allocator<spcd>::storage[];
+ bool allocator<spcd>::allocated = false;
+}
+
+int main()
+{
+ std::shared_ptr<X> s( std::unique_ptr<X>(new X) );
+ VERIFY( std::allocator<spcd>::allocated );
+ s.reset();
+ VERIFY( !std::allocator<spcd>::allocated );
+}