summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Bradshaw <robertwb@gmail.com>2016-03-10 23:51:13 -0800
committerRobert Bradshaw <robertwb@gmail.com>2016-03-10 23:51:13 -0800
commit12df7f321f170bada046a552997022041e307b5a (patch)
tree128c6f39ffc21152796adf2b86b43b014b9948be
parent3822c930795d4a1909ef07a59ae4259dc75ec103 (diff)
parentb74b9630530cf6e85644904b260a0f12b5f59a44 (diff)
downloadcython-12df7f321f170bada046a552997022041e307b5a.tar.gz
Merge branch 'molpopgen'
-rw-r--r--Cython/Compiler/PyrexTypes.py18
-rw-r--r--Cython/Includes/libcpp/deque.pxd2
-rw-r--r--Cython/Includes/libcpp/list.pxd2
-rw-r--r--Cython/Includes/libcpp/map.pxd2
-rw-r--r--Cython/Includes/libcpp/memory.pxd20
-rw-r--r--Cython/Includes/libcpp/unordered_set.pxd2
-rw-r--r--Cython/Includes/libcpp/vector.pxd2
-rw-r--r--tests/run/cpp_smart_ptr.pyx24
-rw-r--r--tests/run/cpp_smart_ptr_helper.h11
-rw-r--r--tests/run/libcpp_all.pyx18
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
+
+