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