build: Don't include <config.h> in native programs when cross-compiling.
[bpt/guile.git] / libguile / vectors.c
CommitLineData
6922d92f 1/* Copyright (C) 1995,1996,1998,1999,2000,2001, 2006, 2008, 2009, 2010,
9b5da400 2 * 2011, 2012, 2014 Free Software Foundation, Inc.
6922d92f 3 *
73be1d9e 4 * This library is free software; you can redistribute it and/or
53befeb7
NJ
5 * modify it under the terms of the GNU Lesser General Public License
6 * as published by the Free Software Foundation; either version 3 of
7 * the License, or (at your option) any later version.
0f2d19dd 8 *
53befeb7
NJ
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
0f2d19dd 13 *
73be1d9e
MV
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
53befeb7
NJ
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301 USA
73be1d9e 18 */
1bbd0b84 19
1bbd0b84 20
0f2d19dd 21\f
dbb605f5
LC
22#ifdef HAVE_CONFIG_H
23# include <config.h>
24#endif
0f2d19dd 25
a0599745
MD
26#include "libguile/_scm.h"
27#include "libguile/eq.h"
28#include "libguile/root.h"
29#include "libguile/strings.h"
30
31#include "libguile/validate.h"
32#include "libguile/vectors.h"
5c39373f 33#include "libguile/arrays.h" /* Hit me with the ugly stick */
f332e957 34#include "libguile/generalized-vectors.h"
88797580
MV
35#include "libguile/strings.h"
36#include "libguile/srfi-13.h"
1d0df896 37#include "libguile/dynwind.h"
6e708ef2 38#include "libguile/deprecation.h"
88797580 39
1c44468d 40#include "libguile/bdw-gc.h"
3a2de079
LC
41
42
0f2d19dd
JB
43\f
44
6e708ef2
MV
45#define VECTOR_MAX_LENGTH (SCM_T_BITS_MAX >> 8)
46
6e708ef2
MV
47int
48scm_is_vector (SCM obj)
49{
24cac655 50 if (SCM_I_IS_NONWEAK_VECTOR (obj))
6e708ef2 51 return 1;
24cac655
AW
52 if (SCM_I_WVECTP (obj))
53 {
54 scm_c_issue_deprecation_warning
55 ("Expecting vector? to be true for weak vectors is deprecated. "
56 "Use weak-vector? instead.");
57 return 1;
58 }
59 if (SCM_I_ARRAYP (obj) && SCM_I_ARRAY_NDIM (obj) == 1)
6e708ef2 60 {
04b87de5 61 SCM v = SCM_I_ARRAY_V (obj);
24cac655
AW
62 if (SCM_I_IS_VECTOR (v))
63 {
64 scm_c_issue_deprecation_warning
65 ("Expecting vector? to be true for rank-1 arrays is deprecated. "
66 "Use array?, array-rank, and array-type instead.");
67 return 1;
68 }
69 return 0;
6e708ef2
MV
70 }
71 return 0;
72}
73
74int
75scm_is_simple_vector (SCM obj)
1d0df896 76{
24cac655
AW
77 if (SCM_I_IS_NONWEAK_VECTOR (obj))
78 return 1;
79 if (SCM_I_WVECTP (obj))
80 {
81 scm_c_issue_deprecation_warning
82 ("Expecting scm_is_simple_vector to be true for weak vectors is "
83 "deprecated. Use scm_is_weak_vector instead.");
84 return 1;
85 }
86 return 0;
1d0df896
MV
87}
88
354116f7
MV
89const SCM *
90scm_vector_elements (SCM vec, scm_t_array_handle *h,
91 size_t *lenp, ssize_t *incp)
92{
3a2de079
LC
93 if (SCM_I_WVECTP (vec))
94 /* FIXME: We should check each (weak) element of the vector for NULL and
95 convert it to SCM_BOOL_F. */
96 abort ();
97
354116f7
MV
98 scm_generalized_vector_get_handle (vec, h);
99 if (lenp)
100 {
101 scm_t_array_dim *dim = scm_array_handle_dims (h);
102 *lenp = dim->ubnd - dim->lbnd + 1;
103 *incp = dim->inc;
104 }
105 return scm_array_handle_elements (h);
106}
107
108SCM *
109scm_vector_writable_elements (SCM vec, scm_t_array_handle *h,
110 size_t *lenp, ssize_t *incp)
111{
3a2de079
LC
112 if (SCM_I_WVECTP (vec))
113 /* FIXME: We should check each (weak) element of the vector for NULL and
114 convert it to SCM_BOOL_F. */
115 abort ();
116
354116f7
MV
117 scm_generalized_vector_get_handle (vec, h);
118 if (lenp)
119 {
120 scm_t_array_dim *dim = scm_array_handle_dims (h);
121 *lenp = dim->ubnd - dim->lbnd + 1;
122 *incp = dim->inc;
123 }
124 return scm_array_handle_writable_elements (h);
125}
126
a1ec6916 127SCM_DEFINE (scm_vector_p, "vector?", 1, 0, 0,
5ffe9968 128 (SCM obj),
1e6808ea
MG
129 "Return @code{#t} if @var{obj} is a vector, otherwise return\n"
130 "@code{#f}.")
1bbd0b84 131#define FUNC_NAME s_scm_vector_p
0f2d19dd 132{
de5c0f58 133 return scm_from_bool (scm_is_vector (obj));
0f2d19dd 134}
1bbd0b84 135#undef FUNC_NAME
0f2d19dd 136
f172c0b7 137SCM_GPROC (s_vector_length, "vector-length", 1, 0, 0, scm_vector_length, g_vector_length);
1e6808ea 138/* Returns the number of elements in @var{vector} as an exact integer. */
0f2d19dd 139SCM
f172c0b7 140scm_vector_length (SCM v)
0f2d19dd 141{
6e708ef2 142 if (SCM_I_IS_VECTOR (v))
9b5da400
AW
143 {
144 if (SCM_I_WVECTP (v))
145 scm_c_issue_deprecation_warning
146 ("Using vector-length on weak vectors is deprecated. "
147 "Use weak-vector-length from (ice-9 weak-vectors) instead.");
148 return scm_from_size_t (SCM_I_VECTOR_LENGTH (v));
149 }
04b87de5 150 else if (SCM_I_ARRAYP (v) && SCM_I_ARRAY_NDIM (v) == 1)
de5c0f58 151 {
04b87de5 152 scm_t_array_dim *dim = SCM_I_ARRAY_DIMS (v);
24cac655
AW
153 scm_c_issue_deprecation_warning
154 ("Using vector-length on arrays is deprecated. "
155 "Use array-length instead.");
de5c0f58
MV
156 return scm_from_size_t (dim->ubnd - dim->lbnd + 1);
157 }
5cfeff11
AW
158 else if (SCM_UNPACK (g_vector_length))
159 {
160 scm_c_issue_deprecation_warning
161 ("Using vector-length as a primitive-generic is deprecated.");
162 return scm_call_generic_1 (g_vector_length, v);
163 }
de5c0f58 164 else
5cfeff11
AW
165 {
166 scm_wrong_type_arg_msg ("vector-length", 1, v, "vector");
167 return SCM_UNDEFINED; /* not reached */
168 }
0f2d19dd
JB
169}
170
88797580
MV
171size_t
172scm_c_vector_length (SCM v)
173{
9b5da400 174 if (SCM_I_IS_NONWEAK_VECTOR (v))
6e708ef2 175 return SCM_I_VECTOR_LENGTH (v);
88797580 176 else
de5c0f58 177 return scm_to_size_t (scm_vector_length (v));
88797580
MV
178}
179
f172c0b7 180SCM_REGISTER_PROC (s_list_to_vector, "list->vector", 1, 0, 0, scm_vector);
5ffe9968 181/*
942e5b91
MG
182 "Return a newly created vector initialized to the elements of"
183 "the list @var{list}.\n\n"
184 "@lisp\n"
185 "(vector->list '#(dah dah didah)) @result{} (dah dah didah)\n"
186 "(list->vector '(dididit dah)) @result{} #(dididit dah)\n"
187 "@end lisp")
5ffe9968 188*/
a1ec6916 189SCM_DEFINE (scm_vector, "vector", 0, 0, 1,
f172c0b7 190 (SCM l),
8f85c0c6
NJ
191 "@deffnx {Scheme Procedure} list->vector l\n"
192 "Return a newly allocated vector composed of the\n"
1e6808ea
MG
193 "given arguments. Analogous to @code{list}.\n"
194 "\n"
942e5b91 195 "@lisp\n"
1e6808ea 196 "(vector 'a 'b 'c) @result{} #(a b c)\n"
942e5b91 197 "@end lisp")
1bbd0b84 198#define FUNC_NAME s_scm_vector
0f2d19dd
JB
199{
200 SCM res;
22a52da1 201 SCM *data;
1d0df896 202 long i, len;
6e708ef2 203 scm_t_array_handle handle;
22a52da1 204
1d0df896 205 SCM_VALIDATE_LIST_COPYLEN (1, l, len);
34d19ef6 206
6e708ef2
MV
207 res = scm_c_make_vector (len, SCM_UNSPECIFIED);
208 data = scm_vector_writable_elements (res, &handle, NULL, NULL);
1d0df896 209 i = 0;
c8857a4d 210 while (scm_is_pair (l) && i < len)
22a52da1 211 {
1d0df896 212 data[i] = SCM_CAR (l);
22a52da1 213 l = SCM_CDR (l);
6e708ef2 214 i += 1;
22a52da1
DH
215 }
216
c8857a4d
MV
217 scm_array_handle_release (&handle);
218
0f2d19dd
JB
219 return res;
220}
1bbd0b84 221#undef FUNC_NAME
0f2d19dd 222
f172c0b7 223SCM_GPROC (s_vector_ref, "vector-ref", 2, 0, 0, scm_vector_ref, g_vector_ref);
1cc91f1b 224
5ffe9968
GB
225/*
226 "@var{k} must be a valid index of @var{vector}.\n"
227 "@samp{Vector-ref} returns the contents of element @var{k} of\n"
228 "@var{vector}.\n\n"
942e5b91
MG
229 "@lisp\n"
230 "(vector-ref '#(1 1 2 3 5 8 13 21) 5) @result{} 8\n"
5ffe9968
GB
231 "(vector-ref '#(1 1 2 3 5 8 13 21)\n"
232 " (let ((i (round (* 2 (acos -1)))))\n"
233 " (if (inexact? i)\n"
234 " (inexact->exact i)\n"
942e5b91
MG
235 " i))) @result{} 13\n"
236 "@end lisp"
5ffe9968
GB
237*/
238
0f2d19dd 239SCM
ea633082 240scm_vector_ref (SCM v, SCM k)
685c0d71 241#define FUNC_NAME s_vector_ref
0f2d19dd 242{
de5c0f58 243 return scm_c_vector_ref (v, scm_to_size_t (k));
0f2d19dd 244}
685c0d71 245#undef FUNC_NAME
0f2d19dd 246
88797580
MV
247SCM
248scm_c_vector_ref (SCM v, size_t k)
249{
9b5da400 250 if (SCM_I_IS_NONWEAK_VECTOR (v))
de5c0f58 251 {
3a2de079
LC
252 register SCM elt;
253
6e708ef2 254 if (k >= SCM_I_VECTOR_LENGTH (v))
3a2de079
LC
255 scm_out_of_range (NULL, scm_from_size_t (k));
256 elt = (SCM_I_VECTOR_ELTS(v))[k];
257
3a2de079 258 return elt;
de5c0f58 259 }
9b5da400
AW
260 else if (SCM_I_WVECTP (v))
261 {
262 scm_c_issue_deprecation_warning
263 ("Using vector-ref on weak vectors is deprecated. "
264 "Instead, use weak-vector-ref from (ice-9 weak-vectors).");
265 return scm_c_weak_vector_ref (v, k);
266 }
04b87de5 267 else if (SCM_I_ARRAYP (v) && SCM_I_ARRAY_NDIM (v) == 1)
88797580 268 {
04b87de5
MV
269 scm_t_array_dim *dim = SCM_I_ARRAY_DIMS (v);
270 SCM vv = SCM_I_ARRAY_V (v);
6e708ef2
MV
271 if (SCM_I_IS_VECTOR (vv))
272 {
3a2de079
LC
273 register SCM elt;
274
24cac655
AW
275 scm_c_issue_deprecation_warning
276 ("Using vector-ref on arrays is deprecated. "
277 "Use array-ref instead.");
278
6e708ef2
MV
279 if (k >= dim->ubnd - dim->lbnd + 1)
280 scm_out_of_range (NULL, scm_from_size_t (k));
04b87de5 281 k = SCM_I_ARRAY_BASE (v) + k*dim->inc;
3a2de079
LC
282 elt = (SCM_I_VECTOR_ELTS (vv))[k];
283
b2b33168 284 if (SCM_UNPACK (elt) == 0 && (SCM_I_WVECTP (vv)))
9b5da400
AW
285 {
286 scm_c_issue_deprecation_warning
287 ("Weak arrays are deprecated. Use weak vectors instead.");
288 /* ELT was a weak pointer and got nullified by the GC. */
289 return SCM_BOOL_F;
290 }
3a2de079
LC
291
292 return elt;
6e708ef2
MV
293 }
294 scm_wrong_type_arg_msg (NULL, 0, v, "non-uniform vector");
88797580 295 }
5cfeff11
AW
296 else if (SCM_UNPACK (g_vector_ref))
297 {
298 scm_c_issue_deprecation_warning
299 ("Using vector-ref as a primitive-generic is deprecated.");
300 return scm_call_generic_2 (g_vector_ref, v, scm_from_size_t (k));
301 }
de5c0f58 302 else
5cfeff11
AW
303 {
304 scm_wrong_type_arg_msg ("vector-ref", 1, v, "vector");
305 return SCM_UNDEFINED; /* not reached */
306 }
88797580
MV
307}
308
f172c0b7 309SCM_GPROC (s_vector_set_x, "vector-set!", 3, 0, 0, scm_vector_set_x, g_vector_set_x);
1cc91f1b 310
942e5b91
MG
311/* "@var{k} must be a valid index of @var{vector}.\n"
312 "@code{Vector-set!} stores @var{obj} in element @var{k} of @var{vector}.\n"
313 "The value returned by @samp{vector-set!} is unspecified.\n"
314 "@lisp\n"
315 "(let ((vec (vector 0 '(2 2 2 2) "Anna")))\n"
316 " (vector-set! vec 1 '("Sue" "Sue"))\n"
317 " vec) @result{} #(0 ("Sue" "Sue") "Anna")\n"
318 "(vector-set! '#(0 1 2) 1 "doe") @result{} @emph{error} ; constant vector\n"
319 "@end lisp"
5ffe9968
GB
320*/
321
0f2d19dd 322SCM
f172c0b7 323scm_vector_set_x (SCM v, SCM k, SCM obj)
685c0d71 324#define FUNC_NAME s_vector_set_x
0f2d19dd 325{
de5c0f58 326 scm_c_vector_set_x (v, scm_to_size_t (k), obj);
60c497a3 327 return SCM_UNSPECIFIED;
0f2d19dd 328}
685c0d71 329#undef FUNC_NAME
0f2d19dd 330
de5c0f58 331void
88797580
MV
332scm_c_vector_set_x (SCM v, size_t k, SCM obj)
333{
9b5da400 334 if (SCM_I_IS_NONWEAK_VECTOR (v))
88797580 335 {
6e708ef2 336 if (k >= SCM_I_VECTOR_LENGTH (v))
de5c0f58 337 scm_out_of_range (NULL, scm_from_size_t (k));
6e708ef2 338 (SCM_I_VECTOR_WELTS(v))[k] = obj;
9b5da400
AW
339 }
340 else if (SCM_I_WVECTP (v))
341 {
342 scm_c_issue_deprecation_warning
343 ("Using vector-set! on weak vectors is deprecated. "
344 "Instead, use weak-vector-set! from (ice-9 weak-vectors).");
345 scm_c_weak_vector_set_x (v, k, obj);
de5c0f58 346 }
04b87de5 347 else if (SCM_I_ARRAYP (v) && SCM_I_ARRAY_NDIM (v) == 1)
de5c0f58 348 {
04b87de5
MV
349 scm_t_array_dim *dim = SCM_I_ARRAY_DIMS (v);
350 SCM vv = SCM_I_ARRAY_V (v);
6e708ef2
MV
351 if (SCM_I_IS_VECTOR (vv))
352 {
24cac655
AW
353 scm_c_issue_deprecation_warning
354 ("Using vector-set! on arrays is deprecated. "
355 "Use array-set! instead, but note the change in argument order.");
356
6e708ef2
MV
357 if (k >= dim->ubnd - dim->lbnd + 1)
358 scm_out_of_range (NULL, scm_from_size_t (k));
04b87de5 359 k = SCM_I_ARRAY_BASE (v) + k*dim->inc;
6e708ef2 360 (SCM_I_VECTOR_WELTS (vv))[k] = obj;
3a2de079
LC
361
362 if (SCM_I_WVECTP (vv))
363 {
364 /* Make it a weak pointer. */
6922d92f
LC
365 SCM *link = & SCM_I_VECTOR_WELTS (vv)[k];
366 SCM_I_REGISTER_DISAPPEARING_LINK ((void **) link, SCM2PTR (obj));
9b5da400
AW
367 scm_c_issue_deprecation_warning
368 ("Weak arrays are deprecated. Use weak vectors instead.");
3a2de079 369 }
6e708ef2
MV
370 }
371 else
372 scm_wrong_type_arg_msg (NULL, 0, v, "non-uniform vector");
88797580 373 }
5cfeff11
AW
374 else if (SCM_UNPACK (g_vector_set_x))
375 {
376 scm_c_issue_deprecation_warning
377 ("Using vector-set! as a primitive-generic is deprecated.");
24cac655 378 scm_call_3 (g_vector_set_x, v, scm_from_size_t (k), obj);
5cfeff11 379 }
88797580 380 else
24cac655 381 scm_wrong_type_arg_msg ("vector-set!", 1, v, "vector");
88797580 382}
0f2d19dd 383
a1ec6916 384SCM_DEFINE (scm_make_vector, "make-vector", 1, 1, 0,
1bbd0b84 385 (SCM k, SCM fill),
1e6808ea 386 "Return a newly allocated vector of @var{k} elements. If a\n"
8f85c0c6
NJ
387 "second argument is given, then each position is initialized to\n"
388 "@var{fill}. Otherwise the initial contents of each position is\n"
1e6808ea 389 "unspecified.")
1bbd0b84 390#define FUNC_NAME s_scm_make_vector
0f2d19dd 391{
6e708ef2 392 size_t l = scm_to_unsigned_integer (k, 0, VECTOR_MAX_LENGTH);
e11e83f3 393
1b9be268 394 if (SCM_UNBNDP (fill))
d60cebe2 395 fill = SCM_UNSPECIFIED;
e11e83f3
MV
396
397 return scm_c_make_vector (l, fill);
00ffa0e7
KN
398}
399#undef FUNC_NAME
400
e382fdbe 401
00ffa0e7 402SCM
88797580 403scm_c_make_vector (size_t k, SCM fill)
00ffa0e7
KN
404#define FUNC_NAME s_scm_make_vector
405{
ed7e0765 406 SCM *vector;
1b9be268 407
ed7e0765
LC
408 vector = (SCM *)
409 scm_gc_malloc ((k + SCM_I_VECTOR_HEADER_SIZE) * sizeof (SCM),
410 "vector");
411
412 if (k > 0)
e382fdbe 413 {
ed7e0765 414 SCM *base;
c014a02e 415 unsigned long int j;
1b9be268 416
6e708ef2 417 SCM_ASSERT_RANGE (1, scm_from_ulong (k), k <= VECTOR_MAX_LENGTH);
1b9be268 418
ed7e0765 419 base = vector + SCM_I_VECTOR_HEADER_SIZE;
e382fdbe 420 for (j = 0; j != k; ++j)
6e708ef2 421 base[j] = fill;
e382fdbe 422 }
1b9be268 423
ed7e0765
LC
424 ((scm_t_bits *) vector)[0] = (k << 8) | scm_tc7_vector;
425 ((scm_t_bits *) vector)[1] = 0;
1b9be268 426
ed7e0765 427 return PTR2SCM (vector);
0f2d19dd 428}
1bbd0b84 429#undef FUNC_NAME
0f2d19dd 430
6e708ef2
MV
431SCM_DEFINE (scm_vector_copy, "vector-copy", 1, 0, 0,
432 (SCM vec),
433 "Return a copy of @var{vec}.")
434#define FUNC_NAME s_scm_vector_copy
435{
436 scm_t_array_handle handle;
437 size_t i, len;
438 ssize_t inc;
439 const SCM *src;
ed7e0765 440 SCM result, *dst;
6e708ef2
MV
441
442 src = scm_vector_elements (vec, &handle, &len, &inc);
ed7e0765
LC
443
444 result = scm_c_make_vector (len, SCM_UNDEFINED);
445 dst = SCM_I_VECTOR_WELTS (result);
6e708ef2
MV
446 for (i = 0; i < len; i++, src += inc)
447 dst[i] = *src;
ed7e0765 448
c8857a4d 449 scm_array_handle_release (&handle);
6e708ef2 450
ed7e0765 451 return result;
6e708ef2
MV
452}
453#undef FUNC_NAME
454
d525e4f9
LC
455\f
456/* Weak vectors. */
457
d525e4f9
LC
458/* Allocate memory for the elements of a weak vector on behalf of the
459 caller. */
ed7e0765
LC
460static SCM
461make_weak_vector (scm_t_bits type, size_t c_size)
6e708ef2 462{
ed7e0765
LC
463 SCM *vector;
464 size_t total_size;
d525e4f9 465
ed7e0765
LC
466 total_size = (c_size + SCM_I_VECTOR_HEADER_SIZE) * sizeof (SCM);
467 vector = (SCM *) scm_gc_malloc_pointerless (total_size, "weak vector");
d525e4f9 468
ed7e0765
LC
469 ((scm_t_bits *) vector)[0] = (c_size << 8) | scm_tc7_wvect;
470 ((scm_t_bits *) vector)[1] = type;
471
472 return PTR2SCM (vector);
d525e4f9
LC
473}
474
475/* Return a new weak vector. The allocated vector will be of the given weak
476 vector subtype. It will contain SIZE elements which are initialized with
477 the FILL object, or, if FILL is undefined, with an unspecified object. */
478SCM
479scm_i_make_weak_vector (scm_t_bits type, SCM size, SCM fill)
480{
481 SCM wv, *base;
482 size_t c_size, j;
483
484 if (SCM_UNBNDP (fill))
485 fill = SCM_UNSPECIFIED;
6e708ef2
MV
486
487 c_size = scm_to_unsigned_integer (size, 0, VECTOR_MAX_LENGTH);
ed7e0765
LC
488 wv = make_weak_vector (type, c_size);
489 base = SCM_I_WVECT_GC_WVELTS (wv);
6e708ef2 490
d525e4f9
LC
491 for (j = 0; j != c_size; ++j)
492 base[j] = fill;
3a2de079 493
d525e4f9
LC
494 return wv;
495}
496
497/* Return a new weak vector with type TYPE and whose content are taken from
498 list LST. */
499SCM
500scm_i_make_weak_vector_from_list (scm_t_bits type, SCM lst)
501{
ed7e0765 502 SCM wv, *elt;
d525e4f9
LC
503 long c_size;
504
505 c_size = scm_ilength (lst);
506 SCM_ASSERT (c_size >= 0, lst, SCM_ARG2, "scm_i_make_weak_vector_from_list");
507
ed7e0765
LC
508 wv = make_weak_vector(type, (size_t) c_size);
509
510 for (elt = SCM_I_WVECT_GC_WVELTS (wv);
d525e4f9
LC
511 scm_is_pair (lst);
512 lst = SCM_CDR (lst), elt++)
513 {
514 *elt = SCM_CAR (lst);
6e708ef2 515 }
6e708ef2 516
d525e4f9 517 return wv;
6e708ef2 518}
e382fdbe 519
d525e4f9
LC
520
521\f
3b3b36dd 522SCM_DEFINE (scm_vector_to_list, "vector->list", 1, 0, 0,
1e6808ea 523 (SCM v),
8f85c0c6 524 "Return a newly allocated list composed of the elements of @var{v}.\n"
1e6808ea 525 "\n"
942e5b91
MG
526 "@lisp\n"
527 "(vector->list '#(dah dah didah)) @result{} (dah dah didah)\n"
528 "(list->vector '(dididit dah)) @result{} #(dididit dah)\n"
529 "@end lisp")
1bbd0b84 530#define FUNC_NAME s_scm_vector_to_list
0f2d19dd 531{
6e708ef2
MV
532 SCM res = SCM_EOL;
533 const SCM *data;
534 scm_t_array_handle handle;
22be72d3 535 size_t i, count, len;
6e708ef2
MV
536 ssize_t inc;
537
538 data = scm_vector_elements (v, &handle, &len, &inc);
22be72d3
LC
539 for (i = (len - 1) * inc, count = 0;
540 count < len;
541 i -= inc, count++)
542 res = scm_cons (data[i], res);
543
c8857a4d 544 scm_array_handle_release (&handle);
6e708ef2 545 return res;
0f2d19dd 546}
1bbd0b84 547#undef FUNC_NAME
0f2d19dd
JB
548
549
a1ec6916 550SCM_DEFINE (scm_vector_fill_x, "vector-fill!", 2, 0, 0,
1e6808ea 551 (SCM v, SCM fill),
8f85c0c6 552 "Store @var{fill} in every position of @var{vector}. The value\n"
1e6808ea 553 "returned by @code{vector-fill!} is unspecified.")
1bbd0b84 554#define FUNC_NAME s_scm_vector_fill_x
0f2d19dd 555{
6e708ef2
MV
556 scm_t_array_handle handle;
557 SCM *data;
558 size_t i, len;
559 ssize_t inc;
560
561 data = scm_vector_writable_elements (v, &handle, &len, &inc);
562 for (i = 0; i < len; i += inc)
563 data[i] = fill;
c8857a4d 564 scm_array_handle_release (&handle);
6e708ef2 565 return SCM_UNSPECIFIED;
0f2d19dd 566}
1bbd0b84 567#undef FUNC_NAME
0f2d19dd
JB
568
569
0f2d19dd 570SCM
354116f7 571scm_i_vector_equal_p (SCM x, SCM y)
0f2d19dd 572{
c014a02e 573 long i;
6e708ef2
MV
574 for (i = SCM_I_VECTOR_LENGTH (x) - 1; i >= 0; i--)
575 if (scm_is_false (scm_equal_p (SCM_I_VECTOR_ELTS (x)[i],
576 SCM_I_VECTOR_ELTS (y)[i])))
0f2d19dd
JB
577 return SCM_BOOL_F;
578 return SCM_BOOL_T;
579}
580
581
a1ec6916 582SCM_DEFINE (scm_vector_move_left_x, "vector-move-left!", 5, 0, 0,
1bbd0b84 583 (SCM vec1, SCM start1, SCM end1, SCM vec2, SCM start2),
694a9bb3
NJ
584 "Copy elements from @var{vec1}, positions @var{start1} to @var{end1},\n"
585 "to @var{vec2} starting at position @var{start2}. @var{start1} and\n"
586 "@var{start2} are inclusive indices; @var{end1} is exclusive.\n\n"
587 "@code{vector-move-left!} copies elements in leftmost order.\n"
588 "Therefore, in the case where @var{vec1} and @var{vec2} refer to the\n"
589 "same vector, @code{vector-move-left!} is usually appropriate when\n"
590 "@var{start1} is greater than @var{start2}.")
1bbd0b84 591#define FUNC_NAME s_scm_vector_move_left_x
0f2d19dd 592{
6e708ef2
MV
593 scm_t_array_handle handle1, handle2;
594 const SCM *elts1;
595 SCM *elts2;
de5c0f58 596 size_t len1, len2;
6e708ef2 597 ssize_t inc1, inc2;
a55c2b68 598 size_t i, j, e;
6e708ef2
MV
599
600 elts1 = scm_vector_elements (vec1, &handle1, &len1, &inc1);
601 elts2 = scm_vector_writable_elements (vec2, &handle2, &len2, &inc2);
34d19ef6 602
de5c0f58
MV
603 i = scm_to_unsigned_integer (start1, 0, len1);
604 e = scm_to_unsigned_integer (end1, i, len1);
ca659673 605 SCM_ASSERT_RANGE (SCM_ARG3, end1, (e-i) <= len2);
551b96d2
AW
606 j = scm_to_unsigned_integer (start2, 0, len2);
607 SCM_ASSERT_RANGE (SCM_ARG5, start2, j <= len2 - (e - i));
de5c0f58 608
6e708ef2
MV
609 i *= inc1;
610 e *= inc1;
611 j *= inc2;
612 for (; i < e; i += inc1, j += inc2)
613 elts2[j] = elts1[i];
614
c8857a4d
MV
615 scm_array_handle_release (&handle2);
616 scm_array_handle_release (&handle1);
617
0f2d19dd
JB
618 return SCM_UNSPECIFIED;
619}
1bbd0b84 620#undef FUNC_NAME
0f2d19dd 621
a1ec6916 622SCM_DEFINE (scm_vector_move_right_x, "vector-move-right!", 5, 0, 0,
1bbd0b84 623 (SCM vec1, SCM start1, SCM end1, SCM vec2, SCM start2),
694a9bb3
NJ
624 "Copy elements from @var{vec1}, positions @var{start1} to @var{end1},\n"
625 "to @var{vec2} starting at position @var{start2}. @var{start1} and\n"
626 "@var{start2} are inclusive indices; @var{end1} is exclusive.\n\n"
627 "@code{vector-move-right!} copies elements in rightmost order.\n"
628 "Therefore, in the case where @var{vec1} and @var{vec2} refer to the\n"
629 "same vector, @code{vector-move-right!} is usually appropriate when\n"
630 "@var{start1} is less than @var{start2}.")
1bbd0b84 631#define FUNC_NAME s_scm_vector_move_right_x
0f2d19dd 632{
6e708ef2
MV
633 scm_t_array_handle handle1, handle2;
634 const SCM *elts1;
635 SCM *elts2;
de5c0f58 636 size_t len1, len2;
6e708ef2 637 ssize_t inc1, inc2;
a55c2b68 638 size_t i, j, e;
6e708ef2
MV
639
640 elts1 = scm_vector_elements (vec1, &handle1, &len1, &inc1);
641 elts2 = scm_vector_writable_elements (vec2, &handle2, &len2, &inc2);
0f2d19dd 642
de5c0f58
MV
643 i = scm_to_unsigned_integer (start1, 0, len1);
644 e = scm_to_unsigned_integer (end1, i, len1);
ca659673 645 SCM_ASSERT_RANGE (SCM_ARG3, end1, (e-i) <= len2);
551b96d2
AW
646 j = scm_to_unsigned_integer (start2, 0, len2);
647 SCM_ASSERT_RANGE (SCM_ARG5, start2, j <= len2 - (e - i));
648
649 j += (e - i);
de5c0f58 650
6e708ef2
MV
651 i *= inc1;
652 e *= inc1;
653 j *= inc2;
654 while (i < e)
de5c0f58 655 {
6e708ef2
MV
656 e -= inc1;
657 j -= inc2;
658 elts2[j] = elts1[e];
de5c0f58 659 }
6e708ef2 660
c8857a4d
MV
661 scm_array_handle_release (&handle2);
662 scm_array_handle_release (&handle1);
663
0f2d19dd
JB
664 return SCM_UNSPECIFIED;
665}
1bbd0b84 666#undef FUNC_NAME
0f2d19dd 667
438974d0 668\f
2a610be5
AW
669static SCM
670vector_handle_ref (scm_t_array_handle *h, size_t idx)
88797580 671{
2a610be5
AW
672 if (idx > h->dims[0].ubnd)
673 scm_out_of_range ("vector-handle-ref", scm_from_size_t (idx));
674 return ((SCM*)h->elements)[idx];
88797580
MV
675}
676
2a610be5
AW
677static void
678vector_handle_set (scm_t_array_handle *h, size_t idx, SCM val)
88797580 679{
2a610be5
AW
680 if (idx > h->dims[0].ubnd)
681 scm_out_of_range ("vector-handle-set!", scm_from_size_t (idx));
682 ((SCM*)h->writable_elements)[idx] = val;
88797580 683}
88797580 684
2a610be5
AW
685static void
686vector_get_handle (SCM v, scm_t_array_handle *h)
88797580 687{
2a610be5
AW
688 h->array = v;
689 h->ndims = 1;
690 h->dims = &h->dim0;
691 h->dim0.lbnd = 0;
692 h->dim0.ubnd = SCM_I_VECTOR_LENGTH (v) - 1;
693 h->dim0.inc = 1;
694 h->element_type = SCM_ARRAY_ELEMENT_TYPE_SCM;
695 h->elements = h->writable_elements = SCM_I_VECTOR_WELTS (v);
88797580
MV
696}
697
c5f17102
AW
698/* the & ~2 allows catching scm_tc7_wvect as well. needs changing if you change
699 tags.h. */
2a610be5
AW
700SCM_ARRAY_IMPLEMENTATION (scm_tc7_vector, 0x7f & ~2,
701 vector_handle_ref, vector_handle_set,
f65e0168 702 vector_get_handle)
f65e0168 703SCM_VECTOR_IMPLEMENTATION (SCM_ARRAY_ELEMENT_TYPE_SCM, scm_make_vector)
88797580 704
1cc91f1b 705
0f2d19dd
JB
706void
707scm_init_vectors ()
0f2d19dd 708{
a0599745 709#include "libguile/vectors.x"
0f2d19dd
JB
710}
711
89e00824
ML
712
713/*
714 Local Variables:
715 c-file-style: "gnu"
716 End:
717*/