blob: 15530a70148aee369782b15acb183ad0bd3e002a [file] [log] [blame]
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001#include "Python.h"
Raymond Hettinger691d8052004-05-30 07:26:47 +00002#include "structmember.h"
Raymond Hettinger756b3f32004-01-29 06:37:52 +00003
4/* collections module implementation of a deque() datatype
5 Written and maintained by Raymond D. Hettinger <python@rcn.com>
6 Copyright (c) 2004 Python Software Foundation.
7 All rights reserved.
8*/
9
Raymond Hettinger77e8bf12004-10-01 15:25:53 +000010/* The block length may be set to any number over 1. Larger numbers
11 * reduce the number of calls to the memory allocator but take more
12 * memory. Ideally, BLOCKLEN should be set with an eye to the
13 * length of a cache line.
14 */
15
16#define BLOCKLEN 46
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000017#define CENTER ((BLOCKLEN - 1) / 2)
Raymond Hettinger756b3f32004-01-29 06:37:52 +000018
Tim Petersd8768d32004-10-01 01:32:53 +000019/* A `dequeobject` is composed of a doubly-linked list of `block` nodes.
20 * This list is not circular (the leftmost block has leftlink==NULL,
21 * and the rightmost block has rightlink==NULL). A deque d's first
22 * element is at d.leftblock[leftindex] and its last element is at
23 * d.rightblock[rightindex]; note that, unlike as for Python slice
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000024 * indices, these indices are inclusive on both ends. By being inclusive
25 * on both ends, algorithms for left and right operations become
26 * symmetrical which simplifies the design.
27 *
28 * The list of blocks is never empty, so d.leftblock and d.rightblock
29 * are never equal to NULL.
30 *
31 * The indices, d.leftindex and d.rightindex are always in the range
32 * 0 <= index < BLOCKLEN.
Raymond Hettinger4ca4c7c2004-10-01 15:14:39 +000033 * Their exact relationship is:
34 * (d.leftindex + d.len - 1) % BLOCKLEN == d.rightindex.
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000035 *
36 * Empty deques have d.len == 0; d.leftblock==d.rightblock;
37 * d.leftindex == CENTER+1; and d.rightindex == CENTER.
38 * Checking for d.len == 0 is the intended way to see whether d is empty.
39 *
40 * Whenever d.leftblock == d.rightblock,
Raymond Hettinger4ca4c7c2004-10-01 15:14:39 +000041 * d.leftindex + d.len - 1 == d.rightindex.
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000042 *
Raymond Hettinger4ca4c7c2004-10-01 15:14:39 +000043 * However, when d.leftblock != d.rightblock, d.leftindex and d.rightindex
44 * become indices into distinct blocks and either may be larger than the
45 * other.
Tim Petersd8768d32004-10-01 01:32:53 +000046 */
47
Raymond Hettinger756b3f32004-01-29 06:37:52 +000048typedef struct BLOCK {
49 struct BLOCK *leftlink;
50 struct BLOCK *rightlink;
51 PyObject *data[BLOCKLEN];
52} block;
53
Tim Peters6f853562004-10-01 01:04:50 +000054static block *
55newblock(block *leftlink, block *rightlink) {
Raymond Hettinger756b3f32004-01-29 06:37:52 +000056 block *b = PyMem_Malloc(sizeof(block));
57 if (b == NULL) {
58 PyErr_NoMemory();
59 return NULL;
60 }
61 b->leftlink = leftlink;
62 b->rightlink = rightlink;
63 return b;
64}
65
66typedef struct {
67 PyObject_HEAD
68 block *leftblock;
69 block *rightblock;
Tim Petersd8768d32004-10-01 01:32:53 +000070 int leftindex; /* in range(BLOCKLEN) */
71 int rightindex; /* in range(BLOCKLEN) */
Raymond Hettinger756b3f32004-01-29 06:37:52 +000072 int len;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +000073 long state; /* incremented whenever the indices move */
Raymond Hettinger691d8052004-05-30 07:26:47 +000074 PyObject *weakreflist; /* List of weak references */
Raymond Hettinger756b3f32004-01-29 06:37:52 +000075} dequeobject;
76
Neal Norwitz87f10132004-02-29 15:40:53 +000077static PyTypeObject deque_type;
Raymond Hettinger738ec902004-02-29 02:15:56 +000078
Raymond Hettinger756b3f32004-01-29 06:37:52 +000079static PyObject *
80deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
81{
82 dequeobject *deque;
83 block *b;
84
85 /* create dequeobject structure */
86 deque = (dequeobject *)type->tp_alloc(type, 0);
87 if (deque == NULL)
88 return NULL;
Tim Peters1065f752004-10-01 01:03:29 +000089
Raymond Hettinger756b3f32004-01-29 06:37:52 +000090 b = newblock(NULL, NULL);
91 if (b == NULL) {
92 Py_DECREF(deque);
93 return NULL;
94 }
95
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000096 assert(BLOCKLEN >= 2);
Raymond Hettinger756b3f32004-01-29 06:37:52 +000097 deque->leftblock = b;
98 deque->rightblock = b;
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000099 deque->leftindex = CENTER + 1;
100 deque->rightindex = CENTER;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000101 deque->len = 0;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000102 deque->state = 0;
Raymond Hettinger691d8052004-05-30 07:26:47 +0000103 deque->weakreflist = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000104
105 return (PyObject *)deque;
106}
107
108static PyObject *
109deque_append(dequeobject *deque, PyObject *item)
110{
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000111 deque->state++;
Armin Rigo974d7572004-10-02 13:59:34 +0000112 if (deque->rightindex == BLOCKLEN-1) {
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000113 block *b = newblock(deque->rightblock, NULL);
114 if (b == NULL)
115 return NULL;
116 assert(deque->rightblock->rightlink == NULL);
117 deque->rightblock->rightlink = b;
118 deque->rightblock = b;
Armin Rigo974d7572004-10-02 13:59:34 +0000119 deque->rightindex = -1;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000120 }
121 Py_INCREF(item);
Armin Rigo974d7572004-10-02 13:59:34 +0000122 deque->len++;
123 deque->rightindex++;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000124 deque->rightblock->data[deque->rightindex] = item;
125 Py_RETURN_NONE;
126}
127
128PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque.");
129
130static PyObject *
131deque_appendleft(dequeobject *deque, PyObject *item)
132{
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000133 deque->state++;
Armin Rigo974d7572004-10-02 13:59:34 +0000134 if (deque->leftindex == 0) {
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000135 block *b = newblock(NULL, deque->leftblock);
136 if (b == NULL)
137 return NULL;
138 assert(deque->leftblock->leftlink == NULL);
139 deque->leftblock->leftlink = b;
140 deque->leftblock = b;
Armin Rigo974d7572004-10-02 13:59:34 +0000141 deque->leftindex = BLOCKLEN;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000142 }
143 Py_INCREF(item);
Armin Rigo974d7572004-10-02 13:59:34 +0000144 deque->len++;
145 deque->leftindex--;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000146 deque->leftblock->data[deque->leftindex] = item;
147 Py_RETURN_NONE;
148}
149
150PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque.");
151
152static PyObject *
153deque_pop(dequeobject *deque, PyObject *unused)
154{
155 PyObject *item;
156 block *prevblock;
157
158 if (deque->len == 0) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000159 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000160 return NULL;
161 }
162 item = deque->rightblock->data[deque->rightindex];
163 deque->rightindex--;
164 deque->len--;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000165 deque->state++;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000166
167 if (deque->rightindex == -1) {
168 if (deque->len == 0) {
169 assert(deque->leftblock == deque->rightblock);
170 assert(deque->leftindex == deque->rightindex+1);
171 /* re-center instead of freeing a block */
Raymond Hettinger61f05fb2004-10-01 06:24:12 +0000172 deque->leftindex = CENTER + 1;
173 deque->rightindex = CENTER;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000174 } else {
175 prevblock = deque->rightblock->leftlink;
176 assert(deque->leftblock != deque->rightblock);
177 PyMem_Free(deque->rightblock);
178 prevblock->rightlink = NULL;
179 deque->rightblock = prevblock;
180 deque->rightindex = BLOCKLEN - 1;
181 }
182 }
183 return item;
184}
185
186PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");
187
188static PyObject *
189deque_popleft(dequeobject *deque, PyObject *unused)
190{
191 PyObject *item;
192 block *prevblock;
193
194 if (deque->len == 0) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000195 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000196 return NULL;
197 }
198 item = deque->leftblock->data[deque->leftindex];
199 deque->leftindex++;
200 deque->len--;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000201 deque->state++;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000202
203 if (deque->leftindex == BLOCKLEN) {
204 if (deque->len == 0) {
205 assert(deque->leftblock == deque->rightblock);
206 assert(deque->leftindex == deque->rightindex+1);
207 /* re-center instead of freeing a block */
Raymond Hettinger61f05fb2004-10-01 06:24:12 +0000208 deque->leftindex = CENTER + 1;
209 deque->rightindex = CENTER;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000210 } else {
211 assert(deque->leftblock != deque->rightblock);
212 prevblock = deque->leftblock->rightlink;
213 assert(deque->leftblock != NULL);
214 PyMem_Free(deque->leftblock);
215 assert(prevblock != NULL);
216 prevblock->leftlink = NULL;
217 deque->leftblock = prevblock;
218 deque->leftindex = 0;
219 }
220 }
221 return item;
222}
223
224PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element.");
225
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000226static PyObject *
227deque_extend(dequeobject *deque, PyObject *iterable)
228{
229 PyObject *it, *item;
230
231 it = PyObject_GetIter(iterable);
232 if (it == NULL)
233 return NULL;
234
235 while ((item = PyIter_Next(it)) != NULL) {
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000236 deque->state++;
Armin Rigo974d7572004-10-02 13:59:34 +0000237 if (deque->rightindex == BLOCKLEN-1) {
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000238 block *b = newblock(deque->rightblock, NULL);
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000239 if (b == NULL) {
240 Py_DECREF(item);
241 Py_DECREF(it);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000242 return NULL;
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000243 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000244 assert(deque->rightblock->rightlink == NULL);
245 deque->rightblock->rightlink = b;
246 deque->rightblock = b;
Armin Rigo974d7572004-10-02 13:59:34 +0000247 deque->rightindex = -1;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000248 }
Armin Rigo974d7572004-10-02 13:59:34 +0000249 deque->len++;
250 deque->rightindex++;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000251 deque->rightblock->data[deque->rightindex] = item;
252 }
253 Py_DECREF(it);
Tim Peters1065f752004-10-01 01:03:29 +0000254 if (PyErr_Occurred())
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000255 return NULL;
256 Py_RETURN_NONE;
257}
258
Tim Peters1065f752004-10-01 01:03:29 +0000259PyDoc_STRVAR(extend_doc,
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000260"Extend the right side of the deque with elements from the iterable");
261
262static PyObject *
263deque_extendleft(dequeobject *deque, PyObject *iterable)
264{
265 PyObject *it, *item;
266
267 it = PyObject_GetIter(iterable);
268 if (it == NULL)
269 return NULL;
270
271 while ((item = PyIter_Next(it)) != NULL) {
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000272 deque->state++;
Armin Rigo974d7572004-10-02 13:59:34 +0000273 if (deque->leftindex == 0) {
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000274 block *b = newblock(NULL, deque->leftblock);
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000275 if (b == NULL) {
276 Py_DECREF(item);
277 Py_DECREF(it);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000278 return NULL;
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000279 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000280 assert(deque->leftblock->leftlink == NULL);
281 deque->leftblock->leftlink = b;
282 deque->leftblock = b;
Armin Rigo974d7572004-10-02 13:59:34 +0000283 deque->leftindex = BLOCKLEN;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000284 }
Armin Rigo974d7572004-10-02 13:59:34 +0000285 deque->len++;
286 deque->leftindex--;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000287 deque->leftblock->data[deque->leftindex] = item;
288 }
289 Py_DECREF(it);
Raymond Hettingera435c532004-07-09 04:10:20 +0000290 if (PyErr_Occurred())
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000291 return NULL;
292 Py_RETURN_NONE;
293}
294
Tim Peters1065f752004-10-01 01:03:29 +0000295PyDoc_STRVAR(extendleft_doc,
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000296"Extend the left side of the deque with elements from the iterable");
297
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000298static PyObject *
299deque_rotate(dequeobject *deque, PyObject *args)
300{
Raymond Hettingeree33b272004-02-08 04:05:26 +0000301 int i, n=1, len=deque->len, halflen=(len+1)>>1;
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000302 PyObject *item, *rv;
303
Raymond Hettingeree33b272004-02-08 04:05:26 +0000304 if (!PyArg_ParseTuple(args, "|i:rotate", &n))
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000305 return NULL;
306
Raymond Hettingeree33b272004-02-08 04:05:26 +0000307 if (len == 0)
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000308 Py_RETURN_NONE;
Raymond Hettingeree33b272004-02-08 04:05:26 +0000309 if (n > halflen || n < -halflen) {
310 n %= len;
311 if (n > halflen)
312 n -= len;
313 else if (n < -halflen)
314 n += len;
315 }
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000316
317 for (i=0 ; i<n ; i++) {
318 item = deque_pop(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000319 assert (item != NULL);
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000320 rv = deque_appendleft(deque, item);
321 Py_DECREF(item);
322 if (rv == NULL)
323 return NULL;
324 Py_DECREF(rv);
325 }
326 for (i=0 ; i>n ; i--) {
327 item = deque_popleft(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000328 assert (item != NULL);
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000329 rv = deque_append(deque, item);
330 Py_DECREF(item);
331 if (rv == NULL)
332 return NULL;
333 Py_DECREF(rv);
334 }
335 Py_RETURN_NONE;
336}
337
Tim Peters1065f752004-10-01 01:03:29 +0000338PyDoc_STRVAR(rotate_doc,
Raymond Hettingeree33b272004-02-08 04:05:26 +0000339"Rotate the deque n steps to the right (default n=1). If n is negative, rotates left.");
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000340
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000341static int
342deque_len(dequeobject *deque)
343{
344 return deque->len;
345}
346
347static int
348deque_clear(dequeobject *deque)
349{
350 PyObject *item;
351
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000352 while (deque->len) {
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000353 item = deque_pop(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000354 assert (item != NULL);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000355 Py_DECREF(item);
356 }
357 assert(deque->leftblock == deque->rightblock &&
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000358 deque->leftindex - 1 == deque->rightindex &&
359 deque->len == 0);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000360 return 0;
361}
362
363static PyObject *
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000364deque_item(dequeobject *deque, int i)
365{
366 block *b;
367 PyObject *item;
Armin Rigo974d7572004-10-02 13:59:34 +0000368 int n, index=i;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000369
370 if (i < 0 || i >= deque->len) {
371 PyErr_SetString(PyExc_IndexError,
372 "deque index out of range");
373 return NULL;
374 }
375
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000376 if (i == 0) {
377 i = deque->leftindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000378 b = deque->leftblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000379 } else if (i == deque->len - 1) {
380 i = deque->rightindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000381 b = deque->rightblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000382 } else {
383 i += deque->leftindex;
384 n = i / BLOCKLEN;
385 i %= BLOCKLEN;
Armin Rigo974d7572004-10-02 13:59:34 +0000386 if (index < (deque->len >> 1)) {
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000387 b = deque->leftblock;
388 while (n--)
389 b = b->rightlink;
390 } else {
391 n = (deque->leftindex + deque->len - 1) / BLOCKLEN - n;
392 b = deque->rightblock;
393 while (n--)
394 b = b->leftlink;
395 }
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000396 }
397 item = b->data[i];
398 Py_INCREF(item);
399 return item;
400}
401
Raymond Hettinger616f4f62004-06-26 04:42:06 +0000402/* delitem() implemented in terms of rotate for simplicity and reasonable
403 performance near the end points. If for some reason this method becomes
Tim Peters1065f752004-10-01 01:03:29 +0000404 popular, it is not hard to re-implement this using direct data movement
Raymond Hettinger616f4f62004-06-26 04:42:06 +0000405 (similar to code in list slice assignment) and achieve a two or threefold
406 performance boost.
407*/
408
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000409static int
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000410deque_del_item(dequeobject *deque, int i)
411{
412 PyObject *item=NULL, *minus_i=NULL, *plus_i=NULL;
413 int rv = -1;
414
Tim Peters1065f752004-10-01 01:03:29 +0000415 assert (i >= 0 && i < deque->len);
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000416
417 minus_i = Py_BuildValue("(i)", -i);
418 if (minus_i == NULL)
419 goto fail;
420
421 plus_i = Py_BuildValue("(i)", i);
422 if (plus_i == NULL)
423 goto fail;
424
425 item = deque_rotate(deque, minus_i);
Tim Peters1065f752004-10-01 01:03:29 +0000426 if (item == NULL)
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000427 goto fail;
428 Py_DECREF(item);
429
430 item = deque_popleft(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000431 assert (item != NULL);
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000432 Py_DECREF(item);
433
434 item = deque_rotate(deque, plus_i);
Tim Peters1065f752004-10-01 01:03:29 +0000435 if (item == NULL)
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000436 goto fail;
437
438 rv = 0;
439fail:
440 Py_XDECREF(item);
441 Py_XDECREF(minus_i);
442 Py_XDECREF(plus_i);
443 return rv;
444}
445
446static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000447deque_ass_item(dequeobject *deque, int i, PyObject *v)
448{
449 PyObject *old_value;
450 block *b;
Raymond Hettingera435c532004-07-09 04:10:20 +0000451 int n, len=deque->len, halflen=(len+1)>>1, index=i;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000452
Raymond Hettingera435c532004-07-09 04:10:20 +0000453 if (i < 0 || i >= len) {
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000454 PyErr_SetString(PyExc_IndexError,
455 "deque index out of range");
456 return -1;
457 }
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000458 if (v == NULL)
459 return deque_del_item(deque, i);
460
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000461 i += deque->leftindex;
462 n = i / BLOCKLEN;
463 i %= BLOCKLEN;
Raymond Hettingera435c532004-07-09 04:10:20 +0000464 if (index <= halflen) {
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000465 b = deque->leftblock;
466 while (n--)
467 b = b->rightlink;
468 } else {
Raymond Hettingera435c532004-07-09 04:10:20 +0000469 n = (deque->leftindex + len - 1) / BLOCKLEN - n;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000470 b = deque->rightblock;
471 while (n--)
472 b = b->leftlink;
473 }
474 Py_INCREF(v);
475 old_value = b->data[i];
476 b->data[i] = v;
477 Py_DECREF(old_value);
478 return 0;
479}
480
481static PyObject *
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000482deque_clearmethod(dequeobject *deque)
483{
Raymond Hettingera435c532004-07-09 04:10:20 +0000484 int rv;
485
486 rv = deque_clear(deque);
487 assert (rv != -1);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000488 Py_RETURN_NONE;
489}
490
491PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
492
493static void
494deque_dealloc(dequeobject *deque)
495{
496 PyObject_GC_UnTrack(deque);
Raymond Hettinger691d8052004-05-30 07:26:47 +0000497 if (deque->weakreflist != NULL)
498 PyObject_ClearWeakRefs((PyObject *) deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000499 if (deque->leftblock != NULL) {
Raymond Hettingere9c89e82004-07-19 00:10:24 +0000500 deque_clear(deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000501 assert(deque->leftblock != NULL);
502 PyMem_Free(deque->leftblock);
503 }
504 deque->leftblock = NULL;
505 deque->rightblock = NULL;
506 deque->ob_type->tp_free(deque);
507}
508
509static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000510deque_traverse(dequeobject *deque, visitproc visit, void *arg)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000511{
Tim Peters10c7e862004-10-01 02:01:04 +0000512 block *b;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000513 PyObject *item;
Tim Peters10c7e862004-10-01 02:01:04 +0000514 int index;
515 int indexlo = deque->leftindex;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000516
Tim Peters10c7e862004-10-01 02:01:04 +0000517 for (b = deque->leftblock; b != NULL; b = b->rightlink) {
518 const int indexhi = b == deque->rightblock ?
519 deque->rightindex :
520 BLOCKLEN - 1;
521
522 for (index = indexlo; index <= indexhi; ++index) {
523 item = b->data[index];
524 Py_VISIT(item);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000525 }
Tim Peters10c7e862004-10-01 02:01:04 +0000526 indexlo = 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000527 }
528 return 0;
529}
530
531static long
532deque_nohash(PyObject *self)
533{
534 PyErr_SetString(PyExc_TypeError, "deque objects are unhashable");
535 return -1;
536}
537
538static PyObject *
539deque_copy(PyObject *deque)
540{
Tim Peters1065f752004-10-01 01:03:29 +0000541 return PyObject_CallFunctionObjArgs((PyObject *)(deque->ob_type),
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000542 deque, NULL);
543}
544
545PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
546
547static PyObject *
548deque_reduce(dequeobject *deque)
549{
550 PyObject *seq, *args, *result;
551
552 seq = PySequence_Tuple((PyObject *)deque);
553 if (seq == NULL)
554 return NULL;
555 args = PyTuple_Pack(1, seq);
556 if (args == NULL) {
557 Py_DECREF(seq);
558 return NULL;
559 }
560 result = PyTuple_Pack(2, deque->ob_type, args);
561 Py_DECREF(seq);
562 Py_DECREF(args);
563 return result;
564}
565
566PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
567
568static PyObject *
569deque_repr(PyObject *deque)
570{
571 PyObject *aslist, *result, *fmt;
572 int i;
573
574 i = Py_ReprEnter(deque);
575 if (i != 0) {
576 if (i < 0)
577 return NULL;
578 return PyString_FromString("[...]");
579 }
580
581 aslist = PySequence_List(deque);
582 if (aslist == NULL) {
583 Py_ReprLeave(deque);
584 return NULL;
585 }
586
587 fmt = PyString_FromString("deque(%r)");
588 if (fmt == NULL) {
589 Py_DECREF(aslist);
590 Py_ReprLeave(deque);
591 return NULL;
592 }
593 result = PyString_Format(fmt, aslist);
594 Py_DECREF(fmt);
595 Py_DECREF(aslist);
596 Py_ReprLeave(deque);
597 return result;
598}
599
600static int
601deque_tp_print(PyObject *deque, FILE *fp, int flags)
602{
603 PyObject *it, *item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000604 char *emit = ""; /* No separator emitted on first pass */
605 char *separator = ", ";
606 int i;
607
608 i = Py_ReprEnter(deque);
609 if (i != 0) {
610 if (i < 0)
611 return i;
612 fputs("[...]", fp);
613 return 0;
614 }
615
616 it = PyObject_GetIter(deque);
617 if (it == NULL)
618 return -1;
619
620 fputs("deque([", fp);
621 while ((item = PyIter_Next(it)) != NULL) {
622 fputs(emit, fp);
623 emit = separator;
624 if (PyObject_Print(item, fp, 0) != 0) {
625 Py_DECREF(item);
626 Py_DECREF(it);
627 Py_ReprLeave(deque);
628 return -1;
629 }
630 Py_DECREF(item);
631 }
632 Py_ReprLeave(deque);
633 Py_DECREF(it);
Tim Peters1065f752004-10-01 01:03:29 +0000634 if (PyErr_Occurred())
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000635 return -1;
636 fputs("])", fp);
637 return 0;
638}
639
Raymond Hettinger738ec902004-02-29 02:15:56 +0000640static PyObject *
641deque_richcompare(PyObject *v, PyObject *w, int op)
642{
643 PyObject *it1=NULL, *it2=NULL, *x, *y;
Armin Rigo974d7572004-10-02 13:59:34 +0000644 int b, vs, ws, cmp=-1;
Raymond Hettinger738ec902004-02-29 02:15:56 +0000645
Tim Peters1065f752004-10-01 01:03:29 +0000646 if (!PyObject_TypeCheck(v, &deque_type) ||
Raymond Hettinger285cfcc2004-05-18 18:15:03 +0000647 !PyObject_TypeCheck(w, &deque_type)) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000648 Py_INCREF(Py_NotImplemented);
649 return Py_NotImplemented;
650 }
651
652 /* Shortcuts */
653 vs = ((dequeobject *)v)->len;
654 ws = ((dequeobject *)w)->len;
655 if (op == Py_EQ) {
656 if (v == w)
657 Py_RETURN_TRUE;
658 if (vs != ws)
659 Py_RETURN_FALSE;
660 }
661 if (op == Py_NE) {
662 if (v == w)
663 Py_RETURN_FALSE;
664 if (vs != ws)
665 Py_RETURN_TRUE;
666 }
667
668 /* Search for the first index where items are different */
669 it1 = PyObject_GetIter(v);
670 if (it1 == NULL)
671 goto done;
672 it2 = PyObject_GetIter(w);
673 if (it2 == NULL)
674 goto done;
Armin Rigo974d7572004-10-02 13:59:34 +0000675 for (;;) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000676 x = PyIter_Next(it1);
Armin Rigo974d7572004-10-02 13:59:34 +0000677 if (x == NULL && PyErr_Occurred())
Raymond Hettinger738ec902004-02-29 02:15:56 +0000678 goto done;
679 y = PyIter_Next(it2);
Armin Rigo974d7572004-10-02 13:59:34 +0000680 if (x == NULL || y == NULL)
681 break;
Raymond Hettinger738ec902004-02-29 02:15:56 +0000682 b = PyObject_RichCompareBool(x, y, Py_EQ);
683 if (b == 0) {
684 cmp = PyObject_RichCompareBool(x, y, op);
685 Py_DECREF(x);
686 Py_DECREF(y);
687 goto done;
688 }
689 Py_DECREF(x);
690 Py_DECREF(y);
691 if (b == -1)
692 goto done;
693 }
Armin Rigo974d7572004-10-02 13:59:34 +0000694 /* We reached the end of one deque or both */
695 Py_XDECREF(x);
696 Py_XDECREF(y);
697 if (PyErr_Occurred())
698 goto done;
Raymond Hettinger738ec902004-02-29 02:15:56 +0000699 switch (op) {
Armin Rigo974d7572004-10-02 13:59:34 +0000700 case Py_LT: cmp = y != NULL; break; /* if w was longer */
701 case Py_LE: cmp = x == NULL; break; /* if v was not longer */
702 case Py_EQ: cmp = x == y; break; /* if we reached the end of both */
703 case Py_NE: cmp = x != y; break; /* if one deque continues */
704 case Py_GT: cmp = x != NULL; break; /* if v was longer */
705 case Py_GE: cmp = y == NULL; break; /* if w was not longer */
Raymond Hettinger738ec902004-02-29 02:15:56 +0000706 }
Tim Peters1065f752004-10-01 01:03:29 +0000707
Raymond Hettinger738ec902004-02-29 02:15:56 +0000708done:
709 Py_XDECREF(it1);
710 Py_XDECREF(it2);
711 if (cmp == 1)
712 Py_RETURN_TRUE;
713 if (cmp == 0)
714 Py_RETURN_FALSE;
715 return NULL;
716}
717
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000718static int
719deque_init(dequeobject *deque, PyObject *args, PyObject *kwds)
720{
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000721 PyObject *iterable = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000722
723 if (!PyArg_UnpackTuple(args, "deque", 0, 1, &iterable))
724 return -1;
725
726 if (iterable != NULL) {
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000727 PyObject *rv = deque_extend(deque, iterable);
728 if (rv == NULL)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000729 return -1;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000730 Py_DECREF(rv);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000731 }
732 return 0;
733}
734
735static PySequenceMethods deque_as_sequence = {
736 (inquiry)deque_len, /* sq_length */
737 0, /* sq_concat */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000738 0, /* sq_repeat */
739 (intargfunc)deque_item, /* sq_item */
740 0, /* sq_slice */
741 (intobjargproc)deque_ass_item, /* sq_ass_item */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000742};
743
744/* deque object ********************************************************/
745
746static PyObject *deque_iter(dequeobject *deque);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000747static PyObject *deque_reviter(dequeobject *deque);
Tim Peters1065f752004-10-01 01:03:29 +0000748PyDoc_STRVAR(reversed_doc,
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000749 "D.__reversed__() -- return a reverse iterator over the deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000750
751static PyMethodDef deque_methods[] = {
Tim Peters1065f752004-10-01 01:03:29 +0000752 {"append", (PyCFunction)deque_append,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000753 METH_O, append_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000754 {"appendleft", (PyCFunction)deque_appendleft,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000755 METH_O, appendleft_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000756 {"clear", (PyCFunction)deque_clearmethod,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000757 METH_NOARGS, clear_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000758 {"__copy__", (PyCFunction)deque_copy,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000759 METH_NOARGS, copy_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000760 {"extend", (PyCFunction)deque_extend,
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000761 METH_O, extend_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000762 {"extendleft", (PyCFunction)deque_extendleft,
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000763 METH_O, extendleft_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000764 {"pop", (PyCFunction)deque_pop,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000765 METH_NOARGS, pop_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000766 {"popleft", (PyCFunction)deque_popleft,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000767 METH_NOARGS, popleft_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000768 {"__reduce__", (PyCFunction)deque_reduce,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000769 METH_NOARGS, reduce_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000770 {"__reversed__", (PyCFunction)deque_reviter,
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000771 METH_NOARGS, reversed_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000772 {"rotate", (PyCFunction)deque_rotate,
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000773 METH_VARARGS, rotate_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000774 {NULL, NULL} /* sentinel */
775};
776
777PyDoc_STRVAR(deque_doc,
778"deque(iterable) --> deque object\n\
779\n\
780Build an ordered collection accessible from endpoints only.");
781
Neal Norwitz87f10132004-02-29 15:40:53 +0000782static PyTypeObject deque_type = {
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000783 PyObject_HEAD_INIT(NULL)
784 0, /* ob_size */
785 "collections.deque", /* tp_name */
786 sizeof(dequeobject), /* tp_basicsize */
787 0, /* tp_itemsize */
788 /* methods */
789 (destructor)deque_dealloc, /* tp_dealloc */
790 (printfunc)deque_tp_print, /* tp_print */
791 0, /* tp_getattr */
792 0, /* tp_setattr */
793 0, /* tp_compare */
794 (reprfunc)deque_repr, /* tp_repr */
795 0, /* tp_as_number */
796 &deque_as_sequence, /* tp_as_sequence */
797 0, /* tp_as_mapping */
798 deque_nohash, /* tp_hash */
799 0, /* tp_call */
800 0, /* tp_str */
801 PyObject_GenericGetAttr, /* tp_getattro */
802 0, /* tp_setattro */
803 0, /* tp_as_buffer */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000804 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
805 Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000806 deque_doc, /* tp_doc */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000807 (traverseproc)deque_traverse, /* tp_traverse */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000808 (inquiry)deque_clear, /* tp_clear */
Raymond Hettinger738ec902004-02-29 02:15:56 +0000809 (richcmpfunc)deque_richcompare, /* tp_richcompare */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000810 offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000811 (getiterfunc)deque_iter, /* tp_iter */
812 0, /* tp_iternext */
813 deque_methods, /* tp_methods */
814 0, /* tp_members */
815 0, /* tp_getset */
816 0, /* tp_base */
817 0, /* tp_dict */
818 0, /* tp_descr_get */
819 0, /* tp_descr_set */
820 0, /* tp_dictoffset */
821 (initproc)deque_init, /* tp_init */
822 PyType_GenericAlloc, /* tp_alloc */
823 deque_new, /* tp_new */
824 PyObject_GC_Del, /* tp_free */
825};
826
827/*********************** Deque Iterator **************************/
828
829typedef struct {
830 PyObject_HEAD
831 int index;
832 block *b;
833 dequeobject *deque;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000834 long state; /* state when the iterator is created */
835 int counter; /* number of items remaining for iteration */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000836} dequeiterobject;
837
838PyTypeObject dequeiter_type;
839
840static PyObject *
841deque_iter(dequeobject *deque)
842{
843 dequeiterobject *it;
844
845 it = PyObject_New(dequeiterobject, &dequeiter_type);
846 if (it == NULL)
847 return NULL;
848 it->b = deque->leftblock;
849 it->index = deque->leftindex;
850 Py_INCREF(deque);
851 it->deque = deque;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000852 it->state = deque->state;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000853 it->counter = deque->len;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000854 return (PyObject *)it;
855}
856
857static void
858dequeiter_dealloc(dequeiterobject *dio)
859{
860 Py_XDECREF(dio->deque);
861 dio->ob_type->tp_free(dio);
862}
863
864static PyObject *
865dequeiter_next(dequeiterobject *it)
866{
867 PyObject *item;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000868
869 if (it->counter == 0)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000870 return NULL;
871
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000872 if (it->deque->state != it->state) {
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000873 it->counter = 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000874 PyErr_SetString(PyExc_RuntimeError,
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000875 "deque mutated during iteration");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000876 return NULL;
877 }
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000878 assert (!(it->b == it->deque->rightblock &&
879 it->index > it->deque->rightindex));
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000880
881 item = it->b->data[it->index];
882 it->index++;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000883 it->counter--;
884 if (it->index == BLOCKLEN && it->counter > 0) {
885 assert (it->b->rightlink != NULL);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000886 it->b = it->b->rightlink;
887 it->index = 0;
888 }
889 Py_INCREF(item);
890 return item;
891}
892
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000893static int
894dequeiter_len(dequeiterobject *it)
895{
896 return it->counter;
897}
898
899static PySequenceMethods dequeiter_as_sequence = {
900 (inquiry)dequeiter_len, /* sq_length */
901 0, /* sq_concat */
902};
903
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000904PyTypeObject dequeiter_type = {
905 PyObject_HEAD_INIT(NULL)
906 0, /* ob_size */
907 "deque_iterator", /* tp_name */
908 sizeof(dequeiterobject), /* tp_basicsize */
909 0, /* tp_itemsize */
910 /* methods */
911 (destructor)dequeiter_dealloc, /* tp_dealloc */
912 0, /* tp_print */
913 0, /* tp_getattr */
914 0, /* tp_setattr */
915 0, /* tp_compare */
916 0, /* tp_repr */
917 0, /* tp_as_number */
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000918 &dequeiter_as_sequence, /* tp_as_sequence */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000919 0, /* tp_as_mapping */
920 0, /* tp_hash */
921 0, /* tp_call */
922 0, /* tp_str */
923 PyObject_GenericGetAttr, /* tp_getattro */
924 0, /* tp_setattro */
925 0, /* tp_as_buffer */
926 Py_TPFLAGS_DEFAULT, /* tp_flags */
927 0, /* tp_doc */
928 0, /* tp_traverse */
929 0, /* tp_clear */
930 0, /* tp_richcompare */
931 0, /* tp_weaklistoffset */
932 PyObject_SelfIter, /* tp_iter */
933 (iternextfunc)dequeiter_next, /* tp_iternext */
934 0,
935};
936
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000937/*********************** Deque Reverse Iterator **************************/
938
939PyTypeObject dequereviter_type;
940
941static PyObject *
942deque_reviter(dequeobject *deque)
943{
944 dequeiterobject *it;
945
946 it = PyObject_New(dequeiterobject, &dequereviter_type);
947 if (it == NULL)
948 return NULL;
949 it->b = deque->rightblock;
950 it->index = deque->rightindex;
951 Py_INCREF(deque);
952 it->deque = deque;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000953 it->state = deque->state;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000954 it->counter = deque->len;
955 return (PyObject *)it;
956}
957
958static PyObject *
959dequereviter_next(dequeiterobject *it)
960{
961 PyObject *item;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000962 if (it->counter == 0)
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000963 return NULL;
964
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000965 if (it->deque->state != it->state) {
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000966 it->counter = 0;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000967 PyErr_SetString(PyExc_RuntimeError,
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000968 "deque mutated during iteration");
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000969 return NULL;
970 }
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000971 assert (!(it->b == it->deque->leftblock &&
972 it->index < it->deque->leftindex));
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000973
974 item = it->b->data[it->index];
975 it->index--;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000976 it->counter--;
977 if (it->index == -1 && it->counter > 0) {
978 assert (it->b->leftlink != NULL);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000979 it->b = it->b->leftlink;
980 it->index = BLOCKLEN - 1;
981 }
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000982 Py_INCREF(item);
983 return item;
984}
985
986PyTypeObject dequereviter_type = {
987 PyObject_HEAD_INIT(NULL)
988 0, /* ob_size */
989 "deque_reverse_iterator", /* tp_name */
990 sizeof(dequeiterobject), /* tp_basicsize */
991 0, /* tp_itemsize */
992 /* methods */
993 (destructor)dequeiter_dealloc, /* tp_dealloc */
994 0, /* tp_print */
995 0, /* tp_getattr */
996 0, /* tp_setattr */
997 0, /* tp_compare */
998 0, /* tp_repr */
999 0, /* tp_as_number */
1000 &dequeiter_as_sequence, /* tp_as_sequence */
1001 0, /* tp_as_mapping */
1002 0, /* tp_hash */
1003 0, /* tp_call */
1004 0, /* tp_str */
1005 PyObject_GenericGetAttr, /* tp_getattro */
1006 0, /* tp_setattro */
1007 0, /* tp_as_buffer */
1008 Py_TPFLAGS_DEFAULT, /* tp_flags */
1009 0, /* tp_doc */
1010 0, /* tp_traverse */
1011 0, /* tp_clear */
1012 0, /* tp_richcompare */
1013 0, /* tp_weaklistoffset */
1014 PyObject_SelfIter, /* tp_iter */
1015 (iternextfunc)dequereviter_next, /* tp_iternext */
1016 0,
1017};
1018
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001019/* module level code ********************************************************/
1020
1021PyDoc_STRVAR(module_doc,
1022"High performance data structures\n\
1023");
1024
1025PyMODINIT_FUNC
1026initcollections(void)
1027{
1028 PyObject *m;
1029
1030 m = Py_InitModule3("collections", NULL, module_doc);
1031
1032 if (PyType_Ready(&deque_type) < 0)
1033 return;
1034 Py_INCREF(&deque_type);
1035 PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
1036
1037 if (PyType_Ready(&dequeiter_type) < 0)
Tim Peters1065f752004-10-01 01:03:29 +00001038 return;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001039
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001040 if (PyType_Ready(&dequereviter_type) < 0)
1041 return;
1042
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001043 return;
1044}