15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#################### View.MemoryView ####################
25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# This utility provides cython.array and cython.view.memoryview
45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import cython
65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# from cpython cimport ...
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef extern from "Python.h":
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int PyIndex_Check "__Pyx_PyIndex_Check" (object)
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    object PyLong_FromVoidPtr(void *)
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef extern from "pythread.h":
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ctypedef void *PyThread_type_lock
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    PyThread_type_lock PyThread_allocate_lock()
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    void PyThread_free_lock(PyThread_type_lock)
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int PyThread_acquire_lock(PyThread_type_lock, int mode) nogil
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    void PyThread_release_lock(PyThread_type_lock) nogil
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef extern from "string.h":
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    void *memset(void *b, int c, size_t len)
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef extern from *:
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int __Pyx_GetBuffer(object, Py_buffer *, int) except -1
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    void __Pyx_ReleaseBuffer(Py_buffer *)
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ctypedef struct PyObject
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ctypedef Py_ssize_t Py_intptr_t
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    void Py_INCREF(PyObject *)
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    void Py_DECREF(PyObject *)
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    void* PyMem_Malloc(size_t n)
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    void PyMem_Free(void *p)
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef struct __pyx_memoryview "__pyx_memoryview_obj":
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        Py_buffer view
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        PyObject *obj
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        __Pyx_TypeInfo *typeinfo
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ctypedef struct {{memviewslice_name}}:
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        __pyx_memoryview *memview
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        char *data
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        Py_ssize_t shape[{{max_dims}}]
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        Py_ssize_t strides[{{max_dims}}]
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        Py_ssize_t suboffsets[{{max_dims}}]
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    void __PYX_INC_MEMVIEW({{memviewslice_name}} *memslice, int have_gil)
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    void __PYX_XDEC_MEMVIEW({{memviewslice_name}} *memslice, int have_gil)
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ctypedef struct __pyx_buffer "Py_buffer":
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        PyObject *obj
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    PyObject *Py_None
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef enum:
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        PyBUF_C_CONTIGUOUS,
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        PyBUF_F_CONTIGUOUS,
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        PyBUF_ANY_CONTIGUOUS
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        PyBUF_FORMAT
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        PyBUF_WRITABLE
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        PyBUF_STRIDES
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        PyBUF_INDIRECT
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        PyBUF_RECORDS
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ctypedef struct __Pyx_TypeInfo:
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        pass
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef object capsule "__pyx_capsule_create" (void *p, char *sig)
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef int __pyx_array_getbuffer(PyObject *obj, Py_buffer view, int flags)
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef int __pyx_memoryview_getbuffer(PyObject *obj, Py_buffer view, int flags)
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef extern from *:
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ctypedef int __pyx_atomic_int
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    {{memviewslice_name}} slice_copy_contig "__pyx_memoryview_copy_new_contig"(
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 __Pyx_memviewslice *from_mvs,
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 char *mode, int ndim,
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 size_t sizeof_dtype, int contig_flag,
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 bint dtype_is_object) nogil except *
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bint slice_is_contig "__pyx_memviewslice_is_contig" (
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            {{memviewslice_name}} *mvs, char order, int ndim) nogil
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bint slices_overlap "__pyx_slices_overlap" ({{memviewslice_name}} *slice1,
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                {{memviewslice_name}} *slice2,
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                int ndim, size_t itemsize) nogil
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef extern from "stdlib.h":
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    void *malloc(size_t) nogil
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    void free(void *) nogil
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    void *memcpy(void *dest, void *src, size_t n) nogil
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)### cython.array class
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname("__pyx_array")
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef class array:
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef:
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        char *data
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        Py_ssize_t len
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        char *format
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        int ndim
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        Py_ssize_t *_shape
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        Py_ssize_t *_strides
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        Py_ssize_t itemsize
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        unicode mode  # FIXME: this should have been a simple 'char'
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        bytes _format
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        void (*callback_free_data)(void *data)
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # cdef object _memview
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef bint free_data
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef bint dtype_is_object
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None,
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                  mode="c", bint allocate_buffer=True):
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef int idx
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef Py_ssize_t i, dim
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef PyObject **p
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.ndim = <int> len(shape)
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.itemsize = itemsize
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if not self.ndim:
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            raise ValueError("Empty shape tuple for cython.array")
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if itemsize <= 0:
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            raise ValueError("itemsize <= 0 for cython.array")
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if isinstance(format, unicode):
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            format = (<unicode>format).encode('ASCII')
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self._format = format  # keep a reference to the byte string
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.format = self._format
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # use single malloc() for both shape and strides
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2)
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self._strides = self._shape + self.ndim
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if not self._shape:
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            raise MemoryError("unable to allocate shape and strides.")
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # cdef Py_ssize_t dim, stride
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        for idx, dim in enumerate(shape):
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if dim <= 0:
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            self._shape[idx] = dim
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef char order
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if mode == 'fortran':
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            order = b'F'
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            self.mode = u'fortran'
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        elif mode == 'c':
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            order = b'C'
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            self.mode = u'c'
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.len = fill_contig_strides_array(self._shape, self._strides,
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                             itemsize, self.ndim, order)
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.free_data = allocate_buffer
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.dtype_is_object = format == b'O'
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if allocate_buffer:
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            # use malloc() for backwards compatibility
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            # in case external code wants to change the data pointer
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            self.data = <char *>malloc(self.len)
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if not self.data:
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                raise MemoryError("unable to allocate array data.")
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if self.dtype_is_object:
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                p = <PyObject **> self.data
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                for i in range(self.len / itemsize):
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    p[i] = Py_None
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    Py_INCREF(Py_None)
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @cname('getbuffer')
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __getbuffer__(self, Py_buffer *info, int flags):
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef int bufmode = -1
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if self.mode == u"c":
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        elif self.mode == u"fortran":
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if not (flags & bufmode):
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            raise ValueError("Can only create a buffer that is contiguous in memory.")
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.buf = self.data
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.len = self.len
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.ndim = self.ndim
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.shape = self._shape
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.strides = self._strides
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.suboffsets = NULL
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.itemsize = self.itemsize
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.readonly = 0
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if flags & PyBUF_FORMAT:
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            info.format = self.format
1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            info.format = NULL
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.obj = self
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __dealloc__(array self):
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if self.callback_free_data != NULL:
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            self.callback_free_data(self.data)
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        elif self.free_data:
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if self.dtype_is_object:
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                refcount_objects_in_slice(self.data, self._shape,
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                          self._strides, self.ndim, False)
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            free(self.data)
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        PyMem_Free(self._shape)
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    property memview:
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        @cname('get_memview')
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        def __get__(self):
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            # Make this a property as 'self.data' may be set after instantiation
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            flags =  PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return  memoryview(self, flags, self.dtype_is_object)
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __getattr__(self, attr):
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return getattr(self.memview, attr)
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __getitem__(self, item):
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return self.memview[item]
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __setitem__(self, item, value):
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.memview[item] = value
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname("__pyx_array_new")
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format,
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          char *mode, char *buf):
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef array result
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if buf == NULL:
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        result = array(shape, itemsize, format, mode.decode('ASCII'))
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else:
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        result = array(shape, itemsize, format, mode.decode('ASCII'),
2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       allocate_buffer=False)
2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        result.data = buf
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return result
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)### Memoryview constants and cython.view.memoryview class
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Disable generic_contiguous, as it makes trouble verifying contiguity:
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#   - 'contiguous' or '::1' means the dimension is contiguous with dtype
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#   - 'indirect_contiguous' means a contiguous list of pointers
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#   - dtype contiguous must be contiguous in the first or last dimension
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#     from the start, or from the dimension following the last indirect dimension
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#   e.g.
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#           int[::indirect_contiguous, ::contiguous, :]
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#   is valid (list of pointers to 2d fortran-contiguous array), but
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#           int[::generic_contiguous, ::contiguous, :]
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#   would mean you'd have assert dimension 0 to be indirect (and pointer contiguous) at runtime.
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#   So it doesn't bring any performance benefit, and it's only confusing.
2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_MemviewEnum')
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef class Enum(object):
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef object name
2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __init__(self, name):
2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.name = name
2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __repr__(self):
2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return self.name
2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef generic = Enum("<strided and direct or indirect>")
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef strided = Enum("<strided and direct>") # default
2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef indirect = Enum("<strided and indirect>")
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Disable generic_contiguous, as it is a troublemaker
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#cdef generic_contiguous = Enum("<contiguous and direct or indirect>")
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef contiguous = Enum("<contiguous and direct>")
2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef indirect_contiguous = Enum("<contiguous and indirect>")
2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# 'follow' is implied when the first or last axis is ::1
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_align_pointer')
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef void *align_pointer(void *memory, size_t alignment) nogil:
2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "Align pointer memory on a given boundary"
2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef size_t offset
2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    with cython.cdivision(True):
2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        offset = aligned_p % alignment
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if offset > 0:
2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        aligned_p += alignment - offset
2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return <void *> aligned_p
3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview')
3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef class memoryview(object):
3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef object obj
3055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef object _size
3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef object _array_interface
3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef PyThread_type_lock lock
3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # the following array will contain a single __pyx_atomic int with
3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # suitable alignment
3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef __pyx_atomic_int acquisition_count[2]
3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef __pyx_atomic_int *acquisition_count_aligned_p
3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef Py_buffer view
3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef int flags
3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef bint dtype_is_object
3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef __Pyx_TypeInfo *typeinfo
3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.obj = obj
3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.flags = flags
3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if type(self) is memoryview or obj is not None:
3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            __Pyx_GetBuffer(obj, &self.view, flags)
3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if <PyObject *> self.view.obj == NULL:
3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                (<__pyx_buffer *> &self.view).obj = Py_None
3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                Py_INCREF(Py_None)
3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.lock = PyThread_allocate_lock()
3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if self.lock == NULL:
3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            raise MemoryError
3295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if flags & PyBUF_FORMAT:
3315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            self.dtype_is_object = self.view.format == b'O'
3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
3335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            self.dtype_is_object = dtype_is_object
3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
3365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                  <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.typeinfo = NULL
3385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __dealloc__(memoryview self):
3405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if self.obj is not None:
3415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            __Pyx_ReleaseBuffer(&self.view)
3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if self.lock != NULL:
3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            PyThread_free_lock(self.lock)
3455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef char *get_item_pointer(memoryview self, object index) except NULL:
3475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef Py_ssize_t dim
3485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef char *itemp = <char *> self.view.buf
3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        for dim, idx in enumerate(index):
3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            itemp = pybuffer_index(&self.view, itemp, idx, dim)
3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return itemp
3545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    #@cname('__pyx_memoryview_getitem')
3565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __getitem__(memoryview self, object index):
3575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if index is Ellipsis:
3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return self
3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        have_slices, indices = _unellipsify(index, self.view.ndim)
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef char *itemp
3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if have_slices:
3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return memview_slice(self, indices)
3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            itemp = self.get_item_pointer(indices)
3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return self.convert_item_to_object(itemp)
3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __setitem__(memoryview self, object index, object value):
3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        have_slices, index = _unellipsify(index, self.view.ndim)
3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if have_slices:
3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            obj = self.is_slice(value)
3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if obj:
3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                self.setitem_slice_assignment(self[index], obj)
3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            else:
3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                self.setitem_slice_assign_scalar(self[index], value)
3785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
3795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            self.setitem_indexed(index, value)
3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef is_slice(self, obj):
3825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if not isinstance(obj, memoryview):
3835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            try:
3845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 self.dtype_is_object)
3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            except TypeError:
3875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                return None
3885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return obj
3905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef setitem_slice_assignment(self, dst, src):
3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef {{memviewslice_name}} dst_slice
3935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef {{memviewslice_name}} src_slice
3945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
3965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 get_slice_from_memview(dst, &dst_slice)[0],
3975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 src.ndim, dst.ndim, self.dtype_is_object)
3985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef setitem_slice_assign_scalar(self, memoryview dst, value):
4005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef int array[128]
4015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef void *tmp = NULL
4025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef void *item
4035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef {{memviewslice_name}} *dst_slice
4055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef {{memviewslice_name}} tmp_slice
4065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        dst_slice = get_slice_from_memview(dst, &tmp_slice)
4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if <size_t>self.view.itemsize > sizeof(array):
4095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            tmp = PyMem_Malloc(self.view.itemsize)
4105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if tmp == NULL:
4115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                raise MemoryError
4125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            item = tmp
4135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
4145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            item = <void *> array
4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        try:
4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if self.dtype_is_object:
4185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                (<PyObject **> item)[0] = <PyObject *> value
4195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            else:
4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                self.assign_item_from_object(<char *> item, value)
4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            # It would be easy to support indirect dimensions, but it's easier
4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            # to disallow :)
4245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if self.view.suboffsets != NULL:
4255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
4275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                item, self.dtype_is_object)
4285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        finally:
4295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            PyMem_Free(tmp)
4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef setitem_indexed(self, index, value):
4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef char *itemp = self.get_item_pointer(index)
4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.assign_item_from_object(itemp, value)
4345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef convert_item_to_object(self, char *itemp):
4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        """Only used if instantiated manually by the user, or if Cython doesn't
4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        know how to convert the type"""
4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        import struct
4395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef bytes bytesitem
4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # Do a manual and complete check here instead of this easy hack
4415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        bytesitem = itemp[:self.view.itemsize]
4425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        try:
4435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            result = struct.unpack(self.view.format, bytesitem)
4445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        except struct.error:
4455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            raise ValueError("Unable to convert item to object")
4465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
4475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if len(self.view.format) == 1:
4485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                return result[0]
4495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return result
4505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef assign_item_from_object(self, char *itemp, object value):
4525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        """Only used if instantiated manually by the user, or if Cython doesn't
4535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        know how to convert the type"""
4545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        import struct
4555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef char c
4565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef bytes bytesvalue
4575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef Py_ssize_t i
4585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if isinstance(value, tuple):
4605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            bytesvalue = struct.pack(self.view.format, *value)
4615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
4625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            bytesvalue = struct.pack(self.view.format, value)
4635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        for i, c in enumerate(bytesvalue):
4655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            itemp[i] = c
4665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    @cname('getbuffer')
4685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __getbuffer__(self, Py_buffer *info, int flags):
4695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if flags & PyBUF_STRIDES:
4705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            info.shape = self.view.shape
4715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
4725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            info.shape = NULL
4735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if flags & PyBUF_STRIDES:
4755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            info.strides = self.view.strides
4765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
4775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            info.strides = NULL
4785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if flags & PyBUF_INDIRECT:
4805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            info.suboffsets = self.view.suboffsets
4815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
4825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            info.suboffsets = NULL
4835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if flags & PyBUF_FORMAT:
4855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            info.format = self.view.format
4865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
4875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            info.format = NULL
4885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.buf = self.view.buf
4905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.ndim = self.view.ndim
4915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.itemsize = self.view.itemsize
4925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.len = self.view.len
4935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.readonly = 0
4945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.obj = self
4955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
4975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # Some properties that have the same sematics as in NumPy
4995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    property T:
5005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        @cname('__pyx_memoryview_transpose')
5015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        def __get__(self):
5025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            cdef _memoryviewslice result = memoryview_copy(self)
5035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            transpose_memslice(&result.from_slice)
5045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return result
5055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    property base:
5075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        @cname('__pyx_memoryview__get__base')
5085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        def __get__(self):
5095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return self.obj
5105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    property shape:
5125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        @cname('__pyx_memoryview_get_shape')
5135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        def __get__(self):
5145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
5155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    property strides:
5175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        @cname('__pyx_memoryview_get_strides')
5185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        def __get__(self):
5195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if self.view.strides == NULL:
5205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                # Note: we always ask for strides, so if this is not set it's a bug
5215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                raise ValueError("Buffer view does not expose strides")
5225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
5245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    property suboffsets:
5265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        @cname('__pyx_memoryview_get_suboffsets')
5275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        def __get__(self):
5285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if self.view.suboffsets == NULL:
5295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                return [-1] * self.view.ndim
5305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)])
5325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    property ndim:
5345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        @cname('__pyx_memoryview_get_ndim')
5355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        def __get__(self):
5365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return self.view.ndim
5375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    property itemsize:
5395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        @cname('__pyx_memoryview_get_itemsize')
5405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        def __get__(self):
5415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return self.view.itemsize
5425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    property nbytes:
5445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        @cname('__pyx_memoryview_get_nbytes')
5455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        def __get__(self):
5465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return self.size * self.view.itemsize
5475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    property size:
5495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        @cname('__pyx_memoryview_get_size')
5505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        def __get__(self):
5515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if self._size is None:
5525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                result = 1
5535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                for length in self.shape:
5555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    result *= length
5565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                self._size = result
5585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return self._size
5605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __len__(self):
5625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if self.view.ndim >= 1:
5635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return self.view.shape[0]
5645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return 0
5665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __repr__(self):
5685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
5695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               id(self))
5705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __str__(self):
5725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
5735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # Support the same attributes as memoryview slices
5755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def is_c_contig(self):
5765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef {{memviewslice_name}} *mslice
5775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef {{memviewslice_name}} tmp
5785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        mslice = get_slice_from_memview(self, &tmp)
5795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return slice_is_contig(mslice, 'C', self.view.ndim)
5805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def is_f_contig(self):
5825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef {{memviewslice_name}} *mslice
5835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef {{memviewslice_name}} tmp
5845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        mslice = get_slice_from_memview(self, &tmp)
5855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return slice_is_contig(mslice, 'F', self.view.ndim)
5865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def copy(self):
5885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef {{memviewslice_name}} mslice
5895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
5905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        slice_copy(self, &mslice)
5925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        mslice = slice_copy_contig(&mslice, "c", self.view.ndim,
5935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   self.view.itemsize,
5945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   flags|PyBUF_C_CONTIGUOUS,
5955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   self.dtype_is_object)
5965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return memoryview_copy_from_slice(self, &mslice)
5985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def copy_fortran(self):
6005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef {{memviewslice_name}} src, dst
6015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
6025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        slice_copy(self, &src)
6045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        dst = slice_copy_contig(&src, "fortran", self.view.ndim,
6055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                self.view.itemsize,
6065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                flags|PyBUF_F_CONTIGUOUS,
6075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                self.dtype_is_object)
6085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return memoryview_copy_from_slice(self, &dst)
6105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview_new')
6135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
6145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef memoryview result = memoryview(o, flags, dtype_is_object)
6155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    result.typeinfo = typeinfo
6165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return result
6175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview_check')
6195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef inline bint memoryview_check(object o):
6205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return isinstance(o, memoryview)
6215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef tuple _unellipsify(object index, int ndim):
6235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
6245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Replace all ellipses with full slices and fill incomplete indices with
6255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    full slices.
6265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
6275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if not isinstance(index, tuple):
6285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        tup = (index,)
6295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else:
6305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        tup = index
6315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    result = []
6335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    have_slices = False
6345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    seen_ellipsis = False
6355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for idx, item in enumerate(tup):
6365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if item is Ellipsis:
6375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if not seen_ellipsis:
6385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                result.extend([slice(None)] * (ndim - len(tup) + 1))
6395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                seen_ellipsis = True
6405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            else:
6415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                result.append(slice(None))
6425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            have_slices = True
6435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
6445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if not isinstance(item, slice) and not PyIndex_Check(item):
6455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                raise TypeError("Cannot index with type '%s'" % type(item))
6465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            have_slices = have_slices or isinstance(item, slice)
6485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            result.append(item)
6495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    nslices = ndim - len(result)
6515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if nslices:
6525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        result.extend([slice(None)] * nslices)
6535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return have_slices or nslices, tuple(result)
6555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
6575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef int i
6585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for i in range(ndim):
6595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if suboffsets[i] >= 0:
6605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            raise ValueError("Indirect dimensions not supported")
6615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
6635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)### Slicing a memoryview
6645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
6655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memview_slice')
6675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef memoryview memview_slice(memoryview memview, object indices):
6685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef int new_ndim = 0, suboffset_dim = -1, dim
6695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef bint negative_step
6705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef {{memviewslice_name}} src, dst
6715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef {{memviewslice_name}} *p_src
6725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # dst is copied by value in memoryview_fromslice -- initialize it
6745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # src is never copied
6755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    memset(&dst, 0, sizeof(dst))
6765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef _memoryviewslice memviewsliceobj
6785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    assert memview.view.ndim > 0
6805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if isinstance(memview, _memoryviewslice):
6825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        memviewsliceobj = memview
6835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        p_src = &memviewsliceobj.from_slice
6845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else:
6855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        slice_copy(memview, &src)
6865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        p_src = &src
6875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # Note: don't use variable src at this point
6895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # SubNote: we should be able to declare variables in blocks...
6905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # memoryview_fromslice() will inc our dst slice
6925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    dst.memview = p_src.memview
6935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    dst.data = p_src.data
6945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # Put everything in temps to avoid this bloody warning:
6965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # "Argument evaluation order in C function call is undefined and
6975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    #  may not be as expected"
6985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef {{memviewslice_name}} *p_dst = &dst
6995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef int *p_suboffset_dim = &suboffset_dim
7005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef Py_ssize_t start, stop, step
7015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef bint have_start, have_stop, have_step
7025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for dim, index in enumerate(indices):
7045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if PyIndex_Check(index):
7055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            slice_memviewslice(
7065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
7075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                dim, new_ndim, p_suboffset_dim,
7085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                index, 0, 0, # start, stop, step
7095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                0, 0, 0, # have_{start,stop,step}
7105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                False)
7115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        elif index is None:
7125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            p_dst.shape[new_ndim] = 1
7135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            p_dst.strides[new_ndim] = 0
7145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            p_dst.suboffsets[new_ndim] = -1
7155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            new_ndim += 1
7165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
7175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            start = index.start or 0
7185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            stop = index.stop or 0
7195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            step = index.step or 0
7205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            have_start = index.start is not None
7225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            have_stop = index.stop is not None
7235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            have_step = index.step is not None
7245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            slice_memviewslice(
7265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
7275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                dim, new_ndim, p_suboffset_dim,
7285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                start, stop, step,
7295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                have_start, have_stop, have_step,
7305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                True)
7315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            new_ndim += 1
7325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if isinstance(memview, _memoryviewslice):
7345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return memoryview_fromslice(dst, new_ndim,
7355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    memviewsliceobj.to_object_func,
7365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    memviewsliceobj.to_dtype_func,
7375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    memview.dtype_is_object)
7385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else:
7395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return memoryview_fromslice(dst, new_ndim, NULL, NULL,
7405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    memview.dtype_is_object)
7415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
7445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)### Slicing in a single dimension of a memoryviewslice
7455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
7465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef extern from "stdlib.h":
7485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    void abort() nogil
7495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    void printf(char *s, ...) nogil
7505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef extern from "stdio.h":
7525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ctypedef struct FILE
7535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    FILE *stderr
7545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int fputs(char *s, FILE *stream)
7555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef extern from "pystate.h":
7575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    void PyThreadState_Get() nogil
7585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # These are not actually nogil, but we check for the GIL before calling them
7605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    void PyErr_SetString(PyObject *type, char *msg) nogil
7615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    PyObject *PyErr_Format(PyObject *exc, char *msg, ...) nogil
7625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview_slice_memviewslice')
7645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef int slice_memviewslice(
7655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        {{memviewslice_name}} *dst,
7665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
7675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        int dim, int new_ndim, int *suboffset_dim,
7685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        Py_ssize_t start, Py_ssize_t stop, Py_ssize_t step,
7695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        int have_start, int have_stop, int have_step,
7705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        bint is_slice) nogil except -1:
7715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
7725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Create a new slice dst given slice src.
7735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    dim             - the current src dimension (indexing will make dimensions
7755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                 disappear)
7765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    new_dim         - the new dst dimension
7775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    suboffset_dim   - pointer to a single int initialized to -1 to keep track of
7785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      where slicing offsets should be added
7795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
7805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef Py_ssize_t new_shape
7825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef bint negative_step
7835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if not is_slice:
7855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # index is a normal integer-like index
7865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if start < 0:
7875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            start += shape
7885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if not 0 <= start < shape:
7895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
7905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else:
7915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # index is a slice
7925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        negative_step = have_step != 0 and step < 0
7935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if have_step and step == 0:
7955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            _err_dim(ValueError, "Step may not be zero (axis %d)", dim)
7965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # check our bounds and set defaults
7985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if have_start:
7995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if start < 0:
8005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                start += shape
8015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                if start < 0:
8025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    start = 0
8035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            elif start >= shape:
8045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                if negative_step:
8055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    start = shape - 1
8065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                else:
8075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    start = shape
8085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
8095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if negative_step:
8105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                start = shape - 1
8115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            else:
8125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                start = 0
8135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if have_stop:
8155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if stop < 0:
8165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                stop += shape
8175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                if stop < 0:
8185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    stop = 0
8195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            elif stop > shape:
8205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                stop = shape
8215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
8225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if negative_step:
8235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                stop = -1
8245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            else:
8255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                stop = shape
8265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if not have_step:
8285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            step = 1
8295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # len = ceil( (stop - start) / step )
8315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        with cython.cdivision(True):
8325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            new_shape = (stop - start) // step
8335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if (stop - start) - step * new_shape:
8355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                new_shape += 1
8365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if new_shape < 0:
8385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            new_shape = 0
8395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # shape/strides/suboffsets
8415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        dst.strides[new_ndim] = stride * step
8425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        dst.shape[new_ndim] = new_shape
8435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        dst.suboffsets[new_ndim] = suboffset
8445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # Add the slicing or idexing offsets to the right suboffset or base data *
8465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if suboffset_dim[0] < 0:
8475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        dst.data += start * stride
8485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else:
8495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        dst.suboffsets[suboffset_dim[0]] += start * stride
8505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if suboffset >= 0:
8525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if not is_slice:
8535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if new_ndim == 0:
8545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                dst.data = (<char **> dst.data)[0] + suboffset
8555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            else:
8565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                _err_dim(IndexError, "All dimensions preceding dimension %d "
8575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     "must be indexed and not sliced", dim)
8585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
8595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            suboffset_dim[0] = new_ndim
8605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return 0
8625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
8645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)### Index a memoryview
8655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
8665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_pybuffer_index')
8675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index,
8685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          Py_ssize_t dim) except NULL:
8695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef Py_ssize_t shape, stride, suboffset = -1
8705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef Py_ssize_t itemsize = view.itemsize
8715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef char *resultp
8725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if view.ndim == 0:
8745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        shape = view.len / itemsize
8755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        stride = itemsize
8765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else:
8775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        shape = view.shape[dim]
8785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        stride = view.strides[dim]
8795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if view.suboffsets != NULL:
8805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            suboffset = view.suboffsets[dim]
8815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if index < 0:
8835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        index += view.shape[dim]
8845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if index < 0:
8855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
8865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if index >= shape:
8885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
8895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    resultp = bufp + index * stride
8915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if suboffset >= 0:
8925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        resultp = (<char **> resultp)[0] + suboffset
8935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return resultp
8955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
8975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)### Transposing a memoryviewslice
8985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
8995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memslice_transpose')
9005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef int transpose_memslice({{memviewslice_name}} *memslice) nogil except 0:
9015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef int ndim = memslice.memview.view.ndim
9025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef Py_ssize_t *shape = memslice.shape
9045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef Py_ssize_t *strides = memslice.strides
9055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # reverse strides and shape
9075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef int i, j
9085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for i in range(ndim / 2):
9095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        j = ndim - 1 - i
9105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        strides[i], strides[j] = strides[j], strides[i]
9115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        shape[i], shape[j] = shape[j], shape[i]
9125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
9145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
9155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return 1
9175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
9195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)### Creating new memoryview objects from slices and memoryviews
9205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
9215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryviewslice')
9225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef class _memoryviewslice(memoryview):
9235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "Internal class for passing memoryview slices to Python"
9245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # We need this to keep our shape/strides/suboffset pointers valid
9265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef {{memviewslice_name}} from_slice
9275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # We need this only to print it's class' name
9285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef object from_object
9295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef object (*to_object_func)(char *)
9315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef int (*to_dtype_func)(char *, object) except 0
9325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __dealloc__(self):
9345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
9355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef convert_item_to_object(self, char *itemp):
9375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if self.to_object_func != NULL:
9385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return self.to_object_func(itemp)
9395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
9405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return memoryview.convert_item_to_object(self, itemp)
9415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef assign_item_from_object(self, char *itemp, object value):
9435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if self.to_dtype_func != NULL:
9445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            self.to_dtype_func(itemp, value)
9455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
9465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            memoryview.assign_item_from_object(self, itemp, value)
9475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    property base:
9495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        @cname('__pyx_memoryviewslice__get__base')
9505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        def __get__(self):
9515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return self.from_object
9525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
9545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview_fromslice')
9575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef memoryview_fromslice({{memviewslice_name}} memviewslice,
9585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          int ndim,
9595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          object (*to_object_func)(char *),
9605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          int (*to_dtype_func)(char *, object) except 0,
9615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          bint dtype_is_object):
9625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef _memoryviewslice result
9645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef int i
9655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if <PyObject *> memviewslice.memview == Py_None:
9675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return None
9685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # assert 0 < ndim <= memviewslice.memview.view.ndim, (
9705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    #                 ndim, memviewslice.memview.view.ndim)
9715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    result = _memoryviewslice(None, 0, dtype_is_object)
9735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    result.from_slice = memviewslice
9755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    __PYX_INC_MEMVIEW(&memviewslice, 1)
9765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    result.from_object = (<memoryview> memviewslice.memview).base
9785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    result.typeinfo = memviewslice.memview.typeinfo
9795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    result.view = memviewslice.memview.view
9815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    result.view.buf = <void *> memviewslice.data
9825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    result.view.ndim = ndim
9835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    (<__pyx_buffer *> &result.view).obj = Py_None
9845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Py_INCREF(Py_None)
9855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    result.flags = PyBUF_RECORDS
9875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    result.view.shape = <Py_ssize_t *> result.from_slice.shape
9895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    result.view.strides = <Py_ssize_t *> result.from_slice.strides
9905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
9915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    result.view.len = result.view.itemsize
9935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for i in range(ndim):
9945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        result.view.len *= result.view.shape[i]
9955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    result.to_object_func = to_object_func
9975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    result.to_dtype_func = to_dtype_func
9985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return result
10005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview_get_slice_from_memoryview')
10025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef {{memviewslice_name}} *get_slice_from_memview(memoryview memview,
10035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                   {{memviewslice_name}} *mslice):
10045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef _memoryviewslice obj
10055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if isinstance(memview, _memoryviewslice):
10065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        obj = memview
10075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return &obj.from_slice
10085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else:
10095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        slice_copy(memview, mslice)
10105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return mslice
10115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview_slice_copy')
10135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef void slice_copy(memoryview memview, {{memviewslice_name}} *dst):
10145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef int dim
10155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef (Py_ssize_t*) shape, strides, suboffsets
10165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    shape = memview.view.shape
10185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    strides = memview.view.strides
10195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    suboffsets = memview.view.suboffsets
10205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    dst.memview = <__pyx_memoryview *> memview
10225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    dst.data = <char *> memview.view.buf
10235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for dim in range(memview.view.ndim):
10255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        dst.shape[dim] = shape[dim]
10265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        dst.strides[dim] = strides[dim]
10275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if suboffsets == NULL:
10285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            dst.suboffsets[dim] = -1
10295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
10305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            dst.suboffsets[dim] = suboffsets[dim]
10315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview_copy_object')
10335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef memoryview_copy(memoryview memview):
10345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "Create a new memoryview object"
10355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef {{memviewslice_name}} memviewslice
10365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    slice_copy(memview, &memviewslice)
10375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return memoryview_copy_from_slice(memview, &memviewslice)
10385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview_copy_object_from_slice')
10405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef memoryview_copy_from_slice(memoryview memview, {{memviewslice_name}} *memviewslice):
10415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
10425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Create a new memoryview object from a given memoryview object and slice.
10435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
10445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef object (*to_object_func)(char *)
10455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef int (*to_dtype_func)(char *, object) except 0
10465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if isinstance(memview, _memoryviewslice):
10485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        to_object_func = (<_memoryviewslice> memview).to_object_func
10495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
10505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else:
10515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        to_object_func = NULL
10525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        to_dtype_func = NULL
10535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return memoryview_fromslice(memviewslice[0], memview.view.ndim,
10555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                to_object_func, to_dtype_func,
10565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                memview.dtype_is_object)
10575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
10605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)### Copy the contents of a memoryview slices
10615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
10625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
10635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if arg < 0:
10645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return -arg
10655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else:
10665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return arg
10675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_get_best_slice_order')
10695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef char get_best_order({{memviewslice_name}} *mslice, int ndim) nogil:
10705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
10715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Figure out the best memory access order for a given slice.
10725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
10735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef int i
10745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef Py_ssize_t c_stride = 0
10755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef Py_ssize_t f_stride = 0
10765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for i in range(ndim - 1, -1, -1):
10785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if mslice.shape[i] > 1:
10795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            c_stride = mslice.strides[i]
10805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            break
10815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for i in range(ndim):
10835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if mslice.shape[i] > 1:
10845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            f_stride = mslice.strides[i]
10855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            break
10865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
10885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return 'C'
10895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else:
10905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return 'F'
10915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cython.cdivision(True)
10935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides,
10945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   char *dst_data, Py_ssize_t *dst_strides,
10955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
10965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   int ndim, size_t itemsize) nogil:
10975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # Note: src_extent is 1 if we're broadcasting
10985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # dst_extent always >= src_extent as we don't do reductions
10995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef Py_ssize_t i
11005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef Py_ssize_t src_extent = src_shape[0]
11015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef Py_ssize_t dst_extent = dst_shape[0]
11025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef Py_ssize_t src_stride = src_strides[0]
11035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef Py_ssize_t dst_stride = dst_strides[0]
11045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
11055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if ndim == 1:
11065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       if (src_stride > 0 and dst_stride > 0 and
11075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)           <size_t> src_stride == itemsize == <size_t> dst_stride):
11085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)           memcpy(dst_data, src_data, itemsize * dst_extent)
11095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       else:
11105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)           for i in range(dst_extent):
11115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               memcpy(dst_data, src_data, itemsize)
11125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               src_data += src_stride
11135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               dst_data += dst_stride
11145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else:
11155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        for i in range(dst_extent):
11165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            _copy_strided_to_strided(src_data, src_strides + 1,
11175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     dst_data, dst_strides + 1,
11185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     src_shape + 1, dst_shape + 1,
11195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     ndim - 1, itemsize)
11205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            src_data += src_stride
11215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            dst_data += dst_stride
11225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
11235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef void copy_strided_to_strided({{memviewslice_name}} *src,
11245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                  {{memviewslice_name}} *dst,
11255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                  int ndim, size_t itemsize) nogil:
11265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    _copy_strided_to_strided(src.data, src.strides, dst.data, dst.strides,
11275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                             src.shape, dst.shape, ndim, itemsize)
11285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
11295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview_slice_get_size')
11305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef Py_ssize_t slice_get_size({{memviewslice_name}} *src, int ndim) nogil:
11315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "Return the size of the memory occupied by the slice in number of bytes"
11325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef int i
11335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef Py_ssize_t size = src.memview.view.itemsize
11345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
11355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for i in range(ndim):
11365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        size *= src.shape[i]
11375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
11385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return size
11395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
11405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_fill_contig_strides_array')
11415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef Py_ssize_t fill_contig_strides_array(
11425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
11435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                int ndim, char order) nogil:
11445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
11455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Fill the strides array for a slice with C or F contiguous strides.
11465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    This is like PyBuffer_FillContiguousStrides, but compatible with py < 2.6
11475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
11485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef int idx
11495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
11505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if order == 'F':
11515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        for idx in range(ndim):
11525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            strides[idx] = stride
11535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            stride = stride * shape[idx]
11545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else:
11555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        for idx in range(ndim - 1, -1, -1):
11565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            strides[idx] = stride
11575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            stride = stride * shape[idx]
11585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
11595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return stride
11605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
11615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview_copy_data_to_temp')
11625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef void *copy_data_to_temp({{memviewslice_name}} *src,
11635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                             {{memviewslice_name}} *tmpslice,
11645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                             char order,
11655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                             int ndim) nogil except NULL:
11665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
11675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Copy a direct slice to temporary contiguous memory. The caller should free
11685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    the result when done.
11695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
11705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef int i
11715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef void *result
11725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
11735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef size_t itemsize = src.memview.view.itemsize
11745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef size_t size = slice_get_size(src, ndim)
11755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
11765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    result = malloc(size)
11775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if not result:
11785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        _err(MemoryError, NULL)
11795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
11805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # tmpslice[0] = src
11815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    tmpslice.data = <char *> result
11825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    tmpslice.memview = src.memview
11835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for i in range(ndim):
11845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        tmpslice.shape[i] = src.shape[i]
11855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        tmpslice.suboffsets[i] = -1
11865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
11875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize,
11885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              ndim, order)
11895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
11905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # We need to broadcast strides again
11915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for i in range(ndim):
11925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if tmpslice.shape[i] == 1:
11935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            tmpslice.strides[i] = 0
11945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
11955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if slice_is_contig(src, order, ndim):
11965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        memcpy(result, src.data, size)
11975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else:
11985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        copy_strided_to_strided(src, tmpslice, ndim, itemsize)
11995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
12005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return result
12015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
12025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Use 'with gil' functions and avoid 'with gil' blocks, as the code within the blocks
12035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# has temporaries that need the GIL to clean up
12045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview_err_extents')
12055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef int _err_extents(int i, Py_ssize_t extent1,
12065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                             Py_ssize_t extent2) except -1 with gil:
12075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    raise ValueError("got differing extents in dimension %d (got %d and %d)" %
12085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                        (i, extent1, extent2))
12095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
12105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview_err_dim')
12115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef int _err_dim(object error, char *msg, int dim) except -1 with gil:
12125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    raise error(msg.decode('ascii') % dim)
12135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
12145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview_err')
12155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef int _err(object error, char *msg) except -1 with gil:
12165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if msg != NULL:
12175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        raise error(msg.decode('ascii'))
12185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else:
12195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        raise error
12205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
12215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview_copy_contents')
12225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef int memoryview_copy_contents({{memviewslice_name}} src,
12235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                  {{memviewslice_name}} dst,
12245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                  int src_ndim, int dst_ndim,
12255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                  bint dtype_is_object) nogil except -1:
12265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
12275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Copy memory from slice src to slice dst.
12285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Check for overlapping memory and verify the shapes.
12295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    """
12305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef void *tmpdata = NULL
12315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef size_t itemsize = src.memview.view.itemsize
12325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef int i
12335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef char order = get_best_order(&src, src_ndim)
12345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef bint broadcasting = False
12355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef bint direct_copy = False
12365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef {{memviewslice_name}} tmp
12375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
12385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if src_ndim < dst_ndim:
12395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        broadcast_leading(&src, src_ndim, dst_ndim)
12405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    elif dst_ndim < src_ndim:
12415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        broadcast_leading(&dst, dst_ndim, src_ndim)
12425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
12435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef int ndim = max(src_ndim, dst_ndim)
12445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
12455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for i in range(ndim):
12465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if src.shape[i] != dst.shape[i]:
12475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if src.shape[i] == 1:
12485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                broadcasting = True
12495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                src.strides[i] = 0
12505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            else:
12515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                _err_extents(i, dst.shape[i], src.shape[i])
12525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
12535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if src.suboffsets[i] >= 0:
12545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            _err_dim(ValueError, "Dimension %d is not direct", i)
12555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
12565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if slices_overlap(&src, &dst, ndim, itemsize):
12575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # slices overlap, copy to temp, copy temp to dst
12585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if not slice_is_contig(&src, order, ndim):
12595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            order = get_best_order(&dst, ndim)
12605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
12615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
12625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        src = tmp
12635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
12645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if not broadcasting:
12655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # See if both slices have equal contiguity, in that case perform a
12665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # direct copy. This only works when we are not broadcasting.
12675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if slice_is_contig(&src, 'C', ndim):
12685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            direct_copy = slice_is_contig(&dst, 'C', ndim)
12695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        elif slice_is_contig(&src, 'F', ndim):
12705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            direct_copy = slice_is_contig(&dst, 'F', ndim)
12715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
12725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if direct_copy:
12735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            # Contiguous slices with same order
12745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            refcount_copying(&dst, dtype_is_object, ndim, False)
12755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            memcpy(dst.data, src.data, slice_get_size(&src, ndim))
12765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            refcount_copying(&dst, dtype_is_object, ndim, True)
12775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            free(tmpdata)
12785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return 0
12795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
12805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if order == 'F' == get_best_order(&dst, ndim):
12815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # see if both slices have Fortran order, transpose them to match our
12825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # C-style indexing order
12835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        transpose_memslice(&src)
12845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        transpose_memslice(&dst)
12855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
12865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    refcount_copying(&dst, dtype_is_object, ndim, False)
12875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    copy_strided_to_strided(&src, &dst, ndim, itemsize)
12885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    refcount_copying(&dst, dtype_is_object, ndim, True)
12895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
12905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    free(tmpdata)
12915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return 0
12925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
12935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview_broadcast_leading')
12945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef void broadcast_leading({{memviewslice_name}} *slice,
12955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            int ndim,
12965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            int ndim_other) nogil:
12975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef int i
12985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef int offset = ndim_other - ndim
12995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
13005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for i in range(ndim - 1, -1, -1):
13015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        slice.shape[i + offset] = slice.shape[i]
13025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        slice.strides[i + offset] = slice.strides[i]
13035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        slice.suboffsets[i + offset] = slice.suboffsets[i]
13045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
13055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for i in range(offset):
13065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        slice.shape[i] = 1
13075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        slice.strides[i] = slice.strides[0]
13085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        slice.suboffsets[i] = -1
13095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
13105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
13115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)### Take care of refcounting the objects in slices. Do this seperately from any copying,
13125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)### to minimize acquiring the GIL
13135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
13145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
13155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview_refcount_copying')
13165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef void refcount_copying({{memviewslice_name}} *dst, bint dtype_is_object,
13175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                           int ndim, bint inc) nogil:
13185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # incref or decref the objects in the destination slice if the dtype is
13195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # object
13205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if dtype_is_object:
13215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        refcount_objects_in_slice_with_gil(dst.data, dst.shape,
13225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                           dst.strides, ndim, inc)
13235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
13245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
13255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape,
13265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                             Py_ssize_t *strides, int ndim,
13275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                             bint inc) with gil:
13285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    refcount_objects_in_slice(data, shape, strides, ndim, inc)
13295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
13305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview_refcount_objects_in_slice')
13315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape,
13325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    Py_ssize_t *strides, int ndim, bint inc):
13335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef Py_ssize_t i
13345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
13355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for i in range(shape[0]):
13365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if ndim == 1:
13375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            if inc:
13385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                Py_INCREF((<PyObject **> data)[0])
13395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            else:
13405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                Py_DECREF((<PyObject **> data)[0])
13415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
13425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            refcount_objects_in_slice(data, shape + 1, strides + 1,
13435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                      ndim - 1, inc)
13445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
13455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        data += strides[0]
13465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
13475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
13485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)### Scalar to slice assignment
13495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#
13505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview_slice_assign_scalar')
13515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef void slice_assign_scalar({{memviewslice_name}} *dst, int ndim,
13525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              size_t itemsize, void *item,
13535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              bint dtype_is_object) nogil:
13545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    refcount_copying(dst, dtype_is_object, ndim, False)
13555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
13565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         itemsize, item)
13575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    refcount_copying(dst, dtype_is_object, ndim, True)
13585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
13595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
13605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_memoryview__slice_assign_scalar')
13615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape,
13625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              Py_ssize_t *strides, int ndim,
13635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              size_t itemsize, void *item) nogil:
13645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef Py_ssize_t i
13655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef Py_ssize_t stride = strides[0]
13665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef Py_ssize_t extent = shape[0]
13675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
13685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if ndim == 1:
13695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        for i in range(extent):
13705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            memcpy(data, item, itemsize)
13715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            data += stride
13725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else:
13735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        for i in range(extent):
13745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            _slice_assign_scalar(data, shape + 1, strides + 1,
13755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                ndim - 1, itemsize, item)
13765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            data += stride
13775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
13785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
13795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)############### BufferFormatFromTypeInfo ###############
13805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef extern from *:
13815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ctypedef struct __Pyx_StructField
13825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
13835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef enum:
13845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        __PYX_BUF_FLAGS_PACKED_STRUCT
13855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        __PYX_BUF_FLAGS_INTEGER_COMPLEX
13865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
13875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ctypedef struct __Pyx_TypeInfo:
13885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      char* name
13895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      __Pyx_StructField* fields
13905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      size_t size
13915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      size_t arraysize[8]
13925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      int ndim
13935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      char typegroup
13945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      char is_unsigned
13955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      int flags
13965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
13975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ctypedef struct __Pyx_StructField:
13985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      __Pyx_TypeInfo* type
13995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      char* name
14005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      size_t offset
14015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
14025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ctypedef struct __Pyx_BufFmt_StackElem:
14035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      __Pyx_StructField* field
14045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      size_t parent_offset
14055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
14065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    #ctypedef struct __Pyx_BufFmt_Context:
14075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    #  __Pyx_StructField root
14085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      __Pyx_BufFmt_StackElem* head
14095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
14105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    struct __pyx_typeinfo_string:
14115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        char string[3]
14125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
14135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    __pyx_typeinfo_string __Pyx_TypeInfoToFormat(__Pyx_TypeInfo *)
14145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
14155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
14165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)@cname('__pyx_format_from_typeinfo')
14175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cdef bytes format_from_typeinfo(__Pyx_TypeInfo *type):
14185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef __Pyx_StructField *field
14195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef __pyx_typeinfo_string fmt
14205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cdef bytes part, result
14215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
14225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if type.typegroup == 'S':
14235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        assert type.fields != NULL and type.fields.type != NULL
14245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
14255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if type.flags & __PYX_BUF_FLAGS_PACKED_STRUCT:
14265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            alignment = b'^'
14275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
14285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            alignment = b''
14295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
14305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        parts = [b"T{"]
14315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        field = type.fields
14325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
14335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        while field.type:
14345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            part = format_from_typeinfo(field.type)
14355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            parts.append(part + b':' + field.name + b':')
14365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            field += 1
14375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
14385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        result = alignment.join(parts) + b'}'
14395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else:
14405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        fmt = __Pyx_TypeInfoToFormat(type)
14415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if type.arraysize[0]:
14425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            extents = [unicode(type.arraysize[i]) for i in range(type.ndim)]
14435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            result = (u"(%s)" % u','.join(extents)).encode('ascii') + fmt.string
14445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
14455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            result = fmt.string
14465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
14475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return result
1448