blob: 9eb332b3011ce718fe66335bd1706d6dfbd86a8c [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum9bfef441993-03-29 10:43:31 +00002Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
3Amsterdam, 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
29object *
30newtupleobject(size)
31 register int size;
32{
33 register int i;
34 register tupleobject *op;
35 if (size < 0) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000036 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000037 return NULL;
38 }
39 op = (tupleobject *)
40 malloc(sizeof(tupleobject) + size * sizeof(object *));
Guido van Rossum2a9096b1990-10-21 22:15:08 +000041 if (op == NULL)
42 return err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000043 NEWREF(op);
44 op->ob_type = &Tupletype;
45 op->ob_size = size;
46 for (i = 0; i < size; i++)
47 op->ob_item[i] = NULL;
48 return (object *) op;
49}
50
51int
52gettuplesize(op)
53 register object *op;
54{
55 if (!is_tupleobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000056 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000057 return -1;
58 }
59 else
60 return ((tupleobject *)op)->ob_size;
61}
62
63object *
64gettupleitem(op, i)
65 register object *op;
66 register int i;
67{
68 if (!is_tupleobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000069 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000070 return NULL;
71 }
72 if (i < 0 || i >= ((tupleobject *)op) -> ob_size) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000073 err_setstr(IndexError, "tuple index out of range");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000074 return NULL;
75 }
76 return ((tupleobject *)op) -> ob_item[i];
77}
78
79int
80settupleitem(op, i, newitem)
81 register object *op;
82 register int i;
83 register object *newitem;
84{
85 register object *olditem;
86 if (!is_tupleobject(op)) {
87 if (newitem != NULL)
88 DECREF(newitem);
Guido van Rossum2a9096b1990-10-21 22:15:08 +000089 err_badcall();
90 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000091 }
92 if (i < 0 || i >= ((tupleobject *)op) -> ob_size) {
93 if (newitem != NULL)
94 DECREF(newitem);
Guido van Rossum2a9096b1990-10-21 22:15:08 +000095 err_setstr(IndexError, "tuple assignment index out of range");
96 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000097 }
98 olditem = ((tupleobject *)op) -> ob_item[i];
99 ((tupleobject *)op) -> ob_item[i] = newitem;
100 if (olditem != NULL)
101 DECREF(olditem);
102 return 0;
103}
104
105/* Methods */
106
107static void
108tupledealloc(op)
109 register tupleobject *op;
110{
111 register int i;
112 for (i = 0; i < op->ob_size; i++) {
113 if (op->ob_item[i] != NULL)
114 DECREF(op->ob_item[i]);
115 }
116 free((ANY *)op);
117}
118
Guido van Rossum49e85141991-06-07 22:59:30 +0000119static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000120tupleprint(op, fp, flags)
121 tupleobject *op;
122 FILE *fp;
123 int flags;
124{
125 int i;
126 fprintf(fp, "(");
Guido van Rossum49e85141991-06-07 22:59:30 +0000127 for (i = 0; i < op->ob_size; i++) {
128 if (i > 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000129 fprintf(fp, ", ");
Guido van Rossum49e85141991-06-07 22:59:30 +0000130 if (printobject(op->ob_item[i], fp, flags) != 0)
131 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000132 }
133 if (op->ob_size == 1)
134 fprintf(fp, ",");
135 fprintf(fp, ")");
Guido van Rossum49e85141991-06-07 22:59:30 +0000136 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000137}
138
139object *
140tuplerepr(v)
141 tupleobject *v;
142{
143 object *s, *t, *comma;
144 int i;
145 s = newstringobject("(");
146 comma = newstringobject(", ");
147 for (i = 0; i < v->ob_size && s != NULL; i++) {
148 if (i > 0)
149 joinstring(&s, comma);
150 t = reprobject(v->ob_item[i]);
151 joinstring(&s, t);
152 if (t != NULL)
153 DECREF(t);
154 }
155 DECREF(comma);
156 if (v->ob_size == 1) {
157 t = newstringobject(",");
158 joinstring(&s, t);
159 DECREF(t);
160 }
161 t = newstringobject(")");
162 joinstring(&s, t);
163 DECREF(t);
164 return s;
165}
166
167static int
168tuplecompare(v, w)
169 register tupleobject *v, *w;
170{
171 register int len =
172 (v->ob_size < w->ob_size) ? v->ob_size : w->ob_size;
173 register int i;
174 for (i = 0; i < len; i++) {
175 int cmp = cmpobject(v->ob_item[i], w->ob_item[i]);
176 if (cmp != 0)
177 return cmp;
178 }
179 return v->ob_size - w->ob_size;
180}
181
Guido van Rossum9bfef441993-03-29 10:43:31 +0000182static long
183tuplehash(v)
184 tupleobject *v;
185{
186 register long x, y;
187 register int len = v->ob_size;
188 register object **p;
189 x = 0x345678L;
190 p = v->ob_item;
191 while (--len >= 0) {
192 y = hashobject(*p++);
193 if (y == -1)
194 return -1;
195 x = (x + x + x) ^ y;
196 }
197 x ^= v->ob_size;
198 if (x == -1)
199 x = -2;
200 return x;
201}
202
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000203static int
204tuplelength(a)
205 tupleobject *a;
206{
207 return a->ob_size;
208}
209
210static object *
211tupleitem(a, i)
212 register tupleobject *a;
213 register int i;
214{
215 if (i < 0 || i >= a->ob_size) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000216 err_setstr(IndexError, "tuple index out of range");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000217 return NULL;
218 }
219 INCREF(a->ob_item[i]);
220 return a->ob_item[i];
221}
222
223static object *
224tupleslice(a, ilow, ihigh)
225 register tupleobject *a;
226 register int ilow, ihigh;
227{
228 register tupleobject *np;
229 register int i;
230 if (ilow < 0)
231 ilow = 0;
232 if (ihigh > a->ob_size)
233 ihigh = a->ob_size;
234 if (ihigh < ilow)
235 ihigh = ilow;
236 if (ilow == 0 && ihigh == a->ob_size) {
237 /* XXX can only do this if tuples are immutable! */
238 INCREF(a);
239 return (object *)a;
240 }
241 np = (tupleobject *)newtupleobject(ihigh - ilow);
242 if (np == NULL)
243 return NULL;
244 for (i = ilow; i < ihigh; i++) {
245 object *v = a->ob_item[i];
246 INCREF(v);
247 np->ob_item[i - ilow] = v;
248 }
249 return (object *)np;
250}
251
Guido van Rossum7c36ad71992-01-14 18:45:33 +0000252object *
253gettupleslice(op, i, j)
254 object *op;
255 int i, j;
256{
257 if (op == NULL || !is_tupleobject(op)) {
258 err_badcall();
259 return NULL;
260 }
261 return tupleslice((tupleobject *)op, i, j);
262}
263
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000264static object *
265tupleconcat(a, bb)
266 register tupleobject *a;
267 register object *bb;
268{
269 register int size;
270 register int i;
271 tupleobject *np;
272 if (!is_tupleobject(bb)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000273 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274 return NULL;
275 }
276#define b ((tupleobject *)bb)
277 size = a->ob_size + b->ob_size;
278 np = (tupleobject *) newtupleobject(size);
279 if (np == NULL) {
Guido van Rossum49e85141991-06-07 22:59:30 +0000280 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000281 }
282 for (i = 0; i < a->ob_size; i++) {
283 object *v = a->ob_item[i];
284 INCREF(v);
285 np->ob_item[i] = v;
286 }
287 for (i = 0; i < b->ob_size; i++) {
288 object *v = b->ob_item[i];
289 INCREF(v);
290 np->ob_item[i + a->ob_size] = v;
291 }
292 return (object *)np;
293#undef b
294}
295
Guido van Rossumb8393da1991-06-04 19:35:24 +0000296static object *
297tuplerepeat(a, n)
298 tupleobject *a;
299 int n;
300{
301 int i, j;
302 int size;
303 tupleobject *np;
304 object **p;
305 if (n < 0)
306 n = 0;
307 if (a->ob_size*n == a->ob_size) {
308 /* Since tuples are immutable, we can return a shared
309 copy in this case */
310 INCREF(a);
311 return (object *)a;
312 }
313 size = a->ob_size * n;
314 np = (tupleobject *) newtupleobject(size);
315 if (np == NULL)
316 return NULL;
317 p = np->ob_item;
318 for (i = 0; i < n; i++) {
319 for (j = 0; j < a->ob_size; j++) {
320 *p = a->ob_item[j];
321 INCREF(*p);
322 p++;
323 }
324 }
325 return (object *) np;
326}
327
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000328static sequence_methods tuple_as_sequence = {
329 tuplelength, /*sq_length*/
330 tupleconcat, /*sq_concat*/
Guido van Rossumb8393da1991-06-04 19:35:24 +0000331 tuplerepeat, /*sq_repeat*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000332 tupleitem, /*sq_item*/
333 tupleslice, /*sq_slice*/
334 0, /*sq_ass_item*/
335 0, /*sq_ass_slice*/
336};
337
338typeobject Tupletype = {
339 OB_HEAD_INIT(&Typetype)
340 0,
341 "tuple",
342 sizeof(tupleobject) - sizeof(object *),
343 sizeof(object *),
344 tupledealloc, /*tp_dealloc*/
345 tupleprint, /*tp_print*/
346 0, /*tp_getattr*/
347 0, /*tp_setattr*/
348 tuplecompare, /*tp_compare*/
349 tuplerepr, /*tp_repr*/
350 0, /*tp_as_number*/
351 &tuple_as_sequence, /*tp_as_sequence*/
352 0, /*tp_as_mapping*/
Guido van Rossum9bfef441993-03-29 10:43:31 +0000353 tuplehash, /*tp_hash*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000354};