[libcxx] r220469 - Add support for "fancy" pointers to shared_ptr. Fixes PR20616

Steven Wu stevenwu at apple.com
Wed Feb 4 15:30:03 PST 2015


Hi Eric

I notice in this commit, you named few local type name to _A. Unfortunately on darwin systems, there are macros in /usr/bin/ctype.h which define a bunch of letters with leading underscore for backward compatibility. Eg.
	#define _A    _CTYPE_A     // _CTYPE_A is a number
This will cause a conflict when anyone includes both <ctype> and <memory>. Can you use a different name for the types?

Thanks

Steven

> On Oct 22, 2014, at 9:12 PM, Eric Fiselier <eric at efcs.ca> wrote:
> 
> Author: ericwf
> Date: Wed Oct 22 23:12:28 2014
> New Revision: 220469
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=220469&view=rev
> Log:
> Add support for "fancy" pointers to shared_ptr. Fixes PR20616
> 
> Summary:
> 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.
> 
> Test Plan: Tests were added using `support/min_allocator.h` to each affected shared_ptr overload and creation function. These tests can only be executed in C++11 or greater since min_allocator is only available then. A extra test was added for the non-variadic versions of allocate_shared. 
> 
> Reviewers: danalbert, mclow.lists
> 
> Reviewed By: mclow.lists
> 
> Subscribers: cfe-commits
> 
> Differential Revision: http://reviews.llvm.org/D4859
> 
> Added:
>    libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_no_variadics.pass.cpp
> Modified:
>    libcxx/trunk/include/memory
>    libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp
>    libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp
>    libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp
> 
> Modified: libcxx/trunk/include/memory
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/memory?rev=220469&r1=220468&r2=220469&view=diff
> ==============================================================================
> --- libcxx/trunk/include/memory (original)
> +++ libcxx/trunk/include/memory Wed Oct 22 23:12:28 2014
> @@ -3677,9 +3677,13 @@ template <class _Tp, class _Dp, class _A
> 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>
> @@ -3742,9 +3746,12 @@ 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;
> @@ -4090,12 +4097,13 @@ shared_ptr<_Tp>::shared_ptr(_Yp* __p, _D
>     {
> #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 +4125,13 @@ shared_ptr<_Tp>::shared_ptr(nullptr_t __
>     {
> #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 +4291,15 @@ shared_ptr<_Tp>
> 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 +4383,15 @@ shared_ptr<_Tp>
> 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 +4402,15 @@ shared_ptr<_Tp>
> 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 +4421,15 @@ shared_ptr<_Tp>
> 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 +4440,15 @@ shared_ptr<_Tp>
> 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;
> }
> 
> Modified: libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp?rev=220469&r1=220468&r2=220469&view=diff
> ==============================================================================
> --- libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp (original)
> +++ libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp Wed Oct 22 23:12:28 2014
> @@ -15,6 +15,7 @@
> #include <cassert>
> #include "../test_deleter.h"
> #include "test_allocator.h"
> +#include "min_allocator.h"
> 
> struct A
> {
> @@ -47,4 +48,38 @@ int main()
>     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;
> +    // Test an allocator with a minimal interface
> +    {
> +    std::shared_ptr<A> p(nullptr, test_deleter<A>(1), bare_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);
> +    test_deleter<A>::dealloc_count = 0;
> +#if __cplusplus >= 201103L
> +    // Test an allocator that returns class-type pointers
> +    {
> +    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
> }
> 
> Modified: libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp?rev=220469&r1=220468&r2=220469&view=diff
> ==============================================================================
> --- libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp (original)
> +++ libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp Wed Oct 22 23:12:28 2014
> @@ -15,6 +15,7 @@
> #include <cassert>
> #include "../test_deleter.h"
> #include "test_allocator.h"
> +#include "min_allocator.h"
> 
> struct A
> {
> @@ -27,6 +28,7 @@ struct A
> 
> int A::count = 0;
> 
> +
> int main()
> {
>     {
> @@ -48,4 +50,40 @@ int main()
>     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;
> +    // Test an allocator with a minimal interface
> +    {
> +    A* ptr = new A;
> +    std::shared_ptr<A> p(ptr, test_deleter<A>(3), bare_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);
> +    test_deleter<A>::dealloc_count = 0;
> +#if __cplusplus >= 201103L
> +    // Test an allocator that returns class-type pointers
> +    {
> +    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
> }
> 
> Modified: libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp?rev=220469&r1=220468&r2=220469&view=diff
> ==============================================================================
> --- libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp (original)
> +++ libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp Wed Oct 22 23:12:28 2014
> @@ -19,6 +19,7 @@
> #include <cstdlib>
> #include <cassert>
> #include "test_allocator.h"
> +#include "min_allocator.h"
> 
> int new_count = 0;
> 
> @@ -54,4 +55,24 @@ int main()
>     }
>     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);
> +    {
> +    int i = 68;
> +    char c = 'f';
> +    std::shared_ptr<A> p = std::allocate_shared<A>(bare_allocator<void>(), i, c);
> +    assert(A::count == 1);
> +    assert(p->get_int() == 68);
> +    assert(p->get_char() == 'f');
> +    }
> +    assert(A::count == 0);
> +#endif
> }
> 
> Added: libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_no_variadics.pass.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_no_variadics.pass.cpp?rev=220469&view=auto
> ==============================================================================
> --- libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_no_variadics.pass.cpp (added)
> +++ libcxx/trunk/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_no_variadics.pass.cpp Wed Oct 22 23:12:28 2014
> @@ -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"
> +
> +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
> +}
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits





More information about the cfe-commits mailing list