diff options
author | Robert Bradshaw <robertwb@gmail.com> | 2016-03-10 23:51:13 -0800 |
---|---|---|
committer | Robert Bradshaw <robertwb@gmail.com> | 2016-03-10 23:51:13 -0800 |
commit | 12df7f321f170bada046a552997022041e307b5a (patch) | |
tree | 128c6f39ffc21152796adf2b86b43b014b9948be | |
parent | 3822c930795d4a1909ef07a59ae4259dc75ec103 (diff) | |
parent | b74b9630530cf6e85644904b260a0f12b5f59a44 (diff) | |
download | cython-12df7f321f170bada046a552997022041e307b5a.tar.gz |
Merge branch 'molpopgen'
-rw-r--r-- | Cython/Compiler/PyrexTypes.py | 18 | ||||
-rw-r--r-- | Cython/Includes/libcpp/deque.pxd | 2 | ||||
-rw-r--r-- | Cython/Includes/libcpp/list.pxd | 2 | ||||
-rw-r--r-- | Cython/Includes/libcpp/map.pxd | 2 | ||||
-rw-r--r-- | Cython/Includes/libcpp/memory.pxd | 20 | ||||
-rw-r--r-- | Cython/Includes/libcpp/unordered_set.pxd | 2 | ||||
-rw-r--r-- | Cython/Includes/libcpp/vector.pxd | 2 | ||||
-rw-r--r-- | tests/run/cpp_smart_ptr.pyx | 24 | ||||
-rw-r--r-- | tests/run/cpp_smart_ptr_helper.h | 11 | ||||
-rw-r--r-- | tests/run/libcpp_all.pyx | 18 |
10 files changed, 89 insertions, 12 deletions
diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index c20484621..6c425f3d0 100644 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -3393,10 +3393,16 @@ class CStructOrUnionType(CType): cpp_string_conversions = ("std::string",) -builtin_cpp_conversions = ("std::pair", - "std::vector", "std::list", - "std::set", "std::unordered_set", - "std::map", "std::unordered_map") +builtin_cpp_conversions = { + # type element template params + "std::pair": 2, + "std::vector": 1, + "std::list": 1, + "std::set": 1, + "std::unordered_set": 1, + "std::map": 2, + "std::unordered_map": 2, +} class CppClassType(CType): # name string @@ -3445,6 +3451,8 @@ class CppClassType(CType): tags = [] declarations = ["cdef extern from *:"] for ix, T in enumerate(self.templates or []): + if ix >= builtin_cpp_conversions[self.cname]: + break if T.is_pyobject or not T.create_from_py_utility_code(env): return False tags.append(T.specialization_name()) @@ -3507,6 +3515,8 @@ class CppClassType(CType): tags = [] declarations = ["cdef extern from *:"] for ix, T in enumerate(self.templates or []): + if ix >= builtin_cpp_conversions[self.cname]: + break if not T.create_to_py_utility_code(env): return False tags.append(T.specialization_name()) diff --git a/Cython/Includes/libcpp/deque.pxd b/Cython/Includes/libcpp/deque.pxd index d7e774745..c36bef3b0 100644 --- a/Cython/Includes/libcpp/deque.pxd +++ b/Cython/Includes/libcpp/deque.pxd @@ -1,5 +1,5 @@ cdef extern from "<deque>" namespace "std" nogil: - cdef cppclass deque[T]: + cdef cppclass deque[T,ALLOCATOR=*]: cppclass iterator: T& operator*() iterator operator++() diff --git a/Cython/Includes/libcpp/list.pxd b/Cython/Includes/libcpp/list.pxd index bad97f2bc..9245a71f9 100644 --- a/Cython/Includes/libcpp/list.pxd +++ b/Cython/Includes/libcpp/list.pxd @@ -1,5 +1,5 @@ cdef extern from "<list>" namespace "std" nogil: - cdef cppclass list[T]: + cdef cppclass list[T,ALLOCATOR=*]: cppclass iterator: iterator() iterator(iterator &) diff --git a/Cython/Includes/libcpp/map.pxd b/Cython/Includes/libcpp/map.pxd index a1c84f1f6..f6b36fec5 100644 --- a/Cython/Includes/libcpp/map.pxd +++ b/Cython/Includes/libcpp/map.pxd @@ -1,7 +1,7 @@ from .utility cimport pair cdef extern from "<map>" namespace "std" nogil: - cdef cppclass map[T, U]: + cdef cppclass map[T, U,COMPARE=*,ALLOCATOR=*]: cppclass iterator: pair[T, U]& operator*() iterator operator++() diff --git a/Cython/Includes/libcpp/memory.pxd b/Cython/Includes/libcpp/memory.pxd index 7056fa795..425ce4658 100644 --- a/Cython/Includes/libcpp/memory.pxd +++ b/Cython/Includes/libcpp/memory.pxd @@ -1,8 +1,24 @@ from libcpp cimport bool, nullptr_t, nullptr cdef extern from "<memory>" namespace "std" nogil: - - cdef cppclass unique_ptr[T]: + cdef cppclass default_delete[T]: + default_delete() + + cdef cppclass allocator[T]: + allocator() + allocator(const allocator &) + #allocator(const allocator[U] &) #unique_ptr unit tests fail w/this + T * address(T &) + const T * address(const T &) const + T * allocate( size_t n ) # Not to standard. should be a second default argument + void deallocate(T * , size_t) + size_t max_size() const + void construct( T *, const T &) #C++98. The C++11 version is variadic AND perfect-forwarding + void destroy(T *) #C++98 + void destroy[U](U *) #unique_ptr unit tests fail w/this + + + cdef cppclass unique_ptr[T,DELETER=*]: unique_ptr() unique_ptr(nullptr_t) unique_ptr(T*) diff --git a/Cython/Includes/libcpp/unordered_set.pxd b/Cython/Includes/libcpp/unordered_set.pxd index 866902c2e..5c9129da4 100644 --- a/Cython/Includes/libcpp/unordered_set.pxd +++ b/Cython/Includes/libcpp/unordered_set.pxd @@ -1,7 +1,7 @@ from .utility cimport pair cdef extern from "<unordered_set>" namespace "std" nogil: - cdef cppclass unordered_set[T]: + cdef cppclass unordered_set[T,HASH=*,PRED=*,ALLOCATOR=*]: cppclass iterator: T& operator*() iterator operator++() diff --git a/Cython/Includes/libcpp/vector.pxd b/Cython/Includes/libcpp/vector.pxd index e8afcd967..ce416debb 100644 --- a/Cython/Includes/libcpp/vector.pxd +++ b/Cython/Includes/libcpp/vector.pxd @@ -1,5 +1,5 @@ cdef extern from "<vector>" namespace "std" nogil: - cdef cppclass vector[T]: + cdef cppclass vector[T,ALLOCATOR=*]: cppclass iterator: T& operator*() iterator operator++() diff --git a/tests/run/cpp_smart_ptr.pyx b/tests/run/cpp_smart_ptr.pyx index 97fcde2ef..037ee6fd9 100644 --- a/tests/run/cpp_smart_ptr.pyx +++ b/tests/run/cpp_smart_ptr.pyx @@ -2,12 +2,16 @@ # mode: run # tag: cpp, werror -from libcpp.memory cimport unique_ptr, shared_ptr +from libcpp.memory cimport unique_ptr, shared_ptr, default_delete +from libcpp cimport nullptr cdef extern from "cpp_smart_ptr_helper.h": cdef cppclass CountAllocDealloc: CountAllocDealloc(int*, int*) + cdef cppclass FreePtr[T]: + pass + def test_unique_ptr(): """ >>> test_unique_ptr() @@ -19,3 +23,21 @@ def test_unique_ptr(): x_ptr.reset() assert alloc_count == 1 assert dealloc_count == 1 + + ##Repeat the above test with an explicit default_delete type + alloc_count = 0 + dealloc_count = 0 + cdef unique_ptr[CountAllocDealloc,default_delete[CountAllocDealloc]] x_ptr2 + x_ptr2.reset(new CountAllocDealloc(&alloc_count, &dealloc_count)) + assert alloc_count == 1 + x_ptr2.reset() + assert alloc_count == 1 + assert dealloc_count == 1 + + alloc_count = 0 + dealloc_count = 0 + cdef unique_ptr[CountAllocDealloc,FreePtr[CountAllocDealloc]] x_ptr3 + x_ptr3.reset(new CountAllocDealloc(&alloc_count, &dealloc_count)) + assert x_ptr3.get() != nullptr; + x_ptr3.reset() + assert x_ptr3.get() == nullptr; diff --git a/tests/run/cpp_smart_ptr_helper.h b/tests/run/cpp_smart_ptr_helper.h index 9fa7df913..9081801f9 100644 --- a/tests/run/cpp_smart_ptr_helper.h +++ b/tests/run/cpp_smart_ptr_helper.h @@ -11,3 +11,14 @@ class CountAllocDealloc { int* _alloc_count; int* _dealloc_count; }; + +template<typename T> +struct FreePtr { + void operator()( T * t ) noexcept + { + if(t != nullptr) { + delete t; + t=nullptr; + } + } +}; diff --git a/tests/run/libcpp_all.pyx b/tests/run/libcpp_all.pyx index ae3223c88..45983bafc 100644 --- a/tests/run/libcpp_all.pyx +++ b/tests/run/libcpp_all.pyx @@ -107,3 +107,21 @@ cdef int ieps = numeric_limits[int].epsilon() cdef int iqnan = numeric_limits[int].quiet_NaN() cdef int isnan = numeric_limits[int].signaling_NaN() cdef int iinf = numeric_limits[int].infinity() + +#API checks for containers with std::allocator declared +from libcpp.memory cimport allocator + +cdef libcpp.vector.vector[int,allocator[int]] vec_alloc_int = libcpp.vector.vector[int,allocator[int]](10,1) +assert vec_alloc_int.size() == 10 + +cdef libcpp.list.list[int,allocator[int]] list_alloc_int = libcpp.list.list[int,allocator[int]](10,1) +assert list_alloc_int.size() == 10 + +##Something about the default params breaks the auto-conversion... +def convert_to_vector(I): + """ + >>> convert_to_vector([1,2,3,4]) + """ + cdef vector[int] x = I + + |