Allocate vectors in a contiguous memory area.
[bpt/guile.git] / libguile / vectors.c
CommitLineData
438974d0 1/* Copyright (C) 1995,1996,1998,1999,2000,2001, 2006, 2008, 2009 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"
c96d76b8 29#include "libguile/lang.h"
a0599745
MD
30
31#include "libguile/validate.h"
32#include "libguile/vectors.h"
f332e957 33#include "libguile/generalized-vectors.h"
2fa901a5 34#include "libguile/arrays.h"
cf396142 35#include "libguile/bitvectors.h"
438974d0 36#include "libguile/bytevectors.h"
5d1b3b2d 37#include "libguile/array-map.h"
88797580
MV
38#include "libguile/srfi-4.h"
39#include "libguile/strings.h"
40#include "libguile/srfi-13.h"
1d0df896 41#include "libguile/dynwind.h"
6e708ef2 42#include "libguile/deprecation.h"
88797580 43
1c44468d 44#include "libguile/bdw-gc.h"
3a2de079
LC
45
46
0f2d19dd
JB
47\f
48
6e708ef2
MV
49#define VECTOR_MAX_LENGTH (SCM_T_BITS_MAX >> 8)
50
6e708ef2
MV
51int
52scm_is_vector (SCM obj)
53{
54 if (SCM_I_IS_VECTOR (obj))
55 return 1;
04b87de5 56 if (SCM_I_ARRAYP (obj) && SCM_I_ARRAY_NDIM (obj) == 1)
6e708ef2 57 {
04b87de5 58 SCM v = SCM_I_ARRAY_V (obj);
6e708ef2
MV
59 return SCM_I_IS_VECTOR (v);
60 }
61 return 0;
62}
63
64int
65scm_is_simple_vector (SCM obj)
1d0df896 66{
6e708ef2 67 return SCM_I_IS_VECTOR (obj);
1d0df896
MV
68}
69
354116f7
MV
70const SCM *
71scm_vector_elements (SCM vec, scm_t_array_handle *h,
72 size_t *lenp, ssize_t *incp)
73{
3a2de079
LC
74 if (SCM_I_WVECTP (vec))
75 /* FIXME: We should check each (weak) element of the vector for NULL and
76 convert it to SCM_BOOL_F. */
77 abort ();
78
354116f7
MV
79 scm_generalized_vector_get_handle (vec, h);
80 if (lenp)
81 {
82 scm_t_array_dim *dim = scm_array_handle_dims (h);
83 *lenp = dim->ubnd - dim->lbnd + 1;
84 *incp = dim->inc;
85 }
86 return scm_array_handle_elements (h);
87}
88
89SCM *
90scm_vector_writable_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_writable_elements (h);
106}
107
a1ec6916 108SCM_DEFINE (scm_vector_p, "vector?", 1, 0, 0,
5ffe9968 109 (SCM obj),
1e6808ea
MG
110 "Return @code{#t} if @var{obj} is a vector, otherwise return\n"
111 "@code{#f}.")
1bbd0b84 112#define FUNC_NAME s_scm_vector_p
0f2d19dd 113{
de5c0f58 114 return scm_from_bool (scm_is_vector (obj));
0f2d19dd 115}
1bbd0b84 116#undef FUNC_NAME
0f2d19dd 117
f172c0b7 118SCM_GPROC (s_vector_length, "vector-length", 1, 0, 0, scm_vector_length, g_vector_length);
1e6808ea 119/* Returns the number of elements in @var{vector} as an exact integer. */
0f2d19dd 120SCM
f172c0b7 121scm_vector_length (SCM v)
0f2d19dd 122{
6e708ef2
MV
123 if (SCM_I_IS_VECTOR (v))
124 return scm_from_size_t (SCM_I_VECTOR_LENGTH (v));
04b87de5 125 else if (SCM_I_ARRAYP (v) && SCM_I_ARRAY_NDIM (v) == 1)
de5c0f58 126 {
04b87de5 127 scm_t_array_dim *dim = SCM_I_ARRAY_DIMS (v);
de5c0f58
MV
128 return scm_from_size_t (dim->ubnd - dim->lbnd + 1);
129 }
130 else
131 SCM_WTA_DISPATCH_1 (g_vector_length, v, 1, NULL);
0f2d19dd
JB
132}
133
88797580
MV
134size_t
135scm_c_vector_length (SCM v)
136{
6e708ef2
MV
137 if (SCM_I_IS_VECTOR (v))
138 return SCM_I_VECTOR_LENGTH (v);
88797580 139 else
de5c0f58 140 return scm_to_size_t (scm_vector_length (v));
88797580
MV
141}
142
f172c0b7 143SCM_REGISTER_PROC (s_list_to_vector, "list->vector", 1, 0, 0, scm_vector);
5ffe9968 144/*
942e5b91
MG
145 "Return a newly created vector initialized to the elements of"
146 "the list @var{list}.\n\n"
147 "@lisp\n"
148 "(vector->list '#(dah dah didah)) @result{} (dah dah didah)\n"
149 "(list->vector '(dididit dah)) @result{} #(dididit dah)\n"
150 "@end lisp")
5ffe9968 151*/
a1ec6916 152SCM_DEFINE (scm_vector, "vector", 0, 0, 1,
f172c0b7 153 (SCM l),
8f85c0c6
NJ
154 "@deffnx {Scheme Procedure} list->vector l\n"
155 "Return a newly allocated vector composed of the\n"
1e6808ea
MG
156 "given arguments. Analogous to @code{list}.\n"
157 "\n"
942e5b91 158 "@lisp\n"
1e6808ea 159 "(vector 'a 'b 'c) @result{} #(a b c)\n"
942e5b91 160 "@end lisp")
1bbd0b84 161#define FUNC_NAME s_scm_vector
0f2d19dd
JB
162{
163 SCM res;
22a52da1 164 SCM *data;
1d0df896 165 long i, len;
6e708ef2 166 scm_t_array_handle handle;
22a52da1 167
1d0df896 168 SCM_VALIDATE_LIST_COPYLEN (1, l, len);
34d19ef6 169
6e708ef2
MV
170 res = scm_c_make_vector (len, SCM_UNSPECIFIED);
171 data = scm_vector_writable_elements (res, &handle, NULL, NULL);
1d0df896 172 i = 0;
c8857a4d 173 while (scm_is_pair (l) && i < len)
22a52da1 174 {
1d0df896 175 data[i] = SCM_CAR (l);
22a52da1 176 l = SCM_CDR (l);
6e708ef2 177 i += 1;
22a52da1
DH
178 }
179
c8857a4d
MV
180 scm_array_handle_release (&handle);
181
0f2d19dd
JB
182 return res;
183}
1bbd0b84 184#undef FUNC_NAME
0f2d19dd 185
f172c0b7 186SCM_GPROC (s_vector_ref, "vector-ref", 2, 0, 0, scm_vector_ref, g_vector_ref);
1cc91f1b 187
5ffe9968
GB
188/*
189 "@var{k} must be a valid index of @var{vector}.\n"
190 "@samp{Vector-ref} returns the contents of element @var{k} of\n"
191 "@var{vector}.\n\n"
942e5b91
MG
192 "@lisp\n"
193 "(vector-ref '#(1 1 2 3 5 8 13 21) 5) @result{} 8\n"
5ffe9968
GB
194 "(vector-ref '#(1 1 2 3 5 8 13 21)\n"
195 " (let ((i (round (* 2 (acos -1)))))\n"
196 " (if (inexact? i)\n"
197 " (inexact->exact i)\n"
942e5b91
MG
198 " i))) @result{} 13\n"
199 "@end lisp"
5ffe9968
GB
200*/
201
0f2d19dd 202SCM
ea633082 203scm_vector_ref (SCM v, SCM k)
685c0d71 204#define FUNC_NAME s_vector_ref
0f2d19dd 205{
de5c0f58 206 return scm_c_vector_ref (v, scm_to_size_t (k));
0f2d19dd 207}
685c0d71 208#undef FUNC_NAME
0f2d19dd 209
88797580
MV
210SCM
211scm_c_vector_ref (SCM v, size_t k)
212{
6e708ef2 213 if (SCM_I_IS_VECTOR (v))
de5c0f58 214 {
3a2de079
LC
215 register SCM elt;
216
6e708ef2 217 if (k >= SCM_I_VECTOR_LENGTH (v))
3a2de079
LC
218 scm_out_of_range (NULL, scm_from_size_t (k));
219 elt = (SCM_I_VECTOR_ELTS(v))[k];
220
221 if ((elt == SCM_PACK (NULL)) && SCM_I_WVECTP (v))
222 /* ELT was a weak pointer and got nullified by the GC. */
223 return SCM_BOOL_F;
224
225 return elt;
de5c0f58 226 }
04b87de5 227 else if (SCM_I_ARRAYP (v) && SCM_I_ARRAY_NDIM (v) == 1)
88797580 228 {
04b87de5
MV
229 scm_t_array_dim *dim = SCM_I_ARRAY_DIMS (v);
230 SCM vv = SCM_I_ARRAY_V (v);
6e708ef2
MV
231 if (SCM_I_IS_VECTOR (vv))
232 {
3a2de079
LC
233 register SCM elt;
234
6e708ef2
MV
235 if (k >= dim->ubnd - dim->lbnd + 1)
236 scm_out_of_range (NULL, scm_from_size_t (k));
04b87de5 237 k = SCM_I_ARRAY_BASE (v) + k*dim->inc;
3a2de079
LC
238 elt = (SCM_I_VECTOR_ELTS (vv))[k];
239
240 if ((elt == SCM_PACK (NULL)) && (SCM_I_WVECTP (vv)))
241 /* ELT was a weak pointer and got nullified by the GC. */
242 return SCM_BOOL_F;
243
244 return elt;
6e708ef2
MV
245 }
246 scm_wrong_type_arg_msg (NULL, 0, v, "non-uniform vector");
88797580 247 }
de5c0f58
MV
248 else
249 SCM_WTA_DISPATCH_2 (g_vector_ref, v, scm_from_size_t (k), 2, NULL);
88797580
MV
250}
251
f172c0b7 252SCM_GPROC (s_vector_set_x, "vector-set!", 3, 0, 0, scm_vector_set_x, g_vector_set_x);
1cc91f1b 253
942e5b91
MG
254/* "@var{k} must be a valid index of @var{vector}.\n"
255 "@code{Vector-set!} stores @var{obj} in element @var{k} of @var{vector}.\n"
256 "The value returned by @samp{vector-set!} is unspecified.\n"
257 "@lisp\n"
258 "(let ((vec (vector 0 '(2 2 2 2) "Anna")))\n"
259 " (vector-set! vec 1 '("Sue" "Sue"))\n"
260 " vec) @result{} #(0 ("Sue" "Sue") "Anna")\n"
261 "(vector-set! '#(0 1 2) 1 "doe") @result{} @emph{error} ; constant vector\n"
262 "@end lisp"
5ffe9968
GB
263*/
264
0f2d19dd 265SCM
f172c0b7 266scm_vector_set_x (SCM v, SCM k, SCM obj)
685c0d71 267#define FUNC_NAME s_vector_set_x
0f2d19dd 268{
de5c0f58 269 scm_c_vector_set_x (v, scm_to_size_t (k), obj);
60c497a3 270 return SCM_UNSPECIFIED;
0f2d19dd 271}
685c0d71 272#undef FUNC_NAME
0f2d19dd 273
de5c0f58 274void
88797580
MV
275scm_c_vector_set_x (SCM v, size_t k, SCM obj)
276{
6e708ef2 277 if (SCM_I_IS_VECTOR (v))
88797580 278 {
6e708ef2 279 if (k >= SCM_I_VECTOR_LENGTH (v))
de5c0f58 280 scm_out_of_range (NULL, scm_from_size_t (k));
6e708ef2 281 (SCM_I_VECTOR_WELTS(v))[k] = obj;
3a2de079
LC
282 if (SCM_I_WVECTP (v))
283 {
284 /* Make it a weak pointer. */
285 GC_PTR link = (GC_PTR) & ((SCM_I_VECTOR_WELTS (v))[k]);
dbe4d258 286 SCM_I_REGISTER_DISAPPEARING_LINK (link, obj);
3a2de079 287 }
de5c0f58 288 }
04b87de5 289 else if (SCM_I_ARRAYP (v) && SCM_I_ARRAY_NDIM (v) == 1)
de5c0f58 290 {
04b87de5
MV
291 scm_t_array_dim *dim = SCM_I_ARRAY_DIMS (v);
292 SCM vv = SCM_I_ARRAY_V (v);
6e708ef2
MV
293 if (SCM_I_IS_VECTOR (vv))
294 {
295 if (k >= dim->ubnd - dim->lbnd + 1)
296 scm_out_of_range (NULL, scm_from_size_t (k));
04b87de5 297 k = SCM_I_ARRAY_BASE (v) + k*dim->inc;
6e708ef2 298 (SCM_I_VECTOR_WELTS (vv))[k] = obj;
3a2de079
LC
299
300 if (SCM_I_WVECTP (vv))
301 {
302 /* Make it a weak pointer. */
303 GC_PTR link = (GC_PTR) & ((SCM_I_VECTOR_WELTS (vv))[k]);
dbe4d258 304 SCM_I_REGISTER_DISAPPEARING_LINK (link, obj);
3a2de079 305 }
6e708ef2
MV
306 }
307 else
308 scm_wrong_type_arg_msg (NULL, 0, v, "non-uniform vector");
88797580
MV
309 }
310 else
311 {
de5c0f58
MV
312 if (SCM_UNPACK (g_vector_set_x))
313 scm_apply_generic (g_vector_set_x,
314 scm_list_3 (v, scm_from_size_t (k), obj));
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);
541 j = scm_to_unsigned_integer (start2, 0, len2 - (i-e));
542
6e708ef2
MV
543 i *= inc1;
544 e *= inc1;
545 j *= inc2;
546 for (; i < e; i += inc1, j += inc2)
547 elts2[j] = elts1[i];
548
c8857a4d
MV
549 scm_array_handle_release (&handle2);
550 scm_array_handle_release (&handle1);
551
0f2d19dd
JB
552 return SCM_UNSPECIFIED;
553}
1bbd0b84 554#undef FUNC_NAME
0f2d19dd 555
a1ec6916 556SCM_DEFINE (scm_vector_move_right_x, "vector-move-right!", 5, 0, 0,
1bbd0b84 557 (SCM vec1, SCM start1, SCM end1, SCM vec2, SCM start2),
694a9bb3
NJ
558 "Copy elements from @var{vec1}, positions @var{start1} to @var{end1},\n"
559 "to @var{vec2} starting at position @var{start2}. @var{start1} and\n"
560 "@var{start2} are inclusive indices; @var{end1} is exclusive.\n\n"
561 "@code{vector-move-right!} copies elements in rightmost order.\n"
562 "Therefore, in the case where @var{vec1} and @var{vec2} refer to the\n"
563 "same vector, @code{vector-move-right!} is usually appropriate when\n"
564 "@var{start1} is less than @var{start2}.")
1bbd0b84 565#define FUNC_NAME s_scm_vector_move_right_x
0f2d19dd 566{
6e708ef2
MV
567 scm_t_array_handle handle1, handle2;
568 const SCM *elts1;
569 SCM *elts2;
de5c0f58 570 size_t len1, len2;
6e708ef2 571 ssize_t inc1, inc2;
a55c2b68 572 size_t i, j, e;
6e708ef2
MV
573
574 elts1 = scm_vector_elements (vec1, &handle1, &len1, &inc1);
575 elts2 = scm_vector_writable_elements (vec2, &handle2, &len2, &inc2);
0f2d19dd 576
de5c0f58
MV
577 i = scm_to_unsigned_integer (start1, 0, len1);
578 e = scm_to_unsigned_integer (end1, i, len1);
579 j = scm_to_unsigned_integer (start2, 0, len2 - (i-e));
580
6e708ef2
MV
581 i *= inc1;
582 e *= inc1;
583 j *= inc2;
584 while (i < e)
de5c0f58 585 {
6e708ef2
MV
586 e -= inc1;
587 j -= inc2;
588 elts2[j] = elts1[e];
de5c0f58 589 }
6e708ef2 590
c8857a4d
MV
591 scm_array_handle_release (&handle2);
592 scm_array_handle_release (&handle1);
593
0f2d19dd
JB
594 return SCM_UNSPECIFIED;
595}
1bbd0b84 596#undef FUNC_NAME
0f2d19dd 597
438974d0 598\f
2a610be5
AW
599static SCM
600vector_handle_ref (scm_t_array_handle *h, size_t idx)
88797580 601{
2a610be5
AW
602 if (idx > h->dims[0].ubnd)
603 scm_out_of_range ("vector-handle-ref", scm_from_size_t (idx));
604 return ((SCM*)h->elements)[idx];
88797580
MV
605}
606
2a610be5
AW
607static void
608vector_handle_set (scm_t_array_handle *h, size_t idx, SCM val)
88797580 609{
2a610be5
AW
610 if (idx > h->dims[0].ubnd)
611 scm_out_of_range ("vector-handle-set!", scm_from_size_t (idx));
612 ((SCM*)h->writable_elements)[idx] = val;
88797580 613}
88797580 614
2a610be5
AW
615static void
616vector_get_handle (SCM v, scm_t_array_handle *h)
88797580 617{
2a610be5
AW
618 h->array = v;
619 h->ndims = 1;
620 h->dims = &h->dim0;
621 h->dim0.lbnd = 0;
622 h->dim0.ubnd = SCM_I_VECTOR_LENGTH (v) - 1;
623 h->dim0.inc = 1;
624 h->element_type = SCM_ARRAY_ELEMENT_TYPE_SCM;
625 h->elements = h->writable_elements = SCM_I_VECTOR_WELTS (v);
88797580
MV
626}
627
2a610be5
AW
628SCM_ARRAY_IMPLEMENTATION (scm_tc7_vector, 0x7f & ~2,
629 vector_handle_ref, vector_handle_set,
630 vector_get_handle);
631SCM_ARRAY_IMPLEMENTATION (scm_tc7_wvect, 0x7f & ~2,
632 vector_handle_ref, vector_handle_set,
633 vector_get_handle);
f45eccff 634SCM_VECTOR_IMPLEMENTATION (SCM_ARRAY_ELEMENT_TYPE_SCM, scm_make_vector);
88797580 635
1cc91f1b 636
0f2d19dd
JB
637void
638scm_init_vectors ()
0f2d19dd 639{
7c33806a
DH
640 scm_nullvect = scm_c_make_vector (0, SCM_UNDEFINED);
641
a0599745 642#include "libguile/vectors.x"
0f2d19dd
JB
643}
644
89e00824
ML
645
646/*
647 Local Variables:
648 c-file-style: "gnu"
649 End:
650*/