1# mode: run
2# tag: cpp, werror, cpp11
3
4from libcpp.memory cimport unique_ptr, shared_ptr, default_delete, dynamic_pointer_cast
5from libcpp cimport nullptr
6
7cdef extern from "cpp_smart_ptr_helper.h":
8    cdef cppclass CountAllocDealloc:
9        CountAllocDealloc(int*, int*)
10
11    cdef cppclass FreePtr[T]:
12        pass
13
14
15ctypedef const CountAllocDealloc const_CountAllocDealloc
16
17
18def test_unique_ptr():
19    """
20    >>> test_unique_ptr()
21    """
22    cdef int alloc_count = 0, dealloc_count = 0
23    cdef unique_ptr[CountAllocDealloc] x_ptr
24    x_ptr.reset(new CountAllocDealloc(&alloc_count, &dealloc_count))
25    assert alloc_count == 1
26    x_ptr.reset()
27    assert alloc_count == 1
28    assert dealloc_count == 1
29
30    ##Repeat the above test with an explicit default_delete type
31    alloc_count = 0
32    dealloc_count = 0
33    cdef unique_ptr[CountAllocDealloc,default_delete[CountAllocDealloc]] x_ptr2
34    x_ptr2.reset(new CountAllocDealloc(&alloc_count, &dealloc_count))
35    assert alloc_count == 1
36    x_ptr2.reset()
37    assert alloc_count == 1
38    assert dealloc_count == 1
39
40    alloc_count = 0
41    dealloc_count = 0
42    cdef unique_ptr[CountAllocDealloc,FreePtr[CountAllocDealloc]] x_ptr3
43    x_ptr3.reset(new CountAllocDealloc(&alloc_count, &dealloc_count))
44    assert x_ptr3.get() != nullptr;
45    x_ptr3.reset()
46    assert x_ptr3.get() == nullptr;
47
48
49def test_const_shared_ptr():
50    """
51    >>> test_const_shared_ptr()
52    """
53    cdef int alloc_count = 0, dealloc_count = 0
54    cdef shared_ptr[const CountAllocDealloc] ptr = shared_ptr[const_CountAllocDealloc](
55        new CountAllocDealloc(&alloc_count, &dealloc_count))
56    assert alloc_count == 1
57    assert dealloc_count == 0
58
59    cdef shared_ptr[const CountAllocDealloc] ptr2 = ptr
60    assert alloc_count == 1
61    assert dealloc_count == 0
62
63    ptr.reset()
64    assert alloc_count == 1
65    assert dealloc_count == 0
66
67    ptr2.reset()
68    assert alloc_count == 1
69    assert dealloc_count == 1
70
71
72cdef cppclass A:
73    void some_method():  # Force this to be a polymorphic class for dynamic cast.
74        pass
75
76cdef cppclass B(A):
77    pass
78
79cdef cppclass C(B):
80    pass
81
82cdef shared_ptr[A] holding_subclass = shared_ptr[A](new C())
83
84def test_dynamic_pointer_cast():
85    """
86    >>> test_dynamic_pointer_cast()
87    """
88    cdef shared_ptr[B] b = shared_ptr[B](new B())
89    cdef shared_ptr[A] a = dynamic_pointer_cast[A, B](b)
90    assert a.get() == b.get()
91
92    a = shared_ptr[A](new A())
93    b = dynamic_pointer_cast[B, A](a)
94    assert b.get() == NULL
95