1
/*===========================================================================
3
* About : Integer types for Scheme implementation
5
* Copyright (C) 2005-2006 YAMAMOTO Kengo <yamaken AT bp.iij4u.or.jp>
6
* Copyright (c) 2007 SigScheme Project <uim AT freedesktop.org>
10
* Redistribution and use in source and binary forms, with or without
11
* modification, are permitted provided that the following conditions
14
* 1. Redistributions of source code must retain the above copyright
15
* notice, this list of conditions and the following disclaimer.
16
* 2. Redistributions in binary form must reproduce the above copyright
17
* notice, this list of conditions and the following disclaimer in the
18
* documentation and/or other materials provided with the distribution.
19
* 3. Neither the name of authors nor the names of its contributors
20
* may be used to endorse or promote products derived from this software
21
* without specific prior written permission.
23
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
24
* IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
27
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
30
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
33
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
===========================================================================*/
37
* This file is independent of SigScheme and can be used to implement Scheme
38
* implementation-neutral generic subordinate parts, such as ports and
39
* character encoding handlers. In our short-term development, this separation
40
* aims that making the underlying port implementations and encoding handlers
41
* directly usable from libuim without SigScheme. It is needed to make libuim
42
* Scheme-implementation independent without problems caused by differences of
43
* implementation-specific character encoding handling behaviors.
45
* The copyright will be succeeded to the uim Project once the subordinate
46
* parts are completely separated from SigScheme.
48
* -- YamaKen 2006-03-30
51
#ifndef __SCM_SCMINT_H
52
#define __SCM_SCMINT_H
54
#include <sigscheme/config.h>
62
#if HAVE_SYS_INTTYPES_H
63
#include <sys/inttypes.h>
66
#include <sys/types.h>
74
/*=======================================
76
=======================================*/
77
#ifndef SCM_EMPTY_EXPR
78
#define SCM_EMPTY_EXPR ((void)0)
81
/*=======================================
82
Type Definitions: stdint.h subtitutes
83
=======================================*/
84
#define SCM_STDINT_MIN(t) ((t)(~(u##t)0))
85
#define SCM_STDINT_MAX(t) ((t)((~(u##t)0) >> 1))
87
/* Note: Since these macros are not pure constant such as (-1LL), testing in
88
* preprocessor directives (such as #if INT32_MAX < LONG_MAX) does not work. */
90
#define INT8_MIN SCM_STDINT_MIN(int8_t)
93
#define INT16_MIN SCM_STDINT_MIN(int16_t)
96
#define INT32_MIN SCM_STDINT_MIN(int32_t)
99
#define INT64_MIN SCM_STDINT_MIN(int64_t)
102
#define INTMAX_MIN SCM_STDINT_MIN(intmax_t)
105
#define INTPTR_MIN SCM_STDINT_MIN(intptr_t)
109
#define INT8_MAX SCM_STDINT_MAX(int8_t)
112
#define INT16_MAX SCM_STDINT_MAX(int16_t)
115
#define INT32_MAX SCM_STDINT_MAX(int32_t)
118
#define INT64_MAX SCM_STDINT_MAX(int64_t)
121
#define INTMAX_MAX SCM_STDINT_MAX(intmax_t)
124
#define INTPTR_MAX SCM_STDINT_MAX(intptr_t)
128
#define UINT8_MAX (~(uint8_t)0)
131
#define UINT16_MAX (~(uint16_t)0)
134
#define UINT32_MAX (~(uint32_t)0)
137
#define UINT64_MAX (~(uint64_t)0)
140
#define UINTMAX_MAX (~(uintmax_t)0)
143
#define UINTPTR_MAX (~(uintptr_t)0)
146
/*=======================================
148
=======================================*/
150
* Our own Boolean type
152
* libsscm does not use C99 stdbool, its autoconf equivalent or popular
153
* combination of {int, TRUE, FALSE}, to avoid system-dependent ABI
154
* incompatibility (such as size difference) and client-dependent problems
155
* (such as an unexpected assumption about TRUE value).
157
* The definition use plain typedef and macro definition to avoid
158
* misrecognition about the usage of the type, such as enum-related ones.
162
* Do not test a value with (val == scm_true). The scm_true is only A TYPICAL
163
* VALUE FOR TRUE. Use (val) or (val != scm_false) instead.
166
typedef int scm_bool;
171
* Fixed bit width numbers
173
* This types define internal representation corresponding to each number
176
* The configuration alters both ABI and storage implementation of
177
* libsscm. Although it specifies the bit width, actual width varies for each
178
* underlying storage implementation. Refer SCM_INT_BITS, SCM_INT_MAX and so
179
* on to know such values.
181
* The integer type defaults to 64-bit on LP64 platforms.
183
#if SCM_USE_64BIT_FIXNUM
184
typedef int64_t scm_int_t;
185
typedef uint64_t scm_uint_t;
186
#define ALIGNOF_SCM_INT_T ALIGNOF_INT64_T
187
#define ALIGNOF_SCM_UINT_T ALIGNOF_INT64_T
188
#define SIZEOF_SCM_INT_T SIZEOF_INT64_T
189
#define SIZEOF_SCM_UINT_T SIZEOF_INT64_T
190
#define SCM_INT_T_MAX INT64_MAX
191
#define SCM_INT_T_MIN INT64_MIN
192
#define SCM_UINT_T_MAX UINT64_MAX
193
#elif SCM_USE_32BIT_FIXNUM
194
typedef int32_t scm_int_t;
195
typedef uint32_t scm_uint_t;
196
#define ALIGNOF_SCM_INT_T ALIGNOF_INT32_T
197
#define ALIGNOF_SCM_UINT_T ALIGNOF_INT32_T
198
#define SIZEOF_SCM_INT_T SIZEOF_INT32_T
199
#define SIZEOF_SCM_UINT_T SIZEOF_INT32_T
200
#define SCM_INT_T_MAX INT32_MAX
201
#define SCM_INT_T_MIN INT32_MIN
202
#define SCM_UINT_T_MAX UINT32_MAX
203
#elif SCM_USE_INT_FIXNUM
204
typedef int scm_int_t;
205
typedef unsigned int scm_uint_t;
206
#define ALIGNOF_SCM_INT_T ALIGNOF_INT
207
#define ALIGNOF_SCM_UINT_T ALIGNOF_INT
208
#define SIZEOF_SCM_INT_T SIZEOF_INT
209
#define SIZEOF_SCM_UINT_T SIZEOF_INT
210
#define SCM_INT_T_MAX INT_MAX
211
#define SCM_INT_T_MIN INT_MIN
212
#define SCM_UINT_T_MAX UINT_MAX
214
#undef SCM_USE_LONG_FIXNUM
215
#define SCM_USE_LONG_FIXNUM 1
216
typedef long scm_int_t;
217
typedef unsigned long scm_uint_t;
218
#define ALIGNOF_SCM_INT_T ALIGNOF_LONG
219
#define ALIGNOF_SCM_UINT_T ALIGNOF_LONG
220
#define SIZEOF_SCM_INT_T SIZEOF_LONG
221
#define SIZEOF_SCM_UINT_T SIZEOF_LONG
222
#define SCM_INT_T_MAX LONG_MAX
223
#define SCM_INT_T_MIN LONG_MIN
224
#define SCM_UINT_T_MAX ULONG_MAX
228
* Integer representation of abstract reference to ScmObj
230
* This types define sufficient width integer which is capable of holding any
231
* ScmRef that is used in currently selected storage implementation.
233
* A ScmRef is abstract reference to a ScmObj. It is usually a pointer, but do
234
* not assume it since another representation may be used. For instance, a pair
235
* of heap index and object index in the heap can be a ScmRef. In such case,
236
* scm_uintref_t can address any object in a heap scattered in full 64-bit
237
* address space even if the bit width of the reference is smaller than a
238
* 64-bit pointer. So any size assumption between pointer and the reference
241
* The integer representation is intended for low-level bitwise processing. Use
242
* ScmRef instead for higher-level code.
244
* Since actual representation is entirely controlled in each storage
245
* implementation, this configuration only specifies the ABI about maximum size
246
* of reference objects. Deal with particular storage implementation if fine
247
* tuning is required. Otherwise simply keep untouched.
249
* The type defaults to direct pointer represenation, so *LP64 gets 64-bit.
251
#if SCM_USE_64BIT_SCMREF
252
typedef int64_t scm_intref_t;
253
typedef uint64_t scm_uintref_t;
254
#define ALIGNOF_SCM_INTREF_T ALIGNOF_INT64_T
255
#define ALIGNOF_SCM_UINTREF_T ALIGNOF_INT64_T
256
#define SIZEOF_SCM_INTREF_T SIZEOF_INT64_T
257
#define SIZEOF_SCM_UINTREF_T SIZEOF_INT64_T
258
#elif SCM_USE_32BIT_SCMREF
259
typedef int32_t scm_intref_t;
260
typedef uint32_t scm_uintref_t;
261
#define ALIGNOF_SCM_INTREF_T ALIGNOF_INT32_T
262
#define ALIGNOF_SCM_UINTREF_T ALIGNOF_INT32_T
263
#define SIZEOF_SCM_INTREF_T SIZEOF_INT32_T
264
#define SIZEOF_SCM_UINTREF_T SIZEOF_INT32_T
266
#undef SCM_USE_INTPTR_SCMREF
267
#define SCM_USE_INTPTR_SCMREF 1
268
typedef intptr_t scm_intref_t;
269
typedef uintptr_t scm_uintref_t;
270
#define ALIGNOF_SCM_INTREF_T ALIGNOF_INTPTR_T
271
#define ALIGNOF_SCM_UINTREF_T ALIGNOF_INTPTR_T
272
#define SIZEOF_SCM_INTREF_T SIZEOF_INTPTR_T
273
#define SIZEOF_SCM_UINTREF_T SIZEOF_INTPTR_T
277
* Integer representation of ScmObj
279
* This types define sufficient width integer which is capable of holding the
280
* ScmObj that is used in currently selected storage implementation.
282
* A ScmObj is abstract Scheme object. Its represenation and size vary for each
283
* storage implementations. But the size is surely defined as larger one of
284
* scm_uint_t and scm_uintref_t. It can be assumed on coding.
286
* The integer representation is intended for low-level bitwise processing. Use
287
* ScmObj instead for higher-level code.
289
* This configuration is passively chosen in accordance with the fixnum size
290
* and reference size. And of course alters the ABI.
292
#if (SIZEOF_SCM_INT_T < SIZEOF_SCM_INTREF_T)
293
typedef scm_intref_t scm_intobj_t;
294
typedef scm_uintref_t scm_uintobj_t;
295
#define ALIGNOF_SCM_INTOBJ_T ALIGNOF_SCM_INTREF_T
296
#define ALIGNOF_SCM_UINTOBJ_T ALIGNOF_SCM_UINTREF_T
297
#define SIZEOF_SCM_INTOBJ_T SIZEOF_SCM_INTREF_T
298
#define SIZEOF_SCM_UINTOBJ_T SIZEOF_SCM_UINTREF_T
300
typedef scm_int_t scm_intobj_t;
301
typedef scm_uint_t scm_uintobj_t;
302
#define ALIGNOF_SCM_INTOBJ_T ALIGNOF_SCM_INT_T
303
#define ALIGNOF_SCM_UINTOBJ_T ALIGNOF_SCM_UINT_T
304
#define SIZEOF_SCM_INTOBJ_T SIZEOF_SCM_INT_T
305
#define SIZEOF_SCM_UINTOBJ_T SIZEOF_SCM_UINT_T
309
* Internal integer representation of Scheme character object
311
* The type is used to pass a Scheme-level character object in C codes.
313
* It is distinguished from the element of fixed-width character string
314
* (scm_wchar_t). This integer type is defined as wide as capable of any
315
* multibyte char, and not configurable, to keep ABI stable regardless of
316
* configuration about scm_wchar_t.
318
* Actual bit width varies for each storage implementation. Refer
319
* SCM_CHAR_BITS, SCM_CHAR_MAX and SCM_CHAR_MIN if needed.
321
typedef int32_t scm_ichar_t;
322
#define ALIGNOF_SCM_ICHAR_T ALIGNOF_INT32_T
323
#define SIZEOF_SCM_ICHAR_T SIZEOF_INT32_T
324
#define SCM_ICHAR_T_MAX INT32_MAX
325
#define SCM_ICHAR_T_MIN INT32_MIN
326
#define SCM_ICHAR_EOF (-1)
329
* Definitive byte type
331
* To avoid the sign-extension problem, platform-dependent signedness variation
332
* (for example, ARM compilers treat 'char' as 'unsigned char'), use this type
333
* for raw strings and so on.
335
typedef unsigned char scm_byte_t;
336
#define ALIGNOF_SCM_BYTE_T ALIGNOF_CHAR
337
#define SIZEOF_SCM_BYTE_T SIZEOF_CHAR
338
#define SCM_BYTE_T_MAX UCHAR_MAX
339
#define SCM_BYTE_T_MIN 0
342
* Constant-width character for strings (not used yet)
344
#if SCM_HAS_4OCT_WCHAR
345
typedef uint32_t scm_wchar_t;
346
#define ALIGNOF_SCM_WCHAR_T ALIGNOF_INT32_T
347
#define SIZEOF_SCM_WCHAR_T SIZEOF_INT32_T
348
#elif SCM_HAS_2OCT_WCHAR
349
typedef uint16_t scm_wchar_t;
350
#define ALIGNOF_SCM_WCHAR_T ALIGNOF_INT16_T
351
#define SIZEOF_SCM_WCHAR_T SIZEOF_INT16_T
353
typedef scm_byte_t scm_wchar_t;
354
#define ALIGNOF_SCM_WCHAR_T ALIGNOF_SCM_BYTE_T
355
#define SIZEOF_SCM_WCHAR_T SIZEOF_SCM_BYTE_T
358
/* size constraints */
359
#if !( SIZEOF_SCM_INT_T == SIZEOF_SCM_UINT_T \
360
&& SIZEOF_SCM_INTREF_T == SIZEOF_SCM_UINTREF_T \
361
&& SIZEOF_SCM_INTOBJ_T == SIZEOF_SCM_UINTOBJ_T \
362
&& SIZEOF_SCM_INTREF_T <= SIZEOF_SCM_INTOBJ_T \
363
&& SIZEOF_SCM_INT_T <= SIZEOF_SCM_INTOBJ_T \
364
&& ((SIZEOF_SCM_UINTREF_T <= SIZEOF_SCM_UINT_T \
365
&& SIZEOF_SCM_UINTOBJ_T == SIZEOF_SCM_UINT_T) \
366
|| (SIZEOF_SCM_UINTREF_T > SIZEOF_SCM_UINT_T \
367
&& SIZEOF_SCM_UINTOBJ_T == SIZEOF_SCM_UINTREF_T)) \
368
&& SIZEOF_SCM_WCHAR_T <= SIZEOF_SCM_ICHAR_T \
369
&& SIZEOF_SCM_ICHAR_T <= SIZEOF_SCM_INT_T)
370
#error "size constraints of primitive types are broken"
373
#define SCM_MAX(a, b) (((a) < (b)) ? (b) : (a))
374
#define SCM_MIN(a, b) (((a) > (b)) ? (b) : (a))
376
/*=======================================
377
Variable Declarations
378
=======================================*/
380
/*=======================================
381
Function Declarations
382
=======================================*/
388
#endif /* __SCM_SCMINT_H */