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