Do no longer handle scm_tc7_bvect bitvectors.
[bpt/guile.git] / libguile / ramap.c
CommitLineData
ac3c6ad6 1/* Copyright (C) 1996,1998,2000,2001,2004 Free Software Foundation, Inc.
0f2d19dd 2 *
73be1d9e
MV
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
0f2d19dd 7 *
73be1d9e
MV
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
0f2d19dd 12 *
73be1d9e
MV
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
1bbd0b84 17
1bbd0b84 18
c209c88e
GB
19/*
20 HWN:FIXME::
21 Someone should rename this to arraymap.c; that would reflect the
22 contents better. */
0f2d19dd
JB
23\f
24
25
26\f
27
a0599745 28#include "libguile/_scm.h"
405aaef9 29#include "libguile/strings.h"
a0599745
MD
30#include "libguile/unif.h"
31#include "libguile/smob.h"
32#include "libguile/chars.h"
33#include "libguile/eq.h"
34#include "libguile/eval.h"
35#include "libguile/feature.h"
36#include "libguile/root.h"
37#include "libguile/vectors.h"
b4bdadde 38#include "libguile/srfi-4.h"
a0599745
MD
39
40#include "libguile/validate.h"
41#include "libguile/ramap.h"
0f2d19dd
JB
42\f
43
0f2d19dd
JB
44typedef struct
45{
46 char *name;
47 SCM sproc;
48 int (*vproc) ();
49} ra_iproc;
50
ad310508
MD
51
52/* These tables are a kluge that will not scale well when more
53 * vectorized subrs are added. It is tempting to steal some bits from
54 * the SCM_CAR of all subrs (like those selected by SCM_SMOBNUM) to hold an
55 * offset into a table of vectorized subrs.
56 */
57
58static ra_iproc ra_rpsubrs[] =
59{
60 {"=", SCM_UNDEFINED, scm_ra_eqp},
61 {"<", SCM_UNDEFINED, scm_ra_lessp},
62 {"<=", SCM_UNDEFINED, scm_ra_leqp},
63 {">", SCM_UNDEFINED, scm_ra_grp},
64 {">=", SCM_UNDEFINED, scm_ra_greqp},
65 {0, 0, 0}
66};
67
68static ra_iproc ra_asubrs[] =
69{
70 {"+", SCM_UNDEFINED, scm_ra_sum},
71 {"-", SCM_UNDEFINED, scm_ra_difference},
72 {"*", SCM_UNDEFINED, scm_ra_product},
73 {"/", SCM_UNDEFINED, scm_ra_divide},
74 {0, 0, 0}
75};
76
0f2d19dd 77
0f2d19dd
JB
78
79/* Fast, recycling scm_vector ref */
80#define RVREF(ra, i, e) (e = scm_cvref(ra, i, e))
81
82/* #define RVREF(ra, i, e) (scm_cvref(ra, i, SCM_UNDEFINED)) to turn off */
83
84/* IVDEP means "ignore scm_vector dependencies", meaning we guarantee that
85 elements of scm_vector operands are not aliased */
86#ifdef _UNICOS
87#define IVDEP(test, line) if (test) {_Pragma("ivdep"); line} else {line}
88#else
89#define IVDEP(test, line) line
90#endif
91
92\f
93
94/* inds must be a uvect or ivect, no check. */
95
1cc91f1b 96
c209c88e
GB
97
98/*
99 Yes, this is really ugly, but it prevents multiple code
100 */
101#define BINARY_ELTS_CODE(OPERATOR, type) \
102do { type *v0 = (type*)SCM_VELTS (ra0);\
103 type *v1 = (type*)SCM_VELTS (ra1);\
104 IVDEP (ra0 != ra1, \
105 for (; n-- > 0; i0 += inc0, i1 += inc1) \
106 v0[i0] OPERATOR v1[i1];) \
c209c88e
GB
107} while (0)
108
109/* This macro is used for all but binary division and
110 multiplication of complex numbers -- see the expanded
111 version in the functions later in this file */
112#define BINARY_PAIR_ELTS_CODE(OPERATOR, type) \
113do { type (*v0)[2] = (type (*)[2]) SCM_VELTS (ra0);\
114 type (*v1)[2] = (type (*)[2]) SCM_VELTS (ra1);\
115 IVDEP (ra0 != ra1, \
116 for (; n-- > 0; i0 += inc0, i1 += inc1) {\
117 v0[i0][0] OPERATOR v1[i1][0]; \
118 v0[i0][1] OPERATOR v1[i1][1]; \
119 }) \
c209c88e
GB
120} while (0)
121
122#define UNARY_ELTS_CODE(OPERATOR, type) \
123 do { type *v0 = (type *) SCM_VELTS (ra0);\
124 for (; n-- > 0; i0 += inc0) \
125 v0[i0] OPERATOR v0[i0];\
c209c88e
GB
126 } while (0)
127
128
129/* This macro is used for all but unary divison
130 of complex numbers -- see the expanded version in the
131 function later in this file. */
132#define UNARY_PAIR_ELTS_CODE(OPERATOR, type) \
133 do { type (*v0)[2] = (type (*)[2]) SCM_VELTS (ra0);\
134 for (; n-- > 0; i0 += inc0) {\
135 v0[i0][0] OPERATOR v0[i0][0];\
136 v0[i0][1] OPERATOR v0[i0][1];\
137 }\
138 break;\
139 } while (0)
140
c014a02e 141static unsigned long
1bbd0b84 142cind (SCM ra, SCM inds)
0f2d19dd 143{
c014a02e 144 unsigned long i;
0f2d19dd 145 int k;
c014a02e 146 long *ve = (long*) SCM_VELTS (inds);
0f2d19dd
JB
147 if (!SCM_ARRAYP (ra))
148 return *ve;
149 i = SCM_ARRAY_BASE (ra);
150 for (k = 0; k < SCM_ARRAY_NDIM (ra); k++)
151 i += (ve[k] - SCM_ARRAY_DIMS (ra)[k].lbnd) * SCM_ARRAY_DIMS (ra)[k].inc;
152 return i;
153}
154
155
156/* Checker for scm_array mapping functions:
157 return values: 4 --> shapes, increments, and bases are the same;
158 3 --> shapes and increments are the same;
159 2 --> shapes are the same;
160 1 --> ras are at least as big as ra0;
161 0 --> no match.
162 */
1cc91f1b 163
0f2d19dd 164int
6e8d25a6 165scm_ra_matchp (SCM ra0, SCM ras)
0f2d19dd
JB
166{
167 SCM ra1;
92c2555f
MV
168 scm_t_array_dim dims;
169 scm_t_array_dim *s0 = &dims;
170 scm_t_array_dim *s1;
c014a02e 171 unsigned long bas0 = 0;
0f2d19dd
JB
172 int i, ndim = 1;
173 int exact = 2 /* 4 */ ; /* Don't care about values >2 (yet?) */
ff467021 174 if (SCM_IMP (ra0)) return 0;
b4bdadde
MV
175 if (scm_is_uniform_vector (ra0))
176 goto uniform_vector_0;
0f2d19dd 177 switch (SCM_TYP7 (ra0))
c209c88e
GB
178 {
179 default:
180 return 0;
181 case scm_tc7_vector:
182 case scm_tc7_wvect:
183 case scm_tc7_string:
c209c88e 184 case scm_tc7_bvect:
b4bdadde 185 uniform_vector_0:
c209c88e
GB
186 s0->lbnd = 0;
187 s0->inc = 1;
e11e83f3 188 s0->ubnd = scm_to_long (scm_uniform_vector_length (ra0)) - 1;
c209c88e
GB
189 break;
190 case scm_tc7_smob:
191 if (!SCM_ARRAYP (ra0))
192 return 0;
193 ndim = SCM_ARRAY_NDIM (ra0);
194 s0 = SCM_ARRAY_DIMS (ra0);
195 bas0 = SCM_ARRAY_BASE (ra0);
196 break;
197 }
368cf54d 198 while (SCM_NIMP (ras))
c209c88e
GB
199 {
200 ra1 = SCM_CAR (ras);
201 if (SCM_IMP (ra1))
202 return 0;
b4bdadde
MV
203 if (scm_is_uniform_vector (ra1))
204 goto uniform_vector_1;
205 switch (SCM_TYP7 (ra1))
c209c88e
GB
206 {
207 default:
208 return 0;
209 case scm_tc7_vector:
210 case scm_tc7_wvect:
211 case scm_tc7_string:
c209c88e 212 case scm_tc7_bvect:
b4bdadde 213 uniform_vector_1:
b226e5f6 214 {
c014a02e 215 unsigned long int length;
b226e5f6
DH
216
217 if (1 != ndim)
218 return 0;
219
e11e83f3 220 length = scm_to_ulong (scm_uniform_vector_length (ra1));
b226e5f6
DH
221
222 switch (exact)
223 {
224 case 4:
225 if (0 != bas0)
226 exact = 3;
227 case 3:
228 if (1 != s0->inc)
229 exact = 2;
230 case 2:
231 if ((0 == s0->lbnd) && (s0->ubnd == length - 1))
232 break;
233 exact = 1;
234 case 1:
235 if (s0->lbnd < 0 || s0->ubnd >= length)
236 return 0;
237 }
238 break;
239 }
c209c88e
GB
240 case scm_tc7_smob:
241 if (!SCM_ARRAYP (ra1) || ndim != SCM_ARRAY_NDIM (ra1))
242 return 0;
243 s1 = SCM_ARRAY_DIMS (ra1);
244 if (bas0 != SCM_ARRAY_BASE (ra1))
245 exact = 3;
246 for (i = 0; i < ndim; i++)
247 switch (exact)
248 {
249 case 4:
250 case 3:
251 if (s0[i].inc != s1[i].inc)
252 exact = 2;
253 case 2:
254 if (s0[i].lbnd == s1[i].lbnd && s0[i].ubnd == s1[i].ubnd)
255 break;
256 exact = 1;
257 default:
258 if (s0[i].lbnd < s1[i].lbnd || s0[i].ubnd > s1[i].ubnd)
259 return (s0[i].lbnd <= s0[i].ubnd ? 0 : 1);
260 }
261 break;
262 }
263 ras = SCM_CDR (ras);
264 }
0f2d19dd
JB
265 return exact;
266}
267
1bbd0b84
GB
268/* array mapper: apply cproc to each dimension of the given arrays?.
269 int (*cproc) (); procedure to call on unrolled arrays?
5c11cc9d 270 cproc (dest, source list) or
1bbd0b84
GB
271 cproc (dest, data, source list).
272 SCM data; data to give to cproc or unbound.
273 SCM ra0; destination array.
274 SCM lra; list of source arrays.
275 const char *what; caller, for error reporting. */
276int
277scm_ramapc (int (*cproc)(), SCM data, SCM ra0, SCM lra, const char *what)
0f2d19dd
JB
278{
279 SCM inds, z;
280 SCM vra0, ra1, vra1;
281 SCM lvra, *plvra;
c014a02e 282 long *vinds;
0f2d19dd
JB
283 int k, kmax;
284 switch (scm_ra_matchp (ra0, lra))
285 {
286 default:
287 case 0:
9cf5d9b7 288 scm_misc_error (what, "array shape mismatch: ~S", scm_list_1 (ra0));
0f2d19dd
JB
289 case 2:
290 case 3:
291 case 4: /* Try unrolling arrays */
292 kmax = (SCM_ARRAYP (ra0) ? SCM_ARRAY_NDIM (ra0) - 1 : 0);
293 if (kmax < 0)
294 goto gencase;
295 vra0 = scm_array_contents (ra0, SCM_UNDEFINED);
ff467021 296 if (SCM_IMP (vra0)) goto gencase;
0f2d19dd
JB
297 if (!SCM_ARRAYP (vra0))
298 {
e11e83f3 299 unsigned long int length = scm_to_ulong (scm_uniform_vector_length (vra0));
0f2d19dd
JB
300 vra1 = scm_make_ra (1);
301 SCM_ARRAY_BASE (vra1) = 0;
302 SCM_ARRAY_DIMS (vra1)->lbnd = 0;
b226e5f6 303 SCM_ARRAY_DIMS (vra1)->ubnd = length - 1;
0f2d19dd
JB
304 SCM_ARRAY_DIMS (vra1)->inc = 1;
305 SCM_ARRAY_V (vra1) = vra0;
306 vra0 = vra1;
307 }
308 lvra = SCM_EOL;
309 plvra = &lvra;
310 for (z = lra; SCM_NIMP (z); z = SCM_CDR (z))
311 {
312 ra1 = SCM_CAR (z);
313 vra1 = scm_make_ra (1);
314 SCM_ARRAY_DIMS (vra1)->lbnd = SCM_ARRAY_DIMS (vra0)->lbnd;
315 SCM_ARRAY_DIMS (vra1)->ubnd = SCM_ARRAY_DIMS (vra0)->ubnd;
316 if (!SCM_ARRAYP (ra1))
317 {
318 SCM_ARRAY_BASE (vra1) = 0;
319 SCM_ARRAY_DIMS (vra1)->inc = 1;
320 SCM_ARRAY_V (vra1) = ra1;
321 }
322 else if (!SCM_ARRAY_CONTP (ra1))
323 goto gencase;
324 else
325 {
326 SCM_ARRAY_BASE (vra1) = SCM_ARRAY_BASE (ra1);
327 SCM_ARRAY_DIMS (vra1)->inc = SCM_ARRAY_DIMS (ra1)[kmax].inc;
328 SCM_ARRAY_V (vra1) = SCM_ARRAY_V (ra1);
329 }
330 *plvra = scm_cons (vra1, SCM_EOL);
25d8012c 331 plvra = SCM_CDRLOC (*plvra);
0f2d19dd
JB
332 }
333 return (SCM_UNBNDP (data) ? cproc(vra0, lvra) : cproc(vra0, data, lvra));
334 case 1:
335 gencase: /* Have to loop over all dimensions. */
c209c88e
GB
336 vra0 = scm_make_ra (1);
337 if (SCM_ARRAYP (ra0))
338 {
339 kmax = SCM_ARRAY_NDIM (ra0) - 1;
340 if (kmax < 0)
0f2d19dd 341 {
c209c88e
GB
342 SCM_ARRAY_DIMS (vra0)->lbnd = 0;
343 SCM_ARRAY_DIMS (vra0)->ubnd = 0;
344 SCM_ARRAY_DIMS (vra0)->inc = 1;
0f2d19dd 345 }
c209c88e
GB
346 else
347 {
348 SCM_ARRAY_DIMS (vra0)->lbnd = SCM_ARRAY_DIMS (ra0)[kmax].lbnd;
349 SCM_ARRAY_DIMS (vra0)->ubnd = SCM_ARRAY_DIMS (ra0)[kmax].ubnd;
350 SCM_ARRAY_DIMS (vra0)->inc = SCM_ARRAY_DIMS (ra0)[kmax].inc;
351 }
352 SCM_ARRAY_BASE (vra0) = SCM_ARRAY_BASE (ra0);
353 SCM_ARRAY_V (vra0) = SCM_ARRAY_V (ra0);
354 }
355 else
356 {
e11e83f3 357 unsigned long length = scm_to_ulong (scm_uniform_vector_length (ra0));
c209c88e
GB
358 kmax = 0;
359 SCM_ARRAY_DIMS (vra0)->lbnd = 0;
b226e5f6 360 SCM_ARRAY_DIMS (vra0)->ubnd = length - 1;
c209c88e
GB
361 SCM_ARRAY_DIMS (vra0)->inc = 1;
362 SCM_ARRAY_BASE (vra0) = 0;
363 SCM_ARRAY_V (vra0) = ra0;
364 ra0 = vra0;
365 }
366 lvra = SCM_EOL;
367 plvra = &lvra;
368 for (z = lra; SCM_NIMP (z); z = SCM_CDR (z))
369 {
370 ra1 = SCM_CAR (z);
371 vra1 = scm_make_ra (1);
372 SCM_ARRAY_DIMS (vra1)->lbnd = SCM_ARRAY_DIMS (vra0)->lbnd;
373 SCM_ARRAY_DIMS (vra1)->ubnd = SCM_ARRAY_DIMS (vra0)->ubnd;
374 if (SCM_ARRAYP (ra1))
375 {
376 if (kmax >= 0)
377 SCM_ARRAY_DIMS (vra1)->inc = SCM_ARRAY_DIMS (ra1)[kmax].inc;
378 SCM_ARRAY_V (vra1) = SCM_ARRAY_V (ra1);
379 }
380 else
381 {
382 SCM_ARRAY_DIMS (vra1)->inc = 1;
383 SCM_ARRAY_V (vra1) = ra1;
384 }
385 *plvra = scm_cons (vra1, SCM_EOL);
386 plvra = SCM_CDRLOC (*plvra);
387 }
e11e83f3 388 inds = scm_make_uve (SCM_ARRAY_NDIM (ra0), scm_from_int (-1));
c014a02e 389 vinds = (long *) SCM_VELTS (inds);
c209c88e
GB
390 for (k = 0; k <= kmax; k++)
391 vinds[k] = SCM_ARRAY_DIMS (ra0)[k].lbnd;
392 k = kmax;
393 do
394 {
395 if (k == kmax)
396 {
397 SCM y = lra;
398 SCM_ARRAY_BASE (vra0) = cind (ra0, inds);
399 for (z = lvra; SCM_NIMP (z); z = SCM_CDR (z), y = SCM_CDR (y))
400 SCM_ARRAY_BASE (SCM_CAR (z)) = cind (SCM_CAR (y), inds);
401 if (0 == (SCM_UNBNDP (data) ? cproc(vra0, lvra) : cproc(vra0, data, lvra)))
402 return 0;
403 k--;
404 continue;
405 }
406 if (vinds[k] < SCM_ARRAY_DIMS (ra0)[k].ubnd)
407 {
408 vinds[k]++;
409 k++;
410 continue;
411 }
412 vinds[k] = SCM_ARRAY_DIMS (ra0)[k].lbnd - 1;
413 k--;
414 }
415 while (k >= 0);
416 return 1;
0f2d19dd
JB
417 }
418}
419
420
3b3b36dd 421SCM_DEFINE (scm_array_fill_x, "array-fill!", 2, 0, 0,
c209c88e 422 (SCM ra, SCM fill),
8f85c0c6 423 "Store @var{fill} in every element of @var{array}. The value returned\n"
b380b885 424 "is unspecified.")
1bbd0b84 425#define FUNC_NAME s_scm_array_fill_x
ad310508 426{
c209c88e 427 scm_ramapc (scm_array_fill_int, fill, ra, SCM_EOL, FUNC_NAME);
ad310508
MD
428 return SCM_UNSPECIFIED;
429}
1bbd0b84 430#undef FUNC_NAME
ad310508 431
5c11cc9d
GH
432/* to be used as cproc in scm_ramapc to fill an array dimension with
433 "fill". */
0f2d19dd 434int
e81d98ec 435scm_array_fill_int (SCM ra, SCM fill, SCM ignore SCM_UNUSED)
1bbd0b84 436#define FUNC_NAME s_scm_array_fill_x
0f2d19dd 437{
c014a02e
ML
438 unsigned long i;
439 unsigned long n = SCM_ARRAY_DIMS (ra)->ubnd - SCM_ARRAY_DIMS (ra)->lbnd + 1;
440 long inc = SCM_ARRAY_DIMS (ra)->inc;
441 unsigned long base = SCM_ARRAY_BASE (ra);
5c11cc9d 442
0f2d19dd 443 ra = SCM_ARRAY_V (ra);
b4bdadde
MV
444
445 if (scm_is_uniform_vector (ra))
446 {
447 for (i = base; n--; i += inc)
448 scm_uniform_vector_set_x (ra, scm_from_ulong (i), fill);
449 return 1;
450 }
451
5c11cc9d
GH
452 switch SCM_TYP7 (ra)
453 {
454 default:
455 for (i = base; n--; i += inc)
e11e83f3 456 scm_array_set_x (ra, fill, scm_from_ulong (i));
5c11cc9d
GH
457 break;
458 case scm_tc7_vector:
459 case scm_tc7_wvect:
460 for (i = base; n--; i += inc)
34d19ef6 461 SCM_VECTOR_SET (ra, i, fill);
5c11cc9d
GH
462 break;
463 case scm_tc7_string:
7866a09b 464 SCM_ASRTGO (SCM_CHARP (fill), badarg2);
cc95e00a
MV
465 {
466 char *data = scm_i_string_writable_chars (ra);
467 for (i = base; n--; i += inc)
468 data[i] = SCM_CHAR (fill);
469 scm_i_string_stop_writing ();
470 }
5c11cc9d 471 break;
5c11cc9d 472 case scm_tc7_bvect:
1bbd0b84 473 { /* scope */
c014a02e
ML
474 long *ve = (long *) SCM_VELTS (ra);
475 if (1 == inc && (n >= SCM_LONG_BIT || n == SCM_BITVECTOR_LENGTH (ra)))
5c11cc9d 476 {
c014a02e 477 i = base / SCM_LONG_BIT;
7888309b 478 if (scm_is_false (fill))
5c11cc9d 479 {
c014a02e
ML
480 if (base % SCM_LONG_BIT) /* leading partial word */
481 ve[i++] &= ~(~0L << (base % SCM_LONG_BIT));
482 for (; i < (base + n) / SCM_LONG_BIT; i++)
5c11cc9d 483 ve[i] = 0L;
c014a02e
ML
484 if ((base + n) % SCM_LONG_BIT) /* trailing partial word */
485 ve[i] &= (~0L << ((base + n) % SCM_LONG_BIT));
5c11cc9d 486 }
bc36d050 487 else if (scm_is_eq (fill, SCM_BOOL_T))
5c11cc9d 488 {
c014a02e
ML
489 if (base % SCM_LONG_BIT)
490 ve[i++] |= ~0L << (base % SCM_LONG_BIT);
491 for (; i < (base + n) / SCM_LONG_BIT; i++)
5c11cc9d 492 ve[i] = ~0L;
c014a02e
ML
493 if ((base + n) % SCM_LONG_BIT)
494 ve[i] |= ~(~0L << ((base + n) % SCM_LONG_BIT));
5c11cc9d
GH
495 }
496 else
276dd677 497 badarg2:SCM_WRONG_TYPE_ARG (2, fill);
5c11cc9d
GH
498 }
499 else
500 {
7888309b 501 if (scm_is_false (fill))
5c11cc9d 502 for (i = base; n--; i += inc)
c014a02e 503 ve[i / SCM_LONG_BIT] &= ~(1L << (i % SCM_LONG_BIT));
bc36d050 504 else if (scm_is_eq (fill, SCM_BOOL_T))
5c11cc9d 505 for (i = base; n--; i += inc)
c014a02e 506 ve[i / SCM_LONG_BIT] |= (1L << (i % SCM_LONG_BIT));
5c11cc9d
GH
507 else
508 goto badarg2;
509 }
510 break;
511 }
5c11cc9d 512 }
0f2d19dd
JB
513 return 1;
514}
1bbd0b84 515#undef FUNC_NAME
0f2d19dd 516
0f2d19dd 517
c209c88e 518
0f2d19dd 519static int
1bbd0b84 520racp (SCM src, SCM dst)
0f2d19dd 521{
c014a02e
ML
522 long n = (SCM_ARRAY_DIMS (src)->ubnd - SCM_ARRAY_DIMS (src)->lbnd + 1);
523 long inc_d, inc_s = SCM_ARRAY_DIMS (src)->inc;
524 unsigned long i_d, i_s = SCM_ARRAY_BASE (src);
0f2d19dd
JB
525 dst = SCM_CAR (dst);
526 inc_d = SCM_ARRAY_DIMS (dst)->inc;
527 i_d = SCM_ARRAY_BASE (dst);
528 src = SCM_ARRAY_V (src);
529 dst = SCM_ARRAY_V (dst);
c209c88e 530
b4bdadde
MV
531 if (scm_is_uniform_vector (src) || scm_is_uniform_vector (dst))
532 goto gencase;
533
405aaef9 534 switch SCM_TYP7 (dst)
c209c88e
GB
535 {
536 default:
537 gencase:
538 case scm_tc7_vector:
539 case scm_tc7_wvect:
95f5b0f5 540
c209c88e 541 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
5e4a4d09
MD
542 scm_array_set_x (dst,
543 scm_cvref (src, i_s, SCM_UNDEFINED),
e11e83f3 544 scm_from_ulong (i_d));
c209c88e
GB
545 break;
546 case scm_tc7_string:
405aaef9
DH
547 if (SCM_TYP7 (src) != scm_tc7_string)
548 goto gencase;
cc95e00a
MV
549 {
550 char *dst_data = scm_i_string_writable_chars (dst);
551 const char *src_data = scm_i_string_chars (src);
552 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
553 dst_data[i_d] = src_data[i_s];
554 scm_i_string_stop_writing ();
555 }
405aaef9 556 break;
c209c88e 557 case scm_tc7_bvect:
405aaef9 558 if (SCM_TYP7 (src) != scm_tc7_bvect)
c209c88e 559 goto gencase;
c014a02e 560 if (1 == inc_d && 1 == inc_s && i_s % SCM_LONG_BIT == i_d % SCM_LONG_BIT && n >= SCM_LONG_BIT)
c209c88e 561 {
c014a02e
ML
562 long *sv = (long *) SCM_VELTS (src);
563 long *dv = (long *) SCM_VELTS (dst);
564 sv += i_s / SCM_LONG_BIT;
565 dv += i_d / SCM_LONG_BIT;
566 if (i_s % SCM_LONG_BIT)
c209c88e 567 { /* leading partial word */
c014a02e 568 *dv = (*dv & ~(~0L << (i_s % SCM_LONG_BIT))) | (*sv & (~0L << (i_s % SCM_LONG_BIT)));
c209c88e
GB
569 dv++;
570 sv++;
c014a02e 571 n -= SCM_LONG_BIT - (i_s % SCM_LONG_BIT);
c209c88e 572 }
5e4a4d09 573 IVDEP (src != dst,
c014a02e 574 for (; n >= SCM_LONG_BIT; n -= SCM_LONG_BIT, sv++, dv++)
5e4a4d09 575 *dv = *sv;)
c209c88e
GB
576 if (n) /* trailing partial word */
577 *dv = (*dv & (~0L << n)) | (*sv & ~(~0L << n));
578 }
579 else
580 {
581 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
582 if (SCM_BITVEC_REF(src, i_s))
583 SCM_BITVEC_SET(dst, i_d);
584 else
585 SCM_BITVEC_CLR(dst, i_d);
586 }
587 break;
c209c88e 588 }
0f2d19dd
JB
589 return 1;
590}
591
592
1bbd0b84 593SCM_REGISTER_PROC(s_array_copy_in_order_x, "array-copy-in-order!", 2, 0, 0, scm_array_copy_x);
1cc91f1b 594
1bbd0b84 595
3b3b36dd 596SCM_DEFINE (scm_array_copy_x, "array-copy!", 2, 0, 0,
c209c88e 597 (SCM src, SCM dst),
8f85c0c6
NJ
598 "@deffnx {Scheme Procedure} array-copy-in-order! src dst\n"
599 "Copy every element from vector or array @var{source} to the\n"
b380b885
MD
600 "corresponding element of @var{destination}. @var{destination} must have\n"
601 "the same rank as @var{source}, and be at least as large in each\n"
602 "dimension. The order is unspecified.")
1bbd0b84 603#define FUNC_NAME s_scm_array_copy_x
0f2d19dd 604{
c209c88e 605 scm_ramapc (racp, SCM_UNDEFINED, src, scm_cons (dst, SCM_EOL), FUNC_NAME);
0f2d19dd
JB
606 return SCM_UNSPECIFIED;
607}
1bbd0b84 608#undef FUNC_NAME
0f2d19dd
JB
609
610/* Functions callable by ARRAY-MAP! */
611
1cc91f1b 612
0f2d19dd 613int
1bbd0b84 614scm_ra_eqp (SCM ra0, SCM ras)
0f2d19dd
JB
615{
616 SCM ra1 = SCM_CAR (ras), ra2 = SCM_CAR (SCM_CDR (ras));
c014a02e
ML
617 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
618 unsigned long i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1), i2 = SCM_ARRAY_BASE (ra2);
619 long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
620 long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
621 long inc2 = SCM_ARRAY_DIMS (ra1)->inc;
0f2d19dd
JB
622 ra0 = SCM_ARRAY_V (ra0);
623 ra1 = SCM_ARRAY_V (ra1);
624 ra2 = SCM_ARRAY_V (ra2);
625 switch (SCM_TYP7 (ra1) == SCM_TYP7 (ra2) ? SCM_TYP7 (ra1) : 0)
626 {
627 default:
628 {
629 SCM e1 = SCM_UNDEFINED, e2 = SCM_UNDEFINED;
630 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
c209c88e 631 if (SCM_BITVEC_REF (ra0, i0))
7888309b 632 if (scm_is_false(scm_eq_p (RVREF (ra1, i1, e1), RVREF (ra2, i2, e2))))
c209c88e 633 SCM_BITVEC_CLR (ra0, i0);
0f2d19dd
JB
634 break;
635 }
0f2d19dd
JB
636 }
637 return 1;
638}
639
640/* opt 0 means <, nonzero means >= */
1cc91f1b 641
0f2d19dd 642static int
34d19ef6 643ra_compare (SCM ra0, SCM ra1, SCM ra2, int opt)
0f2d19dd 644{
c014a02e
ML
645 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
646 unsigned long i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1), i2 = SCM_ARRAY_BASE (ra2);
647 long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
648 long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
649 long inc2 = SCM_ARRAY_DIMS (ra1)->inc;
0f2d19dd
JB
650 ra0 = SCM_ARRAY_V (ra0);
651 ra1 = SCM_ARRAY_V (ra1);
652 ra2 = SCM_ARRAY_V (ra2);
653 switch (SCM_TYP7 (ra1) == SCM_TYP7 (ra2) ? SCM_TYP7 (ra1) : 0)
654 {
655 default:
656 {
657 SCM e1 = SCM_UNDEFINED, e2 = SCM_UNDEFINED;
658 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
c209c88e
GB
659 if (SCM_BITVEC_REF (ra0, i0))
660 if (opt ?
7888309b
MV
661 scm_is_true (scm_less_p (RVREF (ra1, i1, e1), RVREF (ra2, i2, e2))) :
662 scm_is_false (scm_less_p (RVREF (ra1, i1, e1), RVREF (ra2, i2, e2))))
c209c88e 663 SCM_BITVEC_CLR (ra0, i0);
0f2d19dd
JB
664 break;
665 }
0f2d19dd
JB
666 }
667 return 1;
668}
669
670
1cc91f1b 671
0f2d19dd 672int
1bbd0b84 673scm_ra_lessp (SCM ra0, SCM ras)
0f2d19dd
JB
674{
675 return ra_compare (ra0, SCM_CAR (ras), SCM_CAR (SCM_CDR (ras)), 0);
676}
677
1cc91f1b 678
0f2d19dd 679int
1bbd0b84 680scm_ra_leqp (SCM ra0, SCM ras)
0f2d19dd
JB
681{
682 return ra_compare (ra0, SCM_CAR (SCM_CDR (ras)), SCM_CAR (ras), 1);
683}
684
1cc91f1b 685
0f2d19dd 686int
1bbd0b84 687scm_ra_grp (SCM ra0, SCM ras)
0f2d19dd
JB
688{
689 return ra_compare (ra0, SCM_CAR (SCM_CDR (ras)), SCM_CAR (ras), 0);
690}
691
1cc91f1b 692
0f2d19dd 693int
1bbd0b84 694scm_ra_greqp (SCM ra0, SCM ras)
0f2d19dd
JB
695{
696 return ra_compare (ra0, SCM_CAR (ras), SCM_CAR (SCM_CDR (ras)), 1);
697}
698
699
0f2d19dd 700int
1bbd0b84 701scm_ra_sum (SCM ra0, SCM ras)
0f2d19dd 702{
c014a02e
ML
703 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
704 unsigned long i0 = SCM_ARRAY_BASE (ra0);
705 long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
0f2d19dd 706 ra0 = SCM_ARRAY_V (ra0);
d2e53ed6 707 if (!scm_is_null(ras))
c209c88e
GB
708 {
709 SCM ra1 = SCM_CAR (ras);
c014a02e
ML
710 unsigned long i1 = SCM_ARRAY_BASE (ra1);
711 long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
c209c88e
GB
712 ra1 = SCM_ARRAY_V (ra1);
713 switch (SCM_TYP7 (ra0) == SCM_TYP7 (ra1) ? SCM_TYP7 (ra0) : 0)
714 {
715 default:
0f2d19dd 716 {
c209c88e
GB
717 SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
718 for (; n-- > 0; i0 += inc0, i1 += inc1)
719 scm_array_set_x (ra0, scm_sum (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)),
e11e83f3 720 scm_from_ulong (i0));
c209c88e
GB
721 break;
722 }
c209c88e
GB
723 }
724 }
0f2d19dd
JB
725 return 1;
726}
727
728
1cc91f1b 729
0f2d19dd 730int
1bbd0b84 731scm_ra_difference (SCM ra0, SCM ras)
0f2d19dd 732{
c014a02e
ML
733 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
734 unsigned long i0 = SCM_ARRAY_BASE (ra0);
735 long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
0f2d19dd 736 ra0 = SCM_ARRAY_V (ra0);
d2e53ed6 737 if (scm_is_null (ras))
c209c88e
GB
738 {
739 switch (SCM_TYP7 (ra0))
740 {
741 default:
742 {
743 SCM e0 = SCM_UNDEFINED;
744 for (; n-- > 0; i0 += inc0)
745 scm_array_set_x (ra0,
746 scm_difference (RVREF (ra0, i0, e0), SCM_UNDEFINED),
e11e83f3 747 scm_from_ulong (i0));
c209c88e
GB
748 break;
749 }
c209c88e
GB
750 }
751 }
0f2d19dd
JB
752 else
753 {
754 SCM ra1 = SCM_CAR (ras);
c014a02e
ML
755 unsigned long i1 = SCM_ARRAY_BASE (ra1);
756 long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
0f2d19dd
JB
757 ra1 = SCM_ARRAY_V (ra1);
758 switch (SCM_TYP7 (ra0) == SCM_TYP7 (ra1) ? SCM_TYP7 (ra0) : 0)
759 {
760 default:
761 {
762 SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
763 for (; n-- > 0; i0 += inc0, i1 += inc1)
e11e83f3 764 scm_array_set_x (ra0, scm_difference (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)), scm_from_ulong (i0));
0f2d19dd
JB
765 break;
766 }
0f2d19dd
JB
767 }
768 }
769 return 1;
770}
771
772
1cc91f1b 773
0f2d19dd 774int
1bbd0b84 775scm_ra_product (SCM ra0, SCM ras)
0f2d19dd 776{
c014a02e
ML
777 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
778 unsigned long i0 = SCM_ARRAY_BASE (ra0);
779 long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
0f2d19dd 780 ra0 = SCM_ARRAY_V (ra0);
d2e53ed6 781 if (!scm_is_null (ras))
c209c88e
GB
782 {
783 SCM ra1 = SCM_CAR (ras);
c014a02e
ML
784 unsigned long i1 = SCM_ARRAY_BASE (ra1);
785 long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
c209c88e
GB
786 ra1 = SCM_ARRAY_V (ra1);
787 switch (SCM_TYP7 (ra0) == SCM_TYP7 (ra1) ? SCM_TYP7 (ra0) : 0)
788 {
789 default:
0f2d19dd 790 {
c209c88e
GB
791 SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
792 for (; n-- > 0; i0 += inc0, i1 += inc1)
793 scm_array_set_x (ra0, scm_product (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)),
e11e83f3 794 scm_from_ulong (i0));
c209c88e
GB
795 break;
796 }
c209c88e
GB
797 }
798 }
0f2d19dd
JB
799 return 1;
800}
801
1cc91f1b 802
0f2d19dd 803int
1bbd0b84 804scm_ra_divide (SCM ra0, SCM ras)
0f2d19dd 805{
c014a02e
ML
806 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
807 unsigned long i0 = SCM_ARRAY_BASE (ra0);
808 long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
0f2d19dd 809 ra0 = SCM_ARRAY_V (ra0);
d2e53ed6 810 if (scm_is_null (ras))
c209c88e
GB
811 {
812 switch (SCM_TYP7 (ra0))
813 {
814 default:
815 {
816 SCM e0 = SCM_UNDEFINED;
817 for (; n-- > 0; i0 += inc0)
e11e83f3 818 scm_array_set_x (ra0, scm_divide (RVREF (ra0, i0, e0), SCM_UNDEFINED), scm_from_ulong (i0));
c209c88e
GB
819 break;
820 }
c209c88e
GB
821 }
822 }
0f2d19dd
JB
823 else
824 {
825 SCM ra1 = SCM_CAR (ras);
c014a02e
ML
826 unsigned long i1 = SCM_ARRAY_BASE (ra1);
827 long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
0f2d19dd
JB
828 ra1 = SCM_ARRAY_V (ra1);
829 switch (SCM_TYP7 (ra0) == SCM_TYP7 (ra1) ? SCM_TYP7 (ra0) : 0)
830 {
831 default:
832 {
833 SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
834 for (; n-- > 0; i0 += inc0, i1 += inc1)
e11e83f3 835 scm_array_set_x (ra0, scm_divide (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)), scm_from_ulong (i0));
0f2d19dd
JB
836 break;
837 }
0f2d19dd
JB
838 }
839 }
840 return 1;
841}
842
1cc91f1b 843
0f2d19dd 844int
1bbd0b84 845scm_array_identity (SCM dst, SCM src)
0f2d19dd
JB
846{
847 return racp (SCM_CAR (src), scm_cons (dst, SCM_EOL));
848}
849
850
1cc91f1b 851
0f2d19dd 852static int
34d19ef6 853ramap (SCM ra0, SCM proc, SCM ras)
0f2d19dd 854{
c014a02e
ML
855 long i = SCM_ARRAY_DIMS (ra0)->lbnd;
856 long inc = SCM_ARRAY_DIMS (ra0)->inc;
857 long n = SCM_ARRAY_DIMS (ra0)->ubnd;
858 long base = SCM_ARRAY_BASE (ra0) - i * inc;
0f2d19dd 859 ra0 = SCM_ARRAY_V (ra0);
d2e53ed6 860 if (scm_is_null (ras))
c209c88e 861 for (; i <= n; i++)
e11e83f3 862 scm_array_set_x (ra0, scm_call_0 (proc), scm_from_long (i * inc + base));
0f2d19dd
JB
863 else
864 {
865 SCM ra1 = SCM_CAR (ras);
34d19ef6
HWN
866 SCM args;
867 SCM const *ve = &ras;
c014a02e
ML
868 unsigned long k, i1 = SCM_ARRAY_BASE (ra1);
869 long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
0f2d19dd
JB
870 ra1 = SCM_ARRAY_V (ra1);
871 ras = SCM_CDR (ras);
d2e53ed6 872 if (scm_is_null(ras))
c209c88e 873 ras = scm_nullvect;
0f2d19dd
JB
874 else
875 {
876 ras = scm_vector (ras);
877 ve = SCM_VELTS (ras);
878 }
34d19ef6 879
0f2d19dd
JB
880 for (; i <= n; i++, i1 += inc1)
881 {
882 args = SCM_EOL;
e11e83f3
MV
883 for (k = scm_to_ulong (scm_uniform_vector_length (ras)); k--;)
884 args = scm_cons (scm_uniform_vector_ref (ve[k], scm_from_long (i)), args);
0f2d19dd 885 args = scm_cons (scm_cvref (ra1, i1, SCM_UNDEFINED), args);
e11e83f3 886 scm_array_set_x (ra0, scm_apply_0 (proc, args), scm_from_long (i * inc + base));
0f2d19dd
JB
887 }
888 }
889 return 1;
890}
891
1cc91f1b 892
0f2d19dd 893static int
14b18ed6 894ramap_dsubr (SCM ra0, SCM proc, SCM ras)
0f2d19dd
JB
895{
896 SCM ra1 = SCM_CAR (ras);
897 SCM e1 = SCM_UNDEFINED;
c014a02e
ML
898 unsigned long i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1);
899 long inc0 = SCM_ARRAY_DIMS (ra0)->inc, inc1 = SCM_ARRAY_DIMS (ra1)->inc;
900 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra1)->lbnd + 1;
0f2d19dd
JB
901 ra0 = SCM_ARRAY_V (ra0);
902 ra1 = SCM_ARRAY_V (ra1);
ff467021 903 switch (SCM_TYP7 (ra0))
c209c88e
GB
904 {
905 default:
c209c88e 906 for (; n-- > 0; i0 += inc0, i1 += inc1)
e11e83f3 907 scm_array_set_x (ra0, scm_call_1 (proc, RVREF (ra1, i1, e1)), scm_from_ulong (i0));
c209c88e 908 break;
c209c88e 909 }
0f2d19dd
JB
910 return 1;
911}
912
913
1cc91f1b 914
0f2d19dd 915static int
34d19ef6 916ramap_rp (SCM ra0, SCM proc, SCM ras)
0f2d19dd
JB
917{
918 SCM ra1 = SCM_CAR (ras), ra2 = SCM_CAR (SCM_CDR (ras));
919 SCM e1 = SCM_UNDEFINED, e2 = SCM_UNDEFINED;
c014a02e
ML
920 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
921 unsigned long i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1), i2 = SCM_ARRAY_BASE (ra2);
922 long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
923 long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
924 long inc2 = SCM_ARRAY_DIMS (ra1)->inc;
0f2d19dd
JB
925 ra0 = SCM_ARRAY_V (ra0);
926 ra1 = SCM_ARRAY_V (ra1);
927 ra2 = SCM_ARRAY_V (ra2);
928 switch (SCM_TYP7 (ra1) == SCM_TYP7 (ra2) ? SCM_TYP7 (ra1) : 0)
929 {
930 default:
931 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
c209c88e 932 if (SCM_BITVEC_REF (ra0, i0))
7888309b 933 if (scm_is_false (SCM_SUBRF (proc) (RVREF (ra1, i1, e1), RVREF (ra2, i2, e2))))
c209c88e 934 SCM_BITVEC_CLR (ra0, i0);
0f2d19dd 935 break;
0f2d19dd
JB
936 }
937 return 1;
938}
939
940
1cc91f1b 941
0f2d19dd 942static int
34d19ef6 943ramap_1 (SCM ra0, SCM proc, SCM ras)
0f2d19dd
JB
944{
945 SCM ra1 = SCM_CAR (ras);
946 SCM e1 = SCM_UNDEFINED;
c014a02e
ML
947 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
948 unsigned long i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1);
949 long inc0 = SCM_ARRAY_DIMS (ra0)->inc, inc1 = SCM_ARRAY_DIMS (ra1)->inc;
0f2d19dd
JB
950 ra0 = SCM_ARRAY_V (ra0);
951 ra1 = SCM_ARRAY_V (ra1);
95f5b0f5 952 if (scm_tc7_vector == SCM_TYP7 (ra0) || scm_tc7_wvect == SCM_TYP7 (ra0))
0f2d19dd 953 for (; n-- > 0; i0 += inc0, i1 += inc1)
e11e83f3 954 scm_array_set_x (ra0, SCM_SUBRF (proc) (scm_cvref (ra1, i1, SCM_UNDEFINED)), scm_from_ulong (i0));
0f2d19dd
JB
955 else
956 for (; n-- > 0; i0 += inc0, i1 += inc1)
e11e83f3 957 scm_array_set_x (ra0, SCM_SUBRF (proc) (RVREF (ra1, i1, e1)), scm_from_ulong (i0));
0f2d19dd
JB
958 return 1;
959}
960
961
1cc91f1b 962
0f2d19dd 963static int
34d19ef6 964ramap_2o (SCM ra0, SCM proc, SCM ras)
0f2d19dd
JB
965{
966 SCM ra1 = SCM_CAR (ras);
967 SCM e1 = SCM_UNDEFINED;
c014a02e
ML
968 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
969 unsigned long i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1);
970 long inc0 = SCM_ARRAY_DIMS (ra0)->inc, inc1 = SCM_ARRAY_DIMS (ra1)->inc;
0f2d19dd
JB
971 ra0 = SCM_ARRAY_V (ra0);
972 ra1 = SCM_ARRAY_V (ra1);
973 ras = SCM_CDR (ras);
d2e53ed6 974 if (scm_is_null (ras))
c209c88e
GB
975 {
976 if (scm_tc7_vector == SCM_TYP7 (ra0)
977 || scm_tc7_wvect == SCM_TYP7 (ra0))
95f5b0f5 978
c209c88e
GB
979 for (; n-- > 0; i0 += inc0, i1 += inc1)
980 scm_array_set_x (ra0, SCM_SUBRF (proc) (scm_cvref (ra1, i1, SCM_UNDEFINED), SCM_UNDEFINED),
e11e83f3 981 scm_from_ulong (i0));
c209c88e
GB
982 else
983 for (; n-- > 0; i0 += inc0, i1 += inc1)
984 scm_array_set_x (ra0, SCM_SUBRF (proc) (RVREF (ra1, i1, e1), SCM_UNDEFINED),
e11e83f3 985 scm_from_ulong (i0));
c209c88e 986 }
0f2d19dd
JB
987 else
988 {
989 SCM ra2 = SCM_CAR (ras);
990 SCM e2 = SCM_UNDEFINED;
c014a02e
ML
991 unsigned long i2 = SCM_ARRAY_BASE (ra2);
992 long inc2 = SCM_ARRAY_DIMS (ra2)->inc;
0f2d19dd 993 ra2 = SCM_ARRAY_V (ra2);
95f5b0f5 994 if (scm_tc7_vector == SCM_TYP7 (ra0) || scm_tc7_wvect == SCM_TYP7 (ra0))
0f2d19dd
JB
995 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
996 scm_array_set_x (ra0,
c209c88e 997 SCM_SUBRF (proc) (scm_cvref (ra1, i1, SCM_UNDEFINED), scm_cvref (ra2, i2, SCM_UNDEFINED)),
e11e83f3 998 scm_from_ulong (i0));
0f2d19dd
JB
999 else
1000 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
1001 scm_array_set_x (ra0,
c209c88e 1002 SCM_SUBRF (proc) (RVREF (ra1, i1, e1), RVREF (ra2, i2, e2)),
e11e83f3 1003 scm_from_ulong (i0));
0f2d19dd
JB
1004 }
1005 return 1;
1006}
1007
1008
1cc91f1b 1009
0f2d19dd 1010static int
34d19ef6 1011ramap_a (SCM ra0, SCM proc, SCM ras)
0f2d19dd
JB
1012{
1013 SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
c014a02e
ML
1014 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
1015 unsigned long i0 = SCM_ARRAY_BASE (ra0);
1016 long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
0f2d19dd 1017 ra0 = SCM_ARRAY_V (ra0);
d2e53ed6 1018 if (scm_is_null (ras))
c209c88e 1019 for (; n-- > 0; i0 += inc0)
e11e83f3 1020 scm_array_set_x (ra0, SCM_SUBRF (proc) (RVREF (ra0, i0, e0), SCM_UNDEFINED), scm_from_ulong (i0));
0f2d19dd
JB
1021 else
1022 {
1023 SCM ra1 = SCM_CAR (ras);
c014a02e
ML
1024 unsigned long i1 = SCM_ARRAY_BASE (ra1);
1025 long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
0f2d19dd
JB
1026 ra1 = SCM_ARRAY_V (ra1);
1027 for (; n-- > 0; i0 += inc0, i1 += inc1)
1028 scm_array_set_x (ra0, SCM_SUBRF (proc) (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)),
e11e83f3 1029 scm_from_ulong (i0));
0f2d19dd
JB
1030 }
1031 return 1;
1032}
1033
f5f2dcff 1034
1bbd0b84 1035SCM_REGISTER_PROC(s_array_map_in_order_x, "array-map-in-order!", 2, 0, 1, scm_array_map_x);
1cc91f1b 1036
1bbd0b84 1037
3b3b36dd 1038SCM_DEFINE (scm_array_map_x, "array-map!", 2, 0, 1,
c209c88e 1039 (SCM ra0, SCM proc, SCM lra),
8f85c0c6 1040 "@deffnx {Scheme Procedure} array-map-in-order! ra0 proc . lra\n"
b380b885
MD
1041 "@var{array1}, @dots{} must have the same number of dimensions as\n"
1042 "@var{array0} and have a range for each index which includes the range\n"
1043 "for the corresponding index in @var{array0}. @var{proc} is applied to\n"
1044 "each tuple of elements of @var{array1} @dots{} and the result is stored\n"
1045 "as the corresponding element in @var{array0}. The value returned is\n"
1046 "unspecified. The order of application is unspecified.")
1bbd0b84 1047#define FUNC_NAME s_scm_array_map_x
0f2d19dd 1048{
34d19ef6 1049 SCM_VALIDATE_PROC (2, proc);
af45e3b0 1050 SCM_VALIDATE_REST_ARGUMENT (lra);
0f2d19dd 1051 switch (SCM_TYP7 (proc))
c209c88e
GB
1052 {
1053 default:
1054 gencase:
1055 scm_ramapc (ramap, proc, ra0, lra, FUNC_NAME);
1056 return SCM_UNSPECIFIED;
1057 case scm_tc7_subr_1:
1058 scm_ramapc (ramap_1, proc, ra0, lra, FUNC_NAME);
1059 return SCM_UNSPECIFIED;
1060 case scm_tc7_subr_2:
1061 case scm_tc7_subr_2o:
1062 scm_ramapc (ramap_2o, proc, ra0, lra, FUNC_NAME);
1063 return SCM_UNSPECIFIED;
14b18ed6
DH
1064 case scm_tc7_dsubr:
1065 scm_ramapc (ramap_dsubr, proc, ra0, lra, FUNC_NAME);
c209c88e
GB
1066 return SCM_UNSPECIFIED;
1067 case scm_tc7_rpsubr:
0f2d19dd 1068 {
c209c88e 1069 ra_iproc *p;
7888309b 1070 if (scm_is_false (scm_array_p (ra0, SCM_BOOL_T)))
0f2d19dd 1071 goto gencase;
c209c88e
GB
1072 scm_array_fill_x (ra0, SCM_BOOL_T);
1073 for (p = ra_rpsubrs; p->name; p++)
bc36d050 1074 if (scm_is_eq (proc, p->sproc))
c209c88e 1075 {
d2e53ed6 1076 while (!scm_is_null (lra) && !scm_is_null (SCM_CDR (lra)))
c209c88e
GB
1077 {
1078 scm_ramapc (p->vproc, SCM_UNDEFINED, ra0, lra, FUNC_NAME);
1079 lra = SCM_CDR (lra);
1080 }
1081 return SCM_UNSPECIFIED;
1082 }
d2e53ed6 1083 while (!scm_is_null (lra) && !scm_is_null (SCM_CDR (lra)))
c209c88e
GB
1084 {
1085 scm_ramapc (ramap_rp, proc, ra0, lra, FUNC_NAME);
1086 lra = SCM_CDR (lra);
1087 }
0f2d19dd 1088 return SCM_UNSPECIFIED;
c209c88e
GB
1089 }
1090 case scm_tc7_asubr:
d2e53ed6 1091 if (scm_is_null (lra))
c209c88e
GB
1092 {
1093 SCM prot, fill = SCM_SUBRF (proc) (SCM_UNDEFINED, SCM_UNDEFINED);
e11e83f3 1094 if (SCM_I_INUMP(fill))
c209c88e
GB
1095 {
1096 prot = scm_array_prototype (ra0);
eb42e2f0 1097 if (SCM_INEXACTP (prot))
d9a67fc4 1098 fill = scm_from_double ((double) SCM_I_INUM (fill));
c209c88e
GB
1099 }
1100
1101 scm_array_fill_x (ra0, fill);
1102 }
1103 else
0f2d19dd 1104 {
c209c88e
GB
1105 SCM tail, ra1 = SCM_CAR (lra);
1106 SCM v0 = (SCM_ARRAYP (ra0) ? SCM_ARRAY_V (ra0) : ra0);
0f2d19dd 1107 ra_iproc *p;
c209c88e
GB
1108 /* Check to see if order might matter.
1109 This might be an argument for a separate
1110 SERIAL-ARRAY-MAP! */
bc36d050
MV
1111 if (scm_is_eq (v0, ra1)
1112 || (SCM_ARRAYP (ra1) && scm_is_eq (v0, SCM_ARRAY_V (ra1))))
1113 if (!scm_is_eq (ra0, ra1)
fee7ef83 1114 || (SCM_ARRAYP(ra0) && !SCM_ARRAY_CONTP(ra0)))
c209c88e 1115 goto gencase;
d2e53ed6 1116 for (tail = SCM_CDR (lra); !scm_is_null (tail); tail = SCM_CDR (tail))
c209c88e
GB
1117 {
1118 ra1 = SCM_CAR (tail);
bc36d050
MV
1119 if (scm_is_eq (v0, ra1)
1120 || (SCM_ARRAYP (ra1) && scm_is_eq (v0, SCM_ARRAY_V (ra1))))
c209c88e
GB
1121 goto gencase;
1122 }
1123 for (p = ra_asubrs; p->name; p++)
bc36d050 1124 if (scm_is_eq (proc, p->sproc))
0f2d19dd 1125 {
bc36d050 1126 if (!scm_is_eq (ra0, SCM_CAR (lra)))
c209c88e
GB
1127 scm_ramapc (scm_array_identity, SCM_UNDEFINED, ra0, scm_cons (SCM_CAR (lra), SCM_EOL), FUNC_NAME);
1128 lra = SCM_CDR (lra);
1129 while (1)
0f2d19dd 1130 {
c209c88e
GB
1131 scm_ramapc (p->vproc, SCM_UNDEFINED, ra0, lra, FUNC_NAME);
1132 if (SCM_IMP (lra) || SCM_IMP (SCM_CDR (lra)))
1133 return SCM_UNSPECIFIED;
0f2d19dd
JB
1134 lra = SCM_CDR (lra);
1135 }
0f2d19dd 1136 }
c209c88e
GB
1137 scm_ramapc (ramap_2o, proc, ra0, lra, FUNC_NAME);
1138 lra = SCM_CDR (lra);
1139 if (SCM_NIMP (lra))
1140 for (lra = SCM_CDR (lra); SCM_NIMP (lra); lra = SCM_CDR (lra))
1141 scm_ramapc (ramap_a, proc, ra0, lra, FUNC_NAME);
0f2d19dd 1142 }
c209c88e
GB
1143 return SCM_UNSPECIFIED;
1144 }
0f2d19dd 1145}
1bbd0b84 1146#undef FUNC_NAME
0f2d19dd 1147
1cc91f1b 1148
0f2d19dd 1149static int
34d19ef6 1150rafe (SCM ra0, SCM proc, SCM ras)
0f2d19dd 1151{
c014a02e
ML
1152 long i = SCM_ARRAY_DIMS (ra0)->lbnd;
1153 unsigned long i0 = SCM_ARRAY_BASE (ra0);
1154 long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
1155 long n = SCM_ARRAY_DIMS (ra0)->ubnd;
0f2d19dd 1156 ra0 = SCM_ARRAY_V (ra0);
d2e53ed6 1157 if (scm_is_null (ras))
c209c88e 1158 for (; i <= n; i++, i0 += inc0)
fdc28395 1159 scm_call_1 (proc, scm_cvref (ra0, i0, SCM_UNDEFINED));
0f2d19dd
JB
1160 else
1161 {
1162 SCM ra1 = SCM_CAR (ras);
34d19ef6
HWN
1163 SCM args;
1164 SCM const*ve = &ras;
c014a02e
ML
1165 unsigned long k, i1 = SCM_ARRAY_BASE (ra1);
1166 long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
0f2d19dd
JB
1167 ra1 = SCM_ARRAY_V (ra1);
1168 ras = SCM_CDR (ras);
d2e53ed6 1169 if (scm_is_null(ras))
c209c88e 1170 ras = scm_nullvect;
0f2d19dd
JB
1171 else
1172 {
1173 ras = scm_vector (ras);
1174 ve = SCM_VELTS (ras);
1175 }
1176 for (; i <= n; i++, i0 += inc0, i1 += inc1)
1177 {
1178 args = SCM_EOL;
e11e83f3
MV
1179 for (k = scm_to_ulong (scm_uniform_vector_length (ras)); k--;)
1180 args = scm_cons (scm_uniform_vector_ref (ve[k], scm_from_long (i)), args);
0f2d19dd 1181 args = scm_cons2 (scm_cvref (ra0, i0, SCM_UNDEFINED), scm_cvref (ra1, i1, SCM_UNDEFINED), args);
fdc28395 1182 scm_apply_0 (proc, args);
0f2d19dd
JB
1183 }
1184 }
1185 return 1;
1186}
1187
1188
3b3b36dd 1189SCM_DEFINE (scm_array_for_each, "array-for-each", 2, 0, 1,
c209c88e 1190 (SCM proc, SCM ra0, SCM lra),
8f85c0c6 1191 "Apply @var{proc} to each tuple of elements of @var{array0} @dots{}\n"
b380b885 1192 "in row-major order. The value returned is unspecified.")
1bbd0b84 1193#define FUNC_NAME s_scm_array_for_each
0f2d19dd 1194{
34d19ef6 1195 SCM_VALIDATE_PROC (1, proc);
af45e3b0 1196 SCM_VALIDATE_REST_ARGUMENT (lra);
c209c88e 1197 scm_ramapc (rafe, proc, ra0, lra, FUNC_NAME);
0f2d19dd
JB
1198 return SCM_UNSPECIFIED;
1199}
1bbd0b84 1200#undef FUNC_NAME
0f2d19dd 1201
3b3b36dd 1202SCM_DEFINE (scm_array_index_map_x, "array-index-map!", 2, 0, 0,
c209c88e 1203 (SCM ra, SCM proc),
8f85c0c6 1204 "Apply @var{proc} to the indices of each element of @var{array} in\n"
b380b885
MD
1205 "turn, storing the result in the corresponding element. The value\n"
1206 "returned and the order of application are unspecified.\n\n"
1207 "One can implement @var{array-indexes} as\n"
1e6808ea 1208 "@lisp\n"
b380b885
MD
1209 "(define (array-indexes array)\n"
1210 " (let ((ra (apply make-array #f (array-shape array))))\n"
1211 " (array-index-map! ra (lambda x x))\n"
1212 " ra))\n"
1e6808ea 1213 "@end lisp\n"
b380b885 1214 "Another example:\n"
1e6808ea 1215 "@lisp\n"
b380b885
MD
1216 "(define (apl:index-generator n)\n"
1217 " (let ((v (make-uniform-vector n 1)))\n"
1218 " (array-index-map! v (lambda (i) i))\n"
1219 " v))\n"
1e6808ea 1220 "@end lisp")
1bbd0b84 1221#define FUNC_NAME s_scm_array_index_map_x
0f2d19dd 1222{
c014a02e 1223 unsigned long i;
34d19ef6
HWN
1224 SCM_VALIDATE_NIM (1, ra);
1225 SCM_VALIDATE_PROC (2, proc);
b4bdadde
MV
1226 if (scm_is_uniform_vector (ra))
1227 goto uniform_vector;
e42c09cc
RS
1228 switch (SCM_TYP7(ra))
1229 {
1230 default:
276dd677 1231 badarg:SCM_WRONG_TYPE_ARG (1, ra);
e42c09cc
RS
1232 case scm_tc7_vector:
1233 case scm_tc7_wvect:
0f2d19dd 1234 {
b226e5f6 1235 for (i = 0; i < SCM_VECTOR_LENGTH (ra); i++)
e11e83f3 1236 SCM_VECTOR_SET(ra, i, scm_call_1 (proc, scm_from_long (i)));
e42c09cc
RS
1237 return SCM_UNSPECIFIED;
1238 }
1239 case scm_tc7_string:
e42c09cc 1240 case scm_tc7_bvect:
b4bdadde 1241 uniform_vector:
b226e5f6 1242 {
e11e83f3 1243 unsigned long int length = scm_to_ulong (scm_uniform_vector_length (ra));
b226e5f6 1244 for (i = 0; i < length; i++)
e11e83f3
MV
1245 scm_array_set_x (ra, scm_call_1 (proc, scm_from_ulong (i)),
1246 scm_from_ulong (i));
b226e5f6
DH
1247 return SCM_UNSPECIFIED;
1248 }
e42c09cc
RS
1249 case scm_tc7_smob:
1250 SCM_ASRTGO (SCM_ARRAYP (ra), badarg);
1251 {
1252 SCM args = SCM_EOL;
e11e83f3 1253 SCM inds = scm_make_uve (SCM_ARRAY_NDIM (ra), scm_from_int (-1));
c014a02e 1254 long *vinds = (long *) SCM_VELTS (inds);
e42c09cc
RS
1255 int j, k, kmax = SCM_ARRAY_NDIM (ra) - 1;
1256 if (kmax < 0)
fdc28395 1257 return scm_array_set_x (ra, scm_call_0 (proc), SCM_EOL);
e42c09cc
RS
1258 for (k = 0; k <= kmax; k++)
1259 vinds[k] = SCM_ARRAY_DIMS (ra)[k].lbnd;
1260 k = kmax;
1261 do
1262 {
1263 if (k == kmax)
1264 {
1265 vinds[k] = SCM_ARRAY_DIMS (ra)[k].lbnd;
1266 i = cind (ra, inds);
1267 for (; vinds[k] <= SCM_ARRAY_DIMS (ra)[k].ubnd; vinds[k]++)
1268 {
1269 for (j = kmax + 1, args = SCM_EOL; j--;)
e11e83f3 1270 args = scm_cons (scm_from_long (vinds[j]), args);
e42c09cc 1271 scm_array_set_x (SCM_ARRAY_V (ra),
fdc28395 1272 scm_apply_0 (proc, args),
e11e83f3 1273 scm_from_ulong (i));
e42c09cc
RS
1274 i += SCM_ARRAY_DIMS (ra)[k].inc;
1275 }
1276 k--;
1277 continue;
1278 }
1279 if (vinds[k] < SCM_ARRAY_DIMS (ra)[k].ubnd)
1280 {
1281 vinds[k]++;
1282 k++;
1283 continue;
1284 }
1285 vinds[k] = SCM_ARRAY_DIMS (ra)[k].lbnd - 1;
1286 k--;
1287 }
1288 while (k >= 0);
0f2d19dd 1289 return SCM_UNSPECIFIED;
0f2d19dd 1290 }
e42c09cc 1291 }
0f2d19dd 1292}
1bbd0b84 1293#undef FUNC_NAME
0f2d19dd 1294
1cc91f1b 1295
0f2d19dd 1296static int
34d19ef6 1297raeql_1 (SCM ra0, SCM as_equal, SCM ra1)
0f2d19dd
JB
1298{
1299 SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
c014a02e
ML
1300 unsigned long i0 = 0, i1 = 0;
1301 long inc0 = 1, inc1 = 1;
1302 unsigned long n;
0f2d19dd 1303 ra1 = SCM_CAR (ra1);
ff467021 1304 if (SCM_ARRAYP(ra0))
c209c88e
GB
1305 {
1306 n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
1307 i0 = SCM_ARRAY_BASE (ra0);
1308 inc0 = SCM_ARRAY_DIMS (ra0)->inc;
1309 ra0 = SCM_ARRAY_V (ra0);
1310 }
e466c6a2 1311 else
e11e83f3 1312 n = scm_to_ulong (scm_uniform_vector_length (ra0));
ff467021 1313 if (SCM_ARRAYP (ra1))
c209c88e
GB
1314 {
1315 i1 = SCM_ARRAY_BASE (ra1);
1316 inc1 = SCM_ARRAY_DIMS (ra1)->inc;
1317 ra1 = SCM_ARRAY_V (ra1);
1318 }
b4bdadde
MV
1319 if (scm_is_uniform_vector (ra0))
1320 goto uniform_vector;
c209c88e
GB
1321 switch (SCM_TYP7 (ra0))
1322 {
1323 case scm_tc7_vector:
1324 case scm_tc7_wvect:
1325 default:
b4bdadde 1326 uniform_vector:
c209c88e
GB
1327 for (; n--; i0 += inc0, i1 += inc1)
1328 {
7888309b 1329 if (scm_is_false (as_equal))
c209c88e 1330 {
7888309b 1331 if (scm_is_false (scm_array_equal_p (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1))))
c209c88e
GB
1332 return 0;
1333 }
7888309b 1334 else if (scm_is_false (scm_equal_p (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1))))
c209c88e
GB
1335 return 0;
1336 }
1337 return 1;
1338 case scm_tc7_string:
405aaef9 1339 {
cc95e00a
MV
1340 const char *v0 = scm_i_string_chars (ra0) + i0;
1341 const char *v1 = scm_i_string_chars (ra1) + i1;
405aaef9
DH
1342 for (; n--; v0 += inc0, v1 += inc1)
1343 if (*v0 != *v1)
1344 return 0;
1345 return 1;
1346 }
c209c88e
GB
1347 case scm_tc7_bvect:
1348 for (; n--; i0 += inc0, i1 += inc1)
1349 if (SCM_BITVEC_REF (ra0, i0) != SCM_BITVEC_REF (ra1, i1))
1350 return 0;
1351 return 1;
c209c88e 1352 }
0f2d19dd
JB
1353}
1354
1355
1cc91f1b 1356
0f2d19dd 1357static int
34d19ef6 1358raeql (SCM ra0, SCM as_equal, SCM ra1)
0f2d19dd
JB
1359{
1360 SCM v0 = ra0, v1 = ra1;
92c2555f
MV
1361 scm_t_array_dim dim0, dim1;
1362 scm_t_array_dim *s0 = &dim0, *s1 = &dim1;
c014a02e 1363 unsigned long bas0 = 0, bas1 = 0;
0f2d19dd 1364 int k, unroll = 1, vlen = 1, ndim = 1;
ff467021 1365 if (SCM_ARRAYP (ra0))
c209c88e
GB
1366 {
1367 ndim = SCM_ARRAY_NDIM (ra0);
1368 s0 = SCM_ARRAY_DIMS (ra0);
1369 bas0 = SCM_ARRAY_BASE (ra0);
1370 v0 = SCM_ARRAY_V (ra0);
1371 }
0f2d19dd
JB
1372 else
1373 {
1374 s0->inc = 1;
1375 s0->lbnd = 0;
e11e83f3 1376 s0->ubnd = scm_to_long (scm_uniform_vector_length (v0)) - 1;
0f2d19dd
JB
1377 unroll = 0;
1378 }
ff467021 1379 if (SCM_ARRAYP (ra1))
c209c88e
GB
1380 {
1381 if (ndim != SCM_ARRAY_NDIM (ra1))
1382 return 0;
1383 s1 = SCM_ARRAY_DIMS (ra1);
1384 bas1 = SCM_ARRAY_BASE (ra1);
1385 v1 = SCM_ARRAY_V (ra1);
1386 }
0f2d19dd
JB
1387 else
1388 {
c209c88e
GB
1389 /*
1390 Huh ? Schizophrenic return type. --hwn
1391 */
0f2d19dd 1392 if (1 != ndim)
c209c88e 1393 return 0;
0f2d19dd
JB
1394 s1->inc = 1;
1395 s1->lbnd = 0;
e11e83f3 1396 s1->ubnd = scm_to_long (scm_uniform_vector_length (v1)) - 1;
0f2d19dd
JB
1397 unroll = 0;
1398 }
1399 if (SCM_TYP7 (v0) != SCM_TYP7 (v1))
1400 return 0;
1401 for (k = ndim; k--;)
1402 {
1403 if (s0[k].lbnd != s1[k].lbnd || s0[k].ubnd != s1[k].ubnd)
1404 return 0;
1405 if (unroll)
1406 {
1407 unroll = (s0[k].inc == s1[k].inc);
1408 vlen *= s0[k].ubnd - s1[k].lbnd + 1;
1409 }
1410 }
bc36d050 1411 if (unroll && bas0 == bas1 && scm_is_eq (v0, v1))
c209c88e 1412 return 1;
0f2d19dd
JB
1413 return scm_ramapc (raeql_1, as_equal, ra0, scm_cons (ra1, SCM_EOL), "");
1414}
1415
1cc91f1b 1416
0f2d19dd 1417SCM
1bbd0b84 1418scm_raequal (SCM ra0, SCM ra1)
0f2d19dd 1419{
7888309b 1420 return scm_from_bool(raeql (ra0, SCM_BOOL_T, ra1));
0f2d19dd
JB
1421}
1422
4079f87e 1423#if 0
c3ee7520
GB
1424/* GJB:FIXME:: Why not use SCM_DEFINE1 for array-equal? */
1425SCM_DEFINE1 (scm_array_equal_p, "array-equal?", scm_tc7_rpsubr,
c209c88e 1426 (SCM ra0, SCM ra1),
1e6808ea
MG
1427 "Return @code{#t} iff all arguments are arrays with the same\n"
1428 "shape, the same type, and have corresponding elements which are\n"
1429 "either @code{equal?} or @code{array-equal?}. This function\n"
1430 "differs from @code{equal?} in that a one dimensional shared\n"
1431 "array may be @var{array-equal?} but not @var{equal?} to a\n"
1432 "vector or uniform vector.")
4079f87e 1433#define FUNC_NAME s_scm_array_equal_p
0f981281
GB
1434{
1435}
4079f87e
GB
1436#undef FUNC_NAME
1437#endif
1438
0f2d19dd
JB
1439static char s_array_equal_p[] = "array-equal?";
1440
1cc91f1b 1441
0f2d19dd 1442SCM
1bbd0b84 1443scm_array_equal_p (SCM ra0, SCM ra1)
0f2d19dd
JB
1444{
1445 if (SCM_IMP (ra0) || SCM_IMP (ra1))
c209c88e 1446 callequal:return scm_equal_p (ra0, ra1);
ff467021 1447 switch (SCM_TYP7(ra0))
c209c88e
GB
1448 {
1449 default:
1450 goto callequal;
1451 case scm_tc7_bvect:
1452 case scm_tc7_string:
c209c88e
GB
1453 case scm_tc7_vector:
1454 case scm_tc7_wvect:
1455 break;
1456 case scm_tc7_smob:
1457 if (!SCM_ARRAYP (ra0))
0f2d19dd 1458 goto callequal;
c209c88e 1459 }
ff467021 1460 switch (SCM_TYP7 (ra1))
c209c88e
GB
1461 {
1462 default:
1463 goto callequal;
1464 case scm_tc7_bvect:
1465 case scm_tc7_string:
c209c88e
GB
1466 case scm_tc7_vector:
1467 case scm_tc7_wvect:
1468 break;
1469 case scm_tc7_smob:
1470 if (!SCM_ARRAYP (ra1))
0f2d19dd 1471 goto callequal;
c209c88e 1472 }
7888309b 1473 return scm_from_bool(raeql (ra0, SCM_BOOL_F, ra1));
0f2d19dd
JB
1474}
1475
1476
1cc91f1b 1477static void
1bbd0b84 1478init_raprocs (ra_iproc *subra)
0f2d19dd
JB
1479{
1480 for (; subra->name; subra++)
86d31dfe 1481 {
cc95e00a 1482 SCM sym = scm_from_locale_symbol (subra->name);
86d31dfe
MV
1483 SCM var =
1484 scm_sym2var (sym, scm_current_module_lookup_closure (), SCM_BOOL_F);
1485 if (var != SCM_BOOL_F)
1486 subra->sproc = SCM_VARIABLE_REF (var);
1487 else
1488 subra->sproc = SCM_BOOL_F;
1489 }
0f2d19dd
JB
1490}
1491
1cc91f1b 1492
0f2d19dd
JB
1493void
1494scm_init_ramap ()
0f2d19dd
JB
1495{
1496 init_raprocs (ra_rpsubrs);
1497 init_raprocs (ra_asubrs);
9a441ddb 1498 scm_c_define_subr (s_array_equal_p, scm_tc7_rpsubr, scm_array_equal_p);
7a7f7c53 1499 scm_smobs[SCM_TC2SMOBNUM (scm_tc16_array)].equalp = scm_raequal;
a0599745 1500#include "libguile/ramap.x"
1bbd0b84 1501 scm_add_feature (s_scm_array_for_each);
0f2d19dd 1502}
89e00824
ML
1503
1504/*
1505 Local Variables:
1506 c-file-style: "gnu"
1507 End:
1508*/