blob: 0e0b2d6ac85f601d8492d5792922edc0bae05211 [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
37static PyObject *
38deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
39{
40 dequeobject *deque;
41 block *b;
42
43 /* create dequeobject structure */
44 deque = (dequeobject *)type->tp_alloc(type, 0);
45 if (deque == NULL)
46 return NULL;
47
48 b = newblock(NULL, NULL);
49 if (b == NULL) {
50 Py_DECREF(deque);
51 return NULL;
52 }
53
54 deque->leftblock = b;
55 deque->rightblock = b;
56 deque->leftindex = BLOCKLEN / 2 + 1;
57 deque->rightindex = BLOCKLEN / 2;
58 deque->len = 0;
59
60 return (PyObject *)deque;
61}
62
63static PyObject *
64deque_append(dequeobject *deque, PyObject *item)
65{
66 deque->rightindex++;
67 deque->len++;
68 if (deque->rightindex == BLOCKLEN) {
69 block *b = newblock(deque->rightblock, NULL);
70 if (b == NULL)
71 return NULL;
72 assert(deque->rightblock->rightlink == NULL);
73 deque->rightblock->rightlink = b;
74 deque->rightblock = b;
75 deque->rightindex = 0;
76 }
77 Py_INCREF(item);
78 deque->rightblock->data[deque->rightindex] = item;
79 Py_RETURN_NONE;
80}
81
82PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque.");
83
84static PyObject *
85deque_appendleft(dequeobject *deque, PyObject *item)
86{
87 deque->leftindex--;
88 deque->len++;
89 if (deque->leftindex == -1) {
90 block *b = newblock(NULL, deque->leftblock);
91 if (b == NULL)
92 return NULL;
93 assert(deque->leftblock->leftlink == NULL);
94 deque->leftblock->leftlink = b;
95 deque->leftblock = b;
96 deque->leftindex = BLOCKLEN - 1;
97 }
98 Py_INCREF(item);
99 deque->leftblock->data[deque->leftindex] = item;
100 Py_RETURN_NONE;
101}
102
103PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque.");
104
105static PyObject *
106deque_pop(dequeobject *deque, PyObject *unused)
107{
108 PyObject *item;
109 block *prevblock;
110
111 if (deque->len == 0) {
Raymond Hettingerd0814eb2004-01-29 07:29:32 +0000112 PyErr_SetString(PyExc_LookupError, "pop from an empty deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000113 return NULL;
114 }
115 item = deque->rightblock->data[deque->rightindex];
116 deque->rightindex--;
117 deque->len--;
118
119 if (deque->rightindex == -1) {
120 if (deque->len == 0) {
121 assert(deque->leftblock == deque->rightblock);
122 assert(deque->leftindex == deque->rightindex+1);
123 /* re-center instead of freeing a block */
124 deque->leftindex = BLOCKLEN / 2 + 1;
125 deque->rightindex = BLOCKLEN / 2;
126 } else {
127 prevblock = deque->rightblock->leftlink;
128 assert(deque->leftblock != deque->rightblock);
129 PyMem_Free(deque->rightblock);
130 prevblock->rightlink = NULL;
131 deque->rightblock = prevblock;
132 deque->rightindex = BLOCKLEN - 1;
133 }
134 }
135 return item;
136}
137
138PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");
139
140static PyObject *
141deque_popleft(dequeobject *deque, PyObject *unused)
142{
143 PyObject *item;
144 block *prevblock;
145
146 if (deque->len == 0) {
Raymond Hettingerd0814eb2004-01-29 07:29:32 +0000147 PyErr_SetString(PyExc_LookupError, "pop from an empty deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000148 return NULL;
149 }
150 item = deque->leftblock->data[deque->leftindex];
151 deque->leftindex++;
152 deque->len--;
153
154 if (deque->leftindex == BLOCKLEN) {
155 if (deque->len == 0) {
156 assert(deque->leftblock == deque->rightblock);
157 assert(deque->leftindex == deque->rightindex+1);
158 /* re-center instead of freeing a block */
159 deque->leftindex = BLOCKLEN / 2 + 1;
160 deque->rightindex = BLOCKLEN / 2;
161 } else {
162 assert(deque->leftblock != deque->rightblock);
163 prevblock = deque->leftblock->rightlink;
164 assert(deque->leftblock != NULL);
165 PyMem_Free(deque->leftblock);
166 assert(prevblock != NULL);
167 prevblock->leftlink = NULL;
168 deque->leftblock = prevblock;
169 deque->leftindex = 0;
170 }
171 }
172 return item;
173}
174
175PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element.");
176
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000177static PyObject *
178deque_extend(dequeobject *deque, PyObject *iterable)
179{
180 PyObject *it, *item;
181
182 it = PyObject_GetIter(iterable);
183 if (it == NULL)
184 return NULL;
185
186 while ((item = PyIter_Next(it)) != NULL) {
187 deque->rightindex++;
188 deque->len++;
189 if (deque->rightindex == BLOCKLEN) {
190 block *b = newblock(deque->rightblock, NULL);
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000191 if (b == NULL) {
192 Py_DECREF(item);
193 Py_DECREF(it);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000194 return NULL;
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000195 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000196 assert(deque->rightblock->rightlink == NULL);
197 deque->rightblock->rightlink = b;
198 deque->rightblock = b;
199 deque->rightindex = 0;
200 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000201 deque->rightblock->data[deque->rightindex] = item;
202 }
203 Py_DECREF(it);
204 if (PyErr_Occurred())
205 return NULL;
206 Py_RETURN_NONE;
207}
208
209PyDoc_STRVAR(extend_doc,
210"Extend the right side of the deque with elements from the iterable");
211
212static PyObject *
213deque_extendleft(dequeobject *deque, PyObject *iterable)
214{
215 PyObject *it, *item;
216
217 it = PyObject_GetIter(iterable);
218 if (it == NULL)
219 return NULL;
220
221 while ((item = PyIter_Next(it)) != NULL) {
222 deque->leftindex--;
223 deque->len++;
224 if (deque->leftindex == -1) {
225 block *b = newblock(NULL, deque->leftblock);
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000226 if (b == NULL) {
227 Py_DECREF(item);
228 Py_DECREF(it);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000229 return NULL;
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000230 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000231 assert(deque->leftblock->leftlink == NULL);
232 deque->leftblock->leftlink = b;
233 deque->leftblock = b;
234 deque->leftindex = BLOCKLEN - 1;
235 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000236 deque->leftblock->data[deque->leftindex] = item;
237 }
238 Py_DECREF(it);
239 if (PyErr_Occurred())
240 return NULL;
241 Py_RETURN_NONE;
242}
243
244PyDoc_STRVAR(extendleft_doc,
245"Extend the left side of the deque with elements from the iterable");
246
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000247static PyObject *
248deque_rotate(dequeobject *deque, PyObject *args)
249{
Raymond Hettingeree33b272004-02-08 04:05:26 +0000250 int i, n=1, len=deque->len, halflen=(len+1)>>1;
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000251 PyObject *item, *rv;
252
Raymond Hettingeree33b272004-02-08 04:05:26 +0000253 if (!PyArg_ParseTuple(args, "|i:rotate", &n))
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000254 return NULL;
255
Raymond Hettingeree33b272004-02-08 04:05:26 +0000256 if (len == 0)
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000257 Py_RETURN_NONE;
Raymond Hettingeree33b272004-02-08 04:05:26 +0000258 if (n > halflen || n < -halflen) {
259 n %= len;
260 if (n > halflen)
261 n -= len;
262 else if (n < -halflen)
263 n += len;
264 }
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000265
266 for (i=0 ; i<n ; i++) {
267 item = deque_pop(deque, NULL);
268 if (item == NULL)
269 return NULL;
270 rv = deque_appendleft(deque, item);
271 Py_DECREF(item);
272 if (rv == NULL)
273 return NULL;
274 Py_DECREF(rv);
275 }
276 for (i=0 ; i>n ; i--) {
277 item = deque_popleft(deque, NULL);
278 if (item == NULL)
279 return NULL;
280 rv = deque_append(deque, item);
281 Py_DECREF(item);
282 if (rv == NULL)
283 return NULL;
284 Py_DECREF(rv);
285 }
286 Py_RETURN_NONE;
287}
288
289PyDoc_STRVAR(rotate_doc,
Raymond Hettingeree33b272004-02-08 04:05:26 +0000290"Rotate the deque n steps to the right (default n=1). If n is negative, rotates left.");
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000291
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000292static int
293deque_len(dequeobject *deque)
294{
295 return deque->len;
296}
297
298static int
299deque_clear(dequeobject *deque)
300{
301 PyObject *item;
302
303 while (deque_len(deque)) {
304 item = deque_pop(deque, NULL);
305 if (item == NULL)
306 return -1;
307 Py_DECREF(item);
308 }
309 assert(deque->leftblock == deque->rightblock &&
310 deque->leftindex > deque->rightindex);
311 return 0;
312}
313
314static PyObject *
315deque_clearmethod(dequeobject *deque)
316{
317 if (deque_clear(deque) == -1)
318 return NULL;
319 Py_RETURN_NONE;
320}
321
322PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
323
324static void
325deque_dealloc(dequeobject *deque)
326{
327 PyObject_GC_UnTrack(deque);
328 if (deque->leftblock != NULL) {
329 int err = deque_clear(deque);
330 assert(err == 0);
331 assert(deque->leftblock != NULL);
332 PyMem_Free(deque->leftblock);
333 }
334 deque->leftblock = NULL;
335 deque->rightblock = NULL;
336 deque->ob_type->tp_free(deque);
337}
338
339static int
340set_traverse(dequeobject *deque, visitproc visit, void *arg)
341{
342 block * b = deque->leftblock;
343 int index = deque->leftindex;
344 int err;
345 PyObject *item;
346
347 while (b != deque->rightblock || index <= deque->rightindex) {
348 item = b->data[index];
349 index++;
350 if (index == BLOCKLEN && b->rightlink != NULL) {
351 b = b->rightlink;
352 index = 0;
353 }
354 err = visit(item, arg);
355 if (err)
356 return err;
357 }
358 return 0;
359}
360
361static long
362deque_nohash(PyObject *self)
363{
364 PyErr_SetString(PyExc_TypeError, "deque objects are unhashable");
365 return -1;
366}
367
368static PyObject *
369deque_copy(PyObject *deque)
370{
371 return PyObject_CallFunctionObjArgs((PyObject *)(deque->ob_type),
372 deque, NULL);
373}
374
375PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
376
377static PyObject *
378deque_reduce(dequeobject *deque)
379{
380 PyObject *seq, *args, *result;
381
382 seq = PySequence_Tuple((PyObject *)deque);
383 if (seq == NULL)
384 return NULL;
385 args = PyTuple_Pack(1, seq);
386 if (args == NULL) {
387 Py_DECREF(seq);
388 return NULL;
389 }
390 result = PyTuple_Pack(2, deque->ob_type, args);
391 Py_DECREF(seq);
392 Py_DECREF(args);
393 return result;
394}
395
396PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
397
398static PyObject *
399deque_repr(PyObject *deque)
400{
401 PyObject *aslist, *result, *fmt;
402 int i;
403
404 i = Py_ReprEnter(deque);
405 if (i != 0) {
406 if (i < 0)
407 return NULL;
408 return PyString_FromString("[...]");
409 }
410
411 aslist = PySequence_List(deque);
412 if (aslist == NULL) {
413 Py_ReprLeave(deque);
414 return NULL;
415 }
416
417 fmt = PyString_FromString("deque(%r)");
418 if (fmt == NULL) {
419 Py_DECREF(aslist);
420 Py_ReprLeave(deque);
421 return NULL;
422 }
423 result = PyString_Format(fmt, aslist);
424 Py_DECREF(fmt);
425 Py_DECREF(aslist);
426 Py_ReprLeave(deque);
427 return result;
428}
429
430static int
431deque_tp_print(PyObject *deque, FILE *fp, int flags)
432{
433 PyObject *it, *item;
434 int pos=0;
435 char *emit = ""; /* No separator emitted on first pass */
436 char *separator = ", ";
437 int i;
438
439 i = Py_ReprEnter(deque);
440 if (i != 0) {
441 if (i < 0)
442 return i;
443 fputs("[...]", fp);
444 return 0;
445 }
446
447 it = PyObject_GetIter(deque);
448 if (it == NULL)
449 return -1;
450
451 fputs("deque([", fp);
452 while ((item = PyIter_Next(it)) != NULL) {
453 fputs(emit, fp);
454 emit = separator;
455 if (PyObject_Print(item, fp, 0) != 0) {
456 Py_DECREF(item);
457 Py_DECREF(it);
458 Py_ReprLeave(deque);
459 return -1;
460 }
461 Py_DECREF(item);
462 }
463 Py_ReprLeave(deque);
464 Py_DECREF(it);
465 if (PyErr_Occurred())
466 return -1;
467 fputs("])", fp);
468 return 0;
469}
470
471static int
472deque_init(dequeobject *deque, PyObject *args, PyObject *kwds)
473{
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000474 PyObject *iterable = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000475
476 if (!PyArg_UnpackTuple(args, "deque", 0, 1, &iterable))
477 return -1;
478
479 if (iterable != NULL) {
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000480 PyObject *rv = deque_extend(deque, iterable);
481 if (rv == NULL)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000482 return -1;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000483 Py_DECREF(rv);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000484 }
485 return 0;
486}
487
488static PySequenceMethods deque_as_sequence = {
489 (inquiry)deque_len, /* sq_length */
490 0, /* sq_concat */
491};
492
493/* deque object ********************************************************/
494
495static PyObject *deque_iter(dequeobject *deque);
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000496static PyObject *deque_reviter(dequeobject *deque);
497PyDoc_STRVAR(reversed_doc,
498 "D.__reversed__() -- return a reverse iterator over the deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000499
500static PyMethodDef deque_methods[] = {
501 {"append", (PyCFunction)deque_append,
502 METH_O, append_doc},
503 {"appendleft", (PyCFunction)deque_appendleft,
504 METH_O, appendleft_doc},
505 {"clear", (PyCFunction)deque_clearmethod,
506 METH_NOARGS, clear_doc},
507 {"__copy__", (PyCFunction)deque_copy,
508 METH_NOARGS, copy_doc},
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000509 {"extend", (PyCFunction)deque_extend,
510 METH_O, extend_doc},
511 {"extendleft", (PyCFunction)deque_extendleft,
512 METH_O, extendleft_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000513 {"pop", (PyCFunction)deque_pop,
514 METH_NOARGS, pop_doc},
515 {"popleft", (PyCFunction)deque_popleft,
516 METH_NOARGS, popleft_doc},
517 {"__reduce__", (PyCFunction)deque_reduce,
518 METH_NOARGS, reduce_doc},
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000519 {"__reversed__", (PyCFunction)deque_reviter,
520 METH_NOARGS, reversed_doc},
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000521 {"rotate", (PyCFunction)deque_rotate,
522 METH_VARARGS, rotate_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000523 {NULL, NULL} /* sentinel */
524};
525
526PyDoc_STRVAR(deque_doc,
527"deque(iterable) --> deque object\n\
528\n\
529Build an ordered collection accessible from endpoints only.");
530
531PyTypeObject deque_type = {
532 PyObject_HEAD_INIT(NULL)
533 0, /* ob_size */
534 "collections.deque", /* tp_name */
535 sizeof(dequeobject), /* tp_basicsize */
536 0, /* tp_itemsize */
537 /* methods */
538 (destructor)deque_dealloc, /* tp_dealloc */
539 (printfunc)deque_tp_print, /* tp_print */
540 0, /* tp_getattr */
541 0, /* tp_setattr */
542 0, /* tp_compare */
543 (reprfunc)deque_repr, /* tp_repr */
544 0, /* tp_as_number */
545 &deque_as_sequence, /* tp_as_sequence */
546 0, /* tp_as_mapping */
547 deque_nohash, /* tp_hash */
548 0, /* tp_call */
549 0, /* tp_str */
550 PyObject_GenericGetAttr, /* tp_getattro */
551 0, /* tp_setattro */
552 0, /* tp_as_buffer */
553 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
554 deque_doc, /* tp_doc */
555 (traverseproc)set_traverse, /* tp_traverse */
556 (inquiry)deque_clear, /* tp_clear */
557 0, /* tp_richcompare */
558 0, /* tp_weaklistoffset*/
559 (getiterfunc)deque_iter, /* tp_iter */
560 0, /* tp_iternext */
561 deque_methods, /* tp_methods */
562 0, /* tp_members */
563 0, /* tp_getset */
564 0, /* tp_base */
565 0, /* tp_dict */
566 0, /* tp_descr_get */
567 0, /* tp_descr_set */
568 0, /* tp_dictoffset */
569 (initproc)deque_init, /* tp_init */
570 PyType_GenericAlloc, /* tp_alloc */
571 deque_new, /* tp_new */
572 PyObject_GC_Del, /* tp_free */
573};
574
575/*********************** Deque Iterator **************************/
576
577typedef struct {
578 PyObject_HEAD
579 int index;
580 block *b;
581 dequeobject *deque;
582 int len;
583} dequeiterobject;
584
585PyTypeObject dequeiter_type;
586
587static PyObject *
588deque_iter(dequeobject *deque)
589{
590 dequeiterobject *it;
591
592 it = PyObject_New(dequeiterobject, &dequeiter_type);
593 if (it == NULL)
594 return NULL;
595 it->b = deque->leftblock;
596 it->index = deque->leftindex;
597 Py_INCREF(deque);
598 it->deque = deque;
599 it->len = deque->len;
600 return (PyObject *)it;
601}
602
603static void
604dequeiter_dealloc(dequeiterobject *dio)
605{
606 Py_XDECREF(dio->deque);
607 dio->ob_type->tp_free(dio);
608}
609
610static PyObject *
611dequeiter_next(dequeiterobject *it)
612{
613 PyObject *item;
614 if (it->b == it->deque->rightblock && it->index > it->deque->rightindex)
615 return NULL;
616
617 if (it->len != it->deque->len) {
618 it->len = -1; /* Make this state sticky */
619 PyErr_SetString(PyExc_RuntimeError,
620 "deque changed size during iteration");
621 return NULL;
622 }
623
624 item = it->b->data[it->index];
625 it->index++;
626 if (it->index == BLOCKLEN && it->b->rightlink != NULL) {
627 it->b = it->b->rightlink;
628 it->index = 0;
629 }
630 Py_INCREF(item);
631 return item;
632}
633
634PyTypeObject dequeiter_type = {
635 PyObject_HEAD_INIT(NULL)
636 0, /* ob_size */
637 "deque_iterator", /* tp_name */
638 sizeof(dequeiterobject), /* tp_basicsize */
639 0, /* tp_itemsize */
640 /* methods */
641 (destructor)dequeiter_dealloc, /* tp_dealloc */
642 0, /* tp_print */
643 0, /* tp_getattr */
644 0, /* tp_setattr */
645 0, /* tp_compare */
646 0, /* tp_repr */
647 0, /* tp_as_number */
648 0, /* tp_as_sequence */
649 0, /* tp_as_mapping */
650 0, /* tp_hash */
651 0, /* tp_call */
652 0, /* tp_str */
653 PyObject_GenericGetAttr, /* tp_getattro */
654 0, /* tp_setattro */
655 0, /* tp_as_buffer */
656 Py_TPFLAGS_DEFAULT, /* tp_flags */
657 0, /* tp_doc */
658 0, /* tp_traverse */
659 0, /* tp_clear */
660 0, /* tp_richcompare */
661 0, /* tp_weaklistoffset */
662 PyObject_SelfIter, /* tp_iter */
663 (iternextfunc)dequeiter_next, /* tp_iternext */
664 0,
665};
666
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000667/*********************** Deque Reverse Iterator **************************/
668
669PyTypeObject dequereviter_type;
670
671static PyObject *
672deque_reviter(dequeobject *deque)
673{
674 dequeiterobject *it;
675
676 it = PyObject_New(dequeiterobject, &dequereviter_type);
677 if (it == NULL)
678 return NULL;
679 it->b = deque->rightblock;
680 it->index = deque->rightindex;
681 Py_INCREF(deque);
682 it->deque = deque;
683 it->len = deque->len;
684 return (PyObject *)it;
685}
686
687static PyObject *
688dequereviter_next(dequeiterobject *it)
689{
690 PyObject *item;
691 if (it->b == it->deque->leftblock && it->index < it->deque->leftindex)
692 return NULL;
693
694 if (it->len != it->deque->len) {
695 it->len = -1; /* Make this state sticky */
696 PyErr_SetString(PyExc_RuntimeError,
697 "deque changed size during iteration");
698 return NULL;
699 }
700
701 item = it->b->data[it->index];
702 it->index--;
703 if (it->index == -1 && it->b->leftlink != NULL) {
704 it->b = it->b->leftlink;
705 it->index = BLOCKLEN - 1;
706 }
707 Py_INCREF(item);
708 return item;
709}
710
711PyTypeObject dequereviter_type = {
712 PyObject_HEAD_INIT(NULL)
713 0, /* ob_size */
714 "deque_reverse_iterator", /* tp_name */
715 sizeof(dequeiterobject), /* tp_basicsize */
716 0, /* tp_itemsize */
717 /* methods */
718 (destructor)dequeiter_dealloc, /* tp_dealloc */
719 0, /* tp_print */
720 0, /* tp_getattr */
721 0, /* tp_setattr */
722 0, /* tp_compare */
723 0, /* tp_repr */
724 0, /* tp_as_number */
725 0, /* tp_as_sequence */
726 0, /* tp_as_mapping */
727 0, /* tp_hash */
728 0, /* tp_call */
729 0, /* tp_str */
730 PyObject_GenericGetAttr, /* tp_getattro */
731 0, /* tp_setattro */
732 0, /* tp_as_buffer */
733 Py_TPFLAGS_DEFAULT, /* tp_flags */
734 0, /* tp_doc */
735 0, /* tp_traverse */
736 0, /* tp_clear */
737 0, /* tp_richcompare */
738 0, /* tp_weaklistoffset */
739 PyObject_SelfIter, /* tp_iter */
740 (iternextfunc)dequereviter_next, /* tp_iternext */
741 0,
742};
743
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000744/* module level code ********************************************************/
745
746PyDoc_STRVAR(module_doc,
747"High performance data structures\n\
748");
749
750PyMODINIT_FUNC
751initcollections(void)
752{
753 PyObject *m;
754
755 m = Py_InitModule3("collections", NULL, module_doc);
756
757 if (PyType_Ready(&deque_type) < 0)
758 return;
759 Py_INCREF(&deque_type);
760 PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
761
762 if (PyType_Ready(&dequeiter_type) < 0)
763 return;
764
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000765 if (PyType_Ready(&dequereviter_type) < 0)
766 return;
767
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000768 return;
769}