diff options
Diffstat (limited to 'Cython/Utility/CppConvert.pyx')
-rw-r--r-- | Cython/Utility/CppConvert.pyx | 82 |
1 files changed, 59 insertions, 23 deletions
diff --git a/Cython/Utility/CppConvert.pyx b/Cython/Utility/CppConvert.pyx index 03360e510..1c6239b2b 100644 --- a/Cython/Utility/CppConvert.pyx +++ b/Cython/Utility/CppConvert.pyx @@ -5,8 +5,8 @@ cdef extern from *: cdef cppclass string "{{type}}": - string() - string(char* c_str, size_t size) + string() except + + string(char* c_str, size_t size) except + cdef const char* __Pyx_PyObject_AsStringAndSize(object, Py_ssize_t*) except NULL @cname("{{cname}}") @@ -39,7 +39,7 @@ cdef inline object {{cname.replace("PyObject", py_type, 1)}}(const string& s): cdef extern from *: cdef cppclass vector "std::vector" [T]: - void push_back(T&) + void push_back(T&) except + @cname("{{cname}}") cdef vector[X] {{cname}}(object o) except *: @@ -52,20 +52,39 @@ cdef vector[X] {{cname}}(object o) except *: #################### vector.to_py #################### cdef extern from *: - cdef cppclass vector "const std::vector" [T]: + cdef cppclass vector "std::vector" [T]: size_t size() T& operator[](size_t) +cdef extern from "Python.h": + void Py_INCREF(object) + list PyList_New(Py_ssize_t size) + void PyList_SET_ITEM(object list, Py_ssize_t i, object o) + cdef Py_ssize_t PY_SSIZE_T_MAX + @cname("{{cname}}") -cdef object {{cname}}(vector[X]& v): - return [v[i] for i in range(v.size())] +cdef object {{cname}}(const vector[X]& v): + if v.size() > <size_t> PY_SSIZE_T_MAX: + raise MemoryError() + v_size_signed = <Py_ssize_t> v.size() + + o = PyList_New(v_size_signed) + + cdef Py_ssize_t i + cdef object item + for i in range(v_size_signed): + item = v[i] + Py_INCREF(item) + PyList_SET_ITEM(o, i, item) + + return o #################### list.from_py #################### cdef extern from *: cdef cppclass cpp_list "std::list" [T]: - void push_back(T&) + void push_back(T&) except + @cname("{{cname}}") cdef cpp_list[X] {{cname}}(object o) except *: @@ -87,14 +106,32 @@ cdef extern from *: bint operator!=(const_iterator) const_iterator begin() const_iterator end() + size_t size() + +cdef extern from "Python.h": + void Py_INCREF(object) + list PyList_New(Py_ssize_t size) + void PyList_SET_ITEM(object list, Py_ssize_t i, object o) + cdef Py_ssize_t PY_SSIZE_T_MAX @cname("{{cname}}") cdef object {{cname}}(const cpp_list[X]& v): - o = [] + if v.size() > <size_t> PY_SSIZE_T_MAX: + raise MemoryError() + + o = PyList_New(<Py_ssize_t> v.size()) + + cdef object item + cdef Py_ssize_t i = 0 cdef cpp_list[X].const_iterator iter = v.begin() + while iter != v.end(): - o.append(cython.operator.dereference(iter)) + item = cython.operator.dereference(iter) + Py_INCREF(item) + PyList_SET_ITEM(o, i, item) cython.operator.preincrement(iter) + i += 1 + return o @@ -102,7 +139,7 @@ cdef object {{cname}}(const cpp_list[X]& v): cdef extern from *: cdef cppclass set "std::{{maybe_unordered}}set" [T]: - void insert(T&) + void insert(T&) except + @cname("{{cname}}") cdef set[X] {{cname}}(object o) except *: @@ -127,19 +164,14 @@ cdef extern from *: @cname("{{cname}}") cdef object {{cname}}(const cpp_set[X]& s): - o = set() - cdef cpp_set[X].const_iterator iter = s.begin() - while iter != s.end(): - o.add(cython.operator.dereference(iter)) - cython.operator.preincrement(iter) - return o + return {v for v in s} #################### pair.from_py #################### cdef extern from *: cdef cppclass pair "std::pair" [T, U]: - pair() - pair(T&, U&) + pair() except + + pair(T&, U&) except + @cname("{{cname}}") cdef pair[X,Y] {{cname}}(object o) except *: @@ -163,19 +195,23 @@ cdef object {{cname}}(const pair[X,Y]& p): cdef extern from *: cdef cppclass pair "std::pair" [T, U]: - pair(T&, U&) + pair(T&, U&) except + cdef cppclass map "std::{{maybe_unordered}}map" [T, U]: - void insert(pair[T, U]&) + void insert(pair[T, U]&) except + cdef cppclass vector "std::vector" [T]: pass + int PY_MAJOR_VERSION @cname("{{cname}}") cdef map[X,Y] {{cname}}(object o) except *: - cdef dict d = o cdef map[X,Y] m - for key, value in d.iteritems(): - m.insert(pair[X,Y](<X>key, <Y>value)) + if PY_MAJOR_VERSION < 3: + for key, value in o.iteritems(): + m.insert(pair[X,Y](<X>key, <Y>value)) + else: + for key, value in o.items(): + m.insert(pair[X,Y](<X>key, <Y>value)) return m |