Single new array function

Unfortunately cannot use default args in pxd file; I also wouldn't know how the two array functions could be added as methods to the array class.
Restored "inline" attribute for array creation function, it can be disabled with a \#DEF
Removed some unused/redundant attributes.
Moved selected comments to docstrings.
Replaced tabs w/spaces.
parent 8fc6e20b
......@@ -164,7 +164,6 @@ from cpython.weakref cimport *
from cpython.getargs cimport *
from cpython.pythread cimport *
from cpython.pystate cimport *
from cpython.array cimport *
# Python <= 2.x
from cpython.cobject cimport *
......
......@@ -38,7 +38,7 @@
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() optionA
mem.leaks; seamless Python compatibility, buffer() optional
IMPORTANT: arrayarray.h (arrayobject, arraydescr) is not part of
......@@ -48,23 +48,17 @@
last changes: 2009-05-15 rk
: 2009-12-06 bp
: 2012-05-02 andreasvc
"""
from libc cimport stdlib
from libc.string cimport strcat, strncat, \
memset, memchr, memcmp, memcpy, memmove
cdef extern from "stdlib.h" nogil:
void *memset(void *str, int c, size_t n)
char *strcat(char *str1, char *str2)
char *strncat(char *str1, char *str2, size_t n)
void *memchr(void *str, int c, size_t n)
int memcmp(void *str1, void *str2, size_t n)
void *memcpy(void *str1, void *str2, size_t n)
void *memmove(void *str1, void *str2, size_t n)
from cpython.ref cimport PyTypeObject
from cpython.exc cimport PyErr_BadArgument
cdef extern from "arrayarray.h":
ctypedef void PyTypeObject
ctypedef short Py_UNICODE
int PyErr_BadArgument()
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)
......@@ -79,17 +73,10 @@ cdef extern from "arrayarray.h":
cdef:
PyTypeObject* ob_type
int ob_size # number of valid items;
unsigned length # == ob_size (by union)
char* ob_item # to first item
Py_ssize_t allocated # bytes
arraydescr* ob_descr # struct arraydescr *ob_descr;
object weakreflist # /* List of weak references */
# view's of ob_item:
# views of ob_item:
float* _f # direct float pointer access to buffer
double* _d # double ...
int* _i
......@@ -112,7 +99,7 @@ cdef extern from "arrayarray.h":
cdef unsigned rows, columns, itemsize
info.suboffsets = NULL
info.buf = self.ob_item
info.buf = self._c
info.readonly = 0
info.ndim = 1
info.itemsize = itemsize = self.ob_descr.itemsize # e.g. sizeof(float)
......@@ -144,44 +131,40 @@ cdef extern from "arrayarray.h":
int resize_smart(array self, Py_ssize_t n)
# fast creation of a new array - init with zeros
# yet you need a (any) template array of the same item type (but not same size)
cdef inline array zeros_like(array sametype):
cdef array op = newarrayobject(<PyTypeObject*>sametype.ob_type, sametype.ob_size, sametype.ob_descr)
if op:
memset(op.ob_item, 0, op.ob_size * op.ob_descr.itemsize)
return op
# fast creation of a new array - no init with zeros
cdef inline array new_array(array sametype, unsigned n):
return newarrayobject( <PyTypeObject*>sametype.ob_type, n, sametype.ob_descr)
# fast creation of a new array - no init with zeros, same length
cdef inline array empty_like(array sametype):
return newarrayobject(<PyTypeObject*>sametype.ob_type, sametype.op.ob_size,
sametype.ob_descr)
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
op = newarrayobject(template.ob_type, length, template.ob_descr)
if zero and op is not None:
memset(op._c, 0, length * op.ob_descr.itemsize)
return op
cdef inline array copy(array self):
cdef array op = newarrayobject(<PyTypeObject*>self.ob_type, self.ob_size,
self.ob_descr)
memcpy(op.ob_item, self.ob_item, op.ob_size * op.ob_descr.itemsize)
""" make a copy of an array. """
cdef array op
op = newarrayobject(self.ob_type, self.length, self.ob_descr)
memcpy(op._c, self._c, op.length * op.ob_descr.itemsize)
return op
cdef inline int extend_buffer(array self, char* stuff, Py_ssize_t n):
""" efficent 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, orgsize = self.ob_size
if -1 == resize_smart(self, orgsize + n):
""" efficent 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 orgsize = self.length
if resize_smart(self, orgsize + n) == -1:
return -1
memcpy(self.ob_item + orgsize * itemsize, stuff, n * itemsize)
memcpy(self._c + orgsize * itemsize, stuff, n * itemsize)
cdef inline int extend(array self, array other):
""" extend array with data from another array; types must match. """
if self.ob_descr.typecode != self.ob_descr.typecode:
PyErr_BadArgument()
return -1
return extend_buffer(self, other.ob_item, other.ob_size)
return extend_buffer(self, other._c, other.length)
cdef inline void zero(array op):
memset(op.ob_item, 0, op.ob_size * op.ob_descr.itemsize)
""" set all elements of array to zero. """
memset(op._c, 0, op.length * op.ob_descr.itemsize)
......@@ -6,6 +6,7 @@
See array.pxd next to this file
last changes: 2009-05-15 rk
2012-05-02 andreasvc
*/
......@@ -21,10 +22,10 @@ struct arrayobject; /* Forward */
* functions aren't visible yet.
*/
typedef struct arraydescr {
int typecode;
int itemsize;
PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *);
int typecode;
int itemsize;
PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *);
#if PY_VERSION_HEX >= 0x03000000
char *formats;
#endif
......@@ -32,13 +33,13 @@ typedef struct arraydescr {
typedef struct arrayobject {
PyObject_HEAD
PyObject_HEAD
union {
int ob_size;
Py_ssize_t ob_size;
unsigned length;
};
union {
char *ob_item;
char *ob_item;
float *_f;
double *_d;
int *_i;
......@@ -54,11 +55,11 @@ typedef struct arrayobject {
void *_v;
};
#if PY_VERSION_HEX >= 0x02040000
Py_ssize_t allocated;
Py_ssize_t allocated;
#endif
struct arraydescr *ob_descr;
struct arraydescr *ob_descr;
#if PY_VERSION_HEX >= 0x02040000
PyObject *weakreflist; /* List of weak references */
PyObject *weakreflist; /* List of weak references */
#if PY_VERSION_HEX >= 0x03000000
int ob_exports; /* Number of exported buffers */
#endif
......@@ -69,50 +70,50 @@ typedef struct arrayobject {
#ifndef NO_NEWARRAY_INLINE
/*
*
* fast creation of a new array - init with zeros
* fast creation of a new array
*/
PyObject * newarrayobject
(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr) {
arrayobject *op;
size_t nbytes;
if (size < 0) {
PyErr_BadInternalCall();
return NULL;
}
nbytes = size * descr->itemsize;
/* Check for overflow */
if (nbytes / descr->itemsize != (size_t)size) {
return PyErr_NoMemory();
}
op = (arrayobject *) type->tp_alloc(type, 0);
if (op == NULL) {
return NULL;
}
op->ob_descr = descr;
inline PyObject * newarrayobject(PyTypeObject *type, Py_ssize_t size,
struct arraydescr *descr) {
arrayobject *op;
size_t nbytes;
if (size < 0) {
PyErr_BadInternalCall();
return NULL;
}
nbytes = size * descr->itemsize;
/* Check for overflow */
if (nbytes / descr->itemsize != (size_t)size) {
return PyErr_NoMemory();
}
op = (arrayobject *) type->tp_alloc(type, 0);
if (op == NULL) {
return NULL;
}
op->ob_descr = descr;
#if !( PY_VERSION_HEX < 0x02040000 )
op->allocated = size;
op->weakreflist = NULL;
op->allocated = size;
op->weakreflist = NULL;
#endif
Py_SIZE(op) = size;
if (size <= 0) {
op->ob_item = NULL;
}
else {
op->ob_item = PyMem_NEW(char, nbytes);
if (op->ob_item == NULL) {
Py_DECREF(op);
return PyErr_NoMemory();
}
}
return (PyObject *) op;
Py_SIZE(op) = size;
if (size <= 0) {
op->ob_item = NULL;
}
else {
op->ob_item = PyMem_NEW(char, nbytes);
if (op->ob_item == NULL) {
Py_DECREF(op);
return PyErr_NoMemory();
}
}
return (PyObject *) op;
}
#else
PyObject *
newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr);
#endif
PyObject* newarrayobject(PyTypeObject *type, Py_ssize_t size,
struct arraydescr *descr);
#endif /* ifndef NO_NEWARRAY_INLINE */
/* fast resize (reallocation to the point)
not designed for filing small increments (but for fast opaque array apps) */
......@@ -143,7 +144,7 @@ int resize_smart(arrayobject *self, Py_ssize_t n) {
return 0;
}
}
newsize = n * 3 / 2 + 1;
newsize = n * 3 / 2 + 1;
PyMem_Resize(item, char, (size_t)(newsize * self->ob_descr->itemsize));
if (item == NULL) {
PyErr_NoMemory();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment