* These changes add a @deffnx C function declaration and function
[bpt/guile.git] / libguile / vectors.c
CommitLineData
22a52da1 1/* Copyright (C) 1995,1996,1998,1999,2000,2001 Free Software Foundation, Inc.
0f2d19dd
JB
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program 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
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
82892bed
JB
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
0f2d19dd
JB
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
37 *
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
82892bed 40 * If you do not wish that, delete this exception notice. */
1bbd0b84 41
1bbd0b84 42
0f2d19dd
JB
43\f
44
a0599745
MD
45#include "libguile/_scm.h"
46#include "libguile/eq.h"
47#include "libguile/root.h"
48#include "libguile/strings.h"
49
50#include "libguile/validate.h"
51#include "libguile/vectors.h"
52#include "libguile/unif.h"
0f2d19dd
JB
53\f
54
a1ec6916 55SCM_DEFINE (scm_vector_p, "vector?", 1, 0, 0,
5ffe9968 56 (SCM obj),
1e6808ea
MG
57 "Return @code{#t} if @var{obj} is a vector, otherwise return\n"
58 "@code{#f}.")
1bbd0b84 59#define FUNC_NAME s_scm_vector_p
0f2d19dd 60{
5ffe9968 61 return SCM_BOOL (SCM_VECTORP (obj));
0f2d19dd 62}
1bbd0b84 63#undef FUNC_NAME
0f2d19dd 64
f172c0b7 65SCM_GPROC (s_vector_length, "vector-length", 1, 0, 0, scm_vector_length, g_vector_length);
1e6808ea 66/* Returns the number of elements in @var{vector} as an exact integer. */
0f2d19dd 67SCM
f172c0b7 68scm_vector_length (SCM v)
0f2d19dd 69{
f172c0b7
MD
70 SCM_GASSERT1 (SCM_VECTORP(v),
71 g_vector_length, v, SCM_ARG1, s_vector_length);
b5c2579a 72 return SCM_MAKINUM (SCM_VECTOR_LENGTH (v));
0f2d19dd
JB
73}
74
f172c0b7 75SCM_REGISTER_PROC (s_list_to_vector, "list->vector", 1, 0, 0, scm_vector);
5ffe9968 76/*
942e5b91
MG
77 "Return a newly created vector initialized to the elements of"
78 "the list @var{list}.\n\n"
79 "@lisp\n"
80 "(vector->list '#(dah dah didah)) @result{} (dah dah didah)\n"
81 "(list->vector '(dididit dah)) @result{} #(dididit dah)\n"
82 "@end lisp")
5ffe9968 83*/
a1ec6916 84SCM_DEFINE (scm_vector, "vector", 0, 0, 1,
f172c0b7 85 (SCM l),
31daeb2d 86 "@deffnx primitive list->vector l\n"
1e6808ea
MG
87 "Return a newly allocated vector whose elements contain the\n"
88 "given arguments. Analogous to @code{list}.\n"
89 "\n"
942e5b91 90 "@lisp\n"
1e6808ea 91 "(vector 'a 'b 'c) @result{} #(a b c)\n"
942e5b91 92 "@end lisp")
1bbd0b84 93#define FUNC_NAME s_scm_vector
0f2d19dd
JB
94{
95 SCM res;
22a52da1 96 SCM *data;
c014a02e 97 long i;
22a52da1
DH
98
99 /* Dirk:FIXME:: In case of multiple threads, the list might get corrupted
100 while the vector is being created. */
101 SCM_VALIDATE_LIST_COPYLEN (1, l, i);
00ffa0e7 102 res = scm_c_make_vector (i, SCM_UNSPECIFIED);
f172c0b7 103 data = SCM_VELTS (res);
22a52da1
DH
104 while (!SCM_NULLP (l))
105 {
106 *data++ = SCM_CAR (l);
107 l = SCM_CDR (l);
108 }
109
0f2d19dd
JB
110 return res;
111}
1bbd0b84 112#undef FUNC_NAME
0f2d19dd 113
f172c0b7 114SCM_GPROC (s_vector_ref, "vector-ref", 2, 0, 0, scm_vector_ref, g_vector_ref);
1cc91f1b 115
5ffe9968
GB
116/*
117 "@var{k} must be a valid index of @var{vector}.\n"
118 "@samp{Vector-ref} returns the contents of element @var{k} of\n"
119 "@var{vector}.\n\n"
942e5b91
MG
120 "@lisp\n"
121 "(vector-ref '#(1 1 2 3 5 8 13 21) 5) @result{} 8\n"
5ffe9968
GB
122 "(vector-ref '#(1 1 2 3 5 8 13 21)\n"
123 " (let ((i (round (* 2 (acos -1)))))\n"
124 " (if (inexact? i)\n"
125 " (inexact->exact i)\n"
942e5b91
MG
126 " i))) @result{} 13\n"
127 "@end lisp"
5ffe9968
GB
128*/
129
0f2d19dd 130SCM
ea633082 131scm_vector_ref (SCM v, SCM k)
685c0d71 132#define FUNC_NAME s_vector_ref
0f2d19dd 133{
0c95b57d 134 SCM_GASSERT2 (SCM_VECTORP (v),
9eb8500a
MD
135 g_vector_ref, v, k, SCM_ARG1, s_vector_ref);
136 SCM_GASSERT2 (SCM_INUMP (k),
137 g_vector_ref, v, k, SCM_ARG2, s_vector_ref);
b5c2579a 138 SCM_ASSERT_RANGE (2, k, SCM_INUM (k) < SCM_VECTOR_LENGTH (v) && SCM_INUM (k) >= 0);
c014a02e 139 return SCM_VELTS (v)[(long) SCM_INUM (k)];
0f2d19dd 140}
685c0d71 141#undef FUNC_NAME
0f2d19dd 142
f172c0b7 143SCM_GPROC (s_vector_set_x, "vector-set!", 3, 0, 0, scm_vector_set_x, g_vector_set_x);
1cc91f1b 144
942e5b91
MG
145/* "@var{k} must be a valid index of @var{vector}.\n"
146 "@code{Vector-set!} stores @var{obj} in element @var{k} of @var{vector}.\n"
147 "The value returned by @samp{vector-set!} is unspecified.\n"
148 "@lisp\n"
149 "(let ((vec (vector 0 '(2 2 2 2) "Anna")))\n"
150 " (vector-set! vec 1 '("Sue" "Sue"))\n"
151 " vec) @result{} #(0 ("Sue" "Sue") "Anna")\n"
152 "(vector-set! '#(0 1 2) 1 "doe") @result{} @emph{error} ; constant vector\n"
153 "@end lisp"
5ffe9968
GB
154*/
155
0f2d19dd 156SCM
f172c0b7 157scm_vector_set_x (SCM v, SCM k, SCM obj)
685c0d71 158#define FUNC_NAME s_vector_set_x
0f2d19dd 159{
f172c0b7 160 SCM_GASSERTn (SCM_VECTORP (v),
1afff620 161 g_vector_set_x, scm_list_3 (v, k, obj),
9eb8500a 162 SCM_ARG1, s_vector_set_x);
f172c0b7 163 SCM_GASSERTn (SCM_INUMP (k),
1afff620 164 g_vector_set_x, scm_list_3 (v, k, obj),
9eb8500a 165 SCM_ARG2, s_vector_set_x);
b5c2579a 166 SCM_ASSERT_RANGE (2, k, SCM_INUM (k) < SCM_VECTOR_LENGTH (v) && SCM_INUM (k) >= 0);
c014a02e 167 SCM_VELTS(v)[(long) SCM_INUM(k)] = obj;
60c497a3 168 return SCM_UNSPECIFIED;
0f2d19dd 169}
685c0d71 170#undef FUNC_NAME
0f2d19dd
JB
171
172
a1ec6916 173SCM_DEFINE (scm_make_vector, "make-vector", 1, 1, 0,
1bbd0b84 174 (SCM k, SCM fill),
1e6808ea
MG
175 "Return a newly allocated vector of @var{k} elements. If a\n"
176 "second argument is given, then each element is initialized to\n"
177 "@var{fill}. Otherwise the initial contents of each element is\n"
178 "unspecified.")
1bbd0b84 179#define FUNC_NAME s_scm_make_vector
0f2d19dd 180{
1b9be268 181 if (SCM_UNBNDP (fill))
d60cebe2 182 fill = SCM_UNSPECIFIED;
e382fdbe
DH
183
184 if (SCM_INUMP (k))
185 {
cb0d8be2 186 SCM_ASSERT_RANGE (1, k, SCM_INUM (k) >= 0);
e382fdbe
DH
187 return scm_c_make_vector (SCM_INUM (k), fill);
188 }
189 else if (SCM_BIGP (k))
190 SCM_OUT_OF_RANGE (1, k);
191 else
192 SCM_WRONG_TYPE_ARG (1, k);
00ffa0e7
KN
193}
194#undef FUNC_NAME
195
e382fdbe 196
00ffa0e7 197SCM
c014a02e 198scm_c_make_vector (unsigned long int k, SCM fill)
00ffa0e7
KN
199#define FUNC_NAME s_scm_make_vector
200{
201 SCM v;
92c2555f 202 scm_t_bits *base;
1b9be268 203
e382fdbe
DH
204 if (k > 0)
205 {
c014a02e 206 unsigned long int j;
1b9be268 207
c014a02e 208 SCM_ASSERT_RANGE (1, scm_ulong2num (k), k <= SCM_VECTOR_MAX_LENGTH);
1b9be268 209
92c2555f 210 base = scm_must_malloc (k * sizeof (scm_t_bits), FUNC_NAME);
e382fdbe
DH
211 for (j = 0; j != k; ++j)
212 base[j] = SCM_UNPACK (fill);
213 }
214 else
215 base = NULL;
1b9be268 216
e382fdbe
DH
217 SCM_NEWCELL (v);
218 SCM_SET_VECTOR_BASE (v, base);
219 SCM_SET_VECTOR_LENGTH (v, k, scm_tc7_vector);
220 scm_remember_upto_here_1 (fill);
1b9be268 221
0f2d19dd
JB
222 return v;
223}
1bbd0b84 224#undef FUNC_NAME
0f2d19dd 225
e382fdbe 226
3b3b36dd 227SCM_DEFINE (scm_vector_to_list, "vector->list", 1, 0, 0,
1e6808ea
MG
228 (SCM v),
229 "Return a newly allocated list of the objects contained in the\n"
230 "elements of @var{vector}.\n"
231 "\n"
942e5b91
MG
232 "@lisp\n"
233 "(vector->list '#(dah dah didah)) @result{} (dah dah didah)\n"
234 "(list->vector '(dididit dah)) @result{} #(dididit dah)\n"
235 "@end lisp")
1bbd0b84 236#define FUNC_NAME s_scm_vector_to_list
0f2d19dd
JB
237{
238 SCM res = SCM_EOL;
c014a02e 239 long i;
0f2d19dd 240 SCM *data;
3b3b36dd 241 SCM_VALIDATE_VECTOR (1,v);
0f2d19dd 242 data = SCM_VELTS(v);
b5c2579a 243 for(i = SCM_VECTOR_LENGTH(v)-1;i >= 0;i--) res = scm_cons(data[i], res);
0f2d19dd
JB
244 return res;
245}
1bbd0b84 246#undef FUNC_NAME
0f2d19dd
JB
247
248
a1ec6916 249SCM_DEFINE (scm_vector_fill_x, "vector-fill!", 2, 0, 0,
1e6808ea
MG
250 (SCM v, SCM fill),
251 "Store @var{fill} in every element of @var{vector}. The value\n"
252 "returned by @code{vector-fill!} is unspecified.")
1bbd0b84 253#define FUNC_NAME s_scm_vector_fill_x
0f2d19dd 254{
c014a02e 255 register long i;
0f2d19dd 256 register SCM *data;
1be6b49c
ML
257 SCM_VALIDATE_VECTOR (1, v);
258 data = SCM_VELTS (v);
259 for(i = SCM_VECTOR_LENGTH (v) - 1; i >= 0; i--)
1e6808ea 260 data[i] = fill;
0f2d19dd
JB
261 return SCM_UNSPECIFIED;
262}
1bbd0b84 263#undef FUNC_NAME
0f2d19dd
JB
264
265
0f2d19dd 266SCM
1bbd0b84 267scm_vector_equal_p(SCM x, SCM y)
0f2d19dd 268{
c014a02e 269 long i;
1be6b49c
ML
270 for(i = SCM_VECTOR_LENGTH (x) - 1; i >= 0; i--)
271 if (SCM_FALSEP (scm_equal_p (SCM_VELTS (x)[i], SCM_VELTS (y)[i])))
0f2d19dd
JB
272 return SCM_BOOL_F;
273 return SCM_BOOL_T;
274}
275
276
a1ec6916 277SCM_DEFINE (scm_vector_move_left_x, "vector-move-left!", 5, 0, 0,
1bbd0b84 278 (SCM vec1, SCM start1, SCM end1, SCM vec2, SCM start2),
b380b885 279 "Vector version of @code{substring-move-left!}.")
1bbd0b84 280#define FUNC_NAME s_scm_vector_move_left_x
0f2d19dd 281{
c014a02e
ML
282 long i;
283 long j;
284 long e;
0f2d19dd 285
3b3b36dd
GB
286 SCM_VALIDATE_VECTOR (1,vec1);
287 SCM_VALIDATE_INUM_COPY (2,start1,i);
288 SCM_VALIDATE_INUM_COPY (3,end1,e);
289 SCM_VALIDATE_VECTOR (4,vec2);
290 SCM_VALIDATE_INUM_COPY (5,start2,j);
b5c2579a
DH
291 SCM_ASSERT_RANGE (2, start1, i <= SCM_VECTOR_LENGTH (vec1) && i >= 0);
292 SCM_ASSERT_RANGE (5, start2, j <= SCM_VECTOR_LENGTH (vec2) && j >= 0);
293 SCM_ASSERT_RANGE (3, end1, e <= SCM_VECTOR_LENGTH (vec1) && e >= 0);
294 SCM_ASSERT_RANGE (5, start2, e-i+j <= SCM_VECTOR_LENGTH (vec2));
0f2d19dd
JB
295 while (i<e) SCM_VELTS (vec2)[j++] = SCM_VELTS (vec1)[i++];
296 return SCM_UNSPECIFIED;
297}
1bbd0b84 298#undef FUNC_NAME
0f2d19dd 299
a1ec6916 300SCM_DEFINE (scm_vector_move_right_x, "vector-move-right!", 5, 0, 0,
1bbd0b84 301 (SCM vec1, SCM start1, SCM end1, SCM vec2, SCM start2),
b380b885 302 "Vector version of @code{substring-move-right!}.")
1bbd0b84 303#define FUNC_NAME s_scm_vector_move_right_x
0f2d19dd 304{
c014a02e
ML
305 long i;
306 long j;
307 long e;
0f2d19dd 308
3b3b36dd
GB
309 SCM_VALIDATE_VECTOR (1,vec1);
310 SCM_VALIDATE_INUM_COPY (2,start1,i);
311 SCM_VALIDATE_INUM_COPY (3,end1,e);
312 SCM_VALIDATE_VECTOR (4,vec2);
313 SCM_VALIDATE_INUM_COPY (5,start2,j);
b5c2579a
DH
314 SCM_ASSERT_RANGE (2, start1, i <= SCM_VECTOR_LENGTH (vec1) && i >= 0);
315 SCM_ASSERT_RANGE (5, start2, j <= SCM_VECTOR_LENGTH (vec2) && j >= 0);
316 SCM_ASSERT_RANGE (3, end1, e <= SCM_VECTOR_LENGTH (vec1) && e >= 0);
2cc41672 317 j = e - i + j;
b5c2579a 318 SCM_ASSERT_RANGE (5, start2, j <= SCM_VECTOR_LENGTH (vec2));
2cc41672
MD
319 while (i < e)
320 SCM_VELTS (vec2)[--j] = SCM_VELTS (vec1)[--e];
0f2d19dd
JB
321 return SCM_UNSPECIFIED;
322}
1bbd0b84 323#undef FUNC_NAME
0f2d19dd
JB
324
325
1cc91f1b 326
0f2d19dd
JB
327void
328scm_init_vectors ()
0f2d19dd 329{
7c33806a
DH
330 scm_nullvect = scm_c_make_vector (0, SCM_UNDEFINED);
331
8dc9439f 332#ifndef SCM_MAGIC_SNARFER
a0599745 333#include "libguile/vectors.x"
8dc9439f 334#endif
0f2d19dd
JB
335}
336
89e00824
ML
337
338/*
339 Local Variables:
340 c-file-style: "gnu"
341 End:
342*/