| # TODO: Figure out how many of the pass-by-value copies the compiler can eliminate. |
|
|
|
|
| #################### string.from_py #################### |
|
|
| cdef extern from *: |
| cdef cppclass string "{{type}}": |
| string() except + |
| string(char* c_str, size_t size) except + |
| cdef const char* __Pyx_PyObject_AsStringAndSize(object, Py_ssize_t*) except NULL |
|
|
| @cname("{{cname}}") |
| cdef string {{cname}}(object o) except *: |
| cdef Py_ssize_t length = 0 |
| cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) |
| return string(data, <size_t> length) |
|
|
|
|
| #################### string.to_py #################### |
|
|
| #cimport cython |
| #from libcpp.string cimport string |
| cdef extern from *: |
| const Py_ssize_t PY_SSIZE_T_MAX |
| cdef cppclass string "{{type}}": |
| char* data() |
| size_t size() |
|
|
| {{for py_type in ['PyObject', 'PyUnicode', 'PyBytes', 'PyByteArray']}} |
| cdef extern from *: |
| cdef object __Pyx_{{py_type}}_FromStringAndSize(const char*, size_t) |
|
|
| @cname("{{cname.replace("PyObject", py_type, 1)}}") |
| cdef inline object {{cname.replace("PyObject", py_type, 1)}}(const string& s): |
| if s.size() > <size_t> PY_SSIZE_T_MAX: |
| raise MemoryError() |
| return __Pyx_{{py_type}}_FromStringAndSize(s.data(), <Py_ssize_t> s.size()) |
| {{endfor}} |
|
|
|
|
| #################### vector.from_py #################### |
| #@requires: ObjectHandling.c::LengthHint |
|
|
| cdef extern from *: |
| cdef cppclass vector "std::vector" [T]: |
| void push_back(T&) except + |
| void reserve(size_t) except + |
|
|
| cdef Py_ssize_t __Pyx_PyObject_LengthHint(object o, Py_ssize_t defaultval) except -1 |
|
|
| @cname("{{cname}}") |
| cdef vector[X] {{cname}}(object o) except *: |
|
|
| cdef vector[X] v |
| cdef Py_ssize_t s = __Pyx_PyObject_LengthHint(o, 0) |
|
|
| if s > 0: |
| v.reserve(<size_t> s) |
|
|
| for item in o: |
| v.push_back(<X>item) |
|
|
| return v |
|
|
|
|
| #################### vector.to_py #################### |
|
|
| cdef extern from *: |
| 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) |
| int __Pyx_PyList_SET_ITEM(object list, Py_ssize_t i, object o) except -1 |
| const Py_ssize_t PY_SSIZE_T_MAX |
|
|
| @cname("{{cname}}") |
| 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) |
| __Pyx_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&) except + |
|
|
| @cname("{{cname}}") |
| cdef cpp_list[X] {{cname}}(object o) except *: |
| cdef cpp_list[X] l |
| for item in o: |
| l.push_back(<X>item) |
| return l |
|
|
|
|
| #################### list.to_py #################### |
|
|
| cimport cython |
|
|
| cdef extern from *: |
| cdef cppclass cpp_list "std::list" [T]: |
| cppclass const_iterator: |
| T& operator*() |
| const_iterator operator++() |
| 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 __Pyx_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): |
| 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(): |
| item = cython.operator.dereference(iter) |
| Py_INCREF(item) |
| __Pyx_PyList_SET_ITEM(o, i, item) |
| cython.operator.preincrement(iter) |
| i += 1 |
|
|
| return o |
|
|
|
|
| #################### set.from_py #################### |
|
|
| cdef extern from *: |
| cdef cppclass set "std::{{maybe_unordered}}set" [T]: |
| void insert(T&) except + |
|
|
| @cname("{{cname}}") |
| cdef set[X] {{cname}}(object o) except *: |
| cdef set[X] s |
| for item in o: |
| s.insert(<X>item) |
| return s |
|
|
|
|
| #################### set.to_py #################### |
|
|
| cimport cython |
|
|
| cdef extern from *: |
| cdef cppclass cpp_set "std::{{maybe_unordered}}set" [T]: |
| cppclass const_iterator: |
| T& operator*() |
| const_iterator operator++() |
| bint operator!=(const_iterator) |
| const_iterator begin() |
| const_iterator end() |
|
|
| @cname("{{cname}}") |
| cdef object {{cname}}(const cpp_set[X]& s): |
| return {v for v in s} |
|
|
| #################### pair.from_py #################### |
|
|
| cdef extern from *: |
| cdef cppclass pair "std::pair" [T, U]: |
| pair() except + |
| pair(T&, U&) except + |
|
|
| @cname("{{cname}}") |
| cdef pair[X,Y] {{cname}}(object o) except *: |
| x, y = o |
| return pair[X,Y](<X>x, <Y>y) |
|
|
|
|
| #################### pair.to_py #################### |
|
|
| cdef extern from *: |
| cdef cppclass pair "std::pair" [T, U]: |
| T first |
| U second |
|
|
| @cname("{{cname}}") |
| cdef object {{cname}}(const pair[X,Y]& p): |
| return p.first, p.second |
|
|
|
|
| #################### map.from_py #################### |
|
|
| cdef extern from *: |
| cdef cppclass pair "std::pair" [T, U]: |
| pair(T&, U&) except + |
| cdef cppclass map "std::{{maybe_unordered}}map" [T, U]: |
| void insert(pair[T, U]&) except + |
| cdef cppclass vector "std::vector" [T]: |
| pass |
|
|
|
|
| @cname("{{cname}}") |
| cdef map[X,Y] {{cname}}(object o) except *: |
| cdef map[X,Y] m |
| for key, value in o.items(): |
| m.insert(pair[X,Y](<X>key, <Y>value)) |
| return m |
|
|
|
|
| #################### map.to_py #################### |
| # TODO: Work out const so that this can take a const |
| # reference rather than pass by value. |
|
|
| cimport cython |
|
|
| cdef extern from *: |
| cdef cppclass map "std::{{maybe_unordered}}map" [T, U]: |
| cppclass value_type: |
| T first |
| U second |
| cppclass const_iterator: |
| value_type& operator*() |
| const_iterator operator++() |
| bint operator!=(const_iterator) |
| const_iterator begin() |
| const_iterator end() |
|
|
| @cname("{{cname}}") |
| cdef object {{cname}}(const map[X,Y]& s): |
| o = {} |
| cdef const map[X,Y].value_type *key_value |
| cdef map[X,Y].const_iterator iter = s.begin() |
| while iter != s.end(): |
| key_value = &cython.operator.dereference(iter) |
| o[key_value.first] = key_value.second |
| cython.operator.preincrement(iter) |
| return o |
|
|
|
|
| #################### complex.from_py #################### |
|
|
| cdef extern from *: |
| cdef cppclass std_complex "std::complex" [T]: |
| std_complex() |
| std_complex(T, T) except + |
|
|
| @cname("{{cname}}") |
| cdef std_complex[X] {{cname}}(object o) except *: |
| cdef double complex z = o |
| return std_complex[X](<X>z.real, <X>z.imag) |
|
|
|
|
| #################### complex.to_py #################### |
|
|
| cdef extern from *: |
| cdef cppclass std_complex "std::complex" [T]: |
| X real() |
| X imag() |
|
|
| @cname("{{cname}}") |
| cdef object {{cname}}(const std_complex[X]& z): |
| cdef double complex tmp |
| tmp.real = <double>z.real() |
| tmp.imag = <double>z.imag() |
| return tmp |
|
|