comparison cos/python/Objects/tupleobject.c @ 27:7f74363f4c82

Added some files for the python port
author windel
date Tue, 27 Dec 2011 18:59:02 +0100
parents
children
comparison
equal deleted inserted replaced
26:dcce92b1efbc 27:7f74363f4c82
1
2 /* Tuple object implementation */
3
4 #include "Python.h"
5
6 PyObject *
7 PyTuple_New(register Py_ssize_t size)
8 {
9 register PyTupleObject *op;
10 Py_ssize_t i;
11 if (size < 0) {
12 PyErr_BadInternalCall();
13 return NULL;
14 }
15 {
16 Py_ssize_t nbytes = size * sizeof(PyObject *);
17 /* Check for overflow */
18 if (nbytes / sizeof(PyObject *) != (size_t)size ||
19 (nbytes > PY_SSIZE_T_MAX - sizeof(PyTupleObject) - sizeof(PyObject *)))
20 {
21 return PyErr_NoMemory();
22 }
23 /* nbytes += sizeof(PyTupleObject) - sizeof(PyObject *); */
24
25 op = PyObject_GC_NewVar(PyTupleObject, &PyTuple_Type, size);
26 if (op == NULL)
27 return NULL;
28 }
29 for (i=0; i < size; i++)
30 op->ob_item[i] = NULL;
31 _PyObject_GC_TRACK(op);
32 return (PyObject *) op;
33 }
34
35 Py_ssize_t
36 PyTuple_Size(register PyObject *op)
37 {
38 if (!PyTuple_Check(op)) {
39 PyErr_BadInternalCall();
40 return -1;
41 }
42 else
43 return Py_SIZE(op);
44 }
45
46 PyObject *
47 PyTuple_GetItem(register PyObject *op, register Py_ssize_t i)
48 {
49 if (!PyTuple_Check(op)) {
50 PyErr_BadInternalCall();
51 return NULL;
52 }
53 if (i < 0 || i >= Py_SIZE(op)) {
54 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
55 return NULL;
56 }
57 return ((PyTupleObject *)op) -> ob_item[i];
58 }
59
60 int
61 PyTuple_SetItem(register PyObject *op, register Py_ssize_t i, PyObject *newitem)
62 {
63 register PyObject *olditem;
64 register PyObject **p;
65 if (!PyTuple_Check(op) || op->ob_refcnt != 1) {
66 Py_XDECREF(newitem);
67 PyErr_BadInternalCall();
68 return -1;
69 }
70 if (i < 0 || i >= Py_SIZE(op)) {
71 Py_XDECREF(newitem);
72 PyErr_SetString(PyExc_IndexError,
73 "tuple assignment index out of range");
74 return -1;
75 }
76 p = ((PyTupleObject *)op) -> ob_item + i;
77 olditem = *p;
78 *p = newitem;
79 Py_XDECREF(olditem);
80 return 0;
81 }
82
83 void
84 _PyTuple_MaybeUntrack(PyObject *op)
85 {
86 PyTupleObject *t;
87 Py_ssize_t i, n;
88
89 if (!PyTuple_CheckExact(op) || !_PyObject_GC_IS_TRACKED(op))
90 return;
91 t = (PyTupleObject *) op;
92 n = Py_SIZE(t);
93 for (i = 0; i < n; i++) {
94 PyObject *elt = PyTuple_GET_ITEM(t, i);
95 /* Tuple with NULL elements aren't
96 fully constructed, don't untrack
97 them yet. */
98 if (!elt ||
99 _PyObject_GC_MAY_BE_TRACKED(elt))
100 return;
101 }
102 _PyObject_GC_UNTRACK(op);
103 }
104
105 PyObject *
106 PyTuple_Pack(Py_ssize_t n, ...)
107 {
108 Py_ssize_t i;
109 PyObject *o;
110 PyObject *result;
111 PyObject **items;
112 va_list vargs;
113
114 va_start(vargs, n);
115 result = PyTuple_New(n);
116 if (result == NULL)
117 return NULL;
118 items = ((PyTupleObject *)result)->ob_item;
119 for (i = 0; i < n; i++) {
120 o = va_arg(vargs, PyObject *);
121 Py_INCREF(o);
122 items[i] = o;
123 }
124 va_end(vargs);
125 return result;
126 }
127
128
129 /* Methods */
130
131 static void
132 tupledealloc(register PyTupleObject *op)
133 {
134 register Py_ssize_t i;
135 register Py_ssize_t len = Py_SIZE(op);
136 PyObject_GC_UnTrack(op);
137 Py_TRASHCAN_SAFE_BEGIN(op)
138 if (len > 0) {
139 i = len;
140 while (--i >= 0)
141 Py_XDECREF(op->ob_item[i]);
142 }
143 Py_TYPE(op)->tp_free((PyObject *)op);
144 done:
145 Py_TRASHCAN_SAFE_END(op)
146 }
147
148 static PyObject *
149 tuplerepr(PyTupleObject *v)
150 {
151 Py_ssize_t i, n;
152 PyObject *s = NULL;
153 _PyAccu acc;
154 static PyObject *sep = NULL;
155
156 n = Py_SIZE(v);
157 if (n == 0)
158 return PyUnicode_FromString("()");
159
160 if (sep == NULL) {
161 sep = PyUnicode_FromString(", ");
162 if (sep == NULL)
163 return NULL;
164 }
165
166 /* While not mutable, it is still possible to end up with a cycle in a
167 tuple through an object that stores itself within a tuple (and thus
168 infinitely asks for the repr of itself). This should only be
169 possible within a type. */
170 i = Py_ReprEnter((PyObject *)v);
171 if (i != 0) {
172 return i > 0 ? PyUnicode_FromString("(...)") : NULL;
173 }
174
175 if (_PyAccu_Init(&acc))
176 goto error;
177
178 s = PyUnicode_FromString("(");
179 if (s == NULL || _PyAccu_Accumulate(&acc, s))
180 goto error;
181 Py_CLEAR(s);
182
183 /* Do repr() on each element. */
184 for (i = 0; i < n; ++i) {
185 if (Py_EnterRecursiveCall(" while getting the repr of a tuple"))
186 goto error;
187 s = PyObject_Repr(v->ob_item[i]);
188 Py_LeaveRecursiveCall();
189 if (i > 0 && _PyAccu_Accumulate(&acc, sep))
190 goto error;
191 if (s == NULL || _PyAccu_Accumulate(&acc, s))
192 goto error;
193 Py_CLEAR(s);
194 }
195 if (n > 1)
196 s = PyUnicode_FromString(")");
197 else
198 s = PyUnicode_FromString(",)");
199 if (s == NULL || _PyAccu_Accumulate(&acc, s))
200 goto error;
201 Py_CLEAR(s);
202
203 Py_ReprLeave((PyObject *)v);
204 return _PyAccu_Finish(&acc);
205
206 error:
207 _PyAccu_Destroy(&acc);
208 Py_XDECREF(s);
209 Py_ReprLeave((PyObject *)v);
210 return NULL;
211 }
212
213 /* The addend 82520, was selected from the range(0, 1000000) for
214 generating the greatest number of prime multipliers for tuples
215 upto length eight:
216
217 1082527, 1165049, 1082531, 1165057, 1247581, 1330103, 1082533,
218 1330111, 1412633, 1165069, 1247599, 1495177, 1577699
219 */
220
221 static Py_hash_t
222 tuplehash(PyTupleObject *v)
223 {
224 register Py_uhash_t x;
225 register Py_hash_t y;
226 register Py_ssize_t len = Py_SIZE(v);
227 register PyObject **p;
228 Py_uhash_t mult = 1000003;
229 x = 0x345678;
230 p = v->ob_item;
231 while (--len >= 0) {
232 y = PyObject_Hash(*p++);
233 if (y == -1)
234 return -1;
235 x = (x ^ y) * mult;
236 /* the cast might truncate len; that doesn't change hash stability */
237 mult += (Py_hash_t)(82520L + len + len);
238 }
239 x += 97531L;
240 if (x == (Py_uhash_t)-1)
241 x = -2;
242 return x;
243 }
244
245 static Py_ssize_t
246 tuplelength(PyTupleObject *a)
247 {
248 return Py_SIZE(a);
249 }
250
251 static int
252 tuplecontains(PyTupleObject *a, PyObject *el)
253 {
254 Py_ssize_t i;
255 int cmp;
256
257 for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i)
258 cmp = PyObject_RichCompareBool(el, PyTuple_GET_ITEM(a, i),
259 Py_EQ);
260 return cmp;
261 }
262
263 static PyObject *
264 tupleitem(register PyTupleObject *a, register Py_ssize_t i)
265 {
266 if (i < 0 || i >= Py_SIZE(a)) {
267 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
268 return NULL;
269 }
270 Py_INCREF(a->ob_item[i]);
271 return a->ob_item[i];
272 }
273
274 static PyObject *
275 tupleslice(register PyTupleObject *a, register Py_ssize_t ilow,
276 register Py_ssize_t ihigh)
277 {
278 register PyTupleObject *np;
279 PyObject **src, **dest;
280 register Py_ssize_t i;
281 Py_ssize_t len;
282 if (ilow < 0)
283 ilow = 0;
284 if (ihigh > Py_SIZE(a))
285 ihigh = Py_SIZE(a);
286 if (ihigh < ilow)
287 ihigh = ilow;
288 if (ilow == 0 && ihigh == Py_SIZE(a) && PyTuple_CheckExact(a)) {
289 Py_INCREF(a);
290 return (PyObject *)a;
291 }
292 len = ihigh - ilow;
293 np = (PyTupleObject *)PyTuple_New(len);
294 if (np == NULL)
295 return NULL;
296 src = a->ob_item + ilow;
297 dest = np->ob_item;
298 for (i = 0; i < len; i++) {
299 PyObject *v = src[i];
300 Py_INCREF(v);
301 dest[i] = v;
302 }
303 return (PyObject *)np;
304 }
305
306 PyObject *
307 PyTuple_GetSlice(PyObject *op, Py_ssize_t i, Py_ssize_t j)
308 {
309 if (op == NULL || !PyTuple_Check(op)) {
310 PyErr_BadInternalCall();
311 return NULL;
312 }
313 return tupleslice((PyTupleObject *)op, i, j);
314 }
315
316 static PyObject *
317 tupleconcat(register PyTupleObject *a, register PyObject *bb)
318 {
319 register Py_ssize_t size;
320 register Py_ssize_t i;
321 PyObject **src, **dest;
322 PyTupleObject *np;
323 if (!PyTuple_Check(bb)) {
324 PyErr_Format(PyExc_TypeError,
325 "can only concatenate tuple (not \"%.200s\") to tuple",
326 Py_TYPE(bb)->tp_name);
327 return NULL;
328 }
329 #define b ((PyTupleObject *)bb)
330 size = Py_SIZE(a) + Py_SIZE(b);
331 if (size < 0)
332 return PyErr_NoMemory();
333 np = (PyTupleObject *) PyTuple_New(size);
334 if (np == NULL) {
335 return NULL;
336 }
337 src = a->ob_item;
338 dest = np->ob_item;
339 for (i = 0; i < Py_SIZE(a); i++) {
340 PyObject *v = src[i];
341 Py_INCREF(v);
342 dest[i] = v;
343 }
344 src = b->ob_item;
345 dest = np->ob_item + Py_SIZE(a);
346 for (i = 0; i < Py_SIZE(b); i++) {
347 PyObject *v = src[i];
348 Py_INCREF(v);
349 dest[i] = v;
350 }
351 return (PyObject *)np;
352 #undef b
353 }
354
355 static PyObject *
356 tuplerepeat(PyTupleObject *a, Py_ssize_t n)
357 {
358 Py_ssize_t i, j;
359 Py_ssize_t size;
360 PyTupleObject *np;
361 PyObject **p, **items;
362 if (n < 0)
363 n = 0;
364 if (Py_SIZE(a) == 0 || n == 1) {
365 if (PyTuple_CheckExact(a)) {
366 /* Since tuples are immutable, we can return a shared
367 copy in this case */
368 Py_INCREF(a);
369 return (PyObject *)a;
370 }
371 if (Py_SIZE(a) == 0)
372 return PyTuple_New(0);
373 }
374 size = Py_SIZE(a) * n;
375 if (size/Py_SIZE(a) != n)
376 return PyErr_NoMemory();
377 np = (PyTupleObject *) PyTuple_New(size);
378 if (np == NULL)
379 return NULL;
380 p = np->ob_item;
381 items = a->ob_item;
382 for (i = 0; i < n; i++) {
383 for (j = 0; j < Py_SIZE(a); j++) {
384 *p = items[j];
385 Py_INCREF(*p);
386 p++;
387 }
388 }
389 return (PyObject *) np;
390 }
391
392 static PyObject *
393 tupleindex(PyTupleObject *self, PyObject *args)
394 {
395 Py_ssize_t i, start=0, stop=Py_SIZE(self);
396 PyObject *v;
397
398 if (!PyArg_ParseTuple(args, "O|O&O&:index", &v,
399 _PyEval_SliceIndex, &start,
400 _PyEval_SliceIndex, &stop))
401 return NULL;
402 if (start < 0) {
403 start += Py_SIZE(self);
404 if (start < 0)
405 start = 0;
406 }
407 if (stop < 0) {
408 stop += Py_SIZE(self);
409 if (stop < 0)
410 stop = 0;
411 }
412 for (i = start; i < stop && i < Py_SIZE(self); i++) {
413 int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
414 if (cmp > 0)
415 return PyLong_FromSsize_t(i);
416 else if (cmp < 0)
417 return NULL;
418 }
419 PyErr_SetString(PyExc_ValueError, "tuple.index(x): x not in tuple");
420 return NULL;
421 }
422
423 static PyObject *
424 tuplecount(PyTupleObject *self, PyObject *v)
425 {
426 Py_ssize_t count = 0;
427 Py_ssize_t i;
428
429 for (i = 0; i < Py_SIZE(self); i++) {
430 int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
431 if (cmp > 0)
432 count++;
433 else if (cmp < 0)
434 return NULL;
435 }
436 return PyLong_FromSsize_t(count);
437 }
438
439 static int
440 tupletraverse(PyTupleObject *o, visitproc visit, void *arg)
441 {
442 Py_ssize_t i;
443
444 for (i = Py_SIZE(o); --i >= 0; )
445 Py_VISIT(o->ob_item[i]);
446 return 0;
447 }
448
449 static PyObject *
450 tuplerichcompare(PyObject *v, PyObject *w, int op)
451 {
452 PyTupleObject *vt, *wt;
453 Py_ssize_t i;
454 Py_ssize_t vlen, wlen;
455
456 if (!PyTuple_Check(v) || !PyTuple_Check(w))
457 Py_RETURN_NOTIMPLEMENTED;
458
459 vt = (PyTupleObject *)v;
460 wt = (PyTupleObject *)w;
461
462 vlen = Py_SIZE(vt);
463 wlen = Py_SIZE(wt);
464
465 /* Note: the corresponding code for lists has an "early out" test
466 * here when op is EQ or NE and the lengths differ. That pays there,
467 * but Tim was unable to find any real code where EQ/NE tuple
468 * compares don't have the same length, so testing for it here would
469 * have cost without benefit.
470 */
471
472 /* Search for the first index where items are different.
473 * Note that because tuples are immutable, it's safe to reuse
474 * vlen and wlen across the comparison calls.
475 */
476 for (i = 0; i < vlen && i < wlen; i++) {
477 int k = PyObject_RichCompareBool(vt->ob_item[i],
478 wt->ob_item[i], Py_EQ);
479 if (k < 0)
480 return NULL;
481 if (!k)
482 break;
483 }
484
485 if (i >= vlen || i >= wlen) {
486 /* No more items to compare -- compare sizes */
487 int cmp;
488 PyObject *res;
489 switch (op) {
490 case Py_LT: cmp = vlen < wlen; break;
491 case Py_LE: cmp = vlen <= wlen; break;
492 case Py_EQ: cmp = vlen == wlen; break;
493 case Py_NE: cmp = vlen != wlen; break;
494 case Py_GT: cmp = vlen > wlen; break;
495 case Py_GE: cmp = vlen >= wlen; break;
496 default: return NULL; /* cannot happen */
497 }
498 if (cmp)
499 res = Py_True;
500 else
501 res = Py_False;
502 Py_INCREF(res);
503 return res;
504 }
505
506 /* We have an item that differs -- shortcuts for EQ/NE */
507 if (op == Py_EQ) {
508 Py_INCREF(Py_False);
509 return Py_False;
510 }
511 if (op == Py_NE) {
512 Py_INCREF(Py_True);
513 return Py_True;
514 }
515
516 /* Compare the final item again using the proper operator */
517 return PyObject_RichCompare(vt->ob_item[i], wt->ob_item[i], op);
518 }
519
520 static PyObject *
521 tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
522
523 static PyObject *
524 tuple_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
525 {
526 PyObject *arg = NULL;
527 static char *kwlist[] = {"sequence", 0};
528
529 if (type != &PyTuple_Type)
530 return tuple_subtype_new(type, args, kwds);
531 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:tuple", kwlist, &arg))
532 return NULL;
533
534 if (arg == NULL)
535 return PyTuple_New(0);
536 else
537 return PySequence_Tuple(arg);
538 }
539
540 static PyObject *
541 tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
542 {
543 PyObject *tmp, *newobj, *item;
544 Py_ssize_t i, n;
545
546 assert(PyType_IsSubtype(type, &PyTuple_Type));
547 tmp = tuple_new(&PyTuple_Type, args, kwds);
548 if (tmp == NULL)
549 return NULL;
550 assert(PyTuple_Check(tmp));
551 newobj = type->tp_alloc(type, n = PyTuple_GET_SIZE(tmp));
552 if (newobj == NULL)
553 return NULL;
554 for (i = 0; i < n; i++) {
555 item = PyTuple_GET_ITEM(tmp, i);
556 Py_INCREF(item);
557 PyTuple_SET_ITEM(newobj, i, item);
558 }
559 Py_DECREF(tmp);
560 return newobj;
561 }
562
563 PyDoc_STRVAR(tuple_doc,
564 "tuple() -> empty tuple\n\
565 tuple(iterable) -> tuple initialized from iterable's items\n\
566 \n\
567 If the argument is a tuple, the return value is the same object.");
568
569 static PySequenceMethods tuple_as_sequence = {
570 (lenfunc)tuplelength, /* sq_length */
571 (binaryfunc)tupleconcat, /* sq_concat */
572 (ssizeargfunc)tuplerepeat, /* sq_repeat */
573 (ssizeargfunc)tupleitem, /* sq_item */
574 0, /* sq_slice */
575 0, /* sq_ass_item */
576 0, /* sq_ass_slice */
577 (objobjproc)tuplecontains, /* sq_contains */
578 };
579
580 static PyObject*
581 tuplesubscript(PyTupleObject* self, PyObject* item)
582 {
583 if (PyIndex_Check(item)) {
584 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
585 if (i == -1 && PyErr_Occurred())
586 return NULL;
587 if (i < 0)
588 i += PyTuple_GET_SIZE(self);
589 return tupleitem(self, i);
590 }
591 else if (PySlice_Check(item)) {
592 Py_ssize_t start, stop, step, slicelength, cur, i;
593 PyObject* result;
594 PyObject* it;
595 PyObject **src, **dest;
596
597 if (PySlice_GetIndicesEx(item,
598 PyTuple_GET_SIZE(self),
599 &start, &stop, &step, &slicelength) < 0) {
600 return NULL;
601 }
602
603 if (slicelength <= 0) {
604 return PyTuple_New(0);
605 }
606 else if (start == 0 && step == 1 &&
607 slicelength == PyTuple_GET_SIZE(self) &&
608 PyTuple_CheckExact(self)) {
609 Py_INCREF(self);
610 return (PyObject *)self;
611 }
612 else {
613 result = PyTuple_New(slicelength);
614 if (!result) return NULL;
615
616 src = self->ob_item;
617 dest = ((PyTupleObject *)result)->ob_item;
618 for (cur = start, i = 0; i < slicelength;
619 cur += step, i++) {
620 it = src[cur];
621 Py_INCREF(it);
622 dest[i] = it;
623 }
624
625 return result;
626 }
627 }
628 else {
629 PyErr_Format(PyExc_TypeError,
630 "tuple indices must be integers, not %.200s",
631 Py_TYPE(item)->tp_name);
632 return NULL;
633 }
634 }
635
636 static PyObject *
637 tuple_getnewargs(PyTupleObject *v)
638 {
639 return Py_BuildValue("(N)", tupleslice(v, 0, Py_SIZE(v)));
640
641 }
642
643 static PyObject *
644 tuple_sizeof(PyTupleObject *self)
645 {
646 Py_ssize_t res;
647
648 res = PyTuple_Type.tp_basicsize + Py_SIZE(self) * sizeof(PyObject *);
649 return PyLong_FromSsize_t(res);
650 }
651
652 PyDoc_STRVAR(index_doc,
653 "T.index(value, [start, [stop]]) -> integer -- return first index of value.\n"
654 "Raises ValueError if the value is not present."
655 );
656 PyDoc_STRVAR(count_doc,
657 "T.count(value) -> integer -- return number of occurrences of value");
658 PyDoc_STRVAR(sizeof_doc,
659 "T.__sizeof__() -- size of T in memory, in bytes");
660
661 static PyMethodDef tuple_methods[] = {
662 {"__getnewargs__", (PyCFunction)tuple_getnewargs, METH_NOARGS},
663 {"__sizeof__", (PyCFunction)tuple_sizeof, METH_NOARGS, sizeof_doc},
664 {"index", (PyCFunction)tupleindex, METH_VARARGS, index_doc},
665 {"count", (PyCFunction)tuplecount, METH_O, count_doc},
666 {NULL, NULL} /* sentinel */
667 };
668
669 static PyMappingMethods tuple_as_mapping = {
670 (lenfunc)tuplelength,
671 (binaryfunc)tuplesubscript,
672 0
673 };
674
675 static PyObject *tuple_iter(PyObject *seq);
676
677 PyTypeObject PyTuple_Type = {
678 PyVarObject_HEAD_INIT(&PyType_Type, 0)
679 "tuple",
680 sizeof(PyTupleObject) - sizeof(PyObject *),
681 sizeof(PyObject *),
682 (destructor)tupledealloc, /* tp_dealloc */
683 0, /* tp_print */
684 0, /* tp_getattr */
685 0, /* tp_setattr */
686 0, /* tp_reserved */
687 (reprfunc)tuplerepr, /* tp_repr */
688 0, /* tp_as_number */
689 &tuple_as_sequence, /* tp_as_sequence */
690 &tuple_as_mapping, /* tp_as_mapping */
691 (hashfunc)tuplehash, /* tp_hash */
692 0, /* tp_call */
693 0, /* tp_str */
694 PyObject_GenericGetAttr, /* tp_getattro */
695 0, /* tp_setattro */
696 0, /* tp_as_buffer */
697 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
698 Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TUPLE_SUBCLASS, /* tp_flags */
699 tuple_doc, /* tp_doc */
700 (traverseproc)tupletraverse, /* tp_traverse */
701 0, /* tp_clear */
702 tuplerichcompare, /* tp_richcompare */
703 0, /* tp_weaklistoffset */
704 tuple_iter, /* tp_iter */
705 0, /* tp_iternext */
706 tuple_methods, /* tp_methods */
707 0, /* tp_members */
708 0, /* tp_getset */
709 0, /* tp_base */
710 0, /* tp_dict */
711 0, /* tp_descr_get */
712 0, /* tp_descr_set */
713 0, /* tp_dictoffset */
714 0, /* tp_init */
715 0, /* tp_alloc */
716 tuple_new, /* tp_new */
717 PyObject_GC_Del, /* tp_free */
718 };
719
720 /* The following function breaks the notion that tuples are immutable:
721 it changes the size of a tuple. We get away with this only if there
722 is only one module referencing the object. You can also think of it
723 as creating a new tuple object and destroying the old one, only more
724 efficiently. In any case, don't use this if the tuple may already be
725 known to some other part of the code. */
726
727 int
728 _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize)
729 {
730 register PyTupleObject *v;
731 register PyTupleObject *sv;
732 Py_ssize_t i;
733 Py_ssize_t oldsize;
734
735 v = (PyTupleObject *) *pv;
736 if (v == NULL || Py_TYPE(v) != &PyTuple_Type ||
737 (Py_SIZE(v) != 0 && Py_REFCNT(v) != 1)) {
738 *pv = 0;
739 Py_XDECREF(v);
740 PyErr_BadInternalCall();
741 return -1;
742 }
743 oldsize = Py_SIZE(v);
744 if (oldsize == newsize)
745 return 0;
746
747 if (oldsize == 0) {
748 /* Empty tuples are often shared, so we should never
749 resize them in-place even if we do own the only
750 (current) reference */
751 Py_DECREF(v);
752 *pv = PyTuple_New(newsize);
753 return *pv == NULL ? -1 : 0;
754 }
755
756 /* XXX UNREF/NEWREF interface should be more symmetrical */
757 _Py_DEC_REFTOTAL;
758 if (_PyObject_GC_IS_TRACKED(v))
759 _PyObject_GC_UNTRACK(v);
760 _Py_ForgetReference((PyObject *) v);
761 /* DECREF items deleted by shrinkage */
762 for (i = newsize; i < oldsize; i++) {
763 Py_XDECREF(v->ob_item[i]);
764 v->ob_item[i] = NULL;
765 }
766 sv = PyObject_GC_Resize(PyTupleObject, v, newsize);
767 if (sv == NULL) {
768 *pv = NULL;
769 PyObject_GC_Del(v);
770 return -1;
771 }
772 _Py_NewReference((PyObject *) sv);
773 /* Zero out items added by growing */
774 if (newsize > oldsize)
775 memset(&sv->ob_item[oldsize], 0,
776 sizeof(*sv->ob_item) * (newsize - oldsize));
777 *pv = (PyObject *) sv;
778 _PyObject_GC_TRACK(sv);
779 return 0;
780 }
781
782 int
783 PyTuple_ClearFreeList(void)
784 {
785 int freelist_size = 0;
786 return freelist_size;
787 }
788
789 void
790 PyTuple_Fini(void)
791 {
792 }
793
794 /*********************** Tuple Iterator **************************/
795
796 typedef struct {
797 PyObject_HEAD
798 long it_index;
799 PyTupleObject *it_seq; /* Set to NULL when iterator is exhausted */
800 } tupleiterobject;
801
802 static void
803 tupleiter_dealloc(tupleiterobject *it)
804 {
805 _PyObject_GC_UNTRACK(it);
806 Py_XDECREF(it->it_seq);
807 PyObject_GC_Del(it);
808 }
809
810 static int
811 tupleiter_traverse(tupleiterobject *it, visitproc visit, void *arg)
812 {
813 Py_VISIT(it->it_seq);
814 return 0;
815 }
816
817 static PyObject *
818 tupleiter_next(tupleiterobject *it)
819 {
820 PyTupleObject *seq;
821 PyObject *item;
822
823 assert(it != NULL);
824 seq = it->it_seq;
825 if (seq == NULL)
826 return NULL;
827 assert(PyTuple_Check(seq));
828
829 if (it->it_index < PyTuple_GET_SIZE(seq)) {
830 item = PyTuple_GET_ITEM(seq, it->it_index);
831 ++it->it_index;
832 Py_INCREF(item);
833 return item;
834 }
835
836 Py_DECREF(seq);
837 it->it_seq = NULL;
838 return NULL;
839 }
840
841 static PyObject *
842 tupleiter_len(tupleiterobject *it)
843 {
844 Py_ssize_t len = 0;
845 if (it->it_seq)
846 len = PyTuple_GET_SIZE(it->it_seq) - it->it_index;
847 return PyLong_FromSsize_t(len);
848 }
849
850 PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
851
852 static PyMethodDef tupleiter_methods[] = {
853 {"__length_hint__", (PyCFunction)tupleiter_len, METH_NOARGS, length_hint_doc},
854 {NULL, NULL} /* sentinel */
855 };
856
857 PyTypeObject PyTupleIter_Type = {
858 PyVarObject_HEAD_INIT(&PyType_Type, 0)
859 "tuple_iterator", /* tp_name */
860 sizeof(tupleiterobject), /* tp_basicsize */
861 0, /* tp_itemsize */
862 /* methods */
863 (destructor)tupleiter_dealloc, /* tp_dealloc */
864 0, /* tp_print */
865 0, /* tp_getattr */
866 0, /* tp_setattr */
867 0, /* tp_reserved */
868 0, /* tp_repr */
869 0, /* tp_as_number */
870 0, /* tp_as_sequence */
871 0, /* tp_as_mapping */
872 0, /* tp_hash */
873 0, /* tp_call */
874 0, /* tp_str */
875 PyObject_GenericGetAttr, /* tp_getattro */
876 0, /* tp_setattro */
877 0, /* tp_as_buffer */
878 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
879 0, /* tp_doc */
880 (traverseproc)tupleiter_traverse, /* tp_traverse */
881 0, /* tp_clear */
882 0, /* tp_richcompare */
883 0, /* tp_weaklistoffset */
884 PyObject_SelfIter, /* tp_iter */
885 (iternextfunc)tupleiter_next, /* tp_iternext */
886 tupleiter_methods, /* tp_methods */
887 0,
888 };
889
890 static PyObject *
891 tuple_iter(PyObject *seq)
892 {
893 tupleiterobject *it;
894
895 if (!PyTuple_Check(seq)) {
896 PyErr_BadInternalCall();
897 return NULL;
898 }
899 it = PyObject_GC_New(tupleiterobject, &PyTupleIter_Type);
900 if (it == NULL)
901 return NULL;
902 it->it_index = 0;
903 Py_INCREF(seq);
904 it->it_seq = (PyTupleObject *)seq;
905 _PyObject_GC_TRACK(it);
906 return (PyObject *)it;
907 }