Restore signature of `scm_search_path ()' as found in 1.8.
[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{
342 SCM v;
6e708ef2 343 SCM *base;
1b9be268 344
e382fdbe
DH
345 if (k > 0)
346 {
c014a02e 347 unsigned long int j;
1b9be268 348
6e708ef2 349 SCM_ASSERT_RANGE (1, scm_from_ulong (k), k <= VECTOR_MAX_LENGTH);
1b9be268 350
6e708ef2 351 base = scm_gc_malloc (k * sizeof (SCM), "vector");
e382fdbe 352 for (j = 0; j != k; ++j)
6e708ef2 353 base[j] = fill;
e382fdbe
DH
354 }
355 else
356 base = NULL;
1b9be268 357
bc743877 358 v = scm_immutable_cell ((k << 8) | scm_tc7_vector, (scm_t_bits) base);
e382fdbe 359 scm_remember_upto_here_1 (fill);
1b9be268 360
0f2d19dd
JB
361 return v;
362}
1bbd0b84 363#undef FUNC_NAME
0f2d19dd 364
6e708ef2
MV
365SCM_DEFINE (scm_vector_copy, "vector-copy", 1, 0, 0,
366 (SCM vec),
367 "Return a copy of @var{vec}.")
368#define FUNC_NAME s_scm_vector_copy
369{
370 scm_t_array_handle handle;
371 size_t i, len;
372 ssize_t inc;
373 const SCM *src;
374 SCM *dst;
375
376 src = scm_vector_elements (vec, &handle, &len, &inc);
377 dst = scm_gc_malloc (len * sizeof (SCM), "vector");
378 for (i = 0; i < len; i++, src += inc)
379 dst[i] = *src;
c8857a4d 380 scm_array_handle_release (&handle);
6e708ef2
MV
381
382 return scm_cell ((len << 8) | scm_tc7_vector, (scm_t_bits) dst);
383}
384#undef FUNC_NAME
385
386void
387scm_i_vector_free (SCM vec)
388{
389 scm_gc_free (SCM_I_VECTOR_WELTS (vec),
390 SCM_I_VECTOR_LENGTH (vec) * sizeof(SCM),
391 "vector");
392}
393
d525e4f9
LC
394\f
395/* Weak vectors. */
396
397
398/* Initialize RET as a weak vector of type TYPE of SIZE elements pointed to
399 by BASE. */
400#define MAKE_WEAK_VECTOR(_ret, _type, _size, _base) \
401 (_ret) = scm_double_cell ((_size << 8) | scm_tc7_wvect, \
402 (scm_t_bits) (_base), \
403 (_type), \
404 SCM_UNPACK (SCM_EOL));
405
406
407/* Allocate memory for the elements of a weak vector on behalf of the
408 caller. */
409static SCM *
410allocate_weak_vector (scm_t_bits type, size_t c_size)
6e708ef2 411{
6e708ef2 412 SCM *base;
d525e4f9
LC
413
414 if (c_size > 0)
415 /* The base itself should not be scanned for pointers otherwise those
416 pointers will always be reachable. */
417 base = scm_gc_malloc_pointerless (c_size * sizeof (SCM), "weak vector");
418 else
419 base = NULL;
420
421 return base;
422}
423
424/* Return a new weak vector. The allocated vector will be of the given weak
425 vector subtype. It will contain SIZE elements which are initialized with
426 the FILL object, or, if FILL is undefined, with an unspecified object. */
427SCM
428scm_i_make_weak_vector (scm_t_bits type, SCM size, SCM fill)
429{
430 SCM wv, *base;
431 size_t c_size, j;
432
433 if (SCM_UNBNDP (fill))
434 fill = SCM_UNSPECIFIED;
6e708ef2
MV
435
436 c_size = scm_to_unsigned_integer (size, 0, VECTOR_MAX_LENGTH);
d525e4f9 437 base = allocate_weak_vector (type, c_size);
6e708ef2 438
d525e4f9
LC
439 for (j = 0; j != c_size; ++j)
440 base[j] = fill;
3a2de079 441
d525e4f9 442 MAKE_WEAK_VECTOR (wv, type, c_size, base);
3a2de079 443
d525e4f9
LC
444 return wv;
445}
446
447/* Return a new weak vector with type TYPE and whose content are taken from
448 list LST. */
449SCM
450scm_i_make_weak_vector_from_list (scm_t_bits type, SCM lst)
451{
452 SCM wv, *base, *elt;
453 long c_size;
454
455 c_size = scm_ilength (lst);
456 SCM_ASSERT (c_size >= 0, lst, SCM_ARG2, "scm_i_make_weak_vector_from_list");
457
458 base = allocate_weak_vector (type, (size_t)c_size);
459 for (elt = base;
460 scm_is_pair (lst);
461 lst = SCM_CDR (lst), elt++)
462 {
463 *elt = SCM_CAR (lst);
6e708ef2 464 }
6e708ef2 465
d525e4f9 466 MAKE_WEAK_VECTOR (wv, type, (size_t)c_size, base);
6e708ef2 467
d525e4f9 468 return wv;
6e708ef2 469}
e382fdbe 470
d525e4f9
LC
471
472\f
3b3b36dd 473SCM_DEFINE (scm_vector_to_list, "vector->list", 1, 0, 0,
1e6808ea 474 (SCM v),
8f85c0c6 475 "Return a newly allocated list composed of the elements of @var{v}.\n"
1e6808ea 476 "\n"
942e5b91
MG
477 "@lisp\n"
478 "(vector->list '#(dah dah didah)) @result{} (dah dah didah)\n"
479 "(list->vector '(dididit dah)) @result{} #(dididit dah)\n"
480 "@end lisp")
1bbd0b84 481#define FUNC_NAME s_scm_vector_to_list
0f2d19dd 482{
6e708ef2
MV
483 SCM res = SCM_EOL;
484 const SCM *data;
485 scm_t_array_handle handle;
22be72d3 486 size_t i, count, len;
6e708ef2
MV
487 ssize_t inc;
488
489 data = scm_vector_elements (v, &handle, &len, &inc);
22be72d3
LC
490 for (i = (len - 1) * inc, count = 0;
491 count < len;
492 i -= inc, count++)
493 res = scm_cons (data[i], res);
494
c8857a4d 495 scm_array_handle_release (&handle);
6e708ef2 496 return res;
0f2d19dd 497}
1bbd0b84 498#undef FUNC_NAME
0f2d19dd
JB
499
500
a1ec6916 501SCM_DEFINE (scm_vector_fill_x, "vector-fill!", 2, 0, 0,
1e6808ea 502 (SCM v, SCM fill),
8f85c0c6 503 "Store @var{fill} in every position of @var{vector}. The value\n"
1e6808ea 504 "returned by @code{vector-fill!} is unspecified.")
1bbd0b84 505#define FUNC_NAME s_scm_vector_fill_x
0f2d19dd 506{
6e708ef2
MV
507 scm_t_array_handle handle;
508 SCM *data;
509 size_t i, len;
510 ssize_t inc;
511
512 data = scm_vector_writable_elements (v, &handle, &len, &inc);
513 for (i = 0; i < len; i += inc)
514 data[i] = fill;
c8857a4d 515 scm_array_handle_release (&handle);
6e708ef2 516 return SCM_UNSPECIFIED;
0f2d19dd 517}
1bbd0b84 518#undef FUNC_NAME
0f2d19dd
JB
519
520
0f2d19dd 521SCM
354116f7 522scm_i_vector_equal_p (SCM x, SCM y)
0f2d19dd 523{
c014a02e 524 long i;
6e708ef2
MV
525 for (i = SCM_I_VECTOR_LENGTH (x) - 1; i >= 0; i--)
526 if (scm_is_false (scm_equal_p (SCM_I_VECTOR_ELTS (x)[i],
527 SCM_I_VECTOR_ELTS (y)[i])))
0f2d19dd
JB
528 return SCM_BOOL_F;
529 return SCM_BOOL_T;
530}
531
532
a1ec6916 533SCM_DEFINE (scm_vector_move_left_x, "vector-move-left!", 5, 0, 0,
1bbd0b84 534 (SCM vec1, SCM start1, SCM end1, SCM vec2, SCM start2),
694a9bb3
NJ
535 "Copy elements from @var{vec1}, positions @var{start1} to @var{end1},\n"
536 "to @var{vec2} starting at position @var{start2}. @var{start1} and\n"
537 "@var{start2} are inclusive indices; @var{end1} is exclusive.\n\n"
538 "@code{vector-move-left!} copies elements in leftmost order.\n"
539 "Therefore, in the case where @var{vec1} and @var{vec2} refer to the\n"
540 "same vector, @code{vector-move-left!} is usually appropriate when\n"
541 "@var{start1} is greater than @var{start2}.")
1bbd0b84 542#define FUNC_NAME s_scm_vector_move_left_x
0f2d19dd 543{
6e708ef2
MV
544 scm_t_array_handle handle1, handle2;
545 const SCM *elts1;
546 SCM *elts2;
de5c0f58 547 size_t len1, len2;
6e708ef2 548 ssize_t inc1, inc2;
a55c2b68 549 size_t i, j, e;
6e708ef2
MV
550
551 elts1 = scm_vector_elements (vec1, &handle1, &len1, &inc1);
552 elts2 = scm_vector_writable_elements (vec2, &handle2, &len2, &inc2);
34d19ef6 553
de5c0f58
MV
554 i = scm_to_unsigned_integer (start1, 0, len1);
555 e = scm_to_unsigned_integer (end1, i, len1);
556 j = scm_to_unsigned_integer (start2, 0, len2 - (i-e));
557
6e708ef2
MV
558 i *= inc1;
559 e *= inc1;
560 j *= inc2;
561 for (; i < e; i += inc1, j += inc2)
562 elts2[j] = elts1[i];
563
c8857a4d
MV
564 scm_array_handle_release (&handle2);
565 scm_array_handle_release (&handle1);
566
0f2d19dd
JB
567 return SCM_UNSPECIFIED;
568}
1bbd0b84 569#undef FUNC_NAME
0f2d19dd 570
a1ec6916 571SCM_DEFINE (scm_vector_move_right_x, "vector-move-right!", 5, 0, 0,
1bbd0b84 572 (SCM vec1, SCM start1, SCM end1, SCM vec2, SCM start2),
694a9bb3
NJ
573 "Copy elements from @var{vec1}, positions @var{start1} to @var{end1},\n"
574 "to @var{vec2} starting at position @var{start2}. @var{start1} and\n"
575 "@var{start2} are inclusive indices; @var{end1} is exclusive.\n\n"
576 "@code{vector-move-right!} copies elements in rightmost order.\n"
577 "Therefore, in the case where @var{vec1} and @var{vec2} refer to the\n"
578 "same vector, @code{vector-move-right!} is usually appropriate when\n"
579 "@var{start1} is less than @var{start2}.")
1bbd0b84 580#define FUNC_NAME s_scm_vector_move_right_x
0f2d19dd 581{
6e708ef2
MV
582 scm_t_array_handle handle1, handle2;
583 const SCM *elts1;
584 SCM *elts2;
de5c0f58 585 size_t len1, len2;
6e708ef2 586 ssize_t inc1, inc2;
a55c2b68 587 size_t i, j, e;
6e708ef2
MV
588
589 elts1 = scm_vector_elements (vec1, &handle1, &len1, &inc1);
590 elts2 = scm_vector_writable_elements (vec2, &handle2, &len2, &inc2);
0f2d19dd 591
de5c0f58
MV
592 i = scm_to_unsigned_integer (start1, 0, len1);
593 e = scm_to_unsigned_integer (end1, i, len1);
594 j = scm_to_unsigned_integer (start2, 0, len2 - (i-e));
595
6e708ef2
MV
596 i *= inc1;
597 e *= inc1;
598 j *= inc2;
599 while (i < e)
de5c0f58 600 {
6e708ef2
MV
601 e -= inc1;
602 j -= inc2;
603 elts2[j] = elts1[e];
de5c0f58 604 }
6e708ef2 605
c8857a4d
MV
606 scm_array_handle_release (&handle2);
607 scm_array_handle_release (&handle1);
608
0f2d19dd
JB
609 return SCM_UNSPECIFIED;
610}
1bbd0b84 611#undef FUNC_NAME
0f2d19dd 612
438974d0 613\f
2a610be5
AW
614static SCM
615vector_handle_ref (scm_t_array_handle *h, size_t idx)
88797580 616{
2a610be5
AW
617 if (idx > h->dims[0].ubnd)
618 scm_out_of_range ("vector-handle-ref", scm_from_size_t (idx));
619 return ((SCM*)h->elements)[idx];
88797580
MV
620}
621
2a610be5
AW
622static void
623vector_handle_set (scm_t_array_handle *h, size_t idx, SCM val)
88797580 624{
2a610be5
AW
625 if (idx > h->dims[0].ubnd)
626 scm_out_of_range ("vector-handle-set!", scm_from_size_t (idx));
627 ((SCM*)h->writable_elements)[idx] = val;
88797580 628}
88797580 629
2a610be5
AW
630static void
631vector_get_handle (SCM v, scm_t_array_handle *h)
88797580 632{
2a610be5
AW
633 h->array = v;
634 h->ndims = 1;
635 h->dims = &h->dim0;
636 h->dim0.lbnd = 0;
637 h->dim0.ubnd = SCM_I_VECTOR_LENGTH (v) - 1;
638 h->dim0.inc = 1;
639 h->element_type = SCM_ARRAY_ELEMENT_TYPE_SCM;
640 h->elements = h->writable_elements = SCM_I_VECTOR_WELTS (v);
88797580
MV
641}
642
2a610be5
AW
643SCM_ARRAY_IMPLEMENTATION (scm_tc7_vector, 0x7f & ~2,
644 vector_handle_ref, vector_handle_set,
645 vector_get_handle);
646SCM_ARRAY_IMPLEMENTATION (scm_tc7_wvect, 0x7f & ~2,
647 vector_handle_ref, vector_handle_set,
648 vector_get_handle);
f45eccff 649SCM_VECTOR_IMPLEMENTATION (SCM_ARRAY_ELEMENT_TYPE_SCM, scm_make_vector);
88797580 650
1cc91f1b 651
0f2d19dd
JB
652void
653scm_init_vectors ()
0f2d19dd 654{
7c33806a
DH
655 scm_nullvect = scm_c_make_vector (0, SCM_UNDEFINED);
656
a0599745 657#include "libguile/vectors.x"
0f2d19dd
JB
658}
659
89e00824
ML
660
661/*
662 Local Variables:
663 c-file-style: "gnu"
664 End:
665*/