test-kivy-app/kivy_venv/lib/python3.11/site-packages/Cython/Includes/cpython/array.pxd

164 lines
5.9 KiB
Cython
Raw Normal View History

2024-09-15 12:12:16 +00:00
"""
array.pxd
Cython interface to Python's array.array module.
* 1D contiguous data view
* tools for fast array creation, maximum C-speed and handiness
* suitable as allround light weight auto-array within Cython code too
Usage:
>>> cimport array
Usage through Cython buffer interface (Py2.3+):
>>> def f(arg1, unsigned i, double dx)
... array.array[double] a = arg1
... a[i] += dx
Fast C-level new_array(_zeros), resize_array, copy_array, Py_SIZE(obj),
zero_array
cdef array.array[double] k = array.copy(d)
cdef array.array[double] n = array.array(d, Py_SIZE(d) * 2 )
cdef array.array[double] m = array.zeros_like(FLOAT_TEMPLATE)
array.resize(f, 200000)
Zero overhead with naked data pointer views by union:
_f, _d, _i, _c, _u, ...
=> Original C array speed + Python dynamic memory management
cdef array.array a = inarray
if
a._d[2] += 0.66 # use as double array without extra casting
float *subview = vector._f + 10 # starting from 10th element
unsigned char *subview_buffer = vector._B + 4
Suitable as lightweight arrays intra Cython without speed penalty.
Replacement for C stack/malloc arrays; no trouble with refcounting,
mem.leaks; seamless Python compatibility, buffer() optional
last changes: 2009-05-15 rk
: 2009-12-06 bp
: 2012-05-02 andreasvc
: (see revision control)
"""
from libc.string cimport strcat, strncat, \
memset, memchr, memcmp, memcpy, memmove
from cpython.object cimport Py_SIZE
from cpython.ref cimport PyTypeObject, Py_TYPE
from cpython.exc cimport PyErr_BadArgument
from cpython.mem cimport PyObject_Malloc, PyObject_Free
cdef extern from *: # Hard-coded utility code hack.
ctypedef class array.array [object arrayobject]
ctypedef object GETF(array a, Py_ssize_t ix)
ctypedef object SETF(array a, Py_ssize_t ix, object o)
ctypedef struct arraydescr: # [object arraydescr]:
char typecode
int itemsize
GETF getitem # PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
SETF setitem # int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *);
ctypedef union __data_union:
# views of ob_item:
float* as_floats # direct float pointer access to buffer
double* as_doubles # double ...
int* as_ints
unsigned int *as_uints
unsigned char *as_uchars
signed char *as_schars
char *as_chars
unsigned long *as_ulongs
long *as_longs
unsigned long long *as_ulonglongs
long long *as_longlongs
short *as_shorts
unsigned short *as_ushorts
Py_UNICODE *as_pyunicodes
void *as_voidptr
ctypedef class array.array [object arrayobject]:
cdef __cythonbufferdefaults__ = {'ndim' : 1, 'mode':'c'}
cdef:
Py_ssize_t ob_size
arraydescr* ob_descr # struct arraydescr *ob_descr;
__data_union data
def __getbuffer__(self, Py_buffer* info, int flags):
# This implementation of getbuffer is geared towards Cython
# requirements, and does not yet fulfill the PEP.
# In particular strided access is always provided regardless
# of flags
item_count = Py_SIZE(self)
info.suboffsets = NULL
info.buf = self.data.as_chars
info.readonly = 0
info.ndim = 1
info.itemsize = self.ob_descr.itemsize # e.g. sizeof(float)
info.len = info.itemsize * item_count
info.shape = <Py_ssize_t*> PyObject_Malloc(sizeof(Py_ssize_t) + 2)
if not info.shape:
raise MemoryError()
info.shape[0] = item_count # constant regardless of resizing
info.strides = &info.itemsize
info.format = <char*> (info.shape + 1)
info.format[0] = self.ob_descr.typecode
info.format[1] = 0
info.obj = self
def __releasebuffer__(self, Py_buffer* info):
PyObject_Free(info.shape)
array newarrayobject(PyTypeObject* type, Py_ssize_t size, arraydescr *descr)
# fast resize/realloc
# not suitable for small increments; reallocation 'to the point'
int resize(array self, Py_ssize_t n) except -1
# efficient for small increments (not in Py2.3-)
int resize_smart(array self, Py_ssize_t n) except -1
cdef inline array clone(array template, Py_ssize_t length, bint zero):
""" fast creation of a new array, given a template array.
type will be same as template.
if zero is true, new array will be initialized with zeroes."""
cdef array op = newarrayobject(Py_TYPE(template), length, template.ob_descr)
if zero and op is not None:
memset(op.data.as_chars, 0, length * op.ob_descr.itemsize)
return op
cdef inline array copy(array self):
""" make a copy of an array. """
cdef array op = newarrayobject(Py_TYPE(self), Py_SIZE(self), self.ob_descr)
memcpy(op.data.as_chars, self.data.as_chars, Py_SIZE(op) * op.ob_descr.itemsize)
return op
cdef inline int extend_buffer(array self, char* stuff, Py_ssize_t n) except -1:
""" efficient appending of new stuff of same type
(e.g. of same array type)
n: number of elements (not number of bytes!) """
cdef Py_ssize_t itemsize = self.ob_descr.itemsize
cdef Py_ssize_t origsize = Py_SIZE(self)
resize_smart(self, origsize + n)
memcpy(self.data.as_chars + origsize * itemsize, stuff, n * itemsize)
return 0
cdef inline int extend(array self, array other) except -1:
""" extend array with data from another array; types must match. """
if self.ob_descr.typecode != other.ob_descr.typecode:
PyErr_BadArgument()
return extend_buffer(self, other.data.as_chars, Py_SIZE(other))
cdef inline void zero(array self):
""" set all elements of array to zero. """
memset(self.data.as_chars, 0, Py_SIZE(self) * self.ob_descr.itemsize)