#include "Python.h"
#include "structmember.h"
#include "libnumarray.h"
char *_numerictype__doc__ = "_numerictype defines the _numerictype type which is the basetype for numarray's type objects. It exists in C primarily to support fast comparisons.";
#define DEFERRED_ADDRESS(ADDR) 0
typedef struct {
PyObject_HEAD
NumarrayType typeno;
long hash;
PyObject *name;
PyObject *defval;
PyObject *bytes;
} PyNumericTypeObject;
staticforward PyTypeObject _numerictype_type;
static PyObject *typeDict; /* dictionary of aliases name:numerictype */
static PyObject *
_numerictype_name_get(PyNumericTypeObject *self)
{
Py_INCREF(self->name);
return self->name;
}
static PyObject *
_numerictype_typeno_get(PyNumericTypeObject *self)
{
return PyInt_FromLong(self->typeno);
}
static PyObject *
_numerictype_bytes_get(PyNumericTypeObject *self)
{
Py_INCREF(self->bytes);
return self->bytes;
}
static PyObject *
_numerictype_defval_get(PyNumericTypeObject *self)
{
Py_INCREF(self->defval);
return self->defval;
}
static PyGetSetDef _numerictype_getsets[] = {
{"name",
(getter)_numerictype_name_get,
(setter)0,
"determines if Numerictype is unary or binary"},
{"typeno",
(getter)_numerictype_typeno_get,
(setter)0,
"type number / rank of the numerictype"},
{"bytes",
(getter)_numerictype_bytes_get,
(setter)0,
"number of bytes of the numerictype"},
{"default",
(getter)_numerictype_defval_get,
(setter)0,
"default value of the numerictype"},
{0},
};
static PyObject *
_numerictype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyNumericTypeObject *self =
(PyNumericTypeObject *) PyType_GenericNew(type, args, kwds);
if (!self) return NULL;
self->name = PyString_FromString("no name");
if (!self->name) return NULL;
self->defval = Py_None;
Py_INCREF(Py_None);
self->bytes = Py_None;
Py_INCREF(Py_None);
self->typeno = -1;
return (PyObject *) self;
}
static int
_numerictype_init(PyNumericTypeObject *self, PyObject *args, PyObject *kwds)
{
PyObject *name, *bytes, *defval;
long typeno;
if (!PyArg_ParseTuple(args, "OOOl", &name, &bytes, &defval, &typeno))
return -1;
if (!PyString_Check(name)) {
PyErr_Format(PyExc_TypeError, "name must be a string");
return -1;
}
Py_DECREF(self->name);
self->name = name;
Py_INCREF(self->name);
Py_DECREF(self->bytes);
self->bytes = bytes;
Py_INCREF(bytes);
Py_DECREF(self->defval);
self->defval = defval;
Py_INCREF(defval);
self->hash = PyObject_Hash(self->name);
self->typeno = typeno;
return 0;
}
static void
_numerictype_dealloc(PyNumericTypeObject *self)
{
Py_DECREF(self->name);
Py_DECREF(self->bytes);
Py_DECREF(self->defval);
self->ob_type->tp_free((PyObject *)self);
}
static int
_numerictype_compare(PyNumericTypeObject *self, PyObject *other)
{
int diff;
NumarrayType otherno = 1000;
if (PyObject_IsInstance((PyObject *) other,
(PyObject *) &_numerictype_type)) {
otherno = ((PyNumericTypeObject *)other)->typeno;
} else if (PyString_Check(other)) {
PyObject *otherObj = PyDict_GetItem(typeDict, other);
if (otherObj)
return _numerictype_compare(self, otherObj);
}
diff = self->typeno - otherno;
if (diff < 0)
return -1;
else if (diff == 0)
return 0;
else
return 1;
}
static PyObject *
_numerictype_richcompare(PyNumericTypeObject *self, PyObject *other, int op)
{
int result = _numerictype_compare(self, other);
int rval;
switch(op) {
case Py_LT: rval = (result < 0); break;
case Py_LE: rval = (result <= 0); break;
case Py_GT: rval = (result > 0); break;
case Py_GE: rval = (result >= 0); break;
case Py_EQ: rval = (result == 0); break;
case Py_NE: rval = (result != 0); break;
default:
rval = -1;
PyErr_Format(PyExc_RuntimeError,
"_numerictype: unknown rich comparison operator");
break;
}
#if PY_VERSION_HEX < 0x02030000
return PyInt_FromLong(rval);
#else
return PyBool_FromLong(rval);
#endif
}
static PyObject *
_numerictype_repr(PyNumericTypeObject *self)
{
Py_INCREF(self->name);
return self->name;
}
static long
_numerictype_hash(PyNumericTypeObject *self)
{
return self->hash;
}
static PyMethodDef _numerictype_methods[] = {
{NULL, NULL},
};
static PyTypeObject _numerictype_type = {
PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
0,
"numarray._numerictype._numerictype",
sizeof(PyNumericTypeObject),
0,
(destructor) _numerictype_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
(cmpfunc) _numerictype_compare, /* tp_compare */
(reprfunc) _numerictype_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
(hashfunc) _numerictype_hash, /* tp_hash */
0, /* tp_call */
(reprfunc) _numerictype_repr, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT |
Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
(richcmpfunc) _numerictype_richcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
_numerictype_methods, /* tp_methods */
0, /* tp_members */
_numerictype_getsets, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc) _numerictype_init, /* tp_init */
0, /* tp_alloc */
_numerictype_new, /* tp_new */
};
static PyMethodDef _numerictype_functions[] = {
{NULL, NULL} /* sentinel */
};
DL_EXPORT(void)
init_numerictype(void)
{
PyObject *m;
_numerictype_type.tp_alloc = PyType_GenericAlloc;
if (PyType_Ready(&_numerictype_type) < 0)
return;
m = Py_InitModule3("_numerictype",
_numerictype_functions,
_numerictype__doc__);
if (m == NULL)
return;
Py_INCREF(&_numerictype_type);
if (PyModule_AddObject(
m, "_numerictype", (PyObject *) &_numerictype_type) < 0)
return;
typeDict = PyDict_New();
if (PyModule_AddObject(m, "typeDict", typeDict) < 0)
return;
ADD_VERSION(m);
import_libnumarray();
}
syntax highlighted by Code2HTML, v. 0.9.1