00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef CU_BOX_H
00019 #define CU_BOX_H
00020
00021 #include <cu/fwd.h>
00022 #include <cu/conf.h>
00023
00024 #define CU_BOX_IS_UNION 1
00025
00026 CU_BEGIN_DECLARATIONS
00027
00028
00029
00030 #define CU_BOX_SIZE CU_WORD_SIZE
00031
00032 #if CUCONF_SIZEOF_FLOAT <= CU_BOX_SIZE
00033 # define CU_BOX_FITS_FLOAT 1
00034 #endif
00035
00036 #if CUCONF_SIZEOF_DOUBLE <= CU_BOX_SIZE
00037 # define CU_BOX_FITS_DOUBLE 1
00038 #endif
00039
00040 #if CUCONF_SIZEOF_LONGDOUBLE <= CU_BOX_SIZE
00041 # define CU_BOX_FITS_LONGDOUBLE
00042 #endif
00043
00044 #if defined(CU_BOX_IS_UNION) || defined(CU_IN_DOXYGEN)
00045
00046
00047
00048 typedef union {
00049 void *as_ptr;
00050 void (*as_fptr)(void);
00051 cu_word_t as_word;
00052 #ifdef CU_BOX_FITS_FLOAT
00053 float as_float;
00054 #endif
00055 #ifdef CU_BOX_FITS_DOUBLE
00056 double as_double;
00057 #endif
00058 #ifdef CU_BOX_FITS_LONGDOUBLE
00059 long double as_longdouble;
00060 #endif
00061 } cu_box_t;
00062
00063 # ifndef CU_IN_DOXYGEN
00064 CU_SINLINE cu_box_t
00065 cuP_box_ptr(void const *p)
00066 {
00067 cu_box_t box;
00068 box.as_ptr = (void *)p;
00069 return box;
00070 }
00071 CU_SINLINE cu_box_t
00072 cuP_box_fptr(cu_fnptr_t f)
00073 {
00074 cu_box_t box;
00075 box.as_fptr = f;
00076 return box;
00077 }
00078 CU_SINLINE cu_box_t
00079 cuP_box_word(cu_word_t w)
00080 {
00081 cu_box_t box;
00082 box.as_word = w;
00083 return box;
00084 }
00085 # define cuP_unbox_ptr(box) ((box).as_ptr)
00086 # define cuP_unbox_fptr(box) ((box).as_fptr)
00087 # define cuP_unbox_word(box) ((box).as_word)
00088 # define CUP_BOX_PTR_INIT(ptr) { .as_ptr = (ptr) }
00089 # define CUP_BOX_FPTR_INIT(fptr) { .as_fptr = (fptr) }
00090 # define CUP_BOX_WORD_INIT(word) { .as_word = (word) }
00091 # endif
00092
00093
00094
00095 #define CU_BOX_GNEW_TEMPLATE(fn, type) \
00096 cu_box_t fn(type x) \
00097 { \
00098 cu_box_t box; \
00099 box.as_ptr = cu_gnew(type); \
00100 *(type *)box.as_ptr = x; \
00101 return box; \
00102 } \
00103 CU_END_BOILERPLATE
00104
00105 #else
00106
00107 typedef cu_word_t cu_box_t;
00108 # define cuP_box_ptr(val) ((cu_box_t)(val))
00109 # define cuP_box_fptr(val) ((cu_box_t)(val))
00110 # define cuP_box_word(val) ((cu_box_t)(val))
00111 # define cuP_unbox_ptr(box) (box)
00112 # define cuP_unbox_fptr(box) (box)
00113 # define cuP_unbox_word(box) (box)
00114 # define CUP_BOX_PTR_INIT(ptr) cuP_box_ptr(ptr)
00115 # define CUP_BOX_FPTR_INIT(fptr) cuP_box_fptr(fptr)
00116 # define CUP_BOX_WORD_INIT(word) cuP_box_word(word)
00117
00118 #define CU_BOX_GNEW_TEMPLATE(fn, type) \
00119 cu_box_t fn(type x) \
00120 { \
00121 void *p = cu_gnew(type); \
00122 *(type *)p = x; \
00123 return (cu_box_t)p; \
00124 } \
00125 CU_END_BOILERPLATE
00126
00127 #endif
00128
00129 cu_box_t cu_box_galloc(size_t size, void *addr);
00130 #define cu_box_gnew(type, obj) cu_box_galloc(sizeof(type), &(obj))
00131
00132 #define cu_box_void() cuP_box_word(0)
00133 #define CU_BOX_VOID_INIT CUP_BOX_WORD_INIT(0)
00134
00135
00136
00137
00138
00139 #define cu_box_ptr(type, ptr) cuP_box_ptr(1? (ptr) : (type)(ptr))
00140
00141 #define cu_unbox_ptr(type, box) ((type)cuP_unbox_ptr(box))
00142
00143 #define CU_BOX_PTR_INIT(type, ptr) CUP_BOX_PTR_INIT(1? (ptr) : (type)(ptr))
00144
00145 #define CU_BOX_NULL_PTR_INIT CUP_BOX_PTR_INIT(NULL)
00146
00147
00148 #define cu_box_fptr(type, fp) cuP_box_fptr((cu_fnptr_t)(1? (fp) : (type)(fp)))
00149
00150 #define cu_unbox_fptr(type, box) ((type)cuP_unbox_fptr(box))
00151
00152 #define CU_BOX_FPTR_INIT(type, fptr) CUP_BOX_FPTR_INIT(1? (fptr) : (type)(fptr))
00153
00154 #define CU_BOX_NULL_FPTR_INIT CUP_BOX_FPTR_INIT(NULL)
00155
00156
00157 #define cu_box_clop(type, cp) cu_box_ptr(type, cp)
00158
00159 #define cu_unbox_clop(type, box) cu_unbox_ptr(type, box)
00160
00161
00162 #define cu_box_enum(type, i) cuP_box_word(1? (i) : (type)(i))
00163
00164 #define cu_unbox_enum(type, box) ((type)cuP_unbox_word(box))
00165
00166 #define CU_BOX_ENUM_INIT(type, i) CUP_BOX_WORD_INIT(1? (i) : (type)(i))
00167
00168
00169
00170
00171
00172
00173 CU_SINLINE cu_box_t cu_box_int(int i)
00174 { return cuP_box_word(i); }
00175
00176
00177 CU_SINLINE int cu_unbox_int(cu_box_t box)
00178 { return cuP_unbox_word(box); }
00179
00180
00181 CU_SINLINE cu_box_t cu_box_uint(unsigned int i)
00182 { return cuP_box_word(i); }
00183
00184
00185 CU_SINLINE unsigned int cu_unbox_uint(cu_box_t box)
00186 { return cuP_unbox_word(box); }
00187
00188
00189 CU_SINLINE cu_box_t cu_box_long(long i)
00190 { return cuP_box_word(i); }
00191
00192
00193 CU_SINLINE long cu_unbox_long(cu_box_t box)
00194 { return cuP_unbox_word(box); }
00195
00196
00197 CU_SINLINE cu_box_t cu_box_ulong(unsigned long i)
00198 { return cuP_box_word(i); }
00199
00200
00201 CU_SINLINE unsigned long cu_unbox_ulong(cu_box_t box)
00202 { return cuP_unbox_word(box); }
00203
00204
00205
00206
00207
00208 #if defined(CU_BOX_FITS_FLOAT) || defined(CU_IN_DOXYGEN)
00209 # if defined(CU_BOX_IS_UNION) || defined(CU_IN_DOXYGEN)
00210
00211
00212 CU_SINLINE cu_box_t cu_box_float(float x)
00213 { cu_box_t box; box.as_float = x; return box; }
00214
00215
00216 CU_SINLINE float cu_unbox_float(cu_box_t box)
00217 { return box.as_float; }
00218
00219 # else
00220
00221 CU_SINLINE cu_box_t cu_box_float(float x)
00222 { union { cu_box_t box; float x; } u; u.x = x; return u.box; }
00223
00224 CU_SINLINE float cu_unbox_float(cu_box_t box)
00225 { union { cu_box_t box; float x; } u; u.box = box; return u.x; }
00226
00227 # endif
00228
00229 #else
00230 cu_box_t cu_box_float(float x);
00231 CU_SINLINE float cu_unbox_float(cu_box_t box)
00232 { return *cu_unbox_ptr(float *, box); }
00233 #endif
00234
00235
00236 #if defined(CU_BOX_FITS_DOUBLE) || defined(CU_IN_DOXIGEN)
00237 # if defined(CU_BOX_IS_UNION) || defined(CU_IN_DOXYGEN)
00238
00239
00240 CU_SINLINE cu_box_t cu_box_double(double x)
00241 { cu_box_t box; box.as_double = x; return box; }
00242
00243
00244 CU_SINLINE double cu_unbox_double(cu_box_t box)
00245 { return box.as_double; }
00246
00247 # else
00248
00249 CU_SINLINE cu_box_t cu_box_double(double x)
00250 { union { cu_box_t box; double x; } u; u.x = x; return u.box; }
00251
00252 CU_SINLINE double cu_unbox_double(cu_box_t box)
00253 { union { cu_box_t box; double x; } u; u.box = box; return u.x; }
00254
00255 # endif
00256
00257 #else
00258 cu_box_t cu_box_double(double x);
00259 CU_SINLINE double cu_unbox_double(cu_box_t box)
00260 { return *cu_unbox_ptr(double *, box); }
00261 #endif
00262
00263
00264 #if defined(CU_BOX_FITS_LONGDOUBLE) || defined(CU_IN_DOXYGEN)
00265 # if defined(CU_BOX_IS_UNION) || defined(CU_IN_DOXYGEN)
00266
00267
00268 CU_SINLINE cu_box_t cu_box_longdouble(long double x)
00269 { cu_box_t box; box.as_longdouble = x; return box; }
00270
00271
00272 CU_SINLINE long double cu_unbox_longdouble(cu_box_t box)
00273 { return box.as_longdouble; }
00274
00275 # else
00276
00277 CU_SINLINE cu_box_t cu_box_longdouble(long double x)
00278 { union { cu_box_t box; long double x; } u; u.x = x; return u.box; }
00279
00280 CU_SINLINE long double cu_unbox_longdouble(cu_box_t box)
00281 { union { cu_box_t box; long double x; } u; u.box = box; return u.x; }
00282
00283 # endif
00284
00285 #else
00286 cu_box_t cu_box_longdouble(long double x);
00287 CU_SINLINE long double cu_unbox_longdouble(cu_box_t box)
00288 { return *cu_unbox_ptr(long double *, box); }
00289 #endif
00290
00291
00292
00293 CU_END_DECLARATIONS
00294
00295 #endif