1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* Tuple object implementation */
37 #define MAXSAVESIZE 20
41 /* Entries 1 upto MAXSAVESIZE are free lists, entry 0 is the empty
42 tuple () of which at most one instance will be allocated.
44 static PyTupleObject
*free_tuples
[MAXSAVESIZE
];
47 int fast_tuple_allocs
;
48 int tuple_zero_allocs
;
56 register PyTupleObject
*op
;
58 PyErr_BadInternalCall();
62 if (size
== 0 && free_tuples
[0]) {
68 return (PyObject
*) op
;
70 if (0 < size
&& size
< MAXSAVESIZE
&&
71 (op
= free_tuples
[size
]) != NULL
)
73 free_tuples
[size
] = (PyTupleObject
*) op
->ob_item
[0];
78 op
->ob_type
= &PyTuple_Type
;
85 op
= (PyTupleObject
*) malloc(
86 sizeof(PyTupleObject
) + (size
-1) * sizeof(PyObject
*));
88 return PyErr_NoMemory();
90 op
->ob_type
= &PyTuple_Type
;
93 for (i
= 0; i
< size
; i
++)
94 op
->ob_item
[i
] = NULL
;
99 Py_INCREF(op
); /* extra INCREF so that this is never freed */
102 return (PyObject
*) op
;
107 register PyObject
*op
;
109 if (!PyTuple_Check(op
)) {
110 PyErr_BadInternalCall();
114 return ((PyTupleObject
*)op
)->ob_size
;
118 PyTuple_GetItem(op
, i
)
119 register PyObject
*op
;
122 if (!PyTuple_Check(op
)) {
123 PyErr_BadInternalCall();
126 if (i
< 0 || i
>= ((PyTupleObject
*)op
) -> ob_size
) {
127 PyErr_SetString(PyExc_IndexError
, "tuple index out of range");
130 return ((PyTupleObject
*)op
) -> ob_item
[i
];
134 PyTuple_SetItem(op
, i
, newitem
)
135 register PyObject
*op
;
139 register PyObject
*olditem
;
140 register PyObject
**p
;
141 if (!PyTuple_Check(op
) || op
->ob_refcnt
!= 1) {
143 PyErr_BadInternalCall();
146 if (i
< 0 || i
>= ((PyTupleObject
*)op
) -> ob_size
) {
148 PyErr_SetString(PyExc_IndexError
,
149 "tuple assignment index out of range");
152 p
= ((PyTupleObject
*)op
) -> ob_item
+ i
;
163 register PyTupleObject
*op
;
167 if (op
->ob_size
> 0) {
170 Py_XDECREF(op
->ob_item
[i
]);
172 if (op
->ob_size
< MAXSAVESIZE
) {
173 op
->ob_item
[0] = (PyObject
*) free_tuples
[op
->ob_size
];
174 free_tuples
[op
->ob_size
] = op
;
183 tupleprint(op
, fp
, flags
)
190 for (i
= 0; i
< op
->ob_size
; i
++) {
193 if (PyObject_Print(op
->ob_item
[i
], fp
, 0) != 0)
196 if (op
->ob_size
== 1)
208 s
= PyString_FromString("(");
209 comma
= PyString_FromString(", ");
210 for (i
= 0; i
< v
->ob_size
&& s
!= NULL
; i
++) {
212 PyString_Concat(&s
, comma
);
213 PyString_ConcatAndDel(&s
, PyObject_Repr(v
->ob_item
[i
]));
217 PyString_ConcatAndDel(&s
, PyString_FromString(","));
218 PyString_ConcatAndDel(&s
, PyString_FromString(")"));
224 register PyTupleObject
*v
, *w
;
227 (v
->ob_size
< w
->ob_size
) ? v
->ob_size
: w
->ob_size
;
229 for (i
= 0; i
< len
; i
++) {
230 int cmp
= PyObject_Compare(v
->ob_item
[i
], w
->ob_item
[i
]);
234 return v
->ob_size
- w
->ob_size
;
242 register int len
= v
->ob_size
;
243 register PyObject
**p
;
247 y
= PyObject_Hash(*p
++);
267 register PyTupleObject
*a
;
270 if (i
< 0 || i
>= a
->ob_size
) {
271 PyErr_SetString(PyExc_IndexError
, "tuple index out of range");
274 Py_INCREF(a
->ob_item
[i
]);
275 return a
->ob_item
[i
];
279 tupleslice(a
, ilow
, ihigh
)
280 register PyTupleObject
*a
;
281 register int ilow
, ihigh
;
283 register PyTupleObject
*np
;
287 if (ihigh
> a
->ob_size
)
291 if (ilow
== 0 && ihigh
== a
->ob_size
) {
292 /* XXX can only do this if tuples are immutable! */
294 return (PyObject
*)a
;
296 np
= (PyTupleObject
*)PyTuple_New(ihigh
- ilow
);
299 for (i
= ilow
; i
< ihigh
; i
++) {
300 PyObject
*v
= a
->ob_item
[i
];
302 np
->ob_item
[i
- ilow
] = v
;
304 return (PyObject
*)np
;
308 PyTuple_GetSlice(op
, i
, j
)
312 if (op
== NULL
|| !PyTuple_Check(op
)) {
313 PyErr_BadInternalCall();
316 return tupleslice((PyTupleObject
*)op
, i
, j
);
321 register PyTupleObject
*a
;
322 register PyObject
*bb
;
327 if (!PyTuple_Check(bb
)) {
331 #define b ((PyTupleObject *)bb)
332 size
= a
->ob_size
+ b
->ob_size
;
333 np
= (PyTupleObject
*) PyTuple_New(size
);
337 for (i
= 0; i
< a
->ob_size
; i
++) {
338 PyObject
*v
= a
->ob_item
[i
];
342 for (i
= 0; i
< b
->ob_size
; i
++) {
343 PyObject
*v
= b
->ob_item
[i
];
345 np
->ob_item
[i
+ a
->ob_size
] = v
;
347 return (PyObject
*)np
;
362 if (a
->ob_size
*n
== a
->ob_size
) {
363 /* Since tuples are immutable, we can return a shared
366 return (PyObject
*)a
;
368 size
= a
->ob_size
* n
;
369 np
= (PyTupleObject
*) PyTuple_New(size
);
373 for (i
= 0; i
< n
; i
++) {
374 for (j
= 0; j
< a
->ob_size
; j
++) {
380 return (PyObject
*) np
;
383 static PySequenceMethods tuple_as_sequence
= {
384 (inquiry
)tuplelength
, /*sq_length*/
385 (binaryfunc
)tupleconcat
, /*sq_concat*/
386 (intargfunc
)tuplerepeat
, /*sq_repeat*/
387 (intargfunc
)tupleitem
, /*sq_item*/
388 (intintargfunc
)tupleslice
, /*sq_slice*/
393 PyTypeObject PyTuple_Type
= {
394 PyObject_HEAD_INIT(&PyType_Type
)
397 sizeof(PyTupleObject
) - sizeof(PyObject
*),
399 (destructor
)tupledealloc
, /*tp_dealloc*/
400 (printfunc
)tupleprint
, /*tp_print*/
403 (cmpfunc
)tuplecompare
, /*tp_compare*/
404 (reprfunc
)tuplerepr
, /*tp_repr*/
406 &tuple_as_sequence
, /*tp_as_sequence*/
408 (hashfunc
)tuplehash
, /*tp_hash*/
411 /* The following function breaks the notion that tuples are immutable:
412 it changes the size of a tuple. We get away with this only if there
413 is only one module referencing the object. You can also think of it
414 as creating a new tuple object and destroying the old one, only
415 more efficiently. In any case, don't use this if the tuple may
416 already be known to some other part of the code...
417 If last_is_sticky is set, the tuple will grow or shrink at the
418 front, otherwise it will grow or shrink at the end. */
421 _PyTuple_Resize(pv
, newsize
, last_is_sticky
)
426 register PyTupleObject
*v
;
427 register PyTupleObject
*sv
;
431 v
= (PyTupleObject
*) *pv
;
432 if (v
== NULL
|| !PyTuple_Check(v
) || v
->ob_refcnt
!= 1) {
435 PyErr_BadInternalCall();
438 sizediff
= newsize
- v
->ob_size
;
441 /* XXX UNREF/NEWREF interface should be more symmetrical */
445 _Py_ForgetReference(v
);
446 if (last_is_sticky
&& sizediff
< 0) {
448 move entries to the front and zero moved entries */
449 for (i
= 0; i
< newsize
; i
++) {
450 Py_XDECREF(v
->ob_item
[i
]);
451 v
->ob_item
[i
] = v
->ob_item
[i
- sizediff
];
452 v
->ob_item
[i
- sizediff
] = NULL
;
455 for (i
= newsize
; i
< v
->ob_size
; i
++) {
456 Py_XDECREF(v
->ob_item
[i
]);
457 v
->ob_item
[i
] = NULL
;
459 sv
= (PyTupleObject
*)
461 sizeof(PyTupleObject
) + newsize
* sizeof(PyObject
*));
462 *pv
= (PyObject
*) sv
;
468 _Py_NewReference(sv
);
469 for (i
= sv
->ob_size
; i
< newsize
; i
++)
470 sv
->ob_item
[i
] = NULL
;
471 if (last_is_sticky
&& sizediff
> 0) {
472 /* growing: move entries to the end and zero moved entries */
473 for (i
= newsize
- 1; i
>= sizediff
; i
--) {
474 sv
->ob_item
[i
] = sv
->ob_item
[i
- sizediff
];
475 sv
->ob_item
[i
- sizediff
] = NULL
;
478 sv
->ob_size
= newsize
;
488 Py_XDECREF(free_tuples
[0]);
489 free_tuples
[0] = NULL
;
491 for (i
= 1; i
< MAXSAVESIZE
; i
++) {
492 PyTupleObject
*p
, *q
;
494 free_tuples
[i
] = NULL
;
497 p
= (PyTupleObject
*)(p
->ob_item
[0]);