From e2d0d129170ff39f0ed802cf3def3146f609529e Mon Sep 17 00:00:00 2001 From: Robert Bradshaw <robertwb@gmail.com> Date: Tue, 31 Jul 2018 22:51:05 -0700 Subject: [PATCH] Add C++11 smart pointer casts. --- Cython/Includes/libcpp/memory.pxd | 6 ++++++ tests/run/cpp_smart_ptr.pyx | 17 +++++++++++++++-- tests/run/cpp_smart_ptr_helper.h | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/Cython/Includes/libcpp/memory.pxd b/Cython/Includes/libcpp/memory.pxd index b300dda32..2151c1ec7 100644 --- a/Cython/Includes/libcpp/memory.pxd +++ b/Cython/Includes/libcpp/memory.pxd @@ -107,3 +107,9 @@ cdef extern from "<memory>" namespace "std" nogil: # Temporaries used for exception handling break generated code unique_ptr[T] make_unique[T](...) # except + + + # No checking on the compatibility of T and U. + cdef shared_ptr[T] static_pointer_cast[T, U](const shared_ptr[U]&) + cdef shared_ptr[T] dynamic_pointer_cast[T, U](const shared_ptr[U]&) + cdef shared_ptr[T] const_pointer_cast[T, U](const shared_ptr[U]&) + cdef shared_ptr[T] reinterpret_pointer_cast[T, U](const shared_ptr[U]&) diff --git a/tests/run/cpp_smart_ptr.pyx b/tests/run/cpp_smart_ptr.pyx index 7822e287b..e6f2a53cc 100644 --- a/tests/run/cpp_smart_ptr.pyx +++ b/tests/run/cpp_smart_ptr.pyx @@ -2,7 +2,7 @@ # tag: cpp, werror, cpp11 # distutils: extra_compile_args=-std=c++0x -from libcpp.memory cimport unique_ptr, shared_ptr, default_delete +from libcpp.memory cimport unique_ptr, shared_ptr, default_delete, dynamic_pointer_cast from libcpp cimport nullptr cdef extern from "cpp_smart_ptr_helper.h": @@ -71,7 +71,8 @@ def test_const_shared_ptr(): cdef cppclass A: - pass + void some_method(): # Force this to be a polymorphic class for dynamic cast. + pass cdef cppclass B(A): pass @@ -80,3 +81,15 @@ cdef cppclass C(B): pass cdef shared_ptr[A] holding_subclass = shared_ptr[A](new C()) + +def test_dynamic_pointer_cast(): + """ + >>> test_dynamic_pointer_cast() + """ + cdef shared_ptr[B] b = shared_ptr[B](new B()) + cdef shared_ptr[A] a = dynamic_pointer_cast[A, B](b) + assert a.get() == b.get() + + a = shared_ptr[A](new A()) + b = dynamic_pointer_cast[B, A](a) + assert b.get() == NULL diff --git a/tests/run/cpp_smart_ptr_helper.h b/tests/run/cpp_smart_ptr_helper.h index 9081801f9..02d73868c 100644 --- a/tests/run/cpp_smart_ptr_helper.h +++ b/tests/run/cpp_smart_ptr_helper.h @@ -14,7 +14,7 @@ class CountAllocDealloc { template<typename T> struct FreePtr { - void operator()( T * t ) noexcept + void operator()( T * t ) { if(t != nullptr) { delete t; -- 2.30.9