blob: 59660f99042145c31910b47b8edbb22be69de1a9 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum1d5735e1994-08-30 08:27:36 +00002Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Guido van Rossum9bfef441993-03-29 10:43:31 +00003Amsterdam, The 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;
122 register object *newitem;
123{
124 register object *olditem;
125 if (!is_tupleobject(op)) {
Guido van Rossum12d12c51993-10-26 17:58:25 +0000126 XDECREF(newitem);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000127 err_badcall();
128 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000129 }
130 if (i < 0 || i >= ((tupleobject *)op) -> ob_size) {
Guido van Rossum12d12c51993-10-26 17:58:25 +0000131 XDECREF(newitem);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000132 err_setstr(IndexError, "tuple assignment index out of range");
133 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000134 }
135 olditem = ((tupleobject *)op) -> ob_item[i];
136 ((tupleobject *)op) -> ob_item[i] = newitem;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000137 XDECREF(olditem);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000138 return 0;
139}
140
141/* Methods */
142
143static void
144tupledealloc(op)
145 register tupleobject *op;
146{
147 register int i;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000148 for (i = 0; i < op->ob_size; i++)
149 XDECREF(op->ob_item[i]);
Sjoerd Mullender842d2cc1993-10-15 16:18:48 +0000150#if MAXSAVESIZE > 0
151 if (0 < op->ob_size && op->ob_size < MAXSAVESIZE) {
Sjoerd Mullender615194a1993-11-01 13:46:50 +0000152 op->ob_item[0] = (object *) free_tuples[op->ob_size];
153 free_tuples[op->ob_size] = op;
Sjoerd Mullender842d2cc1993-10-15 16:18:48 +0000154 } else
155#endif
156 free((ANY *)op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000157}
158
Guido van Rossum49e85141991-06-07 22:59:30 +0000159static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000160tupleprint(op, fp, flags)
161 tupleobject *op;
162 FILE *fp;
163 int flags;
164{
165 int i;
166 fprintf(fp, "(");
Guido van Rossum49e85141991-06-07 22:59:30 +0000167 for (i = 0; i < op->ob_size; i++) {
168 if (i > 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000169 fprintf(fp, ", ");
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000170 if (printobject(op->ob_item[i], fp, 0) != 0)
Guido van Rossum49e85141991-06-07 22:59:30 +0000171 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000172 }
173 if (op->ob_size == 1)
174 fprintf(fp, ",");
175 fprintf(fp, ")");
Guido van Rossum49e85141991-06-07 22:59:30 +0000176 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000177}
178
Guido van Rossum234f9421993-06-17 12:35:49 +0000179static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000180tuplerepr(v)
181 tupleobject *v;
182{
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000183 object *s, *comma;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000184 int i;
185 s = newstringobject("(");
186 comma = newstringobject(", ");
187 for (i = 0; i < v->ob_size && s != NULL; i++) {
188 if (i > 0)
189 joinstring(&s, comma);
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000190 joinstring_decref(&s, reprobject(v->ob_item[i]));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000191 }
192 DECREF(comma);
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000193 if (v->ob_size == 1)
194 joinstring_decref(&s, newstringobject(","));
195 joinstring_decref(&s, newstringobject(")"));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000196 return s;
197}
198
199static int
200tuplecompare(v, w)
201 register tupleobject *v, *w;
202{
203 register int len =
204 (v->ob_size < w->ob_size) ? v->ob_size : w->ob_size;
205 register int i;
206 for (i = 0; i < len; i++) {
207 int cmp = cmpobject(v->ob_item[i], w->ob_item[i]);
208 if (cmp != 0)
209 return cmp;
210 }
211 return v->ob_size - w->ob_size;
212}
213
Guido van Rossum9bfef441993-03-29 10:43:31 +0000214static long
215tuplehash(v)
216 tupleobject *v;
217{
218 register long x, y;
219 register int len = v->ob_size;
220 register object **p;
221 x = 0x345678L;
222 p = v->ob_item;
223 while (--len >= 0) {
224 y = hashobject(*p++);
225 if (y == -1)
226 return -1;
227 x = (x + x + x) ^ y;
228 }
229 x ^= v->ob_size;
230 if (x == -1)
231 x = -2;
232 return x;
233}
234
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000235static int
236tuplelength(a)
237 tupleobject *a;
238{
239 return a->ob_size;
240}
241
242static object *
243tupleitem(a, i)
244 register tupleobject *a;
245 register int i;
246{
247 if (i < 0 || i >= a->ob_size) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000248 err_setstr(IndexError, "tuple index out of range");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000249 return NULL;
250 }
251 INCREF(a->ob_item[i]);
252 return a->ob_item[i];
253}
254
255static object *
256tupleslice(a, ilow, ihigh)
257 register tupleobject *a;
258 register int ilow, ihigh;
259{
260 register tupleobject *np;
261 register int i;
262 if (ilow < 0)
263 ilow = 0;
264 if (ihigh > a->ob_size)
265 ihigh = a->ob_size;
266 if (ihigh < ilow)
267 ihigh = ilow;
268 if (ilow == 0 && ihigh == a->ob_size) {
269 /* XXX can only do this if tuples are immutable! */
270 INCREF(a);
271 return (object *)a;
272 }
273 np = (tupleobject *)newtupleobject(ihigh - ilow);
274 if (np == NULL)
275 return NULL;
276 for (i = ilow; i < ihigh; i++) {
277 object *v = a->ob_item[i];
278 INCREF(v);
279 np->ob_item[i - ilow] = v;
280 }
281 return (object *)np;
282}
283
Guido van Rossum7c36ad71992-01-14 18:45:33 +0000284object *
285gettupleslice(op, i, j)
286 object *op;
287 int i, j;
288{
289 if (op == NULL || !is_tupleobject(op)) {
290 err_badcall();
291 return NULL;
292 }
293 return tupleslice((tupleobject *)op, i, j);
294}
295
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000296static object *
297tupleconcat(a, bb)
298 register tupleobject *a;
299 register object *bb;
300{
301 register int size;
302 register int i;
303 tupleobject *np;
304 if (!is_tupleobject(bb)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000305 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000306 return NULL;
307 }
308#define b ((tupleobject *)bb)
309 size = a->ob_size + b->ob_size;
310 np = (tupleobject *) newtupleobject(size);
311 if (np == NULL) {
Guido van Rossum49e85141991-06-07 22:59:30 +0000312 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000313 }
314 for (i = 0; i < a->ob_size; i++) {
315 object *v = a->ob_item[i];
316 INCREF(v);
317 np->ob_item[i] = v;
318 }
319 for (i = 0; i < b->ob_size; i++) {
320 object *v = b->ob_item[i];
321 INCREF(v);
322 np->ob_item[i + a->ob_size] = v;
323 }
324 return (object *)np;
325#undef b
326}
327
Guido van Rossumb8393da1991-06-04 19:35:24 +0000328static object *
329tuplerepeat(a, n)
330 tupleobject *a;
331 int n;
332{
333 int i, j;
334 int size;
335 tupleobject *np;
336 object **p;
337 if (n < 0)
338 n = 0;
339 if (a->ob_size*n == a->ob_size) {
340 /* Since tuples are immutable, we can return a shared
341 copy in this case */
342 INCREF(a);
343 return (object *)a;
344 }
345 size = a->ob_size * n;
346 np = (tupleobject *) newtupleobject(size);
347 if (np == NULL)
348 return NULL;
349 p = np->ob_item;
350 for (i = 0; i < n; i++) {
351 for (j = 0; j < a->ob_size; j++) {
352 *p = a->ob_item[j];
353 INCREF(*p);
354 p++;
355 }
356 }
357 return (object *) np;
358}
359
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000360static sequence_methods tuple_as_sequence = {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000361 (inquiry)tuplelength, /*sq_length*/
362 (binaryfunc)tupleconcat, /*sq_concat*/
363 (intargfunc)tuplerepeat, /*sq_repeat*/
364 (intargfunc)tupleitem, /*sq_item*/
365 (intintargfunc)tupleslice, /*sq_slice*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000366 0, /*sq_ass_item*/
367 0, /*sq_ass_slice*/
368};
369
370typeobject Tupletype = {
371 OB_HEAD_INIT(&Typetype)
372 0,
373 "tuple",
374 sizeof(tupleobject) - sizeof(object *),
375 sizeof(object *),
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000376 (destructor)tupledealloc, /*tp_dealloc*/
377 (printfunc)tupleprint, /*tp_print*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000378 0, /*tp_getattr*/
379 0, /*tp_setattr*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000380 (cmpfunc)tuplecompare, /*tp_compare*/
381 (reprfunc)tuplerepr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000382 0, /*tp_as_number*/
383 &tuple_as_sequence, /*tp_as_sequence*/
384 0, /*tp_as_mapping*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000385 (hashfunc)tuplehash, /*tp_hash*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000386};
Guido van Rossum12d12c51993-10-26 17:58:25 +0000387
388/* The following function breaks the notion that tuples are immutable:
389 it changes the size of a tuple. We get away with this only if there
390 is only one module referencing the object. You can also think of it
391 as creating a new tuple object and destroying the old one, only
392 more efficiently. In any case, don't use this if the tuple may
Sjoerd Mullender615194a1993-11-01 13:46:50 +0000393 already be known to some other part of the code...
394 If last_is_sticky is set, the tuple will grow or shrink at the
395 front, otherwise it will grow or shrink at the end. */
Guido van Rossum12d12c51993-10-26 17:58:25 +0000396
397int
Sjoerd Mullender615194a1993-11-01 13:46:50 +0000398resizetuple(pv, newsize, last_is_sticky)
Guido van Rossum12d12c51993-10-26 17:58:25 +0000399 object **pv;
400 int newsize;
Sjoerd Mullender615194a1993-11-01 13:46:50 +0000401 int last_is_sticky;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000402{
Sjoerd Mullender615194a1993-11-01 13:46:50 +0000403 register tupleobject *v;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000404 register tupleobject *sv;
Sjoerd Mullender615194a1993-11-01 13:46:50 +0000405 int i;
406 int sizediff;
407
408 v = (tupleobject *) *pv;
409 sizediff = newsize - v->ob_size;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000410 if (!is_tupleobject(v) || v->ob_refcnt != 1) {
411 *pv = 0;
412 DECREF(v);
413 err_badcall();
414 return -1;
415 }
Sjoerd Mullender615194a1993-11-01 13:46:50 +0000416 if (sizediff == 0)
417 return 0;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000418 /* XXX UNREF/NEWREF interface should be more symmetrical */
419#ifdef REF_DEBUG
420 --ref_total;
421#endif
422 UNREF(v);
Sjoerd Mullender615194a1993-11-01 13:46:50 +0000423 if (last_is_sticky && sizediff < 0) {
424 /* shrinking: move entries to the front and zero moved entries */
425 for (i = 0; i < newsize; i++) {
426 XDECREF(v->ob_item[i]);
427 v->ob_item[i] = v->ob_item[i - sizediff];
428 v->ob_item[i - sizediff] = NULL;
429 }
430 }
431 for (i = newsize; i < v->ob_size; i++) {
432 XDECREF(v->ob_item[i]);
433 v->ob_item[i] = NULL;
434 }
435 sv = (tupleobject *)
Guido van Rossum12d12c51993-10-26 17:58:25 +0000436 realloc((char *)v,
437 sizeof(tupleobject) + newsize * sizeof(object *));
Sjoerd Mullender615194a1993-11-01 13:46:50 +0000438 *pv = (object *) sv;
439 if (sv == NULL) {
Guido van Rossum12d12c51993-10-26 17:58:25 +0000440 DEL(v);
441 err_nomem();
442 return -1;
443 }
Sjoerd Mullender615194a1993-11-01 13:46:50 +0000444 NEWREF(sv);
445 for (i = sv->ob_size; i < newsize; i++)
446 sv->ob_item[i] = NULL;
447 if (last_is_sticky && sizediff > 0) {
448 /* growing: move entries to the end and zero moved entries */
449 for (i = newsize - 1; i >= sizediff; i--) {
450 sv->ob_item[i] = sv->ob_item[i - sizediff];
451 sv->ob_item[i - sizediff] = NULL;
452 }
453 }
454 sv->ob_size = newsize;
Guido van Rossum12d12c51993-10-26 17:58:25 +0000455 return 0;
456}