Commit 12df7f32 authored by Robert Bradshaw's avatar Robert Bradshaw

Merge branch 'molpopgen'

parents 3822c930 b74b9630
...@@ -3393,10 +3393,16 @@ class CStructOrUnionType(CType): ...@@ -3393,10 +3393,16 @@ class CStructOrUnionType(CType):
cpp_string_conversions = ("std::string",) cpp_string_conversions = ("std::string",)
builtin_cpp_conversions = ("std::pair", builtin_cpp_conversions = {
"std::vector", "std::list", # type element template params
"std::set", "std::unordered_set", "std::pair": 2,
"std::map", "std::unordered_map") "std::vector": 1,
"std::list": 1,
"std::set": 1,
"std::unordered_set": 1,
"std::map": 2,
"std::unordered_map": 2,
}
class CppClassType(CType): class CppClassType(CType):
# name string # name string
...@@ -3445,6 +3451,8 @@ class CppClassType(CType): ...@@ -3445,6 +3451,8 @@ class CppClassType(CType):
tags = [] tags = []
declarations = ["cdef extern from *:"] declarations = ["cdef extern from *:"]
for ix, T in enumerate(self.templates or []): 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): if T.is_pyobject or not T.create_from_py_utility_code(env):
return False return False
tags.append(T.specialization_name()) tags.append(T.specialization_name())
...@@ -3507,6 +3515,8 @@ class CppClassType(CType): ...@@ -3507,6 +3515,8 @@ class CppClassType(CType):
tags = [] tags = []
declarations = ["cdef extern from *:"] declarations = ["cdef extern from *:"]
for ix, T in enumerate(self.templates or []): 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): if not T.create_to_py_utility_code(env):
return False return False
tags.append(T.specialization_name()) tags.append(T.specialization_name())
......
cdef extern from "<deque>" namespace "std" nogil: cdef extern from "<deque>" namespace "std" nogil:
cdef cppclass deque[T]: cdef cppclass deque[T,ALLOCATOR=*]:
cppclass iterator: cppclass iterator:
T& operator*() T& operator*()
iterator operator++() iterator operator++()
......
cdef extern from "<list>" namespace "std" nogil: cdef extern from "<list>" namespace "std" nogil:
cdef cppclass list[T]: cdef cppclass list[T,ALLOCATOR=*]:
cppclass iterator: cppclass iterator:
iterator() iterator()
iterator(iterator &) iterator(iterator &)
......
from .utility cimport pair from .utility cimport pair
cdef extern from "<map>" namespace "std" nogil: cdef extern from "<map>" namespace "std" nogil:
cdef cppclass map[T, U]: cdef cppclass map[T, U,COMPARE=*,ALLOCATOR=*]:
cppclass iterator: cppclass iterator:
pair[T, U]& operator*() pair[T, U]& operator*()
iterator operator++() iterator operator++()
......
from libcpp cimport bool, nullptr_t, nullptr from libcpp cimport bool, nullptr_t, nullptr
cdef extern from "<memory>" namespace "std" nogil: cdef extern from "<memory>" namespace "std" nogil:
cdef cppclass default_delete[T]:
cdef cppclass unique_ptr[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()
unique_ptr(nullptr_t) unique_ptr(nullptr_t)
unique_ptr(T*) unique_ptr(T*)
......
from .utility cimport pair from .utility cimport pair
cdef extern from "<unordered_set>" namespace "std" nogil: cdef extern from "<unordered_set>" namespace "std" nogil:
cdef cppclass unordered_set[T]: cdef cppclass unordered_set[T,HASH=*,PRED=*,ALLOCATOR=*]:
cppclass iterator: cppclass iterator:
T& operator*() T& operator*()
iterator operator++() iterator operator++()
......
cdef extern from "<vector>" namespace "std" nogil: cdef extern from "<vector>" namespace "std" nogil:
cdef cppclass vector[T]: cdef cppclass vector[T,ALLOCATOR=*]:
cppclass iterator: cppclass iterator:
T& operator*() T& operator*()
iterator operator++() iterator operator++()
......
...@@ -2,12 +2,16 @@ ...@@ -2,12 +2,16 @@
# mode: run # mode: run
# tag: cpp, werror # 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 extern from "cpp_smart_ptr_helper.h":
cdef cppclass CountAllocDealloc: cdef cppclass CountAllocDealloc:
CountAllocDealloc(int*, int*) CountAllocDealloc(int*, int*)
cdef cppclass FreePtr[T]:
pass
def test_unique_ptr(): def test_unique_ptr():
""" """
>>> test_unique_ptr() >>> test_unique_ptr()
...@@ -19,3 +23,21 @@ def test_unique_ptr(): ...@@ -19,3 +23,21 @@ def test_unique_ptr():
x_ptr.reset() x_ptr.reset()
assert alloc_count == 1 assert alloc_count == 1
assert dealloc_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;
...@@ -11,3 +11,14 @@ class CountAllocDealloc { ...@@ -11,3 +11,14 @@ class CountAllocDealloc {
int* _alloc_count; int* _alloc_count;
int* _dealloc_count; int* _dealloc_count;
}; };
template<typename T>
struct FreePtr {
void operator()( T * t ) noexcept
{
if(t != nullptr) {
delete t;
t=nullptr;
}
}
};
...@@ -107,3 +107,21 @@ cdef int ieps = numeric_limits[int].epsilon() ...@@ -107,3 +107,21 @@ cdef int ieps = numeric_limits[int].epsilon()
cdef int iqnan = numeric_limits[int].quiet_NaN() cdef int iqnan = numeric_limits[int].quiet_NaN()
cdef int isnan = numeric_limits[int].signaling_NaN() cdef int isnan = numeric_limits[int].signaling_NaN()
cdef int iinf = numeric_limits[int].infinity() 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment