1 /*
2  * gauche/vector.h - Vector API
3  *
4  *   Copyright (c) 2000-2020  Shiro Kawai  <shiro@acm.org>
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *   1. Redistributions of source code must retain the above copyright
11  *      notice, this list of conditions and the following disclaimer.
12  *
13  *   2. Redistributions in binary form must reproduce the above copyright
14  *      notice, this list of conditions and the following disclaimer in the
15  *      documentation and/or other materials provided with the distribution.
16  *
17  *   3. Neither the name of the authors nor the names of its contributors
18  *      may be used to endorse or promote products derived from this
19  *      software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27  *   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28  *   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29  *   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30  *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31  *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #ifndef GAUCHE_VECTOR_H
35 #define GAUCHE_VECTOR_H
36 
37 /*
38  * General vector
39  */
40 
41 struct ScmVectorRec {
42     SCM_HEADER;
43 #if GAUCHE_API_VERSION >= 1000
44     ScmWord size_flags;
45 #else  /* GAUCHE_API_VERSION < 1000 */
46     ScmWord size;
47 #endif /* GAUCHE_API_VERSION < 1000 */
48     ScmObj elements[1];
49 };
50 
51 SCM_CLASS_DECL(Scm_VectorClass);
52 #define SCM_CLASS_VECTOR     (&Scm_VectorClass)
53 #define SCM_VECTOR(obj)          ((ScmVector*)(obj))
54 #define SCM_VECTORP(obj)         SCM_XTYPEP(obj, SCM_CLASS_VECTOR)
55 #define SCM_VECTOR_ELEMENTS(obj) (SCM_VECTOR(obj)->elements)
56 #define SCM_VECTOR_ELEMENT(obj, i)   (SCM_VECTOR(obj)->elements[i])
57 
58 /* SCM_VECTOR_SIZE_SLOT_INITIALIZER is used in cgen-generated code  */
59 
60 #if GAUCHE_API_VERSION >= 1000
61 #define SCM_VECTOR_SIZE(obj)        (SCM_VECTOR(obj)->size_flags >> 1)
62 #define SCM_VECTOR_IMMUTABLE_P(obj) (SCM_VECTOR(obj)->size_flags & 1)
63 #define SCM_VECTOR_IMMUTABLE_SET(obj, flag)     \
64     ((flag)                                     \
65      ? (SCM_UVECTOR(obj)->size_flags |= 1)      \
66      : (SCM_UVECTOR(obj)->size_flags &= ~1))
67 #define SCM_VECTOR_SIZE_SLOT_INITIALIZER(len, imm) \
68     SCM_OBJ(((len)<<1)|(imm?1:0))
69 #else  /* GAUCHE_API_VERSION < 1000 */
70 #define SCM_VECTOR_SIZE(obj)        (SCM_VECTOR(obj)->size)
71 #define SCM_VECTOR_IMMUTABLE_P(obj) (!SCM_VECTORP(obj)) /* always FALSE, but need to use obj to avoid unused variable warning */
72 #define SCM_VECTOR_IMMUTABLE_SET(obj, flag)  /*empty*/
73 #define SCM_VECTOR_SIZE_SLOT_INITIALIZER(len, imm)  SCM_OBJ(len)
74 #endif /* GAUCHE_API_VERSION < 1000 */
75 
76 #define SCM_VECTOR_CHECK_MUTABLE(obj)           \
77   do { if (SCM_VECTOR_IMMUTABLE_P(obj)) {       \
78     Scm_Error("vector is immutable: %S", obj);  \
79   }} while (0)
80 
81 SCM_EXTERN ScmObj Scm_MakeVector(ScmSmallInt size, ScmObj fill);
82 SCM_EXTERN ScmObj Scm_VectorRef(ScmVector *vec, ScmSmallInt i, ScmObj fallback);
83 SCM_EXTERN ScmObj Scm_VectorSet(ScmVector *vec, ScmSmallInt i, ScmObj obj);
84 SCM_EXTERN ScmObj Scm_VectorFill(ScmVector *vec, ScmObj fill,
85                                  ScmSmallInt start, ScmSmallInt end);
86 
87 SCM_EXTERN ScmObj Scm_ListToVector(ScmObj l,
88                                    ScmSmallInt start, ScmSmallInt end);
89 SCM_EXTERN ScmObj Scm_VectorToList(ScmVector *v,
90                                    ScmSmallInt start, ScmSmallInt end);
91 SCM_EXTERN ScmObj Scm_VectorCopy(ScmVector *vec,
92                                  ScmSmallInt start, ScmSmallInt end,
93                                  ScmObj fill);
94 
95 /*
96  * Uniform vectors
97  * NB: The Gauche core only includes basic uniform vector APIs, e.g.
98  * constructors, accessors, and srfi-4 literal reader/writer syntax.
99  * All other useful APIs and Scheme bindings are provided in ext/uvector.
100  */
101 
102 /* Common uniform vector structure */
103 
104 typedef struct ScmUVectorRec {
105     SCM_HEADER;
106     ScmWord size_flags;         /* (len<<1)|immutable */
107     void *owner;
108     void *elements;
109 } ScmUVector;
110 
111 SCM_CLASS_DECL(Scm_UVectorClass);
112 #define SCM_CLASS_UVECTOR         (&Scm_UVectorClass)
113 #define SCM_UVECTOR(obj)          ((ScmUVector*)(obj))
114 #define SCM_UVECTORP(obj)         Scm_TypeP(obj, SCM_CLASS_UVECTOR)
115 #define SCM_UVECTOR_OWNER(obj)    (SCM_UVECTOR(obj)->owner)
116 #define SCM_UVECTOR_ELEMENTS(obj) (SCM_UVECTOR(obj)->elements)
117 
118 #define SCM_UVECTOR_SIZE(obj)     (SCM_UVECTOR(obj)->size_flags >> 1)
119 #define SCM_UVECTOR_IMMUTABLE_P(obj) (SCM_UVECTOR(obj)->size_flags & 1)
120 #define SCM_UVECTOR_IMMUTABLE_SET(obj, flag)    \
121     ((flag)                                     \
122      ? (SCM_UVECTOR(obj)->size_flags |= 1)      \
123      : (SCM_UVECTOR(obj)->size_flags &= ~1))
124 #define SCM_UVECTOR_INITIALIZER(klass, size, elements, immutable, owner) \
125     { { SCM_CLASS_STATIC_TAG(klass) }, (((size)<<1)|(immutable?1:0)),    \
126       (owner), (elements) }
127 
128 #define SCM_UVECTOR_CHECK_MUTABLE(obj)                 \
129   do { if (SCM_UVECTOR_IMMUTABLE_P(obj)) {             \
130     Scm_Error("uniform vector is immutable: %S", obj); \
131   }} while (0)
132 
133 /* A convenient enum to dispatch by specific uvector subclasses
134    within a generic uvector API.
135    NB: The value of those enums can be embedded in precompiled files,
136    and also used in Scm_Compare to order between different uvectors.
137    So the order shouldn't be changed.
138 */
139 typedef enum {
140     SCM_UVECTOR_S8,
141     SCM_UVECTOR_U8,
142     SCM_UVECTOR_S16,
143     SCM_UVECTOR_U16,
144     SCM_UVECTOR_S32,
145     SCM_UVECTOR_U32,
146     SCM_UVECTOR_S64,
147     SCM_UVECTOR_U64,
148     SCM_UVECTOR_F16,
149     SCM_UVECTOR_F32,
150     SCM_UVECTOR_F64,
151     SCM_UVECTOR_RESERVED1,      /* reserved for f128*/
152     SCM_UVECTOR_C32,
153     SCM_UVECTOR_C64,
154     SCM_UVECTOR_C128,
155     SCM_UVECTOR_RESERVED2,      /* reserved for c256 */
156     SCM_UVECTOR_INVALID = -1
157 } ScmUVectorType;
158 
159 #define SCM_UVECTOR_SUBTYPE_P(obj, type) \
160     (SCM_UVECTORP(obj)&&Scm_UVectorType(SCM_CLASS_OF(obj))==(type))
161 
162 SCM_EXTERN ScmUVectorType Scm_UVectorType(ScmClass *klass);
163 SCM_EXTERN const char *Scm_UVectorTypeName(int type);
164 SCM_EXTERN int    Scm_UVectorElementSize(ScmClass *klass);
165 SCM_EXTERN int    Scm_UVectorSizeInBytes(ScmUVector *v);
166 SCM_EXTERN ScmObj Scm_MakeUVector(ScmClass *klass,
167                                   ScmSmallInt size, void *init);
168 SCM_EXTERN ScmObj Scm_MakeUVectorFull(ScmClass *klass,
169                                       ScmSmallInt size, void *init,
170                                       int immutablep, void *owner);
171 SCM_EXTERN ScmObj Scm_ListToUVector(ScmClass *klass, ScmObj list, int clamp);
172 SCM_EXTERN ScmObj Scm_VMUVectorRef(ScmUVector *v, int t,
173                                    ScmSmallInt k, ScmObj fallback);
174 SCM_EXTERN ScmObj Scm_UVectorSet(ScmUVector *v, int t,
175                                  ScmSmallInt k, ScmObj val, int clamp);
176 SCM_EXTERN ScmObj Scm_ReadUVector(ScmPort *port, const char *tag,
177                                   ScmReadContext *ctx);
178 
179 /* Individual class definitions.
180    Some of SCM_tagVECTOR* macros are redundant, for SCM_UVECTOR* macros
181    is just enough.  We have them for the backward compatibility.
182  */
183 
184 SCM_CLASS_DECL(Scm_S8VectorClass);
185 #define SCM_CLASS_S8VECTOR         (&Scm_S8VectorClass)
186 #define SCM_S8VECTOR(obj)          SCM_UVECTOR(obj)
187 #define SCM_S8VECTORP(obj)         SCM_XTYPEP(obj, SCM_CLASS_S8VECTOR)
188 #define SCM_S8VECTOR_SIZE(obj)     SCM_UVECTOR_SIZE(obj)
189 #define SCM_S8VECTOR_ELEMENTS(obj) ((int8_t*)SCM_UVECTOR_ELEMENTS(obj))
190 #define SCM_S8VECTOR_ELEMENT(obj,k) SCM_S8VECTOR_ELEMENTS(obj)[k]
191 SCM_EXTERN ScmObj Scm_MakeS8Vector(ScmSmallInt size, int8_t fill);
192 SCM_EXTERN ScmObj Scm_MakeS8VectorFromArray(ScmSmallInt size,
193                                             const int8_t array[]);
194 SCM_EXTERN ScmObj Scm_MakeS8VectorFromArrayShared(ScmSmallInt size,
195                                                   int8_t array[]);
196 
197 SCM_CLASS_DECL(Scm_U8VectorClass);
198 #define SCM_CLASS_U8VECTOR         (&Scm_U8VectorClass)
199 #define SCM_U8VECTOR(obj)          SCM_UVECTOR(obj)
200 #define SCM_U8VECTORP(obj)         SCM_XTYPEP(obj, SCM_CLASS_U8VECTOR)
201 #define SCM_U8VECTOR_SIZE(obj)     SCM_UVECTOR_SIZE(obj)
202 #define SCM_U8VECTOR_ELEMENTS(obj) ((uint8_t*)SCM_UVECTOR_ELEMENTS(obj))
203 #define SCM_U8VECTOR_ELEMENT(obj,k) SCM_U8VECTOR_ELEMENTS(obj)[k]
204 SCM_EXTERN ScmObj Scm_MakeU8Vector(ScmSmallInt size, uint8_t fill);
205 SCM_EXTERN ScmObj Scm_MakeU8VectorFromArray(ScmSmallInt size,
206                                             const uint8_t array[]);
207 SCM_EXTERN ScmObj Scm_MakeU8VectorFromArrayShared(ScmSmallInt size,
208                                                   uint8_t array[]);
209 
210 SCM_CLASS_DECL(Scm_S16VectorClass);
211 #define SCM_CLASS_S16VECTOR         (&Scm_S16VectorClass)
212 #define SCM_S16VECTOR(obj)          SCM_UVECTOR(obj)
213 #define SCM_S16VECTORP(obj)         SCM_XTYPEP(obj, SCM_CLASS_S16VECTOR)
214 #define SCM_S16VECTOR_SIZE(obj)     SCM_UVECTOR_SIZE(obj)
215 #define SCM_S16VECTOR_ELEMENTS(obj) ((int16_t*)SCM_UVECTOR_ELEMENTS(obj))
216 #define SCM_S16VECTOR_ELEMENT(obj,k) SCM_S16VECTOR_ELEMENTS(obj)[k]
217 SCM_EXTERN ScmObj Scm_MakeS16Vector(ScmSmallInt size, int16_t fill);
218 SCM_EXTERN ScmObj Scm_MakeS16VectorFromArray(ScmSmallInt size,
219                                              const int16_t array[]);
220 SCM_EXTERN ScmObj Scm_MakeS16VectorFromArrayShared(ScmSmallInt size,
221                                                    int16_t array[]);
222 
223 SCM_CLASS_DECL(Scm_U16VectorClass);
224 #define SCM_CLASS_U16VECTOR         (&Scm_U16VectorClass)
225 #define SCM_U16VECTOR(obj)          SCM_UVECTOR(obj)
226 #define SCM_U16VECTORP(obj)         SCM_XTYPEP(obj, SCM_CLASS_U16VECTOR)
227 #define SCM_U16VECTOR_SIZE(obj)     SCM_UVECTOR_SIZE(obj)
228 #define SCM_U16VECTOR_ELEMENTS(obj) ((uint16_t*)SCM_UVECTOR_ELEMENTS(obj))
229 #define SCM_U16VECTOR_ELEMENT(obj,k) SCM_U16VECTOR_ELEMENTS(obj)[k]
230 SCM_EXTERN ScmObj Scm_MakeU16Vector(ScmSmallInt size, uint16_t fill);
231 SCM_EXTERN ScmObj Scm_MakeU16VectorFromArray(ScmSmallInt size,
232                                              const uint16_t array[]);
233 SCM_EXTERN ScmObj Scm_MakeU16VectorFromArrayShared(ScmSmallInt size,
234                                                    uint16_t array[]);
235 
236 SCM_CLASS_DECL(Scm_S32VectorClass);
237 #define SCM_CLASS_S32VECTOR         (&Scm_S32VectorClass)
238 #define SCM_S32VECTOR(obj)          SCM_UVECTOR(obj)
239 #define SCM_S32VECTORP(obj)         SCM_XTYPEP(obj, SCM_CLASS_S32VECTOR)
240 #define SCM_S32VECTOR_SIZE(obj)     SCM_UVECTOR_SIZE(obj)
241 #define SCM_S32VECTOR_ELEMENTS(obj) ((int32_t*)SCM_UVECTOR_ELEMENTS(obj))
242 #define SCM_S32VECTOR_ELEMENT(obj,k) SCM_S32VECTOR_ELEMENTS(obj)[k]
243 SCM_EXTERN ScmObj Scm_MakeS32Vector(ScmSmallInt size, int32_t fill);
244 SCM_EXTERN ScmObj Scm_MakeS32VectorFromArray(ScmSmallInt size, const int32_t array[]);
245 SCM_EXTERN ScmObj Scm_MakeS32VectorFromArrayShared(ScmSmallInt size, int32_t array[]);
246 
247 SCM_CLASS_DECL(Scm_U32VectorClass);
248 #define SCM_CLASS_U32VECTOR         (&Scm_U32VectorClass)
249 #define SCM_U32VECTOR(obj)          SCM_UVECTOR(obj)
250 #define SCM_U32VECTORP(obj)         SCM_XTYPEP(obj, SCM_CLASS_U32VECTOR)
251 #define SCM_U32VECTOR_SIZE(obj)     SCM_UVECTOR_SIZE(obj)
252 #define SCM_U32VECTOR_ELEMENTS(obj) ((uint32_t*)SCM_UVECTOR_ELEMENTS(obj))
253 #define SCM_U32VECTOR_ELEMENT(obj,k) SCM_U32VECTOR_ELEMENTS(obj)[k]
254 SCM_EXTERN ScmObj Scm_MakeU32Vector(ScmSmallInt size, uint32_t fill);
255 SCM_EXTERN ScmObj Scm_MakeU32VectorFromArray(ScmSmallInt size,
256                                              const uint32_t array[]);
257 SCM_EXTERN ScmObj Scm_MakeU32VectorFromArrayShared(ScmSmallInt size,
258                                                    uint32_t array[]);
259 
260 SCM_CLASS_DECL(Scm_S64VectorClass);
261 #define SCM_CLASS_S64VECTOR         (&Scm_S64VectorClass)
262 #define SCM_S64VECTOR(obj)          SCM_UVECTOR(obj)
263 #define SCM_S64VECTORP(obj)         SCM_XTYPEP(obj, SCM_CLASS_S64VECTOR)
264 #define SCM_S64VECTOR_SIZE(obj)     SCM_UVECTOR_SIZE(obj)
265 #define SCM_S64VECTOR_ELEMENTS(obj) ((int64_t*)SCM_UVECTOR_ELEMENTS(obj))
266 #define SCM_S64VECTOR_ELEMENT(obj,k) SCM_S64VECTOR_ELEMENTS(obj)[k]
267 SCM_EXTERN ScmObj Scm_MakeS64Vector(ScmSmallInt size, int64_t fill);
268 SCM_EXTERN ScmObj Scm_MakeS64VectorFromArray(ScmSmallInt size,
269                                              const int64_t array[]);
270 SCM_EXTERN ScmObj Scm_MakeS64VectorFromArrayShared(ScmSmallInt size,
271                                                    int64_t array[]);
272 
273 SCM_CLASS_DECL(Scm_U64VectorClass);
274 #define SCM_CLASS_U64VECTOR         (&Scm_U64VectorClass)
275 #define SCM_U64VECTOR(obj)          SCM_UVECTOR(obj)
276 #define SCM_U64VECTORP(obj)         SCM_XTYPEP(obj, SCM_CLASS_U64VECTOR)
277 #define SCM_U64VECTOR_SIZE(obj)     SCM_UVECTOR_SIZE(obj)
278 #define SCM_U64VECTOR_ELEMENTS(obj) ((uint64_t*)SCM_UVECTOR_ELEMENTS(obj))
279 #define SCM_U64VECTOR_ELEMENT(obj,k) SCM_U64VECTOR_ELEMENTS(obj)[k]
280 SCM_EXTERN ScmObj Scm_MakeU64Vector(ScmSmallInt size, uint64_t fill);
281 SCM_EXTERN ScmObj Scm_MakeU64VectorFromArray(ScmSmallInt size,
282                                              const uint64_t array[]);
283 SCM_EXTERN ScmObj Scm_MakeU64VectorFromArrayShared(ScmSmallInt size,
284                                                    uint64_t array[]);
285 
286 SCM_CLASS_DECL(Scm_F16VectorClass);
287 #define SCM_CLASS_F16VECTOR         (&Scm_F16VectorClass)
288 #define SCM_F16VECTOR(obj)          SCM_UVECTOR(obj)
289 #define SCM_F16VECTORP(obj)         SCM_XTYPEP(obj, SCM_CLASS_F16VECTOR)
290 #define SCM_F16VECTOR_SIZE(obj)     SCM_UVECTOR_SIZE(obj)
291 #define SCM_F16VECTOR_ELEMENTS(obj) ((ScmHalfFloat*)SCM_UVECTOR_ELEMENTS(obj))
292 #define SCM_F16VECTOR_ELEMENT(obj,k) SCM_F16VECTOR_ELEMENTS(obj)[k]
293 SCM_EXTERN ScmObj Scm_MakeF16Vector(ScmSmallInt size, ScmHalfFloat fill);
294 SCM_EXTERN ScmObj Scm_MakeF16VectorFromArray(ScmSmallInt size,
295                                              const ScmHalfFloat array[]);
296 SCM_EXTERN ScmObj Scm_MakeF16VectorFromArrayShared(ScmSmallInt size,
297                                                    ScmHalfFloat array[]);
298 
299 SCM_CLASS_DECL(Scm_F32VectorClass);
300 #define SCM_CLASS_F32VECTOR         (&Scm_F32VectorClass)
301 #define SCM_F32VECTOR(obj)          SCM_UVECTOR(obj)
302 #define SCM_F32VECTORP(obj)         SCM_XTYPEP(obj, SCM_CLASS_F32VECTOR)
303 #define SCM_F32VECTOR_SIZE(obj)     SCM_UVECTOR_SIZE(obj)
304 #define SCM_F32VECTOR_ELEMENTS(obj) ((float*)SCM_UVECTOR_ELEMENTS(obj))
305 #define SCM_F32VECTOR_ELEMENT(obj,k) SCM_F32VECTOR_ELEMENTS(obj)[k]
306 SCM_EXTERN ScmObj Scm_MakeF32Vector(ScmSmallInt size, float fill);
307 SCM_EXTERN ScmObj Scm_MakeF32VectorFromArray(ScmSmallInt size,
308                                              const float array[]);
309 SCM_EXTERN ScmObj Scm_MakeF32VectorFromArrayShared(ScmSmallInt size,
310                                                    float array[]);
311 
312 SCM_CLASS_DECL(Scm_F64VectorClass);
313 #define SCM_CLASS_F64VECTOR         (&Scm_F64VectorClass)
314 #define SCM_F64VECTOR(obj)          SCM_UVECTOR(obj)
315 #define SCM_F64VECTORP(obj)         SCM_XTYPEP(obj, SCM_CLASS_F64VECTOR)
316 #define SCM_F64VECTOR_SIZE(obj)     SCM_UVECTOR_SIZE(obj)
317 #define SCM_F64VECTOR_ELEMENTS(obj) ((double*)SCM_UVECTOR_ELEMENTS(obj))
318 #define SCM_F64VECTOR_ELEMENT(obj,k) SCM_F64VECTOR_ELEMENTS(obj)[k]
319 SCM_EXTERN ScmObj Scm_MakeF64Vector(ScmSmallInt size, double fill);
320 SCM_EXTERN ScmObj Scm_MakeF64VectorFromArray(ScmSmallInt size,
321                                              const double array[]);
322 SCM_EXTERN ScmObj Scm_MakeF64VectorFromArrayShared(ScmSmallInt size,
323                                                    double array[]);
324 
325 SCM_CLASS_DECL(Scm_C32VectorClass);
326 #define SCM_CLASS_C32VECTOR         (&Scm_C32VectorClass)
327 #define SCM_C32VECTOR(obj)          SCM_UVECTOR(obj)
328 #define SCM_C32VECTORP(obj)         SCM_XTYPEP(obj, SCM_CLASS_C32VECTOR)
329 #define SCM_C32VECTOR_SIZE(obj)     SCM_UVECTOR_SIZE(obj)
330 #define SCM_C32VECTOR_ELEMENTS(obj) ((ScmHalfComplex*)SCM_UVECTOR_ELEMENTS(obj))
331 #define SCM_C32VECTOR_ELEMENT(obj,k) SCM_C32VECTOR_ELEMENTS(obj)[k]
332 SCM_EXTERN ScmObj Scm_MakeC32Vector(ScmSmallInt size, ScmHalfComplex fill);
333 SCM_EXTERN ScmObj Scm_MakeC32VectorFromArray(ScmSmallInt size,
334                                              const ScmHalfComplex array[]);
335 SCM_EXTERN ScmObj Scm_MakeC32VectorFromArrayShared(ScmSmallInt size,
336                                                    ScmHalfComplex array[]);
337 
338 SCM_CLASS_DECL(Scm_C64VectorClass);
339 #define SCM_CLASS_C64VECTOR         (&Scm_C64VectorClass)
340 #define SCM_C64VECTOR(obj)          SCM_UVECTOR(obj)
341 #define SCM_C64VECTORP(obj)         SCM_XTYPEP(obj, SCM_CLASS_C64VECTOR)
342 #define SCM_C64VECTOR_SIZE(obj)     SCM_UVECTOR_SIZE(obj)
343 #define SCM_C64VECTOR_ELEMENTS(obj) ((ScmFloatComplex*)SCM_UVECTOR_ELEMENTS(obj))
344 #define SCM_C64VECTOR_ELEMENT(obj,k) SCM_C64VECTOR_ELEMENTS(obj)[k]
345 SCM_EXTERN ScmObj Scm_MakeC64Vector(ScmSmallInt size, ScmFloatComplex fill);
346 SCM_EXTERN ScmObj Scm_MakeC64VectorFromArray(ScmSmallInt size,
347                                              const ScmFloatComplex array[]);
348 SCM_EXTERN ScmObj Scm_MakeC64VectorFromArrayShared(ScmSmallInt size,
349                                                    ScmFloatComplex array[]);
350 
351 SCM_CLASS_DECL(Scm_C128VectorClass);
352 #define SCM_CLASS_C128VECTOR         (&Scm_C128VectorClass)
353 #define SCM_C128VECTOR(obj)          SCM_UVECTOR(obj)
354 #define SCM_C128VECTORP(obj)         SCM_XTYPEP(obj, SCM_CLASS_C128VECTOR)
355 #define SCM_C128VECTOR_SIZE(obj)     SCM_UVECTOR_SIZE(obj)
356 #define SCM_C128VECTOR_ELEMENTS(obj) ((ScmDoubleComplex*)SCM_UVECTOR_ELEMENTS(obj))
357 #define SCM_C128VECTOR_ELEMENT(obj,k) SCM_C128VECTOR_ELEMENTS(obj)[k]
358 SCM_EXTERN ScmObj Scm_MakeC128Vector(ScmSmallInt size, ScmDoubleComplex fill);
359 SCM_EXTERN ScmObj Scm_MakeC128VectorFromArray(ScmSmallInt size,
360                                              const ScmDoubleComplex array[]);
361 SCM_EXTERN ScmObj Scm_MakeC128VectorFromArrayShared(ScmSmallInt size,
362                                                    ScmDoubleComplex array[]);
363 
364 
365 /* For the backward compatibility */
366 typedef ScmUVector ScmS8Vector;
367 typedef ScmUVector ScmU8Vector;
368 typedef ScmUVector ScmS16Vector;
369 typedef ScmUVector ScmU16Vector;
370 typedef ScmUVector ScmS32Vector;
371 typedef ScmUVector ScmU32Vector;
372 typedef ScmUVector ScmS64Vector;
373 typedef ScmUVector ScmU64Vector;
374 typedef ScmUVector ScmF16Vector;
375 typedef ScmUVector ScmF32Vector;
376 typedef ScmUVector ScmF64Vector;
377 
378 /*
379  * String/uvector common utility
380  */
381 
382 /* Retrieves underlying byte array */
383 const uint8_t *Scm_GetBytes(ScmObj str_or_uvec, ScmSize *size);
384 
385 /*
386  * Bitvectors (srfi-178)
387  *
388  *   We could view a bitvector as u1vector, but the operations on bitvectors
389  *   are sufficiently different from uniform vectors, so we made them
390  *   disjoint.
391  */
392 
393 typedef struct ScmBitvectorRec {
394     SCM_HEADER;
395     ScmWord size_flags;         /* (len<<1)|immutable */
396     ScmBits *bits;
397 } ScmBitvector;
398 
399 SCM_CLASS_DECL(Scm_BitvectorClass);
400 #define SCM_CLASS_BITVECTOR         (&Scm_BitvectorClass)
401 #define SCM_BITVECTOR(obj)          ((ScmBitvector*)(obj))
402 #define SCM_BITVECTORP(obj)         Scm_TypeP(obj, SCM_CLASS_BITVECTOR)
403 #define SCM_BITVECTOR_BITS(obj)     (SCM_BITVECTOR(obj)->bits)
404 
405 #define SCM_BITVECTOR_SIZE(obj)     (SCM_BITVECTOR(obj)->size_flags >> 1)
406 #define SCM_BITVECTOR_IMMUTABLE_P(obj) (SCM_BITVECTOR(obj)->size_flags & 1)
407 #define SCM_BITVECTOR_IMMUTABLE_SET(obj, flag)    \
408     ((flag)                                     \
409      ? (SCM_BITVECTOR(obj)->size_flags |= 1)      \
410      : (SCM_BITVECTOR(obj)->size_flags &= ~1))
411 
412 #define SCM_BITVECTOR_CHECK_MUTABLE(obj)                 \
413   do { if (SCM_BITVECTOR_IMMUTABLE_P(obj)) {             \
414     Scm_Error("bitvector is immutable: %S", obj); \
415   }} while (0)
416 
417 SCM_EXTERN int    Scm_Bit2Int(ScmObj bit);
418 SCM_EXTERN ScmObj Scm_Bit2Bool(ScmObj bit);
419 SCM_EXTERN ScmObj Scm_MakeBitvector(ScmSmallInt size, ScmObj init);
420 SCM_EXTERN ScmObj Scm_ListToBitvector(ScmObj lis);
421 SCM_EXTERN ScmObj Scm_BitvectorCopy(ScmBitvector *v,
422                                     ScmSmallInt start,
423                                     ScmSmallInt end);
424 SCM_EXTERN ScmObj Scm_BitvectorCopyX(ScmBitvector *dest, ScmSmallInt dstart,
425                                      ScmBitvector *src,
426                                      ScmSmallInt sstart, ScmSmallInt send);
427 
428 SCM_EXTERN ScmObj Scm_StringToBitvector(ScmString *s, int prefix);
429 SCM_EXTERN ScmObj Scm_BitvectorToString(ScmBitvector *v, int prefix);
430 
431 #endif /*GAUCHE_VECTOR_H*/
432