void
__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
{
- typename _Alloc::template rebind<__shared_ptr_pointer>::other __a(__data_.second());
+ typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_pointer>::type _A;
+ typedef allocator_traits<_A> _ATraits;
+ typedef pointer_traits<typename _ATraits::pointer> _PTraits;
+
+ _A __a(__data_.second());
__data_.second().~_Alloc();
- __a.deallocate(this, 1);
+ __a.deallocate(_PTraits::pointer_to(*this), 1);
}
template <class _Tp, class _Alloc>
void
__shared_ptr_emplace<_Tp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
{
- typename _Alloc::template rebind<__shared_ptr_emplace>::other __a(__data_.first());
+ typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type _A;
+ typedef allocator_traits<_A> _ATraits;
+ typedef pointer_traits<typename _ATraits::pointer> _PTraits;
+ _A __a(__data_.first());
__data_.first().~_Alloc();
- __a.deallocate(this, 1);
+ __a.deallocate(_PTraits::pointer_to(*this), 1);
}
template<class _Tp> class _LIBCPP_TYPE_VIS_ONLY enable_shared_from_this;
{
#endif // _LIBCPP_NO_EXCEPTIONS
typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;
- typedef typename _Alloc::template rebind<_CntrlBlk>::other _A2;
+ typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
typedef __allocator_destructor<_A2> _D2;
_A2 __a2(__a);
unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
- ::new(__hold2.get()) _CntrlBlk(__p, __d, __a);
- __cntrl_ = __hold2.release();
+ ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
+ _CntrlBlk(__p, __d, __a);
+ __cntrl_ = _VSTD::addressof(*__hold2.release());
__enable_weak_this(__p);
#ifndef _LIBCPP_NO_EXCEPTIONS
}
{
#endif // _LIBCPP_NO_EXCEPTIONS
typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;
- typedef typename _Alloc::template rebind<_CntrlBlk>::other _A2;
+ typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
typedef __allocator_destructor<_A2> _D2;
_A2 __a2(__a);
unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
- ::new(__hold2.get()) _CntrlBlk(__p, __d, __a);
- __cntrl_ = __hold2.release();
+ ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
+ _CntrlBlk(__p, __d, __a);
+ __cntrl_ = _VSTD::addressof(*__hold2.release());
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _Args&& ...__args)
{
typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
- typedef typename _Alloc::template rebind<_CntrlBlk>::other _A2;
+ typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
typedef __allocator_destructor<_A2> _D2;
_A2 __a2(__a);
unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
- ::new(__hold2.get()) _CntrlBlk(__a, _VSTD::forward<_Args>(__args)...);
+ ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
+ _CntrlBlk(__a, _VSTD::forward<_Args>(__args)...);
shared_ptr<_Tp> __r;
__r.__ptr_ = __hold2.get()->get();
- __r.__cntrl_ = __hold2.release();
+ __r.__cntrl_ = _VSTD::addressof(*__hold2.release());
__r.__enable_weak_this(__r.__ptr_);
return __r;
}
shared_ptr<_Tp>::allocate_shared(const _Alloc& __a)
{
typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
- typedef typename _Alloc::template rebind<_CntrlBlk>::other _Alloc2;
+ typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _Alloc2;
typedef __allocator_destructor<_Alloc2> _D2;
_Alloc2 __alloc2(__a);
unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
- ::new(__hold2.get()) _CntrlBlk(__a);
+ ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
+ _CntrlBlk(__a);
shared_ptr<_Tp> __r;
__r.__ptr_ = __hold2.get()->get();
- __r.__cntrl_ = __hold2.release();
+ __r.__cntrl_ = _VSTD::addressof(*__hold2.release());
__r.__enable_weak_this(__r.__ptr_);
return __r;
}
shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0)
{
typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
- typedef typename _Alloc::template rebind<_CntrlBlk>::other _Alloc2;
+ typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _Alloc2;
typedef __allocator_destructor<_Alloc2> _D2;
_Alloc2 __alloc2(__a);
unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
- ::new(__hold2.get()) _CntrlBlk(__a, __a0);
+ ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
+ _CntrlBlk(__a, __a0);
shared_ptr<_Tp> __r;
__r.__ptr_ = __hold2.get()->get();
- __r.__cntrl_ = __hold2.release();
+ __r.__cntrl_ = _VSTD::addressof(*__hold2.release());
__r.__enable_weak_this(__r.__ptr_);
return __r;
}
shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1)
{
typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
- typedef typename _Alloc::template rebind<_CntrlBlk>::other _Alloc2;
+ typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _Alloc2;
typedef __allocator_destructor<_Alloc2> _D2;
_Alloc2 __alloc2(__a);
unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
- ::new(__hold2.get()) _CntrlBlk(__a, __a0, __a1);
+ ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
+ _CntrlBlk(__a, __a0, __a1);
shared_ptr<_Tp> __r;
__r.__ptr_ = __hold2.get()->get();
- __r.__cntrl_ = __hold2.release();
+ __r.__cntrl_ = _VSTD::addressof(*__hold2.release());
__r.__enable_weak_this(__r.__ptr_);
return __r;
}
shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1, _A2& __a2)
{
typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
- typedef typename _Alloc::template rebind<_CntrlBlk>::other _Alloc2;
+ typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _Alloc2;
typedef __allocator_destructor<_Alloc2> _D2;
_Alloc2 __alloc2(__a);
unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
- ::new(__hold2.get()) _CntrlBlk(__a, __a0, __a1, __a2);
+ ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
+ _CntrlBlk(__a, __a0, __a1, __a2);
shared_ptr<_Tp> __r;
__r.__ptr_ = __hold2.get()->get();
- __r.__cntrl_ = __hold2.release();
+ __r.__cntrl_ = _VSTD::addressof(*__hold2.release());
__r.__enable_weak_this(__r.__ptr_);
return __r;
}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// shared_ptr
+
+// template<class T, class A, class... Args>
+// shared_ptr<T> allocate_shared(const A& a, Args&&... args);
+
+#define _LIBCPP_HAS_NO_VARIADICS
+#include <memory>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+struct Zero
+{
+ static int count;
+ Zero() {++count;}
+ Zero(Zero const &) {++count;}
+ ~Zero() {--count;}
+};
+
+int Zero::count = 0;
+
+struct One
+{
+ static int count;
+ int value;
+ explicit One(int v) : value(v) {++count;}
+ One(One const & o) : value(o.value) {++count;}
+ ~One() {--count;}
+};
+
+int One::count = 0;
+
+
+struct Two
+{
+ static int count;
+ int value;
+ Two(int v, int) : value(v) {++count;}
+ Two(Two const & o) : value(o.value) {++count;}
+ ~Two() {--count;}
+};
+
+int Two::count = 0;
+
+struct Three
+{
+ static int count;
+ int value;
+ Three(int v, int, int) : value(v) {++count;}
+ Three(Three const & o) : value(o.value) {++count;}
+ ~Three() {--count;}
+};
+
+int Three::count = 0;
+
+template <class Alloc>
+void test()
+{
+ int const bad = -1;
+ {
+ std::shared_ptr<Zero> p = std::allocate_shared<Zero>(Alloc());
+ assert(Zero::count == 1);
+ }
+ assert(Zero::count == 0);
+ {
+ int const i = 42;
+ std::shared_ptr<One> p = std::allocate_shared<One>(Alloc(), i);
+ assert(One::count == 1);
+ assert(p->value == i);
+ }
+ assert(One::count == 0);
+ {
+ int const i = 42;
+ std::shared_ptr<Two> p = std::allocate_shared<Two>(Alloc(), i, bad);
+ assert(Two::count == 1);
+ assert(p->value == i);
+ }
+ assert(Two::count == 0);
+ {
+ int const i = 42;
+ std::shared_ptr<Three> p = std::allocate_shared<Three>(Alloc(), i, bad, bad);
+ assert(Three::count == 1);
+ assert(p->value == i);
+ }
+ assert(Three::count == 0);
+}
+
+int main()
+{
+ {
+ int i = 67;
+ int const bad = -1;
+ std::shared_ptr<Two> p = std::allocate_shared<Two>(test_allocator<Two>(54), i, bad);
+ assert(test_allocator<Two>::alloc_count == 1);
+ assert(Two::count == 1);
+ assert(p->value == 67);
+ }
+ assert(Two::count == 0);
+ assert(test_allocator<Two>::alloc_count == 0);
+
+ test<bare_allocator<void> >();
+#if __cplusplus >= 201103L
+ test<min_allocator<void> >();
+#endif
+}