
/* Memoryview object implementation */

#include "Python.h"

static Py_ssize_t
get_shape0(Py_buffer *buf)
{
    if (buf->shape != NULL)
        return buf->shape[0];
    if (buf->ndim == 0)
        return 1;
    PyErr_SetString(PyExc_TypeError,
        "exported buffer does not have any shape information associated "
        "to it");
    return -1;
}

static void
dup_buffer(Py_buffer *dest, Py_buffer *src)
{
    *dest = *src;
    if (src->ndim == 1 && src->shape != NULL) {
        dest->shape = &(dest->smalltable[0]);
        dest->shape[0] = get_shape0(src);
    }
    if (src->ndim == 1 && src->strides != NULL) {
        dest->strides = &(dest->smalltable[1]);
        dest->strides[0] = src->strides[0];
    }
}

static int
memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
{
    int res = 0;
    /* XXX for whatever reason fixing the flags seems necessary */
    if (self->view.readonly)
        flags &= ~PyBUF_WRITABLE;
    if (self->view.obj != NULL)
        res = PyObject_GetBuffer(self->view.obj, view, flags);
    if (view)
        dup_buffer(view, &self->view);
    return res;
}

static void
memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
{
    PyBuffer_Release(view);
}

PyDoc_STRVAR(memory_doc,
"memoryview(object)\n\
\n\
Create a new memoryview object which references the given object.");

PyObject *
PyMemoryView_FromBuffer(Py_buffer *info)
{
    PyMemoryViewObject *mview;

    mview = (PyMemoryViewObject *)
        PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
    if (mview == NULL)
        return NULL;
    mview->base = NULL;
    dup_buffer(&mview->view, info);
    /* NOTE: mview->view.obj should already have been incref'ed as
       part of PyBuffer_FillInfo(). */
    _PyObject_GC_TRACK(mview);
    return (PyObject *)mview;
}

PyObject *
PyMemoryView_FromObject(PyObject *base)
{
    PyMemoryViewObject *mview;
    Py_buffer view;

    if (!PyObject_CheckBuffer(base)) {
        PyErr_SetString(PyExc_TypeError,
            "cannot make memory view because object does "
            "not have the buffer interface");
        return NULL;
    }

    if (PyObject_GetBuffer(base, &view, PyBUF_FULL_RO) < 0)
        return NULL;

    mview = (PyMemoryViewObject *)PyMemoryView_FromBuffer(&view);
    if (mview == NULL) {
        PyBuffer_Release(&view);
        return NULL;
    }

    mview->base = base;
    Py_INCREF(base);
    return (PyObject *)mview;
}

static PyObject *
memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
{
    PyObject *obj;
    static char *kwlist[] = {"object", 0};

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist,
                                     &obj)) {
        return NULL;
    }

    return PyMemoryView_FromObject(obj);
}


static void
_strided_copy_nd(char *dest, char *src, int nd, Py_ssize_t *shape,
                 Py_ssize_t *strides, Py_ssize_t itemsize, char fort)
{
    int k;
    Py_ssize_t outstride;

    if (nd==0) {
        memcpy(dest, src, itemsize);
    }
    else if (nd == 1) {
        for (k = 0; k<shape[0]; k++) {
            memcpy(dest, src, itemsize);
            dest += itemsize;
            src += strides[0];
        }
    }
    else {
        if (fort == 'F') {
            /* Copy first dimension first,
               second dimension second, etc...
               Set up the recursive loop backwards so that final
               dimension is actually copied last.
            */
            outstride = itemsize;
            for (k=1; k<nd-1;k++) {
                outstride *= shape[k];
            }
            for (k=0; k<shape[nd-1]; k++) {
                _strided_copy_nd(dest, src, nd-1, shape,
                                 strides, itemsize, fort);
                dest += outstride;
                src += strides[nd-1];
            }
        }

        else {
            /* Copy last dimension first,
               second-to-last dimension second, etc.
               Set up the recursion so that the
               first dimension is copied last
            */
            outstride = itemsize;
            for (k=1; k < nd; k++) {
                outstride *= shape[k];
            }
            for (k=0; k<shape[0]; k++) {
                _strided_copy_nd(dest, src, nd-1, shape+1,
                                 strides+1, itemsize,
                                 fort);
                dest += outstride;
                src += strides[0];
            }
        }
    }
    return;
}

void _add_one_to_index_F(int nd, Py_ssize_t *index, Py_ssize_t *shape);
void _add_one_to_index_C(int nd, Py_ssize_t *index, Py_ssize_t *shape);

static int
_indirect_copy_nd(char *dest, Py_buffer *view, char fort)
{
    Py_ssize_t *indices;
    int k;
    Py_ssize_t elements;
    char *ptr;
    void (*func)(int, Py_ssize_t *, Py_ssize_t *);

    if (view->ndim > PY_SSIZE_T_MAX / sizeof(Py_ssize_t)) {
        PyErr_NoMemory();
        return -1;
    }

    indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view->ndim);
    if (indices == NULL) {
        PyErr_NoMemory();
        return -1;
    }
    for (k=0; k<view->ndim;k++) {
        indices[k] = 0;
    }

    elements = 1;
    for (k=0; k<view->ndim; k++) {
        elements *= view->shape[k];
    }
    if (fort == 'F') {
        func = _add_one_to_index_F;
    }
    else {
        func = _add_one_to_index_C;
    }
    while (elements--) {
        func(view->ndim, indices, view->shape);
        ptr = PyBuffer_GetPointer(view, indices);
        memcpy(dest, ptr, view->itemsize);
        dest += view->itemsize;
    }

    PyMem_Free(indices);
    return 0;
}

/*
   Get a the data from an object as a contiguous chunk of memory (in
   either 'C' or 'F'ortran order) even if it means copying it into a
   separate memory area.

   Returns a new reference to a Memory view object.  If no copy is needed,
   the memory view object points to the original memory and holds a
   lock on the original.  If a copy is needed, then the memory view object
   points to a brand-new Bytes object (and holds a memory lock on it).

   buffertype

   PyBUF_READ  buffer only needs to be read-only
   PyBUF_WRITE buffer needs to be writable (give error if not contiguous)
   PyBUF_SHADOW buffer needs to be writable so shadow it with
                a contiguous buffer if it is not. The view will point to
                the shadow buffer which can be written to and then
                will be copied back into the other buffer when the memory
                view is de-allocated.  While the shadow buffer is
                being used, it will have an exclusive write lock on
                the original buffer.
 */

PyObject *
PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)
{
    PyMemoryViewObject *mem;
    PyObject *bytes;
    Py_buffer *view;
    int flags;
    char *dest;

    if (!PyObject_CheckBuffer(obj)) {
        PyErr_SetString(PyExc_TypeError,
                        "object does not have the buffer interface");
        return NULL;
    }

    mem = PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
    if (mem == NULL)
        return NULL;

    view = &mem->view;
    flags = PyBUF_FULL_RO;
    switch(buffertype) {
    case PyBUF_WRITE:
        flags = PyBUF_FULL;
        break;
    }

    if (PyObject_GetBuffer(obj, view, flags) != 0) {
        Py_DECREF(mem);
        return NULL;
    }

    if (PyBuffer_IsContiguous(view, fort)) {
        /* no copy needed */
        Py_INCREF(obj);
        mem->base = obj;
        _PyObject_GC_TRACK(mem);
        return (PyObject *)mem;
    }
    /* otherwise a copy is needed */
    if (buffertype == PyBUF_WRITE) {
        Py_DECREF(mem);
        PyErr_SetString(PyExc_BufferError,
                        "writable contiguous buffer requested "
                        "for a non-contiguousobject.");
        return NULL;
    }
    bytes = PyBytes_FromStringAndSize(NULL, view->len);
    if (bytes == NULL) {
        Py_DECREF(mem);
        return NULL;
    }
    dest = PyBytes_AS_STRING(bytes);
    /* different copying strategy depending on whether
       or not any pointer de-referencing is needed
    */
    /* strided or in-direct copy */
    if (view->suboffsets==NULL) {
        _strided_copy_nd(dest, view->buf, view->ndim, view->shape,
                         view->strides, view->itemsize, fort);
    }
    else {
        if (_indirect_copy_nd(dest, view, fort) < 0) {
            Py_DECREF(bytes);
            Py_DECREF(mem);
            return NULL;
        }
    }
    if (buffertype == PyBUF_SHADOW) {
        /* return a shadowed memory-view object */
        view->buf = dest;
        mem->base = PyTuple_Pack(2, obj, bytes);
        Py_DECREF(bytes);
        if (mem->base == NULL) {
            Py_DECREF(mem);
            return NULL;
        }
    }
    else {
        PyBuffer_Release(view);  /* XXX ? */
        /* steal the reference */
        mem->base = bytes;
    }
    _PyObject_GC_TRACK(mem);
    return (PyObject *)mem;
}


static PyObject *
memory_format_get(PyMemoryViewObject *self)
{
    return PyString_FromString(self->view.format);
}

static PyObject *
memory_itemsize_get(PyMemoryViewObject *self)
{
    return PyLong_FromSsize_t(self->view.itemsize);
}

static PyObject *
_IntTupleFromSsizet(int len, Py_ssize_t *vals)
{
    int i;
    PyObject *o;
    PyObject *intTuple;

    if (vals == NULL) {
        Py_INCREF(Py_None);
        return Py_None;
    }
    intTuple = PyTuple_New(len);
    if (!intTuple) return NULL;
    for(i=0; i<len; i++) {
        o = PyLong_FromSsize_t(vals[i]);
        if (!o) {
            Py_DECREF(intTuple);
            return NULL;
        }
        PyTuple_SET_ITEM(intTuple, i, o);
    }
    return intTuple;
}

static PyObject *
memory_shape_get(PyMemoryViewObject *self)
{
    return _IntTupleFromSsizet(self->view.ndim, self->view.shape);
}

static PyObject *
memory_strides_get(PyMemoryViewObject *self)
{
    return _IntTupleFromSsizet(self->view.ndim, self->view.strides);
}

static PyObject *
memory_suboffsets_get(PyMemoryViewObject *self)
{
    return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);
}

static PyObject *
memory_readonly_get(PyMemoryViewObject *self)
{
    return PyBool_FromLong(self->view.readonly);
}

static PyObject *
memory_ndim_get(PyMemoryViewObject *self)
{
    return PyLong_FromLong(self->view.ndim);
}

static PyGetSetDef memory_getsetlist[] ={
    {"format",          (getter)memory_format_get,      NULL, NULL},
    {"itemsize",        (getter)memory_itemsize_get,    NULL, NULL},
    {"shape",           (getter)memory_shape_get,       NULL, NULL},
    {"strides",         (getter)memory_strides_get,     NULL, NULL},
    {"suboffsets",      (getter)memory_suboffsets_get,  NULL, NULL},
    {"readonly",        (getter)memory_readonly_get,    NULL, NULL},
    {"ndim",            (getter)memory_ndim_get,        NULL, NULL},
    {NULL, NULL, NULL, NULL},
};


static PyObject *
memory_tobytes(PyMemoryViewObject *self, PyObject *noargs)
{
    Py_buffer view;
    PyObject *res;

    if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_FULL) < 0)
        return NULL;

    res = PyBytes_FromStringAndSize(NULL, view.len);
    PyBuffer_ToContiguous(PyBytes_AS_STRING(res), &view, view.len, 'C');
    PyBuffer_Release(&view);
    return res;
}

/* TODO: rewrite this function using the struct module to unpack
   each buffer item */

static PyObject *
memory_tolist(PyMemoryViewObject *mem, PyObject *noargs)
{
    Py_buffer *view = &(mem->view);
    Py_ssize_t i;
    PyObject *res, *item;
    char *buf;

    if (strcmp(view->format, "B") || view->itemsize != 1) {
        PyErr_SetString(PyExc_NotImplementedError, 
                "tolist() only supports byte views");
        return NULL;
    }
    if (view->ndim != 1) {
        PyErr_SetString(PyExc_NotImplementedError, 
                "tolist() only supports one-dimensional objects");
        return NULL;
    }
    res = PyList_New(view->len);
    if (res == NULL)
        return NULL;
    buf = view->buf;
    for (i = 0; i < view->len; i++) {
        item = PyInt_FromLong((unsigned char) *buf);
        if (item == NULL) {
            Py_DECREF(res);
            return NULL;
        }
        PyList_SET_ITEM(res, i, item);
        buf++;
    }
    return res;
}

static PyMethodDef memory_methods[] = {
    {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, NULL},
    {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, NULL},
    {NULL,          NULL}           /* sentinel */
};


static void
memory_dealloc(PyMemoryViewObject *self)
{
    _PyObject_GC_UNTRACK(self);
    if (self->view.obj != NULL) {
        if (self->base && PyTuple_Check(self->base)) {
            /* Special case when first element is generic object
               with buffer interface and the second element is a
               contiguous "shadow" that must be copied back into
               the data areay of the first tuple element before
               releasing the buffer on the first element.
            */

            PyObject_CopyData(PyTuple_GET_ITEM(self->base,0),
                              PyTuple_GET_ITEM(self->base,1));

            /* The view member should have readonly == -1 in
               this instance indicating that the memory can
               be "locked" and was locked and will be unlocked
               again after this call.
            */
            PyBuffer_Release(&(self->view));
        }
        else {
            PyBuffer_Release(&(self->view));
        }
        Py_CLEAR(self->base);
    }
    PyObject_GC_Del(self);
}

static PyObject *
memory_repr(PyMemoryViewObject *self)
{
    return PyString_FromFormat("<memory at %p>", self);
}

/* Sequence methods */
static Py_ssize_t
memory_length(PyMemoryViewObject *self)
{
    return get_shape0(&self->view);
}

/* Alternate version of memory_subcript that only accepts indices.
   Used by PySeqIter_New().
*/
static PyObject *
memory_item(PyMemoryViewObject *self, Py_ssize_t result)
{
    Py_buffer *view = &(self->view);

    if (view->ndim == 0) {
        PyErr_SetString(PyExc_IndexError,
                        "invalid indexing of 0-dim memory");
        return NULL;
    }
    if (view->ndim == 1) {
        /* Return a bytes object */
        char *ptr;
        ptr = (char *)view->buf;
        if (result < 0) {
            result += get_shape0(view);
        }
        if ((result < 0) || (result >= get_shape0(view))) {
            PyErr_SetString(PyExc_IndexError,
                                "index out of bounds");
            return NULL;
        }
        if (view->strides == NULL)
            ptr += view->itemsize * result;
        else
            ptr += view->strides[0] * result;
        if (view->suboffsets != NULL &&
            view->suboffsets[0] >= 0) {
            ptr = *((char **)ptr) + view->suboffsets[0];
        }
        return PyBytes_FromStringAndSize(ptr, view->itemsize);
    } else {
        /* Return a new memory-view object */
        Py_buffer newview;
        memset(&newview, 0, sizeof(newview));
        /* XXX:  This needs to be fixed so it actually returns a sub-view */
        return PyMemoryView_FromBuffer(&newview);
    }
}

/*
  mem[obj] returns a bytes object holding the data for one element if
           obj fully indexes the memory view or another memory-view object
           if it does not.

           0-d memory-view objects can be referenced using ... or () but
           not with anything else.
 */
static PyObject *
memory_subscript(PyMemoryViewObject *self, PyObject *key)
{
    Py_buffer *view;
    view = &(self->view);
    
    if (view->ndim == 0) {
        if (key == Py_Ellipsis ||
            (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
            Py_INCREF(self);
            return (PyObject *)self;
        }
        else {
            PyErr_SetString(PyExc_IndexError,
                                "invalid indexing of 0-dim memory");
            return NULL;
        }
    }
    if (PyIndex_Check(key)) {
        Py_ssize_t result;
        result = PyNumber_AsSsize_t(key, NULL);
        if (result == -1 && PyErr_Occurred())
                return NULL;
        return memory_item(self, result);
    }
    else if (PySlice_Check(key)) {
        Py_ssize_t start, stop, step, slicelength;

        if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view),
                                 &start, &stop, &step, &slicelength) < 0) {
            return NULL;
        }
    
        if (step == 1 && view->ndim == 1) {
            Py_buffer newview;
            void *newbuf = (char *) view->buf
                                    + start * view->itemsize;
            int newflags = view->readonly
                    ? PyBUF_CONTIG_RO : PyBUF_CONTIG;
    
            /* XXX There should be an API to create a subbuffer */
            if (view->obj != NULL) {
                if (PyObject_GetBuffer(view->obj, &newview, newflags) == -1)
                    return NULL;
            }
            else {
                newview = *view;
            }
            newview.buf = newbuf;
            newview.len = slicelength * newview.itemsize;
            newview.format = view->format;
            newview.shape = &(newview.smalltable[0]);
            newview.shape[0] = slicelength;
            newview.strides = &(newview.itemsize);
            return PyMemoryView_FromBuffer(&newview);
        }
        PyErr_SetNone(PyExc_NotImplementedError);
        return NULL;
    }
    PyErr_Format(PyExc_TypeError,
        "cannot index memory using \"%.200s\"", 
        key->ob_type->tp_name);
    return NULL;
}


/* Need to support assigning memory if we can */
static int
memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
{
    Py_ssize_t start, len, bytelen, i;
    Py_buffer srcview;
    Py_buffer *view = &(self->view);
    char *srcbuf, *destbuf;

    if (view->readonly) {
        PyErr_SetString(PyExc_TypeError,
            "cannot modify read-only memory");
        return -1;
    }
    if (view->ndim != 1) {
        PyErr_SetNone(PyExc_NotImplementedError);
        return -1;
    }
    if (PyIndex_Check(key)) {
        start = PyNumber_AsSsize_t(key, NULL);
        if (start == -1 && PyErr_Occurred())
            return -1;
        if (start < 0) {
            start += get_shape0(view);
        }
        if ((start < 0) || (start >= get_shape0(view))) {
            PyErr_SetString(PyExc_IndexError,
                            "index out of bounds");
            return -1;
        }
        len = 1;
    }
    else if (PySlice_Check(key)) {
        Py_ssize_t stop, step;

        if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view),
                         &start, &stop, &step, &len) < 0) {
            return -1;
        }
        if (step != 1) {
            PyErr_SetNone(PyExc_NotImplementedError);
            return -1;
        }
    }
    else {
        PyErr_Format(PyExc_TypeError,
            "cannot index memory using \"%.200s\"", 
            key->ob_type->tp_name);
        return -1;
    }
    if (PyObject_GetBuffer(value, &srcview, PyBUF_CONTIG_RO) == -1) {
        return -1;
    }
    /* XXX should we allow assignment of different item sizes
       as long as the byte length is the same?
       (e.g. assign 2 shorts to a 4-byte slice) */
    if (srcview.itemsize != view->itemsize) {
        PyErr_Format(PyExc_TypeError,
            "mismatching item sizes for \"%.200s\" and \"%.200s\"", 
            view->obj->ob_type->tp_name, srcview.obj->ob_type->tp_name);
        goto _error;
    }
    bytelen = len * view->itemsize;
    if (bytelen != srcview.len) {
        PyErr_SetString(PyExc_ValueError,
            "cannot modify size of memoryview object");
        goto _error;
    }
    /* Do the actual copy */
    destbuf = (char *) view->buf + start * view->itemsize;
    srcbuf = (char *) srcview.buf;
    if (destbuf + bytelen < srcbuf || srcbuf + bytelen < destbuf)
        /* No overlapping */
        memcpy(destbuf, srcbuf, bytelen);
    else if (destbuf < srcbuf) {
        /* Copy in ascending order */
        for (i = 0; i < bytelen; i++)
            destbuf[i] = srcbuf[i];
    }
    else {
        /* Copy in descencing order */
        for (i = bytelen - 1; i >= 0; i--)
            destbuf[i] = srcbuf[i];
    }

    PyBuffer_Release(&srcview);
    return 0;

_error:
    PyBuffer_Release(&srcview);
    return -1;
}

static PyObject *
memory_richcompare(PyObject *v, PyObject *w, int op)
{
    Py_buffer vv, ww;
    int equal = 0;
    PyObject *res;

    vv.obj = NULL;
    ww.obj = NULL;
    if (op != Py_EQ && op != Py_NE)
        goto _notimpl;
    if (PyObject_GetBuffer(v, &vv, PyBUF_CONTIG_RO) == -1) {
        PyErr_Clear();
        goto _notimpl;
    }
    if (PyObject_GetBuffer(w, &ww, PyBUF_CONTIG_RO) == -1) {
        PyErr_Clear();
        goto _notimpl;
    }

    if (vv.itemsize != ww.itemsize || vv.len != ww.len)
        goto _end;

    equal = !memcmp(vv.buf, ww.buf, vv.len);

_end:
    PyBuffer_Release(&vv);
    PyBuffer_Release(&ww);
    if ((equal && op == Py_EQ) || (!equal && op == Py_NE))
        res = Py_True;
    else
        res = Py_False;
    Py_INCREF(res);
    return res;

_notimpl:
    PyBuffer_Release(&vv);
    PyBuffer_Release(&ww);
    Py_INCREF(Py_NotImplemented);
    return Py_NotImplemented;
}


static int
memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg)
{
    if (self->base != NULL)
        Py_VISIT(self->base);
    if (self->view.obj != NULL)
        Py_VISIT(self->view.obj);
    return 0;
}

static int
memory_clear(PyMemoryViewObject *self)
{
    Py_CLEAR(self->base);
    PyBuffer_Release(&self->view);
    return 0;
}


/* As mapping */
static PyMappingMethods memory_as_mapping = {
    (lenfunc)memory_length,               /* mp_length */
    (binaryfunc)memory_subscript,         /* mp_subscript */
    (objobjargproc)memory_ass_sub,        /* mp_ass_subscript */
};

static PySequenceMethods memory_as_sequence = {
	0,                                  /* sq_length */
	0,                                  /* sq_concat */
	0,                                  /* sq_repeat */
	(ssizeargfunc)memory_item,          /* sq_item */
};

/* Buffer methods */
static PyBufferProcs memory_as_buffer = {
    0,                                    /* bf_getreadbuffer */
    0,                                    /* bf_getwritebuffer */
    0,                                    /* bf_getsegcount */
    0,                                    /* bf_getcharbuffer */
    (getbufferproc)memory_getbuf,         /* bf_getbuffer */
    (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */
};


PyTypeObject PyMemoryView_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "memoryview",
    sizeof(PyMemoryViewObject),
    0,
    (destructor)memory_dealloc,               /* tp_dealloc */
    0,                                        /* tp_print */
    0,                                        /* tp_getattr */
    0,                                        /* tp_setattr */
    0,                                        /* tp_compare */
    (reprfunc)memory_repr,                    /* tp_repr */
    0,                                        /* tp_as_number */
    &memory_as_sequence,                      /* tp_as_sequence */
    &memory_as_mapping,                       /* tp_as_mapping */
    0,                                        /* tp_hash */
    0,                                        /* tp_call */
    0,                                        /* tp_str */
    PyObject_GenericGetAttr,                  /* tp_getattro */
    0,                                        /* tp_setattro */
    &memory_as_buffer,                        /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
        Py_TPFLAGS_HAVE_NEWBUFFER,            /* tp_flags */
    memory_doc,                               /* tp_doc */
    (traverseproc)memory_traverse,            /* tp_traverse */
    (inquiry)memory_clear,                    /* tp_clear */
    memory_richcompare,                       /* tp_richcompare */
    0,                                        /* tp_weaklistoffset */
    0,                                        /* tp_iter */
    0,                                        /* tp_iternext */
    memory_methods,                           /* tp_methods */
    0,                                        /* tp_members */
    memory_getsetlist,                        /* tp_getset */
    0,                                        /* tp_base */
    0,                                        /* tp_dict */
    0,                                        /* tp_descr_get */
    0,                                        /* tp_descr_set */
    0,                                        /* tp_dictoffset */
    0,                                        /* tp_init */
    0,                                        /* tp_alloc */
    memory_new,                               /* tp_new */
};
