Chris@87: /* Set object interface */ Chris@87: Chris@87: #ifndef Py_SETOBJECT_H Chris@87: #define Py_SETOBJECT_H Chris@87: #ifdef __cplusplus Chris@87: extern "C" { Chris@87: #endif Chris@87: Chris@87: Chris@87: /* Chris@87: There are three kinds of slots in the table: Chris@87: Chris@87: 1. Unused: key == NULL Chris@87: 2. Active: key != NULL and key != dummy Chris@87: 3. Dummy: key == dummy Chris@87: Chris@87: Note: .pop() abuses the hash field of an Unused or Dummy slot to Chris@87: hold a search finger. The hash field of Unused or Dummy slots has Chris@87: no meaning otherwise. Chris@87: */ Chris@87: Chris@87: #define PySet_MINSIZE 8 Chris@87: Chris@87: typedef struct { Chris@87: long hash; /* cached hash code for the entry key */ Chris@87: PyObject *key; Chris@87: } setentry; Chris@87: Chris@87: Chris@87: /* Chris@87: This data structure is shared by set and frozenset objects. Chris@87: */ Chris@87: Chris@87: typedef struct _setobject PySetObject; Chris@87: struct _setobject { Chris@87: PyObject_HEAD Chris@87: Chris@87: Py_ssize_t fill; /* # Active + # Dummy */ Chris@87: Py_ssize_t used; /* # Active */ Chris@87: Chris@87: /* The table contains mask + 1 slots, and that's a power of 2. Chris@87: * We store the mask instead of the size because the mask is more Chris@87: * frequently needed. Chris@87: */ Chris@87: Py_ssize_t mask; Chris@87: Chris@87: /* table points to smalltable for small tables, else to Chris@87: * additional malloc'ed memory. table is never NULL! This rule Chris@87: * saves repeated runtime null-tests. Chris@87: */ Chris@87: setentry *table; Chris@87: setentry *(*lookup)(PySetObject *so, PyObject *key, long hash); Chris@87: setentry smalltable[PySet_MINSIZE]; Chris@87: Chris@87: long hash; /* only used by frozenset objects */ Chris@87: PyObject *weakreflist; /* List of weak references */ Chris@87: }; Chris@87: Chris@87: PyAPI_DATA(PyTypeObject) PySet_Type; Chris@87: PyAPI_DATA(PyTypeObject) PyFrozenSet_Type; Chris@87: Chris@87: /* Invariants for frozensets: Chris@87: * data is immutable. Chris@87: * hash is the hash of the frozenset or -1 if not computed yet. Chris@87: * Invariants for sets: Chris@87: * hash is -1 Chris@87: */ Chris@87: Chris@87: #define PyFrozenSet_CheckExact(ob) (Py_TYPE(ob) == &PyFrozenSet_Type) Chris@87: #define PyAnySet_CheckExact(ob) \ Chris@87: (Py_TYPE(ob) == &PySet_Type || Py_TYPE(ob) == &PyFrozenSet_Type) Chris@87: #define PyAnySet_Check(ob) \ Chris@87: (Py_TYPE(ob) == &PySet_Type || Py_TYPE(ob) == &PyFrozenSet_Type || \ Chris@87: PyType_IsSubtype(Py_TYPE(ob), &PySet_Type) || \ Chris@87: PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) Chris@87: #define PySet_Check(ob) \ Chris@87: (Py_TYPE(ob) == &PySet_Type || \ Chris@87: PyType_IsSubtype(Py_TYPE(ob), &PySet_Type)) Chris@87: #define PyFrozenSet_Check(ob) \ Chris@87: (Py_TYPE(ob) == &PyFrozenSet_Type || \ Chris@87: PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) Chris@87: Chris@87: PyAPI_FUNC(PyObject *) PySet_New(PyObject *); Chris@87: PyAPI_FUNC(PyObject *) PyFrozenSet_New(PyObject *); Chris@87: PyAPI_FUNC(Py_ssize_t) PySet_Size(PyObject *anyset); Chris@87: #define PySet_GET_SIZE(so) (((PySetObject *)(so))->used) Chris@87: PyAPI_FUNC(int) PySet_Clear(PyObject *set); Chris@87: PyAPI_FUNC(int) PySet_Contains(PyObject *anyset, PyObject *key); Chris@87: PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key); Chris@87: PyAPI_FUNC(int) PySet_Add(PyObject *set, PyObject *key); Chris@87: PyAPI_FUNC(int) _PySet_Next(PyObject *set, Py_ssize_t *pos, PyObject **key); Chris@87: PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash); Chris@87: PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set); Chris@87: PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable); Chris@87: Chris@87: #ifdef __cplusplus Chris@87: } Chris@87: #endif Chris@87: #endif /* !Py_SETOBJECT_H */