Fix leaky behavior of `scm_take_TAGvector ()'.
[bpt/guile.git] / libguile / srfi-4.i.c
CommitLineData
6e708ef2 1/* This file defines the procedures related to one type of uniform
f8579182
MV
2 numeric vector. It is included multiple time in srfi-4.c, once for
3 each type.
4
5 Before inclusion, the following macros must be defined. They are
6 undefined at the end of this file to get back to a clean slate for
7 the next inclusion.
8
9 - TYPE
10
11 The type tag of the vector, for example SCM_UVEC_U8
12
13 - TAG
14
15 The tag name of the vector, for example u8. The tag is used to
16 form the function names and is included in the docstrings, for
17 example.
e0e49670
MV
18
19 - CTYPE
20
d2759570
MV
21 The C type of the elements, for example scm_t_uint8. The code
22 below will never do sizeof (CTYPE), thus you can use just 'float'
23 for the c32 type, for example.
00c17d45
MV
24
25 When CTYPE is not defined, the functions using it are excluded.
f8579182
MV
26*/
27
28/* The first level does not expand macros in the arguments. */
29#define paste(a1,a2,a3) a1##a2##a3
30#define s_paste(a1,a2,a3) s_##a1##a2##a3
31#define stringify(a) #a
32
33/* But the second level does. */
34#define F(pre,T,suf) paste(pre,T,suf)
35#define s_F(pre,T,suf) s_paste(pre,T,suf)
36#define S(T) stringify(T)
37
38SCM_DEFINE (F(scm_,TAG,vector_p), S(TAG)"vector?", 1, 0, 0,
39 (SCM obj),
40 "Return @code{#t} if @var{obj} is a vector of type " S(TAG) ",\n"
41 "@code{#f} otherwise.")
42#define FUNC_NAME s_F(scm_, TAG, vector_p)
43{
44 return uvec_p (TYPE, obj);
45}
46#undef FUNC_NAME
47
48SCM_DEFINE (F(scm_make_,TAG,vector), "make-"S(TAG)"vector", 1, 1, 0,
49 (SCM len, SCM fill),
6e708ef2 50 "Return a newly allocated uniform numeric vector which can\n"
f8579182
MV
51 "hold @var{len} elements. If @var{fill} is given, it is used to\n"
52 "initialize the elements, otherwise the contents of the vector\n"
53 "is unspecified.")
54#define FUNC_NAME s_S(scm_make_,TAG,vector)
55{
56 return make_uvec (TYPE, len, fill);
57}
58#undef FUNC_NAME
59
60SCM_DEFINE (F(scm_,TAG,vector), S(TAG)"vector", 0, 0, 1,
61 (SCM l),
6e708ef2 62 "Return a newly allocated uniform numeric vector containing\n"
f8579182
MV
63 "all argument values.")
64#define FUNC_NAME s_F(scm_,TAG,vector)
65{
66 return list_to_uvec (TYPE, l);
67}
68#undef FUNC_NAME
69
70
71SCM_DEFINE (F(scm_,TAG,vector_length), S(TAG)"vector-length", 1, 0, 0,
72 (SCM uvec),
6e708ef2 73 "Return the number of elements in the uniform numeric vector\n"
f8579182
MV
74 "@var{uvec}.")
75#define FUNC_NAME s_F(scm_,TAG,vector_length)
76{
77 return uvec_length (TYPE, uvec);
78}
79#undef FUNC_NAME
80
81
82SCM_DEFINE (F(scm_,TAG,vector_ref), S(TAG)"vector-ref", 2, 0, 0,
83 (SCM uvec, SCM index),
6e708ef2 84 "Return the element at @var{index} in the uniform numeric\n"
f8579182
MV
85 "vector @var{uvec}.")
86#define FUNC_NAME s_F(scm_,TAG,vector_ref)
87{
88 return uvec_ref (TYPE, uvec, index);
89}
90#undef FUNC_NAME
91
92
93SCM_DEFINE (F(scm_,TAG,vector_set_x), S(TAG)"vector-set!", 3, 0, 0,
94 (SCM uvec, SCM index, SCM value),
6e708ef2 95 "Set the element at @var{index} in the uniform numeric\n"
f8579182
MV
96 "vector @var{uvec} to @var{value}. The return value is not\n"
97 "specified.")
98#define FUNC_NAME s_F(scm_,TAG,vector_set_x)
99{
100 return uvec_set_x (TYPE, uvec, index, value);
101}
102#undef FUNC_NAME
103
104
105SCM_DEFINE (F(scm_,TAG,vector_to_list), S(TAG)"vector->list", 1, 0, 0,
106 (SCM uvec),
6e708ef2 107 "Convert the uniform numeric vector @var{uvec} to a list.")
f8579182
MV
108#define FUNC_NAME s_F(scm_,TAG,vector_to_list)
109{
110 return uvec_to_list (TYPE, uvec);
111}
112#undef FUNC_NAME
113
114
115SCM_DEFINE (F(scm_list_to_,TAG,vector), "list->"S(TAG)"vector", 1, 0, 0,
116 (SCM l),
6e708ef2 117 "Convert the list @var{l} to a numeric uniform vector.")
f8579182
MV
118#define FUNC_NAME s_F(scm_list_to_,TAG,vector)
119{
120 return list_to_uvec (TYPE, l);
121}
122#undef FUNC_NAME
123
00c17d45
MV
124#ifdef CTYPE
125
126SCM
ab7acbb7 127F(scm_take_,TAG,vector) (CTYPE *data, size_t n)
00c17d45 128{
d7e7a02a
LC
129 /* The manual says "Return a new uniform numeric vector [...] that uses the
130 memory pointed to by DATA". We *have* to use DATA as the underlying
131 storage; thus we must register a finalizer to eventually free(3) it. */
132 GC_finalization_proc prev_finalizer;
133 GC_PTR prev_finalization_data;
134
135 GC_REGISTER_FINALIZER_NO_ORDER (data, free_user_data, 0,
136 &prev_finalizer,
137 &prev_finalization_data);
138
00c17d45
MV
139 return take_uvec (TYPE, data, n);
140}
141
b590aceb 142const CTYPE *
6e708ef2 143F(scm_array_handle_,TAG,_elements) (scm_t_array_handle *h)
b590aceb 144{
6e708ef2 145 return F(scm_array_handle_,TAG,_writable_elements) (h);
b590aceb
MV
146}
147
148CTYPE *
6e708ef2 149F(scm_array_handle_,TAG,_writable_elements) (scm_t_array_handle *h)
e0e49670 150{
6e708ef2 151 SCM vec = h->array;
04b87de5
MV
152 if (SCM_I_ARRAYP (vec))
153 vec = SCM_I_ARRAY_V (vec);
6e708ef2
MV
154 uvec_assert (TYPE, vec);
155 if (TYPE == SCM_UVEC_C32 || TYPE == SCM_UVEC_C64)
156 return ((CTYPE *)SCM_UVEC_BASE (vec)) + 2*h->base;
157 else
158 return ((CTYPE *)SCM_UVEC_BASE (vec)) + h->base;
159}
160
161const CTYPE *
162F(scm_,TAG,vector_elements) (SCM uvec,
163 scm_t_array_handle *h,
164 size_t *lenp, ssize_t *incp)
165{
166 return F(scm_,TAG,vector_writable_elements) (uvec, h, lenp, incp);
167}
168
169CTYPE *
170F(scm_,TAG,vector_writable_elements) (SCM uvec,
171 scm_t_array_handle *h,
172 size_t *lenp, ssize_t *incp)
173{
996baf27 174 scm_generalized_vector_get_handle (uvec, h);
6e708ef2
MV
175 if (lenp)
176 {
177 scm_t_array_dim *dim = scm_array_handle_dims (h);
178 *lenp = dim->ubnd - dim->lbnd + 1;
179 *incp = dim->inc;
180 }
181 return F(scm_array_handle_,TAG,_writable_elements) (h);
e0e49670
MV
182}
183
00c17d45
MV
184#endif
185
4ea4bc4c 186static SCM
2a610be5 187F(,TAG,ref) (scm_t_array_handle *handle, size_t pos)
4ea4bc4c
MV
188{
189 return uvec_fast_ref (TYPE, handle->elements, pos);
190}
191
192static void
2a610be5 193F(,TAG,set) (scm_t_array_handle *handle, size_t pos, SCM val)
4ea4bc4c
MV
194{
195 uvec_fast_set_x (TYPE, handle->writable_elements, pos, val);
196}
197
f8579182
MV
198#undef paste
199#undef s_paste
200#undef stringify
201#undef F
202#undef s_F
203#undef S
204
205#undef TYPE
206#undef TAG
e0e49670 207#undef CTYPE