Commit | Line | Data |
---|---|---|
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 | ||
38 | SCM_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 | ||
48 | SCM_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 | ||
60 | SCM_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 | ||
71 | SCM_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 | ||
82 | SCM_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 | ||
93 | SCM_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 | ||
105 | SCM_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 | ||
115 | SCM_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 | ||
126 | SCM | |
ab7acbb7 | 127 | F(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 | 142 | const CTYPE * |
6e708ef2 | 143 | F(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 | ||
148 | CTYPE * | |
6e708ef2 | 149 | F(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 | ||
161 | const CTYPE * | |
162 | F(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 | ||
169 | CTYPE * | |
170 | F(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 | 186 | static SCM |
2a610be5 | 187 | F(,TAG,ref) (scm_t_array_handle *handle, size_t pos) |
4ea4bc4c MV |
188 | { |
189 | return uvec_fast_ref (TYPE, handle->elements, pos); | |
190 | } | |
191 | ||
192 | static void | |
2a610be5 | 193 | F(,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 |