1 /** 2 Mirror _dictobject.h 3 */ 4 module deimos.python.dictobject; 5 6 import deimos.python.pyport; 7 import deimos.python.object; 8 import deimos.python.pythonrun; 9 import core.stdc.stdio; 10 11 extern(C): 12 // Python-header-file: Include/dictobject.h: 13 14 /** PyDict_MINSIZE is the minimum size of a dictionary. This many slots are 15 * allocated directly in the dict object (in the ma_smalltable member). 16 * It must be a power of 2, and at least 4. 8 allows dicts with no more 17 * than 5 active entries to live in ma_smalltable (and so avoid an 18 * additional malloc); instrumentation suggested this suffices for the 19 * majority of dicts (consisting mostly of usually-small instance dicts and 20 * usually-small dicts created to pass keyword arguments). 21 */ 22 enum int PyDict_MINSIZE = 8; 23 24 /// _ 25 struct PyDictEntry { 26 /** Cached hash code of me_key. Note that hash codes are C longs. 27 * We have to use Py_ssize_t instead because dict_popitem() abuses 28 * me_hash to hold a search finger. 29 */ 30 version(Python_3_2_Or_Later) { 31 Py_hash_t me_hash; 32 }else version(Python_2_5_Or_Later) { 33 Py_ssize_t me_hash; 34 }else{ 35 C_long me_hash; 36 } 37 /// _ 38 PyObject* me_key; 39 /// _ 40 PyObject* me_value; 41 } 42 43 /** 44 To ensure the lookup algorithm terminates, there must be at least one Unused 45 slot (NULL key) in the table. 46 The value ma_fill is the number of non-NULL keys (sum of Active and Dummy); 47 ma_used is the number of non-NULL, non-dummy keys (== the number of non-NULL 48 values == the number of Active items). 49 To avoid slowing down lookups on a near-full table, we resize the table when 50 it's two-thirds full. 51 52 */ 53 /// subclass of PyObject 54 struct PyDictObject{ 55 mixin PyObject_HEAD; 56 57 /// _ 58 Py_ssize_t ma_fill; 59 /// _ 60 Py_ssize_t ma_used; 61 /** The table contains ma_mask + 1 slots, and that's a power of 2. 62 * We store the mask instead of the size because the mask is more 63 * frequently needed. 64 */ 65 Py_ssize_t ma_mask; 66 /** ma_table points to ma_smalltable for small tables, else to 67 * additional malloc'ed memory. ma_table is never NULL! This rule 68 * saves repeated runtime null-tests in the workhorse getitem and 69 * setitem calls. 70 */ 71 PyDictEntry* ma_table; 72 /// _ 73 PyDictEntry* function(PyDictObject* mp, PyObject* key, Py_hash_t hash) 74 ma_lookup; 75 /// _ 76 PyDictEntry[PyDict_MINSIZE] ma_smalltable; 77 } 78 79 /// _ 80 mixin(PyAPI_DATA!"PyTypeObject PyDict_Type"); 81 version(Python_2_7_Or_Later) { 82 /// Availability: >= 2.7 83 mixin(PyAPI_DATA!"PyTypeObject PyDictIterKey_Type"); 84 /// Availability: >= 2.7 85 mixin(PyAPI_DATA!"PyTypeObject PyDictIterValue_Type"); 86 /// Availability: >= 2.7 87 mixin(PyAPI_DATA!"PyTypeObject PyDictIterItem_Type"); 88 /// Availability: >= 2.7 89 mixin(PyAPI_DATA!"PyTypeObject PyDictKeys_Type"); 90 /// Availability: >= 2.7 91 mixin(PyAPI_DATA!"PyTypeObject PyDictItems_Type"); 92 /// Availability: >= 2.7 93 mixin(PyAPI_DATA!"PyTypeObject PyDictValues_Type"); 94 } 95 96 // D translation of C macro: 97 /// _ 98 int PyDict_Check()(PyObject* op) { 99 return PyObject_TypeCheck(op, &PyDict_Type); 100 } 101 // D translation of C macro: 102 /// _ 103 int PyDict_CheckExact()(PyObject* op) { 104 return Py_TYPE(op) == &PyDict_Type; 105 } 106 107 version(Python_2_7_Or_Later) { 108 /// Availability: >= 2.7 109 int PyDictKeys_Check()(PyObject* op) { 110 return Py_TYPE(op) == &PyDictKeys_Type; 111 } 112 /// Availability: >= 2.7 113 int PyDictItems_Check()(PyObject* op) { 114 return Py_TYPE(op) == &PyDictItems_Type; 115 } 116 /// Availability: >= 2.7 117 int PyDictValues_Check()(PyObject* op) { 118 return Py_TYPE(op) == &PyDictValues_Type; 119 } 120 /// Availability: >= 2.7 121 int PyDictViewSet_Check()(PyObject* op) { 122 return PyDictKeys_Check(op) || PyDictItems_Check(op); 123 } 124 } 125 126 /// _ 127 PyObject* PyDict_New(); 128 /// _ 129 PyObject_BorrowedRef* PyDict_GetItem(PyObject* mp, PyObject* key); 130 version(Python_3_0_Or_Later) { 131 /// Availability: 3.* 132 Borrowed!PyObject* PyDict_GetItemWithError(PyObject* mp, PyObject* key); 133 } 134 /// _ 135 int PyDict_SetItem(PyObject* mp, PyObject* key, PyObject* item); 136 /// _ 137 int PyDict_DelItem(PyObject* mp, PyObject* key); 138 /// _ 139 void PyDict_Clear(PyObject* mp); 140 /// _ 141 int PyDict_Next(PyObject* mp, Py_ssize_t* pos, PyObject_BorrowedRef** key, PyObject_BorrowedRef** value); 142 version(Python_2_5_Or_Later) { 143 /// Availability: >= 2.5 144 int _PyDict_Next( 145 PyObject* mp, Py_ssize_t* pos, Borrowed!PyObject** key, 146 Borrowed!PyObject** value, Py_hash_t* hash); 147 } 148 /// _ 149 PyObject* PyDict_Keys(PyObject* mp); 150 /// _ 151 PyObject* PyDict_Values(PyObject* mp); 152 /// _ 153 PyObject* PyDict_Items(PyObject* mp); 154 /// _ 155 Py_ssize_t PyDict_Size(PyObject* mp); 156 /// _ 157 PyObject* PyDict_Copy(PyObject* mp); 158 /// _ 159 int PyDict_Contains(PyObject* mp, PyObject* key); 160 version(Python_2_5_Or_Later) { 161 /// Availability: >= 2.5 162 int _PyDict_Contains(PyObject* mp, PyObject* key, Py_hash_t* hash); 163 } 164 version(Python_2_6_Or_Later) { 165 /// Availability: >= 2.6 166 PyObject* _PyDict_NewPresized(Py_ssize_t minused); 167 } 168 version(Python_2_7_Or_Later) { 169 /// Availability: >= 2.7 170 void _PyDict_MaybeUntrack(PyObject* mp); 171 } 172 version(Python_3_0_Or_Later) { 173 /// Availability: 3.* 174 int _PyDict_HasOnlyStringKeys(PyObject* mp); 175 } 176 177 /** PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */ 178 int PyDict_Update(PyObject* mp, PyObject* other); 179 /** PyDict_Merge updates/merges from a mapping object (an object that 180 supports PyMapping_Keys() and PyObject_GetItem()). If override is true, 181 the last occurrence of a key wins, else the first. The Python 182 dict.update(other) is equivalent to PyDict_Merge(dict, other, 1). 183 */ 184 int PyDict_Merge(PyObject* mp, PyObject* other, int override_); 185 /** PyDict_MergeFromSeq2 updates/merges from an iterable object producing 186 iterable objects of length 2. If override is true, the last occurrence 187 of a key wins, else the first. The Python dict constructor dict(seq2) 188 is equivalent to dict={}; PyDict_MergeFromSeq(dict, seq2, 1). 189 */ 190 int PyDict_MergeFromSeq2(PyObject* d, PyObject* seq2, int override_); 191 192 /// _ 193 PyObject_BorrowedRef* PyDict_GetItemString(PyObject* dp, const(char)* key); 194 /// _ 195 int PyDict_SetItemString(PyObject* dp, const(char)* key, PyObject* item); 196 /// _ 197 int PyDict_DelItemString(PyObject* dp, const(char)* key); 198 version(Python_2_7_Or_Later) { 199 /// Availability: >= 2.7 200 void _PyDict_DebugMallocStats(FILE* out_); 201 } 202