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 version(Python_3_4_Or_Later) { 25 }else{ 26 /// Availability: ?? 27 struct PyDictEntry { 28 /** Cached hash code of me_key. Note that hash codes are C longs. 29 * We have to use Py_ssize_t instead because dict_popitem() abuses 30 * me_hash to hold a search finger. 31 */ 32 version(Python_3_2_Or_Later) { 33 Py_hash_t me_hash; 34 }else version(Python_2_5_Or_Later) { 35 Py_ssize_t me_hash; 36 }else{ 37 C_long me_hash; 38 } 39 /// _ 40 PyObject* me_key; 41 /// _ 42 PyObject* me_value; 43 } 44 } 45 46 /** 47 To ensure the lookup algorithm terminates, there must be at least one Unused 48 slot (NULL key) in the table. 49 The value ma_fill is the number of non-NULL keys (sum of Active and Dummy); 50 ma_used is the number of non-NULL, non-dummy keys (== the number of non-NULL 51 values == the number of Active items). 52 To avoid slowing down lookups on a near-full table, we resize the table when 53 it's two-thirds full. 54 55 */ 56 57 /// subclass of PyObject 58 version(Python_3_4_Or_Later) { 59 struct PyDictKeysObject { 60 // ??! 61 } 62 63 struct PyDictObject { 64 mixin PyObject_HEAD; 65 /** number of items in the dictionary */ 66 Py_ssize_t ma_used; 67 68 version(Python_3_6_Or_Later) { 69 /** Dictionary version: globally unique, value change each time 70 the dictionary is modified */ 71 ulong ma_version_tag; 72 } 73 PyDictKeysObject* ma_keys; 74 75 /** If ma_values is NULL, the table is "combined": 76 keys and values are stored in ma_keys. 77 78 If ma_values is not NULL, the table is split: 79 keys are stored in ma_keys and values are stored in ma_values */ 80 PyObject** ma_values; 81 } 82 }else{ 83 struct PyDictObject{ 84 mixin PyObject_HEAD; 85 86 /// _ 87 Py_ssize_t ma_fill; 88 /// _ 89 Py_ssize_t ma_used; 90 /** The table contains ma_mask + 1 slots, and that's a power of 2. 91 * We store the mask instead of the size because the mask is more 92 * frequently needed. 93 */ 94 Py_ssize_t ma_mask; 95 /** ma_table points to ma_smalltable for small tables, else to 96 * additional malloc'ed memory. ma_table is never NULL! This rule 97 * saves repeated runtime null-tests in the workhorse getitem and 98 * setitem calls. 99 */ 100 PyDictEntry* ma_table; 101 /// _ 102 PyDictEntry* function(PyDictObject* mp, PyObject* key, Py_hash_t hash) 103 ma_lookup; 104 /// _ 105 PyDictEntry[PyDict_MINSIZE] ma_smalltable; 106 } 107 } 108 109 version(Python_3_5_Or_Later) { 110 struct _PyDictViewObject { 111 mixin PyObject_HEAD; 112 PyDictObject* dv_dict; 113 } 114 } 115 /// _ 116 mixin(PyAPI_DATA!"PyTypeObject PyDict_Type"); 117 118 version(Python_2_7_Or_Later) { 119 /// Availability: >= 2.7 120 mixin(PyAPI_DATA!"PyTypeObject PyDictIterKey_Type"); 121 /// Availability: >= 2.7 122 mixin(PyAPI_DATA!"PyTypeObject PyDictIterValue_Type"); 123 /// Availability: >= 2.7 124 mixin(PyAPI_DATA!"PyTypeObject PyDictIterItem_Type"); 125 /// Availability: >= 2.7 126 mixin(PyAPI_DATA!"PyTypeObject PyDictKeys_Type"); 127 /// Availability: >= 2.7 128 mixin(PyAPI_DATA!"PyTypeObject PyDictItems_Type"); 129 /// Availability: >= 2.7 130 mixin(PyAPI_DATA!"PyTypeObject PyDictValues_Type"); 131 } 132 133 // D translation of C macro: 134 /// _ 135 int PyDict_Check()(PyObject* op) { 136 return PyObject_TypeCheck(op, &PyDict_Type); 137 } 138 // D translation of C macro: 139 /// _ 140 int PyDict_CheckExact()(PyObject* op) { 141 return Py_TYPE(op) == &PyDict_Type; 142 } 143 144 version(Python_2_7_Or_Later) { 145 /// Availability: >= 2.7 146 int PyDictKeys_Check()(PyObject* op) { 147 return Py_TYPE(op) == &PyDictKeys_Type; 148 } 149 /// Availability: >= 2.7 150 int PyDictItems_Check()(PyObject* op) { 151 return Py_TYPE(op) == &PyDictItems_Type; 152 } 153 /// Availability: >= 2.7 154 int PyDictValues_Check()(PyObject* op) { 155 return Py_TYPE(op) == &PyDictValues_Type; 156 } 157 /// Availability: >= 2.7 158 int PyDictViewSet_Check()(PyObject* op) { 159 return PyDictKeys_Check(op) || PyDictItems_Check(op); 160 } 161 } 162 163 /// _ 164 PyObject* PyDict_New(); 165 /// _ 166 PyObject_BorrowedRef* PyDict_GetItem(PyObject* mp, PyObject* key); 167 version(Python_3_0_Or_Later) { 168 /// Availability: 3.* 169 Borrowed!PyObject* PyDict_GetItemWithError(PyObject* mp, PyObject* key); 170 } 171 /// _ 172 int PyDict_SetItem(PyObject* mp, PyObject* key, PyObject* item); 173 /// _ 174 int PyDict_DelItem(PyObject* mp, PyObject* key); 175 /// _ 176 void PyDict_Clear(PyObject* mp); 177 /// _ 178 int PyDict_Next(PyObject* mp, Py_ssize_t* pos, PyObject_BorrowedRef** key, PyObject_BorrowedRef** value); 179 version(Python_2_5_Or_Later) { 180 /// Availability: >= 2.5 181 int _PyDict_Next( 182 PyObject* mp, Py_ssize_t* pos, Borrowed!PyObject** key, 183 Borrowed!PyObject** value, Py_hash_t* hash); 184 } 185 /// _ 186 PyObject* PyDict_Keys(PyObject* mp); 187 /// _ 188 PyObject* PyDict_Values(PyObject* mp); 189 /// _ 190 PyObject* PyDict_Items(PyObject* mp); 191 /// _ 192 Py_ssize_t PyDict_Size(PyObject* mp); 193 /// _ 194 PyObject* PyDict_Copy(PyObject* mp); 195 /// _ 196 int PyDict_Contains(PyObject* mp, PyObject* key); 197 version(Python_3_7_Or_Later) { 198 Py_ssize_t PyDict_GET_SIZE()(PyObject* mp) { 199 return (cast(PyDictObject*)mp).ma_used; 200 } 201 } 202 version(Python_2_5_Or_Later) { 203 /// Availability: >= 2.5 204 int _PyDict_Contains(PyObject* mp, PyObject* key, Py_hash_t* hash); 205 } 206 version(Python_2_6_Or_Later) { 207 /// Availability: >= 2.6 208 PyObject* _PyDict_NewPresized(Py_ssize_t minused); 209 } 210 version(Python_2_7_Or_Later) { 211 /// Availability: >= 2.7 212 void _PyDict_MaybeUntrack(PyObject* mp); 213 } 214 version(Python_3_0_Or_Later) { 215 /// Availability: 3.* 216 int _PyDict_HasOnlyStringKeys(PyObject* mp); 217 } 218 219 /** PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */ 220 int PyDict_Update(PyObject* mp, PyObject* other); 221 /** PyDict_Merge updates/merges from a mapping object (an object that 222 supports PyMapping_Keys() and PyObject_GetItem()). If override is true, 223 the last occurrence of a key wins, else the first. The Python 224 dict.update(other) is equivalent to PyDict_Merge(dict, other, 1). 225 */ 226 int PyDict_Merge(PyObject* mp, PyObject* other, int override_); 227 /** PyDict_MergeFromSeq2 updates/merges from an iterable object producing 228 iterable objects of length 2. If override is true, the last occurrence 229 of a key wins, else the first. The Python dict constructor dict(seq2) 230 is equivalent to dict={}; PyDict_MergeFromSeq(dict, seq2, 1). 231 */ 232 int PyDict_MergeFromSeq2(PyObject* d, PyObject* seq2, int override_); 233 234 /// _ 235 PyObject_BorrowedRef* PyDict_GetItemString(PyObject* dp, const(char)* key); 236 /// _ 237 int PyDict_SetItemString(PyObject* dp, const(char)* key, PyObject* item); 238 /// _ 239 int PyDict_DelItemString(PyObject* dp, const(char)* key); 240 version(Python_2_7_Or_Later) { 241 /// Availability: >= 2.7 242 void _PyDict_DebugMallocStats(FILE* out_); 243 } 244