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