blob: 4026ea50efde1bdd0427b403e65cc5387e74035f [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
Nicholas Bastin1ce9e4c2004-06-17 18:27:18 +00004#ifdef __SUNPRO_C
5#pragma error_messages (off,E_END_OF_LOOP_CODE_NOT_REACHED)
6#endif
7
Raymond Hettinger756b3f32004-01-29 06:37:52 +00008/* collections module implementation of a deque() datatype
9 Written and maintained by Raymond D. Hettinger <python@rcn.com>
10 Copyright (c) 2004 Python Software Foundation.
11 All rights reserved.
12*/
13
14#define BLOCKLEN 46
15
16typedef struct BLOCK {
17 struct BLOCK *leftlink;
18 struct BLOCK *rightlink;
19 PyObject *data[BLOCKLEN];
20} block;
21
22static block *newblock(block *leftlink, block *rightlink) {
23 block *b = PyMem_Malloc(sizeof(block));
24 if (b == NULL) {
25 PyErr_NoMemory();
26 return NULL;
27 }
28 b->leftlink = leftlink;
29 b->rightlink = rightlink;
30 return b;
31}
32
33typedef struct {
34 PyObject_HEAD
35 block *leftblock;
36 block *rightblock;
37 int leftindex;
38 int rightindex;
39 int len;
Raymond Hettinger691d8052004-05-30 07:26:47 +000040 PyObject *weakreflist; /* List of weak references */
Raymond Hettinger756b3f32004-01-29 06:37:52 +000041} dequeobject;
42
Neal Norwitz87f10132004-02-29 15:40:53 +000043static PyTypeObject deque_type;
Raymond Hettinger738ec902004-02-29 02:15:56 +000044
Raymond Hettinger756b3f32004-01-29 06:37:52 +000045static PyObject *
46deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
47{
48 dequeobject *deque;
49 block *b;
50
51 /* create dequeobject structure */
52 deque = (dequeobject *)type->tp_alloc(type, 0);
53 if (deque == NULL)
54 return NULL;
55
56 b = newblock(NULL, NULL);
57 if (b == NULL) {
58 Py_DECREF(deque);
59 return NULL;
60 }
61
62 deque->leftblock = b;
63 deque->rightblock = b;
64 deque->leftindex = BLOCKLEN / 2 + 1;
65 deque->rightindex = BLOCKLEN / 2;
66 deque->len = 0;
Raymond Hettinger691d8052004-05-30 07:26:47 +000067 deque->weakreflist = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +000068
69 return (PyObject *)deque;
70}
71
72static PyObject *
73deque_append(dequeobject *deque, PyObject *item)
74{
75 deque->rightindex++;
76 deque->len++;
77 if (deque->rightindex == BLOCKLEN) {
78 block *b = newblock(deque->rightblock, NULL);
79 if (b == NULL)
80 return NULL;
81 assert(deque->rightblock->rightlink == NULL);
82 deque->rightblock->rightlink = b;
83 deque->rightblock = b;
84 deque->rightindex = 0;
85 }
86 Py_INCREF(item);
87 deque->rightblock->data[deque->rightindex] = item;
88 Py_RETURN_NONE;
89}
90
91PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque.");
92
93static PyObject *
94deque_appendleft(dequeobject *deque, PyObject *item)
95{
96 deque->leftindex--;
97 deque->len++;
98 if (deque->leftindex == -1) {
99 block *b = newblock(NULL, deque->leftblock);
100 if (b == NULL)
101 return NULL;
102 assert(deque->leftblock->leftlink == NULL);
103 deque->leftblock->leftlink = b;
104 deque->leftblock = b;
105 deque->leftindex = BLOCKLEN - 1;
106 }
107 Py_INCREF(item);
108 deque->leftblock->data[deque->leftindex] = item;
109 Py_RETURN_NONE;
110}
111
112PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque.");
113
114static PyObject *
115deque_pop(dequeobject *deque, PyObject *unused)
116{
117 PyObject *item;
118 block *prevblock;
119
120 if (deque->len == 0) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000121 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000122 return NULL;
123 }
124 item = deque->rightblock->data[deque->rightindex];
125 deque->rightindex--;
126 deque->len--;
127
128 if (deque->rightindex == -1) {
129 if (deque->len == 0) {
130 assert(deque->leftblock == deque->rightblock);
131 assert(deque->leftindex == deque->rightindex+1);
132 /* re-center instead of freeing a block */
133 deque->leftindex = BLOCKLEN / 2 + 1;
134 deque->rightindex = BLOCKLEN / 2;
135 } else {
136 prevblock = deque->rightblock->leftlink;
137 assert(deque->leftblock != deque->rightblock);
138 PyMem_Free(deque->rightblock);
139 prevblock->rightlink = NULL;
140 deque->rightblock = prevblock;
141 deque->rightindex = BLOCKLEN - 1;
142 }
143 }
144 return item;
145}
146
147PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");
148
149static PyObject *
150deque_popleft(dequeobject *deque, PyObject *unused)
151{
152 PyObject *item;
153 block *prevblock;
154
155 if (deque->len == 0) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000156 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000157 return NULL;
158 }
159 item = deque->leftblock->data[deque->leftindex];
160 deque->leftindex++;
161 deque->len--;
162
163 if (deque->leftindex == BLOCKLEN) {
164 if (deque->len == 0) {
165 assert(deque->leftblock == deque->rightblock);
166 assert(deque->leftindex == deque->rightindex+1);
167 /* re-center instead of freeing a block */
168 deque->leftindex = BLOCKLEN / 2 + 1;
169 deque->rightindex = BLOCKLEN / 2;
170 } else {
171 assert(deque->leftblock != deque->rightblock);
172 prevblock = deque->leftblock->rightlink;
173 assert(deque->leftblock != NULL);
174 PyMem_Free(deque->leftblock);
175 assert(prevblock != NULL);
176 prevblock->leftlink = NULL;
177 deque->leftblock = prevblock;
178 deque->leftindex = 0;
179 }
180 }
181 return item;
182}
183
184PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element.");
185
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000186static PyObject *
187deque_extend(dequeobject *deque, PyObject *iterable)
188{
189 PyObject *it, *item;
190
191 it = PyObject_GetIter(iterable);
192 if (it == NULL)
193 return NULL;
194
195 while ((item = PyIter_Next(it)) != NULL) {
196 deque->rightindex++;
197 deque->len++;
198 if (deque->rightindex == BLOCKLEN) {
199 block *b = newblock(deque->rightblock, NULL);
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000200 if (b == NULL) {
201 Py_DECREF(item);
202 Py_DECREF(it);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000203 return NULL;
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000204 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000205 assert(deque->rightblock->rightlink == NULL);
206 deque->rightblock->rightlink = b;
207 deque->rightblock = b;
208 deque->rightindex = 0;
209 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000210 deque->rightblock->data[deque->rightindex] = item;
211 }
212 Py_DECREF(it);
213 if (PyErr_Occurred())
214 return NULL;
215 Py_RETURN_NONE;
216}
217
218PyDoc_STRVAR(extend_doc,
219"Extend the right side of the deque with elements from the iterable");
220
221static PyObject *
222deque_extendleft(dequeobject *deque, PyObject *iterable)
223{
224 PyObject *it, *item;
225
226 it = PyObject_GetIter(iterable);
227 if (it == NULL)
228 return NULL;
229
230 while ((item = PyIter_Next(it)) != NULL) {
231 deque->leftindex--;
232 deque->len++;
233 if (deque->leftindex == -1) {
234 block *b = newblock(NULL, deque->leftblock);
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000235 if (b == NULL) {
236 Py_DECREF(item);
237 Py_DECREF(it);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000238 return NULL;
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000239 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000240 assert(deque->leftblock->leftlink == NULL);
241 deque->leftblock->leftlink = b;
242 deque->leftblock = b;
243 deque->leftindex = BLOCKLEN - 1;
244 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000245 deque->leftblock->data[deque->leftindex] = item;
246 }
247 Py_DECREF(it);
248 if (PyErr_Occurred())
249 return NULL;
250 Py_RETURN_NONE;
251}
252
253PyDoc_STRVAR(extendleft_doc,
254"Extend the left side of the deque with elements from the iterable");
255
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000256static PyObject *
257deque_rotate(dequeobject *deque, PyObject *args)
258{
Raymond Hettingeree33b272004-02-08 04:05:26 +0000259 int i, n=1, len=deque->len, halflen=(len+1)>>1;
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000260 PyObject *item, *rv;
261
Raymond Hettingeree33b272004-02-08 04:05:26 +0000262 if (!PyArg_ParseTuple(args, "|i:rotate", &n))
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000263 return NULL;
264
Raymond Hettingeree33b272004-02-08 04:05:26 +0000265 if (len == 0)
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000266 Py_RETURN_NONE;
Raymond Hettingeree33b272004-02-08 04:05:26 +0000267 if (n > halflen || n < -halflen) {
268 n %= len;
269 if (n > halflen)
270 n -= len;
271 else if (n < -halflen)
272 n += len;
273 }
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000274
275 for (i=0 ; i<n ; i++) {
276 item = deque_pop(deque, NULL);
277 if (item == NULL)
278 return NULL;
279 rv = deque_appendleft(deque, item);
280 Py_DECREF(item);
281 if (rv == NULL)
282 return NULL;
283 Py_DECREF(rv);
284 }
285 for (i=0 ; i>n ; i--) {
286 item = deque_popleft(deque, NULL);
287 if (item == NULL)
288 return NULL;
289 rv = deque_append(deque, item);
290 Py_DECREF(item);
291 if (rv == NULL)
292 return NULL;
293 Py_DECREF(rv);
294 }
295 Py_RETURN_NONE;
296}
297
298PyDoc_STRVAR(rotate_doc,
Raymond Hettingeree33b272004-02-08 04:05:26 +0000299"Rotate the deque n steps to the right (default n=1). If n is negative, rotates left.");
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000300
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000301static int
302deque_len(dequeobject *deque)
303{
304 return deque->len;
305}
306
307static int
308deque_clear(dequeobject *deque)
309{
310 PyObject *item;
311
312 while (deque_len(deque)) {
313 item = deque_pop(deque, NULL);
314 if (item == NULL)
315 return -1;
316 Py_DECREF(item);
317 }
318 assert(deque->leftblock == deque->rightblock &&
319 deque->leftindex > deque->rightindex);
320 return 0;
321}
322
323static PyObject *
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000324deque_item(dequeobject *deque, int i)
325{
326 block *b;
327 PyObject *item;
328 int n;
329
330 if (i < 0 || i >= deque->len) {
331 PyErr_SetString(PyExc_IndexError,
332 "deque index out of range");
333 return NULL;
334 }
335
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000336 if (i == 0) {
337 i = deque->leftindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000338 b = deque->leftblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000339 } else if (i == deque->len - 1) {
340 i = deque->rightindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000341 b = deque->rightblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000342 } else {
343 i += deque->leftindex;
344 n = i / BLOCKLEN;
345 i %= BLOCKLEN;
346 if (i < (deque->len >> 1)) {
347 b = deque->leftblock;
348 while (n--)
349 b = b->rightlink;
350 } else {
351 n = (deque->leftindex + deque->len - 1) / BLOCKLEN - n;
352 b = deque->rightblock;
353 while (n--)
354 b = b->leftlink;
355 }
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000356 }
357 item = b->data[i];
358 Py_INCREF(item);
359 return item;
360}
361
362static int
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000363deque_del_item(dequeobject *deque, int i)
364{
365 PyObject *item=NULL, *minus_i=NULL, *plus_i=NULL;
366 int rv = -1;
367
368 assert (i >= 0 && i < deque->len);
369
370 minus_i = Py_BuildValue("(i)", -i);
371 if (minus_i == NULL)
372 goto fail;
373
374 plus_i = Py_BuildValue("(i)", i);
375 if (plus_i == NULL)
376 goto fail;
377
378 item = deque_rotate(deque, minus_i);
379 if (item == NULL)
380 goto fail;
381 Py_DECREF(item);
382
383 item = deque_popleft(deque, NULL);
384 if (item == NULL)
385 goto fail;
386 Py_DECREF(item);
387
388 item = deque_rotate(deque, plus_i);
389 if (item == NULL)
390 goto fail;
391
392 rv = 0;
393fail:
394 Py_XDECREF(item);
395 Py_XDECREF(minus_i);
396 Py_XDECREF(plus_i);
397 return rv;
398}
399
400static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000401deque_ass_item(dequeobject *deque, int i, PyObject *v)
402{
403 PyObject *old_value;
404 block *b;
405 int n;
406
407 if (i < 0 || i >= deque->len) {
408 PyErr_SetString(PyExc_IndexError,
409 "deque index out of range");
410 return -1;
411 }
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000412 if (v == NULL)
413 return deque_del_item(deque, i);
414
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000415 i += deque->leftindex;
416 n = i / BLOCKLEN;
417 i %= BLOCKLEN;
418 if (i < (deque->len >> 1)) {
419 b = deque->leftblock;
420 while (n--)
421 b = b->rightlink;
422 } else {
423 n = (deque->leftindex + deque->len - 1) / BLOCKLEN - n;
424 b = deque->rightblock;
425 while (n--)
426 b = b->leftlink;
427 }
428 Py_INCREF(v);
429 old_value = b->data[i];
430 b->data[i] = v;
431 Py_DECREF(old_value);
432 return 0;
433}
434
435static PyObject *
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000436deque_clearmethod(dequeobject *deque)
437{
438 if (deque_clear(deque) == -1)
439 return NULL;
440 Py_RETURN_NONE;
441}
442
443PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
444
445static void
446deque_dealloc(dequeobject *deque)
447{
448 PyObject_GC_UnTrack(deque);
Raymond Hettinger691d8052004-05-30 07:26:47 +0000449 if (deque->weakreflist != NULL)
450 PyObject_ClearWeakRefs((PyObject *) deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000451 if (deque->leftblock != NULL) {
452 int err = deque_clear(deque);
453 assert(err == 0);
454 assert(deque->leftblock != NULL);
455 PyMem_Free(deque->leftblock);
456 }
457 deque->leftblock = NULL;
458 deque->rightblock = NULL;
459 deque->ob_type->tp_free(deque);
460}
461
462static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000463deque_traverse(dequeobject *deque, visitproc visit, void *arg)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000464{
465 block * b = deque->leftblock;
466 int index = deque->leftindex;
467 int err;
468 PyObject *item;
469
470 while (b != deque->rightblock || index <= deque->rightindex) {
471 item = b->data[index];
472 index++;
473 if (index == BLOCKLEN && b->rightlink != NULL) {
474 b = b->rightlink;
475 index = 0;
476 }
477 err = visit(item, arg);
478 if (err)
479 return err;
480 }
481 return 0;
482}
483
484static long
485deque_nohash(PyObject *self)
486{
487 PyErr_SetString(PyExc_TypeError, "deque objects are unhashable");
488 return -1;
489}
490
491static PyObject *
492deque_copy(PyObject *deque)
493{
494 return PyObject_CallFunctionObjArgs((PyObject *)(deque->ob_type),
495 deque, NULL);
496}
497
498PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
499
500static PyObject *
501deque_reduce(dequeobject *deque)
502{
503 PyObject *seq, *args, *result;
504
505 seq = PySequence_Tuple((PyObject *)deque);
506 if (seq == NULL)
507 return NULL;
508 args = PyTuple_Pack(1, seq);
509 if (args == NULL) {
510 Py_DECREF(seq);
511 return NULL;
512 }
513 result = PyTuple_Pack(2, deque->ob_type, args);
514 Py_DECREF(seq);
515 Py_DECREF(args);
516 return result;
517}
518
519PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
520
521static PyObject *
522deque_repr(PyObject *deque)
523{
524 PyObject *aslist, *result, *fmt;
525 int i;
526
527 i = Py_ReprEnter(deque);
528 if (i != 0) {
529 if (i < 0)
530 return NULL;
531 return PyString_FromString("[...]");
532 }
533
534 aslist = PySequence_List(deque);
535 if (aslist == NULL) {
536 Py_ReprLeave(deque);
537 return NULL;
538 }
539
540 fmt = PyString_FromString("deque(%r)");
541 if (fmt == NULL) {
542 Py_DECREF(aslist);
543 Py_ReprLeave(deque);
544 return NULL;
545 }
546 result = PyString_Format(fmt, aslist);
547 Py_DECREF(fmt);
548 Py_DECREF(aslist);
549 Py_ReprLeave(deque);
550 return result;
551}
552
553static int
554deque_tp_print(PyObject *deque, FILE *fp, int flags)
555{
556 PyObject *it, *item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000557 char *emit = ""; /* No separator emitted on first pass */
558 char *separator = ", ";
559 int i;
560
561 i = Py_ReprEnter(deque);
562 if (i != 0) {
563 if (i < 0)
564 return i;
565 fputs("[...]", fp);
566 return 0;
567 }
568
569 it = PyObject_GetIter(deque);
570 if (it == NULL)
571 return -1;
572
573 fputs("deque([", fp);
574 while ((item = PyIter_Next(it)) != NULL) {
575 fputs(emit, fp);
576 emit = separator;
577 if (PyObject_Print(item, fp, 0) != 0) {
578 Py_DECREF(item);
579 Py_DECREF(it);
580 Py_ReprLeave(deque);
581 return -1;
582 }
583 Py_DECREF(item);
584 }
585 Py_ReprLeave(deque);
586 Py_DECREF(it);
587 if (PyErr_Occurred())
588 return -1;
589 fputs("])", fp);
590 return 0;
591}
592
Raymond Hettinger738ec902004-02-29 02:15:56 +0000593static PyObject *
594deque_richcompare(PyObject *v, PyObject *w, int op)
595{
596 PyObject *it1=NULL, *it2=NULL, *x, *y;
597 int i, b, vs, ws, minlen, cmp=-1;
598
Raymond Hettinger285cfcc2004-05-18 18:15:03 +0000599 if (!PyObject_TypeCheck(v, &deque_type) ||
600 !PyObject_TypeCheck(w, &deque_type)) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000601 Py_INCREF(Py_NotImplemented);
602 return Py_NotImplemented;
603 }
604
605 /* Shortcuts */
606 vs = ((dequeobject *)v)->len;
607 ws = ((dequeobject *)w)->len;
608 if (op == Py_EQ) {
609 if (v == w)
610 Py_RETURN_TRUE;
611 if (vs != ws)
612 Py_RETURN_FALSE;
613 }
614 if (op == Py_NE) {
615 if (v == w)
616 Py_RETURN_FALSE;
617 if (vs != ws)
618 Py_RETURN_TRUE;
619 }
620
621 /* Search for the first index where items are different */
622 it1 = PyObject_GetIter(v);
623 if (it1 == NULL)
624 goto done;
625 it2 = PyObject_GetIter(w);
626 if (it2 == NULL)
627 goto done;
628 minlen = (vs < ws) ? vs : ws;
629 for (i=0 ; i < minlen ; i++) {
630 x = PyIter_Next(it1);
631 if (x == NULL)
632 goto done;
633 y = PyIter_Next(it2);
634 if (y == NULL) {
635 Py_DECREF(x);
636 goto done;
637 }
638 b = PyObject_RichCompareBool(x, y, Py_EQ);
639 if (b == 0) {
640 cmp = PyObject_RichCompareBool(x, y, op);
641 Py_DECREF(x);
642 Py_DECREF(y);
643 goto done;
644 }
645 Py_DECREF(x);
646 Py_DECREF(y);
647 if (b == -1)
648 goto done;
649 }
650 /* Elements are equal through minlen. The longest input is the greatest */
651 switch (op) {
652 case Py_LT: cmp = vs < ws; break;
653 case Py_LE: cmp = vs <= ws; break;
654 case Py_EQ: cmp = vs == ws; break;
655 case Py_NE: cmp = vs != ws; break;
656 case Py_GT: cmp = vs > ws; break;
657 case Py_GE: cmp = vs >= ws; break;
658 }
659
660done:
661 Py_XDECREF(it1);
662 Py_XDECREF(it2);
663 if (cmp == 1)
664 Py_RETURN_TRUE;
665 if (cmp == 0)
666 Py_RETURN_FALSE;
667 return NULL;
668}
669
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000670static int
671deque_init(dequeobject *deque, PyObject *args, PyObject *kwds)
672{
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000673 PyObject *iterable = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000674
675 if (!PyArg_UnpackTuple(args, "deque", 0, 1, &iterable))
676 return -1;
677
678 if (iterable != NULL) {
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000679 PyObject *rv = deque_extend(deque, iterable);
680 if (rv == NULL)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000681 return -1;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000682 Py_DECREF(rv);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000683 }
684 return 0;
685}
686
687static PySequenceMethods deque_as_sequence = {
688 (inquiry)deque_len, /* sq_length */
689 0, /* sq_concat */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000690 0, /* sq_repeat */
691 (intargfunc)deque_item, /* sq_item */
692 0, /* sq_slice */
693 (intobjargproc)deque_ass_item, /* sq_ass_item */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000694};
695
696/* deque object ********************************************************/
697
698static PyObject *deque_iter(dequeobject *deque);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000699static PyObject *deque_reviter(dequeobject *deque);
700PyDoc_STRVAR(reversed_doc,
701 "D.__reversed__() -- return a reverse iterator over the deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000702
703static PyMethodDef deque_methods[] = {
704 {"append", (PyCFunction)deque_append,
705 METH_O, append_doc},
706 {"appendleft", (PyCFunction)deque_appendleft,
707 METH_O, appendleft_doc},
708 {"clear", (PyCFunction)deque_clearmethod,
709 METH_NOARGS, clear_doc},
710 {"__copy__", (PyCFunction)deque_copy,
711 METH_NOARGS, copy_doc},
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000712 {"extend", (PyCFunction)deque_extend,
713 METH_O, extend_doc},
714 {"extendleft", (PyCFunction)deque_extendleft,
715 METH_O, extendleft_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000716 {"pop", (PyCFunction)deque_pop,
717 METH_NOARGS, pop_doc},
718 {"popleft", (PyCFunction)deque_popleft,
719 METH_NOARGS, popleft_doc},
720 {"__reduce__", (PyCFunction)deque_reduce,
721 METH_NOARGS, reduce_doc},
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000722 {"__reversed__", (PyCFunction)deque_reviter,
723 METH_NOARGS, reversed_doc},
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000724 {"rotate", (PyCFunction)deque_rotate,
725 METH_VARARGS, rotate_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000726 {NULL, NULL} /* sentinel */
727};
728
729PyDoc_STRVAR(deque_doc,
730"deque(iterable) --> deque object\n\
731\n\
732Build an ordered collection accessible from endpoints only.");
733
Neal Norwitz87f10132004-02-29 15:40:53 +0000734static PyTypeObject deque_type = {
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000735 PyObject_HEAD_INIT(NULL)
736 0, /* ob_size */
737 "collections.deque", /* tp_name */
738 sizeof(dequeobject), /* tp_basicsize */
739 0, /* tp_itemsize */
740 /* methods */
741 (destructor)deque_dealloc, /* tp_dealloc */
742 (printfunc)deque_tp_print, /* tp_print */
743 0, /* tp_getattr */
744 0, /* tp_setattr */
745 0, /* tp_compare */
746 (reprfunc)deque_repr, /* tp_repr */
747 0, /* tp_as_number */
748 &deque_as_sequence, /* tp_as_sequence */
749 0, /* tp_as_mapping */
750 deque_nohash, /* tp_hash */
751 0, /* tp_call */
752 0, /* tp_str */
753 PyObject_GenericGetAttr, /* tp_getattro */
754 0, /* tp_setattro */
755 0, /* tp_as_buffer */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000756 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
757 Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000758 deque_doc, /* tp_doc */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000759 (traverseproc)deque_traverse, /* tp_traverse */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000760 (inquiry)deque_clear, /* tp_clear */
Raymond Hettinger738ec902004-02-29 02:15:56 +0000761 (richcmpfunc)deque_richcompare, /* tp_richcompare */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000762 offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000763 (getiterfunc)deque_iter, /* tp_iter */
764 0, /* tp_iternext */
765 deque_methods, /* tp_methods */
766 0, /* tp_members */
767 0, /* tp_getset */
768 0, /* tp_base */
769 0, /* tp_dict */
770 0, /* tp_descr_get */
771 0, /* tp_descr_set */
772 0, /* tp_dictoffset */
773 (initproc)deque_init, /* tp_init */
774 PyType_GenericAlloc, /* tp_alloc */
775 deque_new, /* tp_new */
776 PyObject_GC_Del, /* tp_free */
777};
778
779/*********************** Deque Iterator **************************/
780
781typedef struct {
782 PyObject_HEAD
783 int index;
784 block *b;
785 dequeobject *deque;
786 int len;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000787 int counter;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000788} dequeiterobject;
789
790PyTypeObject dequeiter_type;
791
792static PyObject *
793deque_iter(dequeobject *deque)
794{
795 dequeiterobject *it;
796
797 it = PyObject_New(dequeiterobject, &dequeiter_type);
798 if (it == NULL)
799 return NULL;
800 it->b = deque->leftblock;
801 it->index = deque->leftindex;
802 Py_INCREF(deque);
803 it->deque = deque;
804 it->len = deque->len;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000805 it->counter = deque->len;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000806 return (PyObject *)it;
807}
808
809static void
810dequeiter_dealloc(dequeiterobject *dio)
811{
812 Py_XDECREF(dio->deque);
813 dio->ob_type->tp_free(dio);
814}
815
816static PyObject *
817dequeiter_next(dequeiterobject *it)
818{
819 PyObject *item;
820 if (it->b == it->deque->rightblock && it->index > it->deque->rightindex)
821 return NULL;
822
823 if (it->len != it->deque->len) {
824 it->len = -1; /* Make this state sticky */
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000825 it->counter = 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000826 PyErr_SetString(PyExc_RuntimeError,
827 "deque changed size during iteration");
828 return NULL;
829 }
830
831 item = it->b->data[it->index];
832 it->index++;
833 if (it->index == BLOCKLEN && it->b->rightlink != NULL) {
834 it->b = it->b->rightlink;
835 it->index = 0;
836 }
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000837 it->counter--;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000838 Py_INCREF(item);
839 return item;
840}
841
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000842static int
843dequeiter_len(dequeiterobject *it)
844{
845 return it->counter;
846}
847
848static PySequenceMethods dequeiter_as_sequence = {
849 (inquiry)dequeiter_len, /* sq_length */
850 0, /* sq_concat */
851};
852
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000853PyTypeObject dequeiter_type = {
854 PyObject_HEAD_INIT(NULL)
855 0, /* ob_size */
856 "deque_iterator", /* tp_name */
857 sizeof(dequeiterobject), /* tp_basicsize */
858 0, /* tp_itemsize */
859 /* methods */
860 (destructor)dequeiter_dealloc, /* tp_dealloc */
861 0, /* tp_print */
862 0, /* tp_getattr */
863 0, /* tp_setattr */
864 0, /* tp_compare */
865 0, /* tp_repr */
866 0, /* tp_as_number */
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000867 &dequeiter_as_sequence, /* tp_as_sequence */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000868 0, /* tp_as_mapping */
869 0, /* tp_hash */
870 0, /* tp_call */
871 0, /* tp_str */
872 PyObject_GenericGetAttr, /* tp_getattro */
873 0, /* tp_setattro */
874 0, /* tp_as_buffer */
875 Py_TPFLAGS_DEFAULT, /* tp_flags */
876 0, /* tp_doc */
877 0, /* tp_traverse */
878 0, /* tp_clear */
879 0, /* tp_richcompare */
880 0, /* tp_weaklistoffset */
881 PyObject_SelfIter, /* tp_iter */
882 (iternextfunc)dequeiter_next, /* tp_iternext */
883 0,
884};
885
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000886/*********************** Deque Reverse Iterator **************************/
887
888PyTypeObject dequereviter_type;
889
890static PyObject *
891deque_reviter(dequeobject *deque)
892{
893 dequeiterobject *it;
894
895 it = PyObject_New(dequeiterobject, &dequereviter_type);
896 if (it == NULL)
897 return NULL;
898 it->b = deque->rightblock;
899 it->index = deque->rightindex;
900 Py_INCREF(deque);
901 it->deque = deque;
902 it->len = deque->len;
903 it->counter = deque->len;
904 return (PyObject *)it;
905}
906
907static PyObject *
908dequereviter_next(dequeiterobject *it)
909{
910 PyObject *item;
911 if (it->b == it->deque->leftblock && it->index < it->deque->leftindex)
912 return NULL;
913
914 if (it->len != it->deque->len) {
915 it->len = -1; /* Make this state sticky */
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000916 it->counter = 0;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000917 PyErr_SetString(PyExc_RuntimeError,
918 "deque changed size during iteration");
919 return NULL;
920 }
921
922 item = it->b->data[it->index];
923 it->index--;
924 if (it->index == -1 && it->b->leftlink != NULL) {
925 it->b = it->b->leftlink;
926 it->index = BLOCKLEN - 1;
927 }
928 it->counter--;
929 Py_INCREF(item);
930 return item;
931}
932
933PyTypeObject dequereviter_type = {
934 PyObject_HEAD_INIT(NULL)
935 0, /* ob_size */
936 "deque_reverse_iterator", /* tp_name */
937 sizeof(dequeiterobject), /* tp_basicsize */
938 0, /* tp_itemsize */
939 /* methods */
940 (destructor)dequeiter_dealloc, /* tp_dealloc */
941 0, /* tp_print */
942 0, /* tp_getattr */
943 0, /* tp_setattr */
944 0, /* tp_compare */
945 0, /* tp_repr */
946 0, /* tp_as_number */
947 &dequeiter_as_sequence, /* tp_as_sequence */
948 0, /* tp_as_mapping */
949 0, /* tp_hash */
950 0, /* tp_call */
951 0, /* tp_str */
952 PyObject_GenericGetAttr, /* tp_getattro */
953 0, /* tp_setattro */
954 0, /* tp_as_buffer */
955 Py_TPFLAGS_DEFAULT, /* tp_flags */
956 0, /* tp_doc */
957 0, /* tp_traverse */
958 0, /* tp_clear */
959 0, /* tp_richcompare */
960 0, /* tp_weaklistoffset */
961 PyObject_SelfIter, /* tp_iter */
962 (iternextfunc)dequereviter_next, /* tp_iternext */
963 0,
964};
965
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000966/* module level code ********************************************************/
967
968PyDoc_STRVAR(module_doc,
969"High performance data structures\n\
970");
971
972PyMODINIT_FUNC
973initcollections(void)
974{
975 PyObject *m;
976
977 m = Py_InitModule3("collections", NULL, module_doc);
978
979 if (PyType_Ready(&deque_type) < 0)
980 return;
981 Py_INCREF(&deque_type);
982 PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
983
984 if (PyType_Ready(&dequeiter_type) < 0)
985 return;
986
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000987 if (PyType_Ready(&dequereviter_type) < 0)
988 return;
989
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000990 return;
991}