blob: 7fae2647b0dcac44e0e0c0591d6067d5bfe0fd04 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum6610ad91995-01-04 19:07:38 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* Tuple object implementation */
26
Guido van Rossum3f5da241990-12-20 15:06:42 +000027#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028
Sjoerd Mullender842d2cc1993-10-15 16:18:48 +000029#ifndef MAXSAVESIZE
30#define MAXSAVESIZE 20
31#endif
32
33#if MAXSAVESIZE > 0
34/* Entries 1 upto MAXSAVESIZE are free lists, entry 0 is the empty
35 tuple () of which at most one instance will be allocated.
36*/
Sjoerd Mullender615194a1993-11-01 13:46:50 +000037static tupleobject *free_tuples[MAXSAVESIZE];
Sjoerd Mullender842d2cc1993-10-15 16:18:48 +000038#endif
39#ifdef COUNT_ALLOCS
40int fast_tuple_allocs;
41int tuple_zero_allocs;
42#endif
43
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000044object *
45newtupleobject(size)
46 register int size;
47{
48 register int i;
49 register tupleobject *op;
50 if (size < 0) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000051 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000052 return NULL;
53 }
Sjoerd Mullender842d2cc1993-10-15 16:18:48 +000054#if MAXSAVESIZE > 0
Sjoerd Mullender615194a1993-11-01 13:46:50 +000055 if (size == 0 && free_tuples[0]) {
56 op = free_tuples[0];
Sjoerd Mullender842d2cc1993-10-15 16:18:48 +000057 INCREF(op);
58#ifdef COUNT_ALLOCS
59 tuple_zero_allocs++;
60#endif
61 return (object *) op;
62 }
Sjoerd Mullender615194a1993-11-01 13:46:50 +000063 if (0 < size && size < MAXSAVESIZE && (op = free_tuples[size]) != NULL) {
64 free_tuples[size] = (tupleobject *) op->ob_item[0];
Sjoerd Mullender842d2cc1993-10-15 16:18:48 +000065#ifdef COUNT_ALLOCS
66 fast_tuple_allocs++;
67#endif
68 } else
69#endif
70 {
71 op = (tupleobject *)
72 malloc(sizeof(tupleobject) + size * sizeof(object *));
73 if (op == NULL)
74 return err_nomem();
75 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000076 op->ob_type = &Tupletype;
77 op->ob_size = size;
78 for (i = 0; i < size; i++)
79 op->ob_item[i] = NULL;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000080 NEWREF(op);
Sjoerd Mullender842d2cc1993-10-15 16:18:48 +000081#if MAXSAVESIZE > 0
82 if (size == 0) {
Sjoerd Mullender615194a1993-11-01 13:46:50 +000083 free_tuples[0] = op;
Sjoerd Mullender842d2cc1993-10-15 16:18:48 +000084 INCREF(op); /* extra INCREF so that this is never freed */
85 }
86#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000087 return (object *) op;
88}
89
90int
91gettuplesize(op)
92 register object *op;
93{
94 if (!is_tupleobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000095 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000096 return -1;
97 }
98 else
99 return ((tupleobject *)op)->ob_size;
100}
101
102object *
103gettupleitem(op, i)
104 register object *op;
105 register int i;
106{
107 if (!is_tupleobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000108 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000109 return NULL;
110 }
111 if (i < 0 || i >= ((tupleobject *)op) -> ob_size) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000112 err_setstr(IndexError, "tuple index out of range");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000113 return NULL;
114 }
115 return ((tupleobject *)op) -> ob_item[i];
116}
117
118int
119settupleitem(op, i, newitem)
120 register object *op;
121 register int i;
Guido van Rossum5fe60581995-03-09 12:12:50 +0000122 object *newitem;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000123{
124 register object *olditem;
Guido van Rossum5fe60581995-03-09 12:12:50 +0000125 register object **p;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000126 if (!is_tupleobject(op)) {
Guido van Rossum12d12c51993-10-26 17:58:25 +0000127 XDECREF(newitem);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000128 err_badcall();
129 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000130 }
131 if (i < 0 || i >= ((tupleobject *)op) -> ob_size) {
Guido van Rossum12d12c51993-10-26 17:58:25 +0000132 XDECREF(newitem);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000133 err_setstr(IndexError, "tuple assignment index out of range");
134 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000135 }
Guido van Rossum5fe60581995-03-09 12:12:50 +0000136 p = ((tupleobject *)op) -> ob_item + i;
137 olditem = *p;
138 *p = newitem;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000139 XDECREF(olditem);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000140 return 0;
141}
142
143/* Methods */
144
145static void
146tupledealloc(op)
147 register tupleobject *op;
148{
149 register int i;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000150 for (i = 0; i < op->ob_size; i++)
151 XDECREF(op->ob_item[i]);
Sjoerd Mullender842d2cc1993-10-15 16:18:48 +0000152#if MAXSAVESIZE > 0
153 if (0 < op->ob_size && op->ob_size < MAXSAVESIZE) {
Sjoerd Mullender615194a1993-11-01 13:46:50 +0000154 op->ob_item[0] = (object *) free_tuples[op->ob_size];
155 free_tuples[op->ob_size] = op;
Sjoerd Mullender842d2cc1993-10-15 16:18:48 +0000156 } else
157#endif
158 free((ANY *)op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000159}
160
Guido van Rossum49e85141991-06-07 22:59:30 +0000161static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000162tupleprint(op, fp, flags)
163 tupleobject *op;
164 FILE *fp;
165 int flags;
166{
167 int i;
168 fprintf(fp, "(");
Guido van Rossum49e85141991-06-07 22:59:30 +0000169 for (i = 0; i < op->ob_size; i++) {
170 if (i > 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000171 fprintf(fp, ", ");
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000172 if (printobject(op->ob_item[i], fp, 0) != 0)
Guido van Rossum49e85141991-06-07 22:59:30 +0000173 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000174 }
175 if (op->ob_size == 1)
176 fprintf(fp, ",");
177 fprintf(fp, ")");
Guido van Rossum49e85141991-06-07 22:59:30 +0000178 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000179}
180
Guido van Rossum234f9421993-06-17 12:35:49 +0000181static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000182tuplerepr(v)
183 tupleobject *v;
184{
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000185 object *s, *comma;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000186 int i;
187 s = newstringobject("(");
188 comma = newstringobject(", ");
189 for (i = 0; i < v->ob_size && s != NULL; i++) {
190 if (i > 0)
191 joinstring(&s, comma);
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000192 joinstring_decref(&s, reprobject(v->ob_item[i]));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000193 }
194 DECREF(comma);
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000195 if (v->ob_size == 1)
196 joinstring_decref(&s, newstringobject(","));
197 joinstring_decref(&s, newstringobject(")"));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000198 return s;
199}
200
201static int
202tuplecompare(v, w)
203 register tupleobject *v, *w;
204{
205 register int len =
206 (v->ob_size < w->ob_size) ? v->ob_size : w->ob_size;
207 register int i;
208 for (i = 0; i < len; i++) {
209 int cmp = cmpobject(v->ob_item[i], w->ob_item[i]);
210 if (cmp != 0)
211 return cmp;
212 }
213 return v->ob_size - w->ob_size;
214}
215
Guido van Rossum9bfef441993-03-29 10:43:31 +0000216static long
217tuplehash(v)
218 tupleobject *v;
219{
220 register long x, y;
221 register int len = v->ob_size;
222 register object **p;
223 x = 0x345678L;
224 p = v->ob_item;
225 while (--len >= 0) {
226 y = hashobject(*p++);
227 if (y == -1)
228 return -1;
229 x = (x + x + x) ^ y;
230 }
231 x ^= v->ob_size;
232 if (x == -1)
233 x = -2;
234 return x;
235}
236
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237static int
238tuplelength(a)
239 tupleobject *a;
240{
241 return a->ob_size;
242}
243
244static object *
245tupleitem(a, i)
246 register tupleobject *a;
247 register int i;
248{
249 if (i < 0 || i >= a->ob_size) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000250 err_setstr(IndexError, "tuple index out of range");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000251 return NULL;
252 }
253 INCREF(a->ob_item[i]);
254 return a->ob_item[i];
255}
256
257static object *
258tupleslice(a, ilow, ihigh)
259 register tupleobject *a;
260 register int ilow, ihigh;
261{
262 register tupleobject *np;
263 register int i;
264 if (ilow < 0)
265 ilow = 0;
266 if (ihigh > a->ob_size)
267 ihigh = a->ob_size;
268 if (ihigh < ilow)
269 ihigh = ilow;
270 if (ilow == 0 && ihigh == a->ob_size) {
271 /* XXX can only do this if tuples are immutable! */
272 INCREF(a);
273 return (object *)a;
274 }
275 np = (tupleobject *)newtupleobject(ihigh - ilow);
276 if (np == NULL)
277 return NULL;
278 for (i = ilow; i < ihigh; i++) {
279 object *v = a->ob_item[i];
280 INCREF(v);
281 np->ob_item[i - ilow] = v;
282 }
283 return (object *)np;
284}
285
Guido van Rossum7c36ad71992-01-14 18:45:33 +0000286object *
287gettupleslice(op, i, j)
288 object *op;
289 int i, j;
290{
291 if (op == NULL || !is_tupleobject(op)) {
292 err_badcall();
293 return NULL;
294 }
295 return tupleslice((tupleobject *)op, i, j);
296}
297
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000298static object *
299tupleconcat(a, bb)
300 register tupleobject *a;
301 register object *bb;
302{
303 register int size;
304 register int i;
305 tupleobject *np;
306 if (!is_tupleobject(bb)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000307 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000308 return NULL;
309 }
310#define b ((tupleobject *)bb)
311 size = a->ob_size + b->ob_size;
312 np = (tupleobject *) newtupleobject(size);
313 if (np == NULL) {
Guido van Rossum49e85141991-06-07 22:59:30 +0000314 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000315 }
316 for (i = 0; i < a->ob_size; i++) {
317 object *v = a->ob_item[i];
318 INCREF(v);
319 np->ob_item[i] = v;
320 }
321 for (i = 0; i < b->ob_size; i++) {
322 object *v = b->ob_item[i];
323 INCREF(v);
324 np->ob_item[i + a->ob_size] = v;
325 }
326 return (object *)np;
327#undef b
328}
329
Guido van Rossumb8393da1991-06-04 19:35:24 +0000330static object *
331tuplerepeat(a, n)
332 tupleobject *a;
333 int n;
334{
335 int i, j;
336 int size;
337 tupleobject *np;
338 object **p;
339 if (n < 0)
340 n = 0;
341 if (a->ob_size*n == a->ob_size) {
342 /* Since tuples are immutable, we can return a shared
343 copy in this case */
344 INCREF(a);
345 return (object *)a;
346 }
347 size = a->ob_size * n;
348 np = (tupleobject *) newtupleobject(size);
349 if (np == NULL)
350 return NULL;
351 p = np->ob_item;
352 for (i = 0; i < n; i++) {
353 for (j = 0; j < a->ob_size; j++) {
354 *p = a->ob_item[j];
355 INCREF(*p);
356 p++;
357 }
358 }
359 return (object *) np;
360}
361
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000362static sequence_methods tuple_as_sequence = {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000363 (inquiry)tuplelength, /*sq_length*/
364 (binaryfunc)tupleconcat, /*sq_concat*/
365 (intargfunc)tuplerepeat, /*sq_repeat*/
366 (intargfunc)tupleitem, /*sq_item*/
367 (intintargfunc)tupleslice, /*sq_slice*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000368 0, /*sq_ass_item*/
369 0, /*sq_ass_slice*/
370};
371
372typeobject Tupletype = {
373 OB_HEAD_INIT(&Typetype)
374 0,
375 "tuple",
376 sizeof(tupleobject) - sizeof(object *),
377 sizeof(object *),
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000378 (destructor)tupledealloc, /*tp_dealloc*/
379 (printfunc)tupleprint, /*tp_print*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000380 0, /*tp_getattr*/
381 0, /*tp_setattr*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000382 (cmpfunc)tuplecompare, /*tp_compare*/
383 (reprfunc)tuplerepr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000384 0, /*tp_as_number*/
385 &tuple_as_sequence, /*tp_as_sequence*/
386 0, /*tp_as_mapping*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000387 (hashfunc)tuplehash, /*tp_hash*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000388};
Guido van Rossum12d12c51993-10-26 17:58:25 +0000389
390/* The following function breaks the notion that tuples are immutable:
391 it changes the size of a tuple. We get away with this only if there
392 is only one module referencing the object. You can also think of it
393 as creating a new tuple object and destroying the old one, only
394 more efficiently. In any case, don't use this if the tuple may
Sjoerd Mullender615194a1993-11-01 13:46:50 +0000395 already be known to some other part of the code...
396 If last_is_sticky is set, the tuple will grow or shrink at the
397 front, otherwise it will grow or shrink at the end. */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000398
399int
Sjoerd Mullender615194a1993-11-01 13:46:50 +0000400resizetuple(pv, newsize, last_is_sticky)
Guido van Rossum12d12c51993-10-26 17:58:25 +0000401 object **pv;
402 int newsize;
Sjoerd Mullender615194a1993-11-01 13:46:50 +0000403 int last_is_sticky;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000404{
Sjoerd Mullender615194a1993-11-01 13:46:50 +0000405 register tupleobject *v;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000406 register tupleobject *sv;
Sjoerd Mullender615194a1993-11-01 13:46:50 +0000407 int i;
408 int sizediff;
409
410 v = (tupleobject *) *pv;
411 sizediff = newsize - v->ob_size;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000412 if (!is_tupleobject(v) || v->ob_refcnt != 1) {
413 *pv = 0;
414 DECREF(v);
415 err_badcall();
416 return -1;
417 }
Sjoerd Mullender615194a1993-11-01 13:46:50 +0000418 if (sizediff == 0)
419 return 0;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000420 /* XXX UNREF/NEWREF interface should be more symmetrical */
421#ifdef REF_DEBUG
Guido van Rossum6f9e4331995-03-29 16:57:48 +0000422 --_Py_RefTotal;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000423#endif
424 UNREF(v);
Sjoerd Mullender615194a1993-11-01 13:46:50 +0000425 if (last_is_sticky && sizediff < 0) {
426 /* shrinking: move entries to the front and zero moved entries */
427 for (i = 0; i < newsize; i++) {
428 XDECREF(v->ob_item[i]);
429 v->ob_item[i] = v->ob_item[i - sizediff];
430 v->ob_item[i - sizediff] = NULL;
431 }
432 }
433 for (i = newsize; i < v->ob_size; i++) {
434 XDECREF(v->ob_item[i]);
435 v->ob_item[i] = NULL;
436 }
437 sv = (tupleobject *)
Guido van Rossum12d12c51993-10-26 17:58:25 +0000438 realloc((char *)v,
439 sizeof(tupleobject) + newsize * sizeof(object *));
Sjoerd Mullender615194a1993-11-01 13:46:50 +0000440 *pv = (object *) sv;
441 if (sv == NULL) {
Guido van Rossum12d12c51993-10-26 17:58:25 +0000442 DEL(v);
443 err_nomem();
444 return -1;
445 }
Sjoerd Mullender615194a1993-11-01 13:46:50 +0000446 NEWREF(sv);
447 for (i = sv->ob_size; i < newsize; i++)
448 sv->ob_item[i] = NULL;
449 if (last_is_sticky && sizediff > 0) {
450 /* growing: move entries to the end and zero moved entries */
451 for (i = newsize - 1; i >= sizediff; i--) {
452 sv->ob_item[i] = sv->ob_item[i - sizediff];
453 sv->ob_item[i - sizediff] = NULL;
454 }
455 }
456 sv->ob_size = newsize;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000457 return 0;
458}