remove a stale comment
[bpt/guile.git] / libguile / vectors.c
CommitLineData
b2b33168 1/* Copyright (C) 1995,1996,1998,1999,2000,2001, 2006, 2008, 2009, 2010, 2011 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
fa075d40 126 return scm_wta_dispatch_1 (g_vector_length, v, 1, "vector-length");
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
b2b33168 216 if (SCM_UNPACK (elt) == 0 && SCM_I_WVECTP (v))
3a2de079
LC
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
b2b33168 235 if (SCM_UNPACK (elt) == 0 && (SCM_I_WVECTP (vv)))
3a2de079
LC
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 243 else
fa075d40
AW
244 return scm_wta_dispatch_2 (g_vector_ref, v, scm_from_size_t (k), 2,
245 "vector-ref");
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. */
281 GC_PTR link = (GC_PTR) & ((SCM_I_VECTOR_WELTS (v))[k]);
d3464bb6
AW
282 SCM_I_REGISTER_DISAPPEARING_LINK (link,
283 (GC_PTR) SCM2PTR (obj));
3a2de079 284 }
de5c0f58 285 }
04b87de5 286 else if (SCM_I_ARRAYP (v) && SCM_I_ARRAY_NDIM (v) == 1)
de5c0f58 287 {
04b87de5
MV
288 scm_t_array_dim *dim = SCM_I_ARRAY_DIMS (v);
289 SCM vv = SCM_I_ARRAY_V (v);
6e708ef2
MV
290 if (SCM_I_IS_VECTOR (vv))
291 {
292 if (k >= dim->ubnd - dim->lbnd + 1)
293 scm_out_of_range (NULL, scm_from_size_t (k));
04b87de5 294 k = SCM_I_ARRAY_BASE (v) + k*dim->inc;
6e708ef2 295 (SCM_I_VECTOR_WELTS (vv))[k] = obj;
3a2de079
LC
296
297 if (SCM_I_WVECTP (vv))
298 {
299 /* Make it a weak pointer. */
300 GC_PTR link = (GC_PTR) & ((SCM_I_VECTOR_WELTS (vv))[k]);
d3464bb6
AW
301 SCM_I_REGISTER_DISAPPEARING_LINK (link,
302 (GC_PTR) SCM2PTR (obj));
3a2de079 303 }
6e708ef2
MV
304 }
305 else
306 scm_wrong_type_arg_msg (NULL, 0, v, "non-uniform vector");
88797580
MV
307 }
308 else
309 {
de5c0f58 310 if (SCM_UNPACK (g_vector_set_x))
fa075d40
AW
311 scm_wta_dispatch_n (g_vector_set_x,
312 scm_list_3 (v, scm_from_size_t (k), obj),
313 0,
314 "vector-set!");
de5c0f58
MV
315 else
316 scm_wrong_type_arg_msg (NULL, 0, v, "vector");
88797580
MV
317 }
318}
0f2d19dd 319
a1ec6916 320SCM_DEFINE (scm_make_vector, "make-vector", 1, 1, 0,
1bbd0b84 321 (SCM k, SCM fill),
1e6808ea 322 "Return a newly allocated vector of @var{k} elements. If a\n"
8f85c0c6
NJ
323 "second argument is given, then each position is initialized to\n"
324 "@var{fill}. Otherwise the initial contents of each position is\n"
1e6808ea 325 "unspecified.")
1bbd0b84 326#define FUNC_NAME s_scm_make_vector
0f2d19dd 327{
6e708ef2 328 size_t l = scm_to_unsigned_integer (k, 0, VECTOR_MAX_LENGTH);
e11e83f3 329
1b9be268 330 if (SCM_UNBNDP (fill))
d60cebe2 331 fill = SCM_UNSPECIFIED;
e11e83f3
MV
332
333 return scm_c_make_vector (l, fill);
00ffa0e7
KN
334}
335#undef FUNC_NAME
336
e382fdbe 337
00ffa0e7 338SCM
88797580 339scm_c_make_vector (size_t k, SCM fill)
00ffa0e7
KN
340#define FUNC_NAME s_scm_make_vector
341{
ed7e0765 342 SCM *vector;
1b9be268 343
ed7e0765
LC
344 vector = (SCM *)
345 scm_gc_malloc ((k + SCM_I_VECTOR_HEADER_SIZE) * sizeof (SCM),
346 "vector");
347
348 if (k > 0)
e382fdbe 349 {
ed7e0765 350 SCM *base;
c014a02e 351 unsigned long int j;
1b9be268 352
6e708ef2 353 SCM_ASSERT_RANGE (1, scm_from_ulong (k), k <= VECTOR_MAX_LENGTH);
1b9be268 354
ed7e0765 355 base = vector + SCM_I_VECTOR_HEADER_SIZE;
e382fdbe 356 for (j = 0; j != k; ++j)
6e708ef2 357 base[j] = fill;
e382fdbe 358 }
1b9be268 359
ed7e0765
LC
360 ((scm_t_bits *) vector)[0] = (k << 8) | scm_tc7_vector;
361 ((scm_t_bits *) vector)[1] = 0;
1b9be268 362
ed7e0765 363 return PTR2SCM (vector);
0f2d19dd 364}
1bbd0b84 365#undef FUNC_NAME
0f2d19dd 366
6e708ef2
MV
367SCM_DEFINE (scm_vector_copy, "vector-copy", 1, 0, 0,
368 (SCM vec),
369 "Return a copy of @var{vec}.")
370#define FUNC_NAME s_scm_vector_copy
371{
372 scm_t_array_handle handle;
373 size_t i, len;
374 ssize_t inc;
375 const SCM *src;
ed7e0765 376 SCM result, *dst;
6e708ef2
MV
377
378 src = scm_vector_elements (vec, &handle, &len, &inc);
ed7e0765
LC
379
380 result = scm_c_make_vector (len, SCM_UNDEFINED);
381 dst = SCM_I_VECTOR_WELTS (result);
6e708ef2
MV
382 for (i = 0; i < len; i++, src += inc)
383 dst[i] = *src;
ed7e0765 384
c8857a4d 385 scm_array_handle_release (&handle);
6e708ef2 386
ed7e0765 387 return result;
6e708ef2
MV
388}
389#undef FUNC_NAME
390
d525e4f9
LC
391\f
392/* Weak vectors. */
393
d525e4f9
LC
394/* Allocate memory for the elements of a weak vector on behalf of the
395 caller. */
ed7e0765
LC
396static SCM
397make_weak_vector (scm_t_bits type, size_t c_size)
6e708ef2 398{
ed7e0765
LC
399 SCM *vector;
400 size_t total_size;
d525e4f9 401
ed7e0765
LC
402 total_size = (c_size + SCM_I_VECTOR_HEADER_SIZE) * sizeof (SCM);
403 vector = (SCM *) scm_gc_malloc_pointerless (total_size, "weak vector");
d525e4f9 404
ed7e0765
LC
405 ((scm_t_bits *) vector)[0] = (c_size << 8) | scm_tc7_wvect;
406 ((scm_t_bits *) vector)[1] = type;
407
408 return PTR2SCM (vector);
d525e4f9
LC
409}
410
411/* Return a new weak vector. The allocated vector will be of the given weak
412 vector subtype. It will contain SIZE elements which are initialized with
413 the FILL object, or, if FILL is undefined, with an unspecified object. */
414SCM
415scm_i_make_weak_vector (scm_t_bits type, SCM size, SCM fill)
416{
417 SCM wv, *base;
418 size_t c_size, j;
419
420 if (SCM_UNBNDP (fill))
421 fill = SCM_UNSPECIFIED;
6e708ef2
MV
422
423 c_size = scm_to_unsigned_integer (size, 0, VECTOR_MAX_LENGTH);
ed7e0765
LC
424 wv = make_weak_vector (type, c_size);
425 base = SCM_I_WVECT_GC_WVELTS (wv);
6e708ef2 426
d525e4f9
LC
427 for (j = 0; j != c_size; ++j)
428 base[j] = fill;
3a2de079 429
d525e4f9
LC
430 return wv;
431}
432
433/* Return a new weak vector with type TYPE and whose content are taken from
434 list LST. */
435SCM
436scm_i_make_weak_vector_from_list (scm_t_bits type, SCM lst)
437{
ed7e0765 438 SCM wv, *elt;
d525e4f9
LC
439 long c_size;
440
441 c_size = scm_ilength (lst);
442 SCM_ASSERT (c_size >= 0, lst, SCM_ARG2, "scm_i_make_weak_vector_from_list");
443
ed7e0765
LC
444 wv = make_weak_vector(type, (size_t) c_size);
445
446 for (elt = SCM_I_WVECT_GC_WVELTS (wv);
d525e4f9
LC
447 scm_is_pair (lst);
448 lst = SCM_CDR (lst), elt++)
449 {
450 *elt = SCM_CAR (lst);
6e708ef2 451 }
6e708ef2 452
d525e4f9 453 return wv;
6e708ef2 454}
e382fdbe 455
d525e4f9
LC
456
457\f
3b3b36dd 458SCM_DEFINE (scm_vector_to_list, "vector->list", 1, 0, 0,
1e6808ea 459 (SCM v),
8f85c0c6 460 "Return a newly allocated list composed of the elements of @var{v}.\n"
1e6808ea 461 "\n"
942e5b91
MG
462 "@lisp\n"
463 "(vector->list '#(dah dah didah)) @result{} (dah dah didah)\n"
464 "(list->vector '(dididit dah)) @result{} #(dididit dah)\n"
465 "@end lisp")
1bbd0b84 466#define FUNC_NAME s_scm_vector_to_list
0f2d19dd 467{
6e708ef2
MV
468 SCM res = SCM_EOL;
469 const SCM *data;
470 scm_t_array_handle handle;
22be72d3 471 size_t i, count, len;
6e708ef2
MV
472 ssize_t inc;
473
474 data = scm_vector_elements (v, &handle, &len, &inc);
22be72d3
LC
475 for (i = (len - 1) * inc, count = 0;
476 count < len;
477 i -= inc, count++)
478 res = scm_cons (data[i], res);
479
c8857a4d 480 scm_array_handle_release (&handle);
6e708ef2 481 return res;
0f2d19dd 482}
1bbd0b84 483#undef FUNC_NAME
0f2d19dd
JB
484
485
a1ec6916 486SCM_DEFINE (scm_vector_fill_x, "vector-fill!", 2, 0, 0,
1e6808ea 487 (SCM v, SCM fill),
8f85c0c6 488 "Store @var{fill} in every position of @var{vector}. The value\n"
1e6808ea 489 "returned by @code{vector-fill!} is unspecified.")
1bbd0b84 490#define FUNC_NAME s_scm_vector_fill_x
0f2d19dd 491{
6e708ef2
MV
492 scm_t_array_handle handle;
493 SCM *data;
494 size_t i, len;
495 ssize_t inc;
496
497 data = scm_vector_writable_elements (v, &handle, &len, &inc);
498 for (i = 0; i < len; i += inc)
499 data[i] = fill;
c8857a4d 500 scm_array_handle_release (&handle);
6e708ef2 501 return SCM_UNSPECIFIED;
0f2d19dd 502}
1bbd0b84 503#undef FUNC_NAME
0f2d19dd
JB
504
505
0f2d19dd 506SCM
354116f7 507scm_i_vector_equal_p (SCM x, SCM y)
0f2d19dd 508{
c014a02e 509 long i;
6e708ef2
MV
510 for (i = SCM_I_VECTOR_LENGTH (x) - 1; i >= 0; i--)
511 if (scm_is_false (scm_equal_p (SCM_I_VECTOR_ELTS (x)[i],
512 SCM_I_VECTOR_ELTS (y)[i])))
0f2d19dd
JB
513 return SCM_BOOL_F;
514 return SCM_BOOL_T;
515}
516
517
a1ec6916 518SCM_DEFINE (scm_vector_move_left_x, "vector-move-left!", 5, 0, 0,
1bbd0b84 519 (SCM vec1, SCM start1, SCM end1, SCM vec2, SCM start2),
694a9bb3
NJ
520 "Copy elements from @var{vec1}, positions @var{start1} to @var{end1},\n"
521 "to @var{vec2} starting at position @var{start2}. @var{start1} and\n"
522 "@var{start2} are inclusive indices; @var{end1} is exclusive.\n\n"
523 "@code{vector-move-left!} copies elements in leftmost order.\n"
524 "Therefore, in the case where @var{vec1} and @var{vec2} refer to the\n"
525 "same vector, @code{vector-move-left!} is usually appropriate when\n"
526 "@var{start1} is greater than @var{start2}.")
1bbd0b84 527#define FUNC_NAME s_scm_vector_move_left_x
0f2d19dd 528{
6e708ef2
MV
529 scm_t_array_handle handle1, handle2;
530 const SCM *elts1;
531 SCM *elts2;
de5c0f58 532 size_t len1, len2;
6e708ef2 533 ssize_t inc1, inc2;
a55c2b68 534 size_t i, j, e;
6e708ef2
MV
535
536 elts1 = scm_vector_elements (vec1, &handle1, &len1, &inc1);
537 elts2 = scm_vector_writable_elements (vec2, &handle2, &len2, &inc2);
34d19ef6 538
de5c0f58
MV
539 i = scm_to_unsigned_integer (start1, 0, len1);
540 e = scm_to_unsigned_integer (end1, i, len1);
ca659673 541 SCM_ASSERT_RANGE (SCM_ARG3, end1, (e-i) <= len2);
551b96d2
AW
542 j = scm_to_unsigned_integer (start2, 0, len2);
543 SCM_ASSERT_RANGE (SCM_ARG5, start2, j <= len2 - (e - i));
de5c0f58 544
6e708ef2
MV
545 i *= inc1;
546 e *= inc1;
547 j *= inc2;
548 for (; i < e; i += inc1, j += inc2)
549 elts2[j] = elts1[i];
550
c8857a4d
MV
551 scm_array_handle_release (&handle2);
552 scm_array_handle_release (&handle1);
553
0f2d19dd
JB
554 return SCM_UNSPECIFIED;
555}
1bbd0b84 556#undef FUNC_NAME
0f2d19dd 557
a1ec6916 558SCM_DEFINE (scm_vector_move_right_x, "vector-move-right!", 5, 0, 0,
1bbd0b84 559 (SCM vec1, SCM start1, SCM end1, SCM vec2, SCM start2),
694a9bb3
NJ
560 "Copy elements from @var{vec1}, positions @var{start1} to @var{end1},\n"
561 "to @var{vec2} starting at position @var{start2}. @var{start1} and\n"
562 "@var{start2} are inclusive indices; @var{end1} is exclusive.\n\n"
563 "@code{vector-move-right!} copies elements in rightmost order.\n"
564 "Therefore, in the case where @var{vec1} and @var{vec2} refer to the\n"
565 "same vector, @code{vector-move-right!} is usually appropriate when\n"
566 "@var{start1} is less than @var{start2}.")
1bbd0b84 567#define FUNC_NAME s_scm_vector_move_right_x
0f2d19dd 568{
6e708ef2
MV
569 scm_t_array_handle handle1, handle2;
570 const SCM *elts1;
571 SCM *elts2;
de5c0f58 572 size_t len1, len2;
6e708ef2 573 ssize_t inc1, inc2;
a55c2b68 574 size_t i, j, e;
6e708ef2
MV
575
576 elts1 = scm_vector_elements (vec1, &handle1, &len1, &inc1);
577 elts2 = scm_vector_writable_elements (vec2, &handle2, &len2, &inc2);
0f2d19dd 578
de5c0f58
MV
579 i = scm_to_unsigned_integer (start1, 0, len1);
580 e = scm_to_unsigned_integer (end1, i, len1);
ca659673 581 SCM_ASSERT_RANGE (SCM_ARG3, end1, (e-i) <= len2);
551b96d2
AW
582 j = scm_to_unsigned_integer (start2, 0, len2);
583 SCM_ASSERT_RANGE (SCM_ARG5, start2, j <= len2 - (e - i));
584
585 j += (e - i);
de5c0f58 586
6e708ef2
MV
587 i *= inc1;
588 e *= inc1;
589 j *= inc2;
590 while (i < e)
de5c0f58 591 {
6e708ef2
MV
592 e -= inc1;
593 j -= inc2;
594 elts2[j] = elts1[e];
de5c0f58 595 }
6e708ef2 596
c8857a4d
MV
597 scm_array_handle_release (&handle2);
598 scm_array_handle_release (&handle1);
599
0f2d19dd
JB
600 return SCM_UNSPECIFIED;
601}
1bbd0b84 602#undef FUNC_NAME
0f2d19dd 603
438974d0 604\f
2a610be5
AW
605static SCM
606vector_handle_ref (scm_t_array_handle *h, size_t idx)
88797580 607{
2a610be5
AW
608 if (idx > h->dims[0].ubnd)
609 scm_out_of_range ("vector-handle-ref", scm_from_size_t (idx));
610 return ((SCM*)h->elements)[idx];
88797580
MV
611}
612
2a610be5
AW
613static void
614vector_handle_set (scm_t_array_handle *h, size_t idx, SCM val)
88797580 615{
2a610be5
AW
616 if (idx > h->dims[0].ubnd)
617 scm_out_of_range ("vector-handle-set!", scm_from_size_t (idx));
618 ((SCM*)h->writable_elements)[idx] = val;
88797580 619}
88797580 620
2a610be5
AW
621static void
622vector_get_handle (SCM v, scm_t_array_handle *h)
88797580 623{
2a610be5
AW
624 h->array = v;
625 h->ndims = 1;
626 h->dims = &h->dim0;
627 h->dim0.lbnd = 0;
628 h->dim0.ubnd = SCM_I_VECTOR_LENGTH (v) - 1;
629 h->dim0.inc = 1;
630 h->element_type = SCM_ARRAY_ELEMENT_TYPE_SCM;
631 h->elements = h->writable_elements = SCM_I_VECTOR_WELTS (v);
88797580
MV
632}
633
c5f17102
AW
634/* the & ~2 allows catching scm_tc7_wvect as well. needs changing if you change
635 tags.h. */
2a610be5
AW
636SCM_ARRAY_IMPLEMENTATION (scm_tc7_vector, 0x7f & ~2,
637 vector_handle_ref, vector_handle_set,
f65e0168 638 vector_get_handle)
f65e0168 639SCM_VECTOR_IMPLEMENTATION (SCM_ARRAY_ELEMENT_TYPE_SCM, scm_make_vector)
88797580 640
1cc91f1b 641
0f2d19dd
JB
642void
643scm_init_vectors ()
0f2d19dd 644{
a0599745 645#include "libguile/vectors.x"
0f2d19dd
JB
646}
647
89e00824
ML
648
649/*
650 Local Variables:
651 c-file-style: "gnu"
652 End:
653*/