Hi mclow.lists, danalbert,

This patch add support for "fancy pointers/allocators" as well as fixing 
support for shared_pointer and "minimal" allocators.

Fancy pointers are class types that meet the NullablePointer requirements. In 
our case they are created by fancy allocators. `support/min_allocator.h` is an 
archetype for these types.

There are three types of changes made in this patch:
1. `_Alloc::template rebind<T>::other` -> `__allocator_traits_rebind<_Alloc, 
T>::type`.
This change was made because allocators don't need a rebind template. 
`__allocator_traits_rebind` is used instead of `allocator_traits::rebind` 
because use of `allocator_traits::rebind` requires a workaround for when 
template aliases are unavailable.
2. `a.deallocate(this, 1)` -> 
`a.deallocate(pointer_traits<self>::pointer_to(*this), 1)`. This change change 
is made because fancy pointers aren't always constructible from raw pointers. 
3. `p.get()` -> `addressof(*p.get())`. Fancy pointers aren't actually a 
pointer. When we need a "real" pointer we take the address of dereferencing the 
fancy pointer. This should give us the actual raw pointer.

http://reviews.llvm.org/D4859

Files:
  include/memory
  
test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp
  
test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp
  
test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp
  
test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_no_variadics.pass.cpp
Index: include/memory
===================================================================
--- include/memory
+++ include/memory
@@ -3677,9 +3677,13 @@
 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 _A::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>
@@ -3742,9 +3746,11 @@
 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 pointer_traits<typename _A::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;
@@ -4090,12 +4096,13 @@
     {
 #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
     }
@@ -4117,12 +4124,13 @@
     {
 #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 (...)
@@ -4282,14 +4290,15 @@
 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;
 }
@@ -4373,14 +4382,15 @@
 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;
 }
@@ -4391,14 +4401,15 @@
 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;
 }
@@ -4409,14 +4420,15 @@
 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;
 }
@@ -4427,14 +4439,15 @@
 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;
 }
Index: test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp
===================================================================
--- test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp
+++ test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "../test_deleter.h"
 #include "test_allocator.h"
+#include "min_allocator.h"
 
 struct A
 {
@@ -47,4 +48,21 @@
     assert(test_deleter<A>::dealloc_count == 1);
     assert(test_allocator<A>::count == 0);
     assert(test_allocator<A>::alloc_count == 0);
+    test_deleter<A>::dealloc_count = 0;
+#if __cplusplus >= 201103L
+    {
+    std::shared_ptr<A> p(nullptr, test_deleter<A>(1), min_allocator<void>());
+    assert(A::count == 0);
+    assert(p.use_count() == 1);
+    assert(p.get() == 0);
+    test_deleter<A>* d = std::get_deleter<test_deleter<A> >(p);
+    assert(test_deleter<A>::count ==1);
+    assert(test_deleter<A>::dealloc_count == 0);
+    assert(d);
+    assert(d->state() == 1);
+    }
+    assert(A::count == 0);
+    assert(test_deleter<A>::count == 0);
+    assert(test_deleter<A>::dealloc_count == 1);
+#endif
 }
Index: test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp
===================================================================
--- test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp
+++ test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "../test_deleter.h"
 #include "test_allocator.h"
+#include "min_allocator.h"
 
 struct A
 {
@@ -27,6 +28,7 @@
 
 int A::count = 0;
 
+
 int main()
 {
     {
@@ -48,4 +50,22 @@
     assert(test_deleter<A>::dealloc_count == 1);
     assert(test_allocator<A>::count == 0);
     assert(test_allocator<A>::alloc_count == 0);
+    test_deleter<A>::dealloc_count = 0;
+#if __cplusplus >= 201103L
+    {
+    A* ptr = new A;
+    std::shared_ptr<A> p(ptr, test_deleter<A>(3), min_allocator<void>());
+    assert(A::count == 1);
+    assert(p.use_count() == 1);
+    assert(p.get() == ptr);
+    test_deleter<A>* d = std::get_deleter<test_deleter<A> >(p);
+    assert(test_deleter<A>::count == 1);
+    assert(test_deleter<A>::dealloc_count == 0);
+    assert(d);
+    assert(d->state() == 3);
+    }
+    assert(A::count == 0);
+    assert(test_deleter<A>::count == 0);
+    assert(test_deleter<A>::dealloc_count == 1);
+#endif
 }
Index: test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp
===================================================================
--- test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp
+++ test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp
@@ -19,6 +19,7 @@
 #include <cstdlib>
 #include <cassert>
 #include "test_allocator.h"
+#include "min_allocator.h"
 
 int new_count = 0;
 
@@ -54,4 +55,15 @@
     }
     assert(A::count == 0);
     assert(test_allocator<A>::alloc_count == 0);
+#if __cplusplus >= 201103L
+    {
+    int i = 67;
+    char c = 'e';
+    std::shared_ptr<A> p = std::allocate_shared<A>(min_allocator<void>(), i, c);
+    assert(A::count == 1);
+    assert(p->get_int() == 67);
+    assert(p->get_char() == 'e');
+    }
+    assert(A::count == 0);
+#endif
 }
Index: test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_no_variadics.pass.cpp
===================================================================
--- /dev/null
+++ test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_no_variadics.pass.cpp
@@ -0,0 +1,118 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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"
+
+int new_count = 0;
+
+struct A
+{
+    static int count;
+
+    A(int i, char c) : int_(i), char_(c) {++count;}
+    A(const A& a)
+        : int_(a.int_), char_(a.char_)
+        {++count;}
+    ~A() {--count;}
+
+    int get_int() const {return int_;}
+    char get_char() const {return char_;}
+private:
+    int int_;
+    char char_;
+};
+
+int A::count = 0;
+
+struct B
+{
+    static int count;
+    B() {++count;}
+    B(B const &) {++count;}
+    ~B() {--count;}
+};
+
+int B::count = 0;
+
+struct C
+{
+    static int count;
+
+    C(int i, char c, char) : int_(i), char_(c) {++count;}
+    C(const C& a)
+        : int_(a.int_), char_(a.char_)
+        {++count;}
+    ~C() {--count;}
+
+    int get_int() const {return int_;}
+    char get_char() const {return char_;}
+private:
+    int int_;
+    char char_;
+};
+
+int C::count = 0;
+
+int main()
+{
+    {
+    int i = 67;
+    char c = 'e';
+    std::shared_ptr<A> p = std::allocate_shared<A>(test_allocator<A>(54), i, c);
+    assert(test_allocator<A>::alloc_count == 1);
+    assert(A::count == 1);
+    assert(p->get_int() == 67);
+    assert(p->get_char() == 'e');
+    }
+    assert(A::count == 0);
+    assert(test_allocator<A>::alloc_count == 0);
+#if __cplusplus >= 201103L
+    {
+    int i = 67;
+    char c = 'e';
+    std::shared_ptr<C> p = std::allocate_shared<C>(min_allocator<void>(), i, c, c);
+    assert(C::count == 1);
+    assert(p->get_int() == 67);
+    assert(p->get_char() == 'e');
+    }
+    assert(C::count == 0);
+    {
+    int i = 67;
+    char c = 'e';
+    std::shared_ptr<A> p = std::allocate_shared<A>(min_allocator<void>(), i, c);
+    assert(A::count == 1);
+    assert(p->get_int() == 67);
+    assert(p->get_char() == 'e');
+    }
+    assert(A::count == 0);
+    {
+    int i = 67;
+    std::shared_ptr<int> p = std::allocate_shared<int>(min_allocator<void>(), i);
+    assert(*p == i);
+    }
+    {
+    std::shared_ptr<B> p = std::allocate_shared<B>(min_allocator<void>());
+    assert(B::count == 1);
+    }
+    assert(B::count == 0);
+#endif
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to