blob: 368f0b6ca0962cb8946d3f0909be42ca7c329e27 [file] [log] [blame]
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001#include "Python.h"
2
3/* collections module implementation of a deque() datatype
4 Written and maintained by Raymond D. Hettinger <python@rcn.com>
5 Copyright (c) 2004 Python Software Foundation.
6 All rights reserved.
7*/
8
9#define BLOCKLEN 46
10
11typedef struct BLOCK {
12 struct BLOCK *leftlink;
13 struct BLOCK *rightlink;
14 PyObject *data[BLOCKLEN];
15} block;
16
17static block *newblock(block *leftlink, block *rightlink) {
18 block *b = PyMem_Malloc(sizeof(block));
19 if (b == NULL) {
20 PyErr_NoMemory();
21 return NULL;
22 }
23 b->leftlink = leftlink;
24 b->rightlink = rightlink;
25 return b;
26}
27
28typedef struct {
29 PyObject_HEAD
30 block *leftblock;
31 block *rightblock;
32 int leftindex;
33 int rightindex;
34 int len;
35} dequeobject;
36
Neal Norwitz87f10132004-02-29 15:40:53 +000037static PyTypeObject deque_type;
Raymond Hettinger738ec902004-02-29 02:15:56 +000038
Raymond Hettinger756b3f32004-01-29 06:37:52 +000039static PyObject *
40deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
41{
42 dequeobject *deque;
43 block *b;
44
45 /* create dequeobject structure */
46 deque = (dequeobject *)type->tp_alloc(type, 0);
47 if (deque == NULL)
48 return NULL;
49
50 b = newblock(NULL, NULL);
51 if (b == NULL) {
52 Py_DECREF(deque);
53 return NULL;
54 }
55
56 deque->leftblock = b;
57 deque->rightblock = b;
58 deque->leftindex = BLOCKLEN / 2 + 1;
59 deque->rightindex = BLOCKLEN / 2;
60 deque->len = 0;
61
62 return (PyObject *)deque;
63}
64
65static PyObject *
66deque_append(dequeobject *deque, PyObject *item)
67{
68 deque->rightindex++;
69 deque->len++;
70 if (deque->rightindex == BLOCKLEN) {
71 block *b = newblock(deque->rightblock, NULL);
72 if (b == NULL)
73 return NULL;
74 assert(deque->rightblock->rightlink == NULL);
75 deque->rightblock->rightlink = b;
76 deque->rightblock = b;
77 deque->rightindex = 0;
78 }
79 Py_INCREF(item);
80 deque->rightblock->data[deque->rightindex] = item;
81 Py_RETURN_NONE;
82}
83
84PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque.");
85
86static PyObject *
87deque_appendleft(dequeobject *deque, PyObject *item)
88{
89 deque->leftindex--;
90 deque->len++;
91 if (deque->leftindex == -1) {
92 block *b = newblock(NULL, deque->leftblock);
93 if (b == NULL)
94 return NULL;
95 assert(deque->leftblock->leftlink == NULL);
96 deque->leftblock->leftlink = b;
97 deque->leftblock = b;
98 deque->leftindex = BLOCKLEN - 1;
99 }
100 Py_INCREF(item);
101 deque->leftblock->data[deque->leftindex] = item;
102 Py_RETURN_NONE;
103}
104
105PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque.");
106
107static PyObject *
108deque_pop(dequeobject *deque, PyObject *unused)
109{
110 PyObject *item;
111 block *prevblock;
112
113 if (deque->len == 0) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000114 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000115 return NULL;
116 }
117 item = deque->rightblock->data[deque->rightindex];
118 deque->rightindex--;
119 deque->len--;
120
121 if (deque->rightindex == -1) {
122 if (deque->len == 0) {
123 assert(deque->leftblock == deque->rightblock);
124 assert(deque->leftindex == deque->rightindex+1);
125 /* re-center instead of freeing a block */
126 deque->leftindex = BLOCKLEN / 2 + 1;
127 deque->rightindex = BLOCKLEN / 2;
128 } else {
129 prevblock = deque->rightblock->leftlink;
130 assert(deque->leftblock != deque->rightblock);
131 PyMem_Free(deque->rightblock);
132 prevblock->rightlink = NULL;
133 deque->rightblock = prevblock;
134 deque->rightindex = BLOCKLEN - 1;
135 }
136 }
137 return item;
138}
139
140PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");
141
142static PyObject *
143deque_popleft(dequeobject *deque, PyObject *unused)
144{
145 PyObject *item;
146 block *prevblock;
147
148 if (deque->len == 0) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000149 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000150 return NULL;
151 }
152 item = deque->leftblock->data[deque->leftindex];
153 deque->leftindex++;
154 deque->len--;
155
156 if (deque->leftindex == BLOCKLEN) {
157 if (deque->len == 0) {
158 assert(deque->leftblock == deque->rightblock);
159 assert(deque->leftindex == deque->rightindex+1);
160 /* re-center instead of freeing a block */
161 deque->leftindex = BLOCKLEN / 2 + 1;
162 deque->rightindex = BLOCKLEN / 2;
163 } else {
164 assert(deque->leftblock != deque->rightblock);
165 prevblock = deque->leftblock->rightlink;
166 assert(deque->leftblock != NULL);
167 PyMem_Free(deque->leftblock);
168 assert(prevblock != NULL);
169 prevblock->leftlink = NULL;
170 deque->leftblock = prevblock;
171 deque->leftindex = 0;
172 }
173 }
174 return item;
175}
176
177PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element.");
178
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000179static PyObject *
180deque_extend(dequeobject *deque, PyObject *iterable)
181{
182 PyObject *it, *item;
183
184 it = PyObject_GetIter(iterable);
185 if (it == NULL)
186 return NULL;
187
188 while ((item = PyIter_Next(it)) != NULL) {
189 deque->rightindex++;
190 deque->len++;
191 if (deque->rightindex == BLOCKLEN) {
192 block *b = newblock(deque->rightblock, NULL);
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000193 if (b == NULL) {
194 Py_DECREF(item);
195 Py_DECREF(it);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000196 return NULL;
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000197 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000198 assert(deque->rightblock->rightlink == NULL);
199 deque->rightblock->rightlink = b;
200 deque->rightblock = b;
201 deque->rightindex = 0;
202 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000203 deque->rightblock->data[deque->rightindex] = item;
204 }
205 Py_DECREF(it);
206 if (PyErr_Occurred())
207 return NULL;
208 Py_RETURN_NONE;
209}
210
211PyDoc_STRVAR(extend_doc,
212"Extend the right side of the deque with elements from the iterable");
213
214static PyObject *
215deque_extendleft(dequeobject *deque, PyObject *iterable)
216{
217 PyObject *it, *item;
218
219 it = PyObject_GetIter(iterable);
220 if (it == NULL)
221 return NULL;
222
223 while ((item = PyIter_Next(it)) != NULL) {
224 deque->leftindex--;
225 deque->len++;
226 if (deque->leftindex == -1) {
227 block *b = newblock(NULL, deque->leftblock);
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000228 if (b == NULL) {
229 Py_DECREF(item);
230 Py_DECREF(it);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000231 return NULL;
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000232 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000233 assert(deque->leftblock->leftlink == NULL);
234 deque->leftblock->leftlink = b;
235 deque->leftblock = b;
236 deque->leftindex = BLOCKLEN - 1;
237 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000238 deque->leftblock->data[deque->leftindex] = item;
239 }
240 Py_DECREF(it);
241 if (PyErr_Occurred())
242 return NULL;
243 Py_RETURN_NONE;
244}
245
246PyDoc_STRVAR(extendleft_doc,
247"Extend the left side of the deque with elements from the iterable");
248
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000249static PyObject *
250deque_rotate(dequeobject *deque, PyObject *args)
251{
Raymond Hettingeree33b272004-02-08 04:05:26 +0000252 int i, n=1, len=deque->len, halflen=(len+1)>>1;
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000253 PyObject *item, *rv;
254
Raymond Hettingeree33b272004-02-08 04:05:26 +0000255 if (!PyArg_ParseTuple(args, "|i:rotate", &n))
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000256 return NULL;
257
Raymond Hettingeree33b272004-02-08 04:05:26 +0000258 if (len == 0)
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000259 Py_RETURN_NONE;
Raymond Hettingeree33b272004-02-08 04:05:26 +0000260 if (n > halflen || n < -halflen) {
261 n %= len;
262 if (n > halflen)
263 n -= len;
264 else if (n < -halflen)
265 n += len;
266 }
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000267
268 for (i=0 ; i<n ; i++) {
269 item = deque_pop(deque, NULL);
270 if (item == NULL)
271 return NULL;
272 rv = deque_appendleft(deque, item);
273 Py_DECREF(item);
274 if (rv == NULL)
275 return NULL;
276 Py_DECREF(rv);
277 }
278 for (i=0 ; i>n ; i--) {
279 item = deque_popleft(deque, NULL);
280 if (item == NULL)
281 return NULL;
282 rv = deque_append(deque, item);
283 Py_DECREF(item);
284 if (rv == NULL)
285 return NULL;
286 Py_DECREF(rv);
287 }
288 Py_RETURN_NONE;
289}
290
291PyDoc_STRVAR(rotate_doc,
Raymond Hettingeree33b272004-02-08 04:05:26 +0000292"Rotate the deque n steps to the right (default n=1). If n is negative, rotates left.");
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000293
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000294static int
295deque_len(dequeobject *deque)
296{
297 return deque->len;
298}
299
300static int
301deque_clear(dequeobject *deque)
302{
303 PyObject *item;
304
305 while (deque_len(deque)) {
306 item = deque_pop(deque, NULL);
307 if (item == NULL)
308 return -1;
309 Py_DECREF(item);
310 }
311 assert(deque->leftblock == deque->rightblock &&
312 deque->leftindex > deque->rightindex);
313 return 0;
314}
315
316static PyObject *
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000317deque_item(dequeobject *deque, int i)
318{
319 block *b;
320 PyObject *item;
321 int n;
322
323 if (i < 0 || i >= deque->len) {
324 PyErr_SetString(PyExc_IndexError,
325 "deque index out of range");
326 return NULL;
327 }
328
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000329 if (i == 0) {
330 i = deque->leftindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000331 b = deque->leftblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000332 } else if (i == deque->len - 1) {
333 i = deque->rightindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000334 b = deque->rightblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000335 } else {
336 i += deque->leftindex;
337 n = i / BLOCKLEN;
338 i %= BLOCKLEN;
339 if (i < (deque->len >> 1)) {
340 b = deque->leftblock;
341 while (n--)
342 b = b->rightlink;
343 } else {
344 n = (deque->leftindex + deque->len - 1) / BLOCKLEN - n;
345 b = deque->rightblock;
346 while (n--)
347 b = b->leftlink;
348 }
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000349 }
350 item = b->data[i];
351 Py_INCREF(item);
352 return item;
353}
354
355static int
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000356deque_del_item(dequeobject *deque, int i)
357{
358 PyObject *item=NULL, *minus_i=NULL, *plus_i=NULL;
359 int rv = -1;
360
361 assert (i >= 0 && i < deque->len);
362
363 minus_i = Py_BuildValue("(i)", -i);
364 if (minus_i == NULL)
365 goto fail;
366
367 plus_i = Py_BuildValue("(i)", i);
368 if (plus_i == NULL)
369 goto fail;
370
371 item = deque_rotate(deque, minus_i);
372 if (item == NULL)
373 goto fail;
374 Py_DECREF(item);
375
376 item = deque_popleft(deque, NULL);
377 if (item == NULL)
378 goto fail;
379 Py_DECREF(item);
380
381 item = deque_rotate(deque, plus_i);
382 if (item == NULL)
383 goto fail;
384
385 rv = 0;
386fail:
387 Py_XDECREF(item);
388 Py_XDECREF(minus_i);
389 Py_XDECREF(plus_i);
390 return rv;
391}
392
393static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000394deque_ass_item(dequeobject *deque, int i, PyObject *v)
395{
396 PyObject *old_value;
397 block *b;
398 int n;
399
400 if (i < 0 || i >= deque->len) {
401 PyErr_SetString(PyExc_IndexError,
402 "deque index out of range");
403 return -1;
404 }
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000405 if (v == NULL)
406 return deque_del_item(deque, i);
407
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000408 i += deque->leftindex;
409 n = i / BLOCKLEN;
410 i %= BLOCKLEN;
411 if (i < (deque->len >> 1)) {
412 b = deque->leftblock;
413 while (n--)
414 b = b->rightlink;
415 } else {
416 n = (deque->leftindex + deque->len - 1) / BLOCKLEN - n;
417 b = deque->rightblock;
418 while (n--)
419 b = b->leftlink;
420 }
421 Py_INCREF(v);
422 old_value = b->data[i];
423 b->data[i] = v;
424 Py_DECREF(old_value);
425 return 0;
426}
427
428static PyObject *
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000429deque_clearmethod(dequeobject *deque)
430{
431 if (deque_clear(deque) == -1)
432 return NULL;
433 Py_RETURN_NONE;
434}
435
436PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
437
438static void
439deque_dealloc(dequeobject *deque)
440{
441 PyObject_GC_UnTrack(deque);
442 if (deque->leftblock != NULL) {
443 int err = deque_clear(deque);
444 assert(err == 0);
445 assert(deque->leftblock != NULL);
446 PyMem_Free(deque->leftblock);
447 }
448 deque->leftblock = NULL;
449 deque->rightblock = NULL;
450 deque->ob_type->tp_free(deque);
451}
452
453static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000454deque_traverse(dequeobject *deque, visitproc visit, void *arg)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000455{
456 block * b = deque->leftblock;
457 int index = deque->leftindex;
458 int err;
459 PyObject *item;
460
461 while (b != deque->rightblock || index <= deque->rightindex) {
462 item = b->data[index];
463 index++;
464 if (index == BLOCKLEN && b->rightlink != NULL) {
465 b = b->rightlink;
466 index = 0;
467 }
468 err = visit(item, arg);
469 if (err)
470 return err;
471 }
472 return 0;
473}
474
475static long
476deque_nohash(PyObject *self)
477{
478 PyErr_SetString(PyExc_TypeError, "deque objects are unhashable");
479 return -1;
480}
481
482static PyObject *
483deque_copy(PyObject *deque)
484{
485 return PyObject_CallFunctionObjArgs((PyObject *)(deque->ob_type),
486 deque, NULL);
487}
488
489PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
490
491static PyObject *
492deque_reduce(dequeobject *deque)
493{
494 PyObject *seq, *args, *result;
495
496 seq = PySequence_Tuple((PyObject *)deque);
497 if (seq == NULL)
498 return NULL;
499 args = PyTuple_Pack(1, seq);
500 if (args == NULL) {
501 Py_DECREF(seq);
502 return NULL;
503 }
504 result = PyTuple_Pack(2, deque->ob_type, args);
505 Py_DECREF(seq);
506 Py_DECREF(args);
507 return result;
508}
509
510PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
511
512static PyObject *
513deque_repr(PyObject *deque)
514{
515 PyObject *aslist, *result, *fmt;
516 int i;
517
518 i = Py_ReprEnter(deque);
519 if (i != 0) {
520 if (i < 0)
521 return NULL;
522 return PyString_FromString("[...]");
523 }
524
525 aslist = PySequence_List(deque);
526 if (aslist == NULL) {
527 Py_ReprLeave(deque);
528 return NULL;
529 }
530
531 fmt = PyString_FromString("deque(%r)");
532 if (fmt == NULL) {
533 Py_DECREF(aslist);
534 Py_ReprLeave(deque);
535 return NULL;
536 }
537 result = PyString_Format(fmt, aslist);
538 Py_DECREF(fmt);
539 Py_DECREF(aslist);
540 Py_ReprLeave(deque);
541 return result;
542}
543
544static int
545deque_tp_print(PyObject *deque, FILE *fp, int flags)
546{
547 PyObject *it, *item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000548 char *emit = ""; /* No separator emitted on first pass */
549 char *separator = ", ";
550 int i;
551
552 i = Py_ReprEnter(deque);
553 if (i != 0) {
554 if (i < 0)
555 return i;
556 fputs("[...]", fp);
557 return 0;
558 }
559
560 it = PyObject_GetIter(deque);
561 if (it == NULL)
562 return -1;
563
564 fputs("deque([", fp);
565 while ((item = PyIter_Next(it)) != NULL) {
566 fputs(emit, fp);
567 emit = separator;
568 if (PyObject_Print(item, fp, 0) != 0) {
569 Py_DECREF(item);
570 Py_DECREF(it);
571 Py_ReprLeave(deque);
572 return -1;
573 }
574 Py_DECREF(item);
575 }
576 Py_ReprLeave(deque);
577 Py_DECREF(it);
578 if (PyErr_Occurred())
579 return -1;
580 fputs("])", fp);
581 return 0;
582}
583
Raymond Hettinger738ec902004-02-29 02:15:56 +0000584static PyObject *
585deque_richcompare(PyObject *v, PyObject *w, int op)
586{
587 PyObject *it1=NULL, *it2=NULL, *x, *y;
588 int i, b, vs, ws, minlen, cmp=-1;
589
Raymond Hettinger285cfcc2004-05-18 18:15:03 +0000590 if (!PyObject_TypeCheck(v, &deque_type) ||
591 !PyObject_TypeCheck(w, &deque_type)) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000592 Py_INCREF(Py_NotImplemented);
593 return Py_NotImplemented;
594 }
595
596 /* Shortcuts */
597 vs = ((dequeobject *)v)->len;
598 ws = ((dequeobject *)w)->len;
599 if (op == Py_EQ) {
600 if (v == w)
601 Py_RETURN_TRUE;
602 if (vs != ws)
603 Py_RETURN_FALSE;
604 }
605 if (op == Py_NE) {
606 if (v == w)
607 Py_RETURN_FALSE;
608 if (vs != ws)
609 Py_RETURN_TRUE;
610 }
611
612 /* Search for the first index where items are different */
613 it1 = PyObject_GetIter(v);
614 if (it1 == NULL)
615 goto done;
616 it2 = PyObject_GetIter(w);
617 if (it2 == NULL)
618 goto done;
619 minlen = (vs < ws) ? vs : ws;
620 for (i=0 ; i < minlen ; i++) {
621 x = PyIter_Next(it1);
622 if (x == NULL)
623 goto done;
624 y = PyIter_Next(it2);
625 if (y == NULL) {
626 Py_DECREF(x);
627 goto done;
628 }
629 b = PyObject_RichCompareBool(x, y, Py_EQ);
630 if (b == 0) {
631 cmp = PyObject_RichCompareBool(x, y, op);
632 Py_DECREF(x);
633 Py_DECREF(y);
634 goto done;
635 }
636 Py_DECREF(x);
637 Py_DECREF(y);
638 if (b == -1)
639 goto done;
640 }
641 /* Elements are equal through minlen. The longest input is the greatest */
642 switch (op) {
643 case Py_LT: cmp = vs < ws; break;
644 case Py_LE: cmp = vs <= ws; break;
645 case Py_EQ: cmp = vs == ws; break;
646 case Py_NE: cmp = vs != ws; break;
647 case Py_GT: cmp = vs > ws; break;
648 case Py_GE: cmp = vs >= ws; break;
649 }
650
651done:
652 Py_XDECREF(it1);
653 Py_XDECREF(it2);
654 if (cmp == 1)
655 Py_RETURN_TRUE;
656 if (cmp == 0)
657 Py_RETURN_FALSE;
658 return NULL;
659}
660
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000661static int
662deque_init(dequeobject *deque, PyObject *args, PyObject *kwds)
663{
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000664 PyObject *iterable = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000665
666 if (!PyArg_UnpackTuple(args, "deque", 0, 1, &iterable))
667 return -1;
668
669 if (iterable != NULL) {
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000670 PyObject *rv = deque_extend(deque, iterable);
671 if (rv == NULL)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000672 return -1;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000673 Py_DECREF(rv);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000674 }
675 return 0;
676}
677
678static PySequenceMethods deque_as_sequence = {
679 (inquiry)deque_len, /* sq_length */
680 0, /* sq_concat */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000681 0, /* sq_repeat */
682 (intargfunc)deque_item, /* sq_item */
683 0, /* sq_slice */
684 (intobjargproc)deque_ass_item, /* sq_ass_item */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000685};
686
687/* deque object ********************************************************/
688
689static PyObject *deque_iter(dequeobject *deque);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000690static PyObject *deque_reviter(dequeobject *deque);
691PyDoc_STRVAR(reversed_doc,
692 "D.__reversed__() -- return a reverse iterator over the deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000693
694static PyMethodDef deque_methods[] = {
695 {"append", (PyCFunction)deque_append,
696 METH_O, append_doc},
697 {"appendleft", (PyCFunction)deque_appendleft,
698 METH_O, appendleft_doc},
699 {"clear", (PyCFunction)deque_clearmethod,
700 METH_NOARGS, clear_doc},
701 {"__copy__", (PyCFunction)deque_copy,
702 METH_NOARGS, copy_doc},
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000703 {"extend", (PyCFunction)deque_extend,
704 METH_O, extend_doc},
705 {"extendleft", (PyCFunction)deque_extendleft,
706 METH_O, extendleft_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000707 {"pop", (PyCFunction)deque_pop,
708 METH_NOARGS, pop_doc},
709 {"popleft", (PyCFunction)deque_popleft,
710 METH_NOARGS, popleft_doc},
711 {"__reduce__", (PyCFunction)deque_reduce,
712 METH_NOARGS, reduce_doc},
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000713 {"__reversed__", (PyCFunction)deque_reviter,
714 METH_NOARGS, reversed_doc},
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000715 {"rotate", (PyCFunction)deque_rotate,
716 METH_VARARGS, rotate_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000717 {NULL, NULL} /* sentinel */
718};
719
720PyDoc_STRVAR(deque_doc,
721"deque(iterable) --> deque object\n\
722\n\
723Build an ordered collection accessible from endpoints only.");
724
Neal Norwitz87f10132004-02-29 15:40:53 +0000725static PyTypeObject deque_type = {
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000726 PyObject_HEAD_INIT(NULL)
727 0, /* ob_size */
728 "collections.deque", /* tp_name */
729 sizeof(dequeobject), /* tp_basicsize */
730 0, /* tp_itemsize */
731 /* methods */
732 (destructor)deque_dealloc, /* tp_dealloc */
733 (printfunc)deque_tp_print, /* tp_print */
734 0, /* tp_getattr */
735 0, /* tp_setattr */
736 0, /* tp_compare */
737 (reprfunc)deque_repr, /* tp_repr */
738 0, /* tp_as_number */
739 &deque_as_sequence, /* tp_as_sequence */
740 0, /* tp_as_mapping */
741 deque_nohash, /* tp_hash */
742 0, /* tp_call */
743 0, /* tp_str */
744 PyObject_GenericGetAttr, /* tp_getattro */
745 0, /* tp_setattro */
746 0, /* tp_as_buffer */
747 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
748 deque_doc, /* tp_doc */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000749 (traverseproc)deque_traverse, /* tp_traverse */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000750 (inquiry)deque_clear, /* tp_clear */
Raymond Hettinger738ec902004-02-29 02:15:56 +0000751 (richcmpfunc)deque_richcompare, /* tp_richcompare */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000752 0, /* tp_weaklistoffset*/
753 (getiterfunc)deque_iter, /* tp_iter */
754 0, /* tp_iternext */
755 deque_methods, /* tp_methods */
756 0, /* tp_members */
757 0, /* tp_getset */
758 0, /* tp_base */
759 0, /* tp_dict */
760 0, /* tp_descr_get */
761 0, /* tp_descr_set */
762 0, /* tp_dictoffset */
763 (initproc)deque_init, /* tp_init */
764 PyType_GenericAlloc, /* tp_alloc */
765 deque_new, /* tp_new */
766 PyObject_GC_Del, /* tp_free */
767};
768
769/*********************** Deque Iterator **************************/
770
771typedef struct {
772 PyObject_HEAD
773 int index;
774 block *b;
775 dequeobject *deque;
776 int len;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000777 int counter;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000778} dequeiterobject;
779
780PyTypeObject dequeiter_type;
781
782static PyObject *
783deque_iter(dequeobject *deque)
784{
785 dequeiterobject *it;
786
787 it = PyObject_New(dequeiterobject, &dequeiter_type);
788 if (it == NULL)
789 return NULL;
790 it->b = deque->leftblock;
791 it->index = deque->leftindex;
792 Py_INCREF(deque);
793 it->deque = deque;
794 it->len = deque->len;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000795 it->counter = deque->len;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000796 return (PyObject *)it;
797}
798
799static void
800dequeiter_dealloc(dequeiterobject *dio)
801{
802 Py_XDECREF(dio->deque);
803 dio->ob_type->tp_free(dio);
804}
805
806static PyObject *
807dequeiter_next(dequeiterobject *it)
808{
809 PyObject *item;
810 if (it->b == it->deque->rightblock && it->index > it->deque->rightindex)
811 return NULL;
812
813 if (it->len != it->deque->len) {
814 it->len = -1; /* Make this state sticky */
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000815 it->counter = 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000816 PyErr_SetString(PyExc_RuntimeError,
817 "deque changed size during iteration");
818 return NULL;
819 }
820
821 item = it->b->data[it->index];
822 it->index++;
823 if (it->index == BLOCKLEN && it->b->rightlink != NULL) {
824 it->b = it->b->rightlink;
825 it->index = 0;
826 }
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000827 it->counter--;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000828 Py_INCREF(item);
829 return item;
830}
831
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000832static int
833dequeiter_len(dequeiterobject *it)
834{
835 return it->counter;
836}
837
838static PySequenceMethods dequeiter_as_sequence = {
839 (inquiry)dequeiter_len, /* sq_length */
840 0, /* sq_concat */
841};
842
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000843PyTypeObject dequeiter_type = {
844 PyObject_HEAD_INIT(NULL)
845 0, /* ob_size */
846 "deque_iterator", /* tp_name */
847 sizeof(dequeiterobject), /* tp_basicsize */
848 0, /* tp_itemsize */
849 /* methods */
850 (destructor)dequeiter_dealloc, /* tp_dealloc */
851 0, /* tp_print */
852 0, /* tp_getattr */
853 0, /* tp_setattr */
854 0, /* tp_compare */
855 0, /* tp_repr */
856 0, /* tp_as_number */
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000857 &dequeiter_as_sequence, /* tp_as_sequence */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000858 0, /* tp_as_mapping */
859 0, /* tp_hash */
860 0, /* tp_call */
861 0, /* tp_str */
862 PyObject_GenericGetAttr, /* tp_getattro */
863 0, /* tp_setattro */
864 0, /* tp_as_buffer */
865 Py_TPFLAGS_DEFAULT, /* tp_flags */
866 0, /* tp_doc */
867 0, /* tp_traverse */
868 0, /* tp_clear */
869 0, /* tp_richcompare */
870 0, /* tp_weaklistoffset */
871 PyObject_SelfIter, /* tp_iter */
872 (iternextfunc)dequeiter_next, /* tp_iternext */
873 0,
874};
875
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000876/*********************** Deque Reverse Iterator **************************/
877
878PyTypeObject dequereviter_type;
879
880static PyObject *
881deque_reviter(dequeobject *deque)
882{
883 dequeiterobject *it;
884
885 it = PyObject_New(dequeiterobject, &dequereviter_type);
886 if (it == NULL)
887 return NULL;
888 it->b = deque->rightblock;
889 it->index = deque->rightindex;
890 Py_INCREF(deque);
891 it->deque = deque;
892 it->len = deque->len;
893 it->counter = deque->len;
894 return (PyObject *)it;
895}
896
897static PyObject *
898dequereviter_next(dequeiterobject *it)
899{
900 PyObject *item;
901 if (it->b == it->deque->leftblock && it->index < it->deque->leftindex)
902 return NULL;
903
904 if (it->len != it->deque->len) {
905 it->len = -1; /* Make this state sticky */
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000906 it->counter = 0;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000907 PyErr_SetString(PyExc_RuntimeError,
908 "deque changed size during iteration");
909 return NULL;
910 }
911
912 item = it->b->data[it->index];
913 it->index--;
914 if (it->index == -1 && it->b->leftlink != NULL) {
915 it->b = it->b->leftlink;
916 it->index = BLOCKLEN - 1;
917 }
918 it->counter--;
919 Py_INCREF(item);
920 return item;
921}
922
923PyTypeObject dequereviter_type = {
924 PyObject_HEAD_INIT(NULL)
925 0, /* ob_size */
926 "deque_reverse_iterator", /* tp_name */
927 sizeof(dequeiterobject), /* tp_basicsize */
928 0, /* tp_itemsize */
929 /* methods */
930 (destructor)dequeiter_dealloc, /* tp_dealloc */
931 0, /* tp_print */
932 0, /* tp_getattr */
933 0, /* tp_setattr */
934 0, /* tp_compare */
935 0, /* tp_repr */
936 0, /* tp_as_number */
937 &dequeiter_as_sequence, /* tp_as_sequence */
938 0, /* tp_as_mapping */
939 0, /* tp_hash */
940 0, /* tp_call */
941 0, /* tp_str */
942 PyObject_GenericGetAttr, /* tp_getattro */
943 0, /* tp_setattro */
944 0, /* tp_as_buffer */
945 Py_TPFLAGS_DEFAULT, /* tp_flags */
946 0, /* tp_doc */
947 0, /* tp_traverse */
948 0, /* tp_clear */
949 0, /* tp_richcompare */
950 0, /* tp_weaklistoffset */
951 PyObject_SelfIter, /* tp_iter */
952 (iternextfunc)dequereviter_next, /* tp_iternext */
953 0,
954};
955
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000956/* module level code ********************************************************/
957
958PyDoc_STRVAR(module_doc,
959"High performance data structures\n\
960");
961
962PyMODINIT_FUNC
963initcollections(void)
964{
965 PyObject *m;
966
967 m = Py_InitModule3("collections", NULL, module_doc);
968
969 if (PyType_Ready(&deque_type) < 0)
970 return;
971 Py_INCREF(&deque_type);
972 PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
973
974 if (PyType_Ready(&dequeiter_type) < 0)
975 return;
976
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000977 if (PyType_Ready(&dequereviter_type) < 0)
978 return;
979
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000980 return;
981}