X-Git-Url: https://git.distorted.org.uk/~mdw/pyke/blobdiff_plain/85d110a41cee7dd8c91e10017068fc39dc99eeb0..78daa0e0a7bd479a1618ba5409ef2a187588a941:/pyke.h diff --git a/pyke.h b/pyke.h index 64608d9..2934543 100644 --- a/pyke.h +++ b/pyke.h @@ -371,6 +371,55 @@ extern PyMethodDef *donemethods(void); /*----- Generic mapping support -------------------------------------------*/ +/* Operations table. ME is the mapping object throughout. */ +typedef struct gmap_ops { + size_t isz; /* iterator size */ + + void *(*lookup)(PyObject *me, PyObject *key, unsigned *f); + /* Lookup the KEY. If it is found, return an entry pointer for it; if F + * is not null, set *F nonzero. Otherwise, if F is null, return a null + * pointer (without setting a pending exception); if F is not null, then + * set *F zero and return a fresh entry pointer. Return null on a Python + * exception (the caller will notice the difference.) + */ + + void (*iter_init)(PyObject *me, void *i); + /* Initialize an iterator at I. */ + + void *(*iter_next)(PyObject *me, void *i); + /* Return an entry pointer for a different item, or null if all have been + * visited. + */ + + PyObject *(*entry_key)(PyObject *me, void *e); + /* Return the key object for a mapping entry. */ + + PyObject *(*entry_value)(PyObject *me, void *e); + /* Return the value object for a mapping entry. */ + + int (*set_entry)(PyObject *me, void *e, PyObject *val); + /* Modify the entry by storing VAL in its place. Return 0 on success, + * or -1 on a Python error. + */ + + int (*del_entry)(PyObject *me, void *e); + /* Delete the entry. (It may be necessary to delete a freshly allocated + * entry, e.g., if `set_entry' failed.) Return 0 on success, or -1 on a + * Python error. + */ +} gmap_ops; + +/* The intrusion at the head of a mapping object. */ +#define GMAP_PYOBJ_HEAD \ + PyObject_HEAD \ + const gmap_ops *gmops; + +typedef struct gmap_pyobj { + GMAP_PYOBJ_HEAD +} gmap_pyobj; +#define GMAP_OPS(obj) (((gmap_pyobj *)(obj))->gmops) + /* Discover the operations from a mapping object. */ + /* Mapping methods. */ #define GMAP_METMNAME(func) gmapmeth_##func #define GMAP_METH(func, doc) STD_METHOD(GMAP_METMNAME, func, 0, doc) @@ -399,7 +448,7 @@ extern PyMethodDef *donemethods(void); KWMETH(setdefault, "D.setdefault(K, [default = None]) -> VALUE") \ KWMETH(pop, "D.pop(KEY, [default = ]) -> VALUE") \ NAMETH(popitem, "D.popitem() -> (KEY, VALUE)") \ - METH (update, "D.update(MAP)") + KWMETH(update, "D.update(MAP)") GMAP_DOMETHODS(GMAP_METHDECL, GMAP_KWMETHDECL, GMAP_NAMETHDECL) #define GMAP_ROMETHODS GMAP_DOROMETHODS(GMAP_METH, GMAP_KWMETH, GMAP_NAMETH) @@ -407,7 +456,12 @@ GMAP_DOMETHODS(GMAP_METHDECL, GMAP_KWMETHDECL, GMAP_NAMETHDECL) /* Mapping protocol implementation. */ extern Py_ssize_t gmap_pysize(PyObject *); /* for `mp_length' */ +extern PyObject *gmap_pyiter(PyObject *); /* for `tp_iter' */ +extern PyObject *gmap_pylookup(PyObject *, PyObject *); /* for `mp_subscript' */ +extern int gmap_pystore(PyObject *, PyObject *, PyObject *); /* for `mp_ass_subscript' */ +extern int gmap_pyhaskey(PyObject *, PyObject *); /* for `sq_contains' */ extern const PySequenceMethods gmap_pysequence; /* for `tp_as_sequence' */ +extern const PyMethodDef gmapro_pymethods[]; /* read-only methods */ extern const PyMethodDef gmap_pymethods[]; /* all the standard methods */ /*----- That's all, folks -------------------------------------------------*/