00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef CUOO_META_H
00019 #define CUOO_META_H
00020
00021 #include <cuoo/fwd.h>
00022
00023 CU_BEGIN_DECLARATIONS
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #define CUEX_PRIoMETA PRIoPTR
00052 #define CUEX_PRIuMETA PRIuPTR
00053 #define CUEX_PRIxMETA PRIxPTR
00054 #define CUEX_PRIXMETA PRIXPTR
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 #define CUEX_META_MASK(shift, width) \
00065 (((CUEX_META_C(1) << (width)) - CUEX_META_C(1)) << (shift))
00066
00067 #define CUEX_METAKIND_WIDTH 2
00068 #define CUEX_METAKIND_MASK 3
00069
00070 #define CUEX_OPR_FLAGS_WIDTH 4
00071 #define CUEX_OPR_ARITY_WIDTH 6
00072 #define CUEX_OPR_SELECT_WIDTH 20
00073
00074 #define CUEX_OPR_FLAGS_SHIFT CUEX_METAKIND_WIDTH
00075 #define CUEX_OPR_ARITY_SHIFT (CUEX_OPR_FLAGS_SHIFT + CUEX_OPR_FLAGS_WIDTH)
00076 #define CUEX_OPR_SELECT_SHIFT (CUEX_OPR_ARITY_SHIFT + CUEX_OPR_ARITY_WIDTH)
00077
00078 #define CUEX_META_WIDTH (CUEX_OPR_SELECT_SHIFT + CUEX_OPR_SELECT_WIDTH)
00079 #if CUEX_META_WIDTH != 32
00080 # error CUEX_OPR_META_WIDTH does not add up to 32 bits
00081 #endif
00082
00083 #define CUEX_OPR_FLAGS_MASK \
00084 CUEX_META_MASK(CUEX_OPR_FLAGS_SHIFT, CUEX_OPR_FLAGS_WIDTH)
00085 #define CUEX_OPR_ARITY_MASK \
00086 CUEX_META_MASK(CUEX_OPR_ARITY_SHIFT, CUEX_OPR_ARITY_WIDTH)
00087 #define CUEX_OPR_SELECT_MASK \
00088 CUEX_META_MASK(CUEX_OPR_SELECT_SHIFT, CUEX_OPR_SELECT_WIDTH)
00089
00090 #define CUEX_OPRFLAG_CTOR (CUEX_META_C(1) << CUEX_OPR_FLAGS_SHIFT)
00091 #define CUEX_OPRFLAG_AUX (CUEX_META_C(2) << CUEX_OPR_FLAGS_SHIFT)
00092
00093 typedef enum {
00094 cuex_meta_kind_type = 0,
00095 cuex_meta_kind_opr = 1,
00096 cuex_meta_kind_other = 2,
00097 cuex_meta_kind_ignore = 3,
00098 } cuex_meta_kind_t;
00099
00100 #define cuex_meta_kind(meta) ((cuex_meta_kind_t)((meta) & 3))
00101
00102
00103 #define CUEXP_VARMETA_SELECT_WIDTH 3
00104 #define CUEXP_VARMETA_SELECT_MASK CUEX_META_C(7)
00105 #define CUEXP_VARMETA_SELECT_VALUE CUEX_META_C(6)
00106 #define CUEXP_VARMETA_WSIZE_SHIFT CUEXP_VARMETA_SELECT_WIDTH
00107 #define CUEXP_VARMETA_WSIZE_WIDTH 2
00108 #define CUEXP_VARMETA_WSIZE_MASK \
00109 CUEX_META_MASK(CUEXP_VARMETA_WSIZE_SHIFT, CUEXP_VARMETA_WSIZE_WIDTH)
00110 #define cuexP_varmeta_wsize(meta) \
00111 ((meta & CUEXP_VARMETA_WSIZE_MASK) >> CUEXP_VARMETA_WSIZE_SHIFT)
00112
00113
00114
00115
00116
00117 CU_SINLINE cuoo_type_t
00118 cuoo_type_from_meta(cuex_meta_t meta)
00119 { return (cuoo_type_t)meta; }
00120
00121
00122 CU_SINLINE cuex_meta_t
00123 cuoo_type_to_meta(cuex_t type)
00124 { return (cuex_meta_t)type; }
00125
00126
00127 CU_SINLINE cu_bool_t
00128 cuex_meta_is_opr(cuex_meta_t meta)
00129 { return cuex_meta_kind(meta) == cuex_meta_kind_opr; }
00130
00131
00132 CU_SINLINE cu_rank_t
00133 cuex_opr_r(cuex_meta_t opr)
00134 { return ((opr) & CUEX_OPR_ARITY_MASK) >> CUEX_OPR_ARITY_SHIFT; }
00135
00136
00137 CU_SINLINE cu_bool_t
00138 cuex_meta_is_opr_r(cu_rank_t r, cuex_meta_t meta)
00139 { return cuex_meta_is_opr(meta) && cuex_opr_r(meta) == r; }
00140
00141
00142
00143
00144 CU_SINLINE cu_bool_t
00145 cuex_meta_has_aux(cuex_meta_t meta)
00146 { return !!(meta & CUEX_OPRFLAG_AUX); }
00147
00148 #if CUCONF_SIZEOF_VOID_P == 4 || defined(CU_IN_DOXYGEN)
00149
00150
00151
00152
00153 CU_SINLINE cuex_opr_t
00154 cuex_meta_opr(cuex_meta_t meta)
00155 { return meta & ~CUEX_OPR_FLAGS_MASK; }
00156
00157
00158
00159
00160
00161 CU_SINLINE uint32_t
00162 cuex_meta_aux(cuex_meta_t meta, cuex_t e)
00163 { return *((uint32_t *)(e) + cuex_opr_r(meta)); }
00164
00165 #elif CUCONF_SIZEOF_VOID_P == 8
00166
00167 CU_SINLINE cuex_opr_t
00168 cuex_meta_opr(cuex_meta_t meta)
00169 { return meta & (0xffffffffu & ~CUEX_OPR_FLAGS_MASK); }
00170
00171 CU_SINLINE uint32_t
00172 cuex_meta_aux(cuex_meta_t meta, cuex_t e)
00173 { return meta >> 32; }
00174
00175 #else
00176 # error "Missing case."
00177 #endif
00178
00179
00180 CU_SINLINE cuex_meta_t
00181 cuex_meta(void *obj)
00182 { return *((cuex_meta_t *)obj - 1) - 1; }
00183
00184
00185 CU_END_DECLARATIONS
00186
00187 #endif