* validate.h, deprecated.h (SCM_VALIDATE_INUM, SCM_VALIDATE_INUM_COPY,
[bpt/guile.git] / libguile / vectors.c
CommitLineData
22a52da1 1/* Copyright (C) 1995,1996,1998,1999,2000,2001 Free Software Foundation, Inc.
0f2d19dd 2 *
73be1d9e
MV
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
0f2d19dd 7 *
73be1d9e
MV
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
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
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
1bbd0b84 17
1bbd0b84 18
0f2d19dd
JB
19\f
20
a0599745
MD
21#include "libguile/_scm.h"
22#include "libguile/eq.h"
23#include "libguile/root.h"
24#include "libguile/strings.h"
c96d76b8 25#include "libguile/lang.h"
a0599745
MD
26
27#include "libguile/validate.h"
28#include "libguile/vectors.h"
29#include "libguile/unif.h"
0f2d19dd
JB
30\f
31
a1ec6916 32SCM_DEFINE (scm_vector_p, "vector?", 1, 0, 0,
5ffe9968 33 (SCM obj),
1e6808ea
MG
34 "Return @code{#t} if @var{obj} is a vector, otherwise return\n"
35 "@code{#f}.")
1bbd0b84 36#define FUNC_NAME s_scm_vector_p
0f2d19dd 37{
7888309b 38 return scm_from_bool (SCM_VECTORP (obj));
0f2d19dd 39}
1bbd0b84 40#undef FUNC_NAME
0f2d19dd 41
f172c0b7 42SCM_GPROC (s_vector_length, "vector-length", 1, 0, 0, scm_vector_length, g_vector_length);
1e6808ea 43/* Returns the number of elements in @var{vector} as an exact integer. */
0f2d19dd 44SCM
f172c0b7 45scm_vector_length (SCM v)
0f2d19dd 46{
f172c0b7
MD
47 SCM_GASSERT1 (SCM_VECTORP(v),
48 g_vector_length, v, SCM_ARG1, s_vector_length);
93ccaef0 49 return SCM_I_MAKINUM (SCM_VECTOR_LENGTH (v));
0f2d19dd
JB
50}
51
f172c0b7 52SCM_REGISTER_PROC (s_list_to_vector, "list->vector", 1, 0, 0, scm_vector);
5ffe9968 53/*
942e5b91
MG
54 "Return a newly created vector initialized to the elements of"
55 "the list @var{list}.\n\n"
56 "@lisp\n"
57 "(vector->list '#(dah dah didah)) @result{} (dah dah didah)\n"
58 "(list->vector '(dididit dah)) @result{} #(dididit dah)\n"
59 "@end lisp")
5ffe9968 60*/
a1ec6916 61SCM_DEFINE (scm_vector, "vector", 0, 0, 1,
f172c0b7 62 (SCM l),
8f85c0c6
NJ
63 "@deffnx {Scheme Procedure} list->vector l\n"
64 "Return a newly allocated vector composed of the\n"
1e6808ea
MG
65 "given arguments. Analogous to @code{list}.\n"
66 "\n"
942e5b91 67 "@lisp\n"
1e6808ea 68 "(vector 'a 'b 'c) @result{} #(a b c)\n"
942e5b91 69 "@end lisp")
1bbd0b84 70#define FUNC_NAME s_scm_vector
0f2d19dd
JB
71{
72 SCM res;
22a52da1 73 SCM *data;
c014a02e 74 long i;
22a52da1
DH
75
76 /* Dirk:FIXME:: In case of multiple threads, the list might get corrupted
77 while the vector is being created. */
78 SCM_VALIDATE_LIST_COPYLEN (1, l, i);
00ffa0e7 79 res = scm_c_make_vector (i, SCM_UNSPECIFIED);
34d19ef6
HWN
80
81 /*
82 this code doesn't alloc. -- accessing RES is safe.
83 */
84 data = SCM_WRITABLE_VELTS (res);
c96d76b8 85 while (!SCM_NULL_OR_NIL_P (l))
22a52da1
DH
86 {
87 *data++ = SCM_CAR (l);
88 l = SCM_CDR (l);
89 }
90
0f2d19dd
JB
91 return res;
92}
1bbd0b84 93#undef FUNC_NAME
0f2d19dd 94
f172c0b7 95SCM_GPROC (s_vector_ref, "vector-ref", 2, 0, 0, scm_vector_ref, g_vector_ref);
1cc91f1b 96
5ffe9968
GB
97/*
98 "@var{k} must be a valid index of @var{vector}.\n"
99 "@samp{Vector-ref} returns the contents of element @var{k} of\n"
100 "@var{vector}.\n\n"
942e5b91
MG
101 "@lisp\n"
102 "(vector-ref '#(1 1 2 3 5 8 13 21) 5) @result{} 8\n"
5ffe9968
GB
103 "(vector-ref '#(1 1 2 3 5 8 13 21)\n"
104 " (let ((i (round (* 2 (acos -1)))))\n"
105 " (if (inexact? i)\n"
106 " (inexact->exact i)\n"
942e5b91
MG
107 " i))) @result{} 13\n"
108 "@end lisp"
5ffe9968
GB
109*/
110
0f2d19dd 111SCM
ea633082 112scm_vector_ref (SCM v, SCM k)
685c0d71 113#define FUNC_NAME s_vector_ref
0f2d19dd 114{
0c95b57d 115 SCM_GASSERT2 (SCM_VECTORP (v),
9eb8500a
MD
116 g_vector_ref, v, k, SCM_ARG1, s_vector_ref);
117 SCM_GASSERT2 (SCM_INUMP (k),
118 g_vector_ref, v, k, SCM_ARG2, s_vector_ref);
b5c2579a 119 SCM_ASSERT_RANGE (2, k, SCM_INUM (k) < SCM_VECTOR_LENGTH (v) && SCM_INUM (k) >= 0);
c014a02e 120 return SCM_VELTS (v)[(long) SCM_INUM (k)];
0f2d19dd 121}
685c0d71 122#undef FUNC_NAME
0f2d19dd 123
f172c0b7 124SCM_GPROC (s_vector_set_x, "vector-set!", 3, 0, 0, scm_vector_set_x, g_vector_set_x);
1cc91f1b 125
942e5b91
MG
126/* "@var{k} must be a valid index of @var{vector}.\n"
127 "@code{Vector-set!} stores @var{obj} in element @var{k} of @var{vector}.\n"
128 "The value returned by @samp{vector-set!} is unspecified.\n"
129 "@lisp\n"
130 "(let ((vec (vector 0 '(2 2 2 2) "Anna")))\n"
131 " (vector-set! vec 1 '("Sue" "Sue"))\n"
132 " vec) @result{} #(0 ("Sue" "Sue") "Anna")\n"
133 "(vector-set! '#(0 1 2) 1 "doe") @result{} @emph{error} ; constant vector\n"
134 "@end lisp"
5ffe9968
GB
135*/
136
0f2d19dd 137SCM
f172c0b7 138scm_vector_set_x (SCM v, SCM k, SCM obj)
685c0d71 139#define FUNC_NAME s_vector_set_x
0f2d19dd 140{
f172c0b7 141 SCM_GASSERTn (SCM_VECTORP (v),
1afff620 142 g_vector_set_x, scm_list_3 (v, k, obj),
9eb8500a 143 SCM_ARG1, s_vector_set_x);
f172c0b7 144 SCM_GASSERTn (SCM_INUMP (k),
1afff620 145 g_vector_set_x, scm_list_3 (v, k, obj),
9eb8500a 146 SCM_ARG2, s_vector_set_x);
b5c2579a 147 SCM_ASSERT_RANGE (2, k, SCM_INUM (k) < SCM_VECTOR_LENGTH (v) && SCM_INUM (k) >= 0);
34d19ef6 148 SCM_VECTOR_SET (v, (long) SCM_INUM(k), obj);
60c497a3 149 return SCM_UNSPECIFIED;
0f2d19dd 150}
685c0d71 151#undef FUNC_NAME
0f2d19dd
JB
152
153
a1ec6916 154SCM_DEFINE (scm_make_vector, "make-vector", 1, 1, 0,
1bbd0b84 155 (SCM k, SCM fill),
1e6808ea 156 "Return a newly allocated vector of @var{k} elements. If a\n"
8f85c0c6
NJ
157 "second argument is given, then each position is initialized to\n"
158 "@var{fill}. Otherwise the initial contents of each position is\n"
1e6808ea 159 "unspecified.")
1bbd0b84 160#define FUNC_NAME s_scm_make_vector
0f2d19dd 161{
1b9be268 162 if (SCM_UNBNDP (fill))
d60cebe2 163 fill = SCM_UNSPECIFIED;
e382fdbe
DH
164
165 if (SCM_INUMP (k))
166 {
cb0d8be2 167 SCM_ASSERT_RANGE (1, k, SCM_INUM (k) >= 0);
e382fdbe
DH
168 return scm_c_make_vector (SCM_INUM (k), fill);
169 }
170 else if (SCM_BIGP (k))
171 SCM_OUT_OF_RANGE (1, k);
172 else
173 SCM_WRONG_TYPE_ARG (1, k);
00ffa0e7
KN
174}
175#undef FUNC_NAME
176
e382fdbe 177
00ffa0e7 178SCM
c014a02e 179scm_c_make_vector (unsigned long int k, SCM fill)
00ffa0e7
KN
180#define FUNC_NAME s_scm_make_vector
181{
182 SCM v;
92c2555f 183 scm_t_bits *base;
1b9be268 184
e382fdbe
DH
185 if (k > 0)
186 {
c014a02e 187 unsigned long int j;
1b9be268 188
c014a02e 189 SCM_ASSERT_RANGE (1, scm_ulong2num (k), k <= SCM_VECTOR_MAX_LENGTH);
1b9be268 190
4c9419ac 191 base = scm_gc_malloc (k * sizeof (scm_t_bits), "vector");
e382fdbe
DH
192 for (j = 0; j != k; ++j)
193 base[j] = SCM_UNPACK (fill);
194 }
195 else
196 base = NULL;
1b9be268 197
228a24ef 198 v = scm_cell (SCM_MAKE_VECTOR_TAG (k, scm_tc7_vector), (scm_t_bits) base);
e382fdbe 199 scm_remember_upto_here_1 (fill);
1b9be268 200
0f2d19dd
JB
201 return v;
202}
1bbd0b84 203#undef FUNC_NAME
0f2d19dd 204
e382fdbe 205
3b3b36dd 206SCM_DEFINE (scm_vector_to_list, "vector->list", 1, 0, 0,
1e6808ea 207 (SCM v),
8f85c0c6 208 "Return a newly allocated list composed of the elements of @var{v}.\n"
1e6808ea 209 "\n"
942e5b91
MG
210 "@lisp\n"
211 "(vector->list '#(dah dah didah)) @result{} (dah dah didah)\n"
212 "(list->vector '(dididit dah)) @result{} #(dididit dah)\n"
213 "@end lisp")
1bbd0b84 214#define FUNC_NAME s_scm_vector_to_list
0f2d19dd
JB
215{
216 SCM res = SCM_EOL;
c014a02e 217 long i;
34d19ef6
HWN
218 SCM const *data;
219 SCM_VALIDATE_VECTOR (1, v);
0f2d19dd 220 data = SCM_VELTS(v);
b5c2579a 221 for(i = SCM_VECTOR_LENGTH(v)-1;i >= 0;i--) res = scm_cons(data[i], res);
0f2d19dd
JB
222 return res;
223}
1bbd0b84 224#undef FUNC_NAME
0f2d19dd
JB
225
226
a1ec6916 227SCM_DEFINE (scm_vector_fill_x, "vector-fill!", 2, 0, 0,
1e6808ea 228 (SCM v, SCM fill),
8f85c0c6 229 "Store @var{fill} in every position of @var{vector}. The value\n"
1e6808ea 230 "returned by @code{vector-fill!} is unspecified.")
1bbd0b84 231#define FUNC_NAME s_scm_vector_fill_x
0f2d19dd 232{
c014a02e 233 register long i;
1be6b49c 234 SCM_VALIDATE_VECTOR (1, v);
34d19ef6 235
1be6b49c 236 for(i = SCM_VECTOR_LENGTH (v) - 1; i >= 0; i--)
34d19ef6 237 SCM_VECTOR_SET(v, i, fill);
0f2d19dd
JB
238 return SCM_UNSPECIFIED;
239}
1bbd0b84 240#undef FUNC_NAME
0f2d19dd
JB
241
242
0f2d19dd 243SCM
1bbd0b84 244scm_vector_equal_p(SCM x, SCM y)
0f2d19dd 245{
c014a02e 246 long i;
1be6b49c 247 for(i = SCM_VECTOR_LENGTH (x) - 1; i >= 0; i--)
7888309b 248 if (scm_is_false (scm_equal_p (SCM_VELTS (x)[i], SCM_VELTS (y)[i])))
0f2d19dd
JB
249 return SCM_BOOL_F;
250 return SCM_BOOL_T;
251}
252
253
a1ec6916 254SCM_DEFINE (scm_vector_move_left_x, "vector-move-left!", 5, 0, 0,
1bbd0b84 255 (SCM vec1, SCM start1, SCM end1, SCM vec2, SCM start2),
694a9bb3
NJ
256 "Copy elements from @var{vec1}, positions @var{start1} to @var{end1},\n"
257 "to @var{vec2} starting at position @var{start2}. @var{start1} and\n"
258 "@var{start2} are inclusive indices; @var{end1} is exclusive.\n\n"
259 "@code{vector-move-left!} copies elements in leftmost order.\n"
260 "Therefore, in the case where @var{vec1} and @var{vec2} refer to the\n"
261 "same vector, @code{vector-move-left!} is usually appropriate when\n"
262 "@var{start1} is greater than @var{start2}.")
1bbd0b84 263#define FUNC_NAME s_scm_vector_move_left_x
0f2d19dd 264{
a55c2b68 265 size_t i, j, e;
0f2d19dd 266
34d19ef6 267 SCM_VALIDATE_VECTOR (1, vec1);
34d19ef6 268 SCM_VALIDATE_VECTOR (4, vec2);
a55c2b68
MV
269 i = scm_to_unsigned_integer (start1, 0, SCM_VECTOR_LENGTH(vec1));
270 e = scm_to_unsigned_integer (end1, i, SCM_VECTOR_LENGTH(vec1));
271 j = scm_to_unsigned_integer (start2, 0, SCM_VECTOR_LENGTH(vec2)-(i-e));
34d19ef6
HWN
272
273 while (i<e)
1d1559ce
HWN
274 {
275 SCM_VECTOR_SET (vec2, j, SCM_VELTS (vec1)[i]);
276 i++;
277 j++;
278 }
34d19ef6 279
0f2d19dd
JB
280 return SCM_UNSPECIFIED;
281}
1bbd0b84 282#undef FUNC_NAME
0f2d19dd 283
a1ec6916 284SCM_DEFINE (scm_vector_move_right_x, "vector-move-right!", 5, 0, 0,
1bbd0b84 285 (SCM vec1, SCM start1, SCM end1, SCM vec2, SCM start2),
694a9bb3
NJ
286 "Copy elements from @var{vec1}, positions @var{start1} to @var{end1},\n"
287 "to @var{vec2} starting at position @var{start2}. @var{start1} and\n"
288 "@var{start2} are inclusive indices; @var{end1} is exclusive.\n\n"
289 "@code{vector-move-right!} copies elements in rightmost order.\n"
290 "Therefore, in the case where @var{vec1} and @var{vec2} refer to the\n"
291 "same vector, @code{vector-move-right!} is usually appropriate when\n"
292 "@var{start1} is less than @var{start2}.")
1bbd0b84 293#define FUNC_NAME s_scm_vector_move_right_x
0f2d19dd 294{
a55c2b68 295 size_t i, j, e;
0f2d19dd 296
34d19ef6 297 SCM_VALIDATE_VECTOR (1, vec1);
34d19ef6 298 SCM_VALIDATE_VECTOR (4, vec2);
a55c2b68
MV
299 i = scm_to_unsigned_integer (start1, 0, SCM_VECTOR_LENGTH(vec1));
300 e = scm_to_unsigned_integer (end1, i, SCM_VECTOR_LENGTH(vec1));
301 j = scm_to_unsigned_integer (start2, 0, SCM_VECTOR_LENGTH(vec2)-(i-e));
302
303 j += e - i;
2cc41672 304 while (i < e)
1d1559ce
HWN
305 {
306 j--;
307 e--;
308 SCM_VECTOR_SET (vec2, j, SCM_VELTS (vec1)[e]);
309 }
310
0f2d19dd
JB
311 return SCM_UNSPECIFIED;
312}
1bbd0b84 313#undef FUNC_NAME
0f2d19dd
JB
314
315
1cc91f1b 316
0f2d19dd
JB
317void
318scm_init_vectors ()
0f2d19dd 319{
7c33806a
DH
320 scm_nullvect = scm_c_make_vector (0, SCM_UNDEFINED);
321
a0599745 322#include "libguile/vectors.x"
0f2d19dd
JB
323}
324
89e00824
ML
325
326/*
327 Local Variables:
328 c-file-style: "gnu"
329 End:
330*/