00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef CU_CLOS_H
00019 #define CU_CLOS_H
00020
00021 #include <cu/fwd.h>
00022 #include <cu/util.h>
00023
00024 #ifndef CU_IN_DOXYGEN
00025 #define CU_CLOS_CONTEXT_FIRST 1
00026
00027 CU_BEGIN_DECLARATIONS
00028
00029 #define cuPP_splice(...) __VA_ARGS__
00030 #define cuPP_argl_append(argl, arg) (cuPP_splice argl, arg)
00031 #define cuPP_argl_prepend(argl, arg) (arg, cuPP_splice argl)
00032 #define cuPP_argl0_append(argl, arg) (arg)
00033 #define cuPP_argl0_prepend(argl, arg) (arg)
00034
00035 typedef struct cu_clos_self_s *cu_clos_self_t;
00036
00037 #if CU_CLOS_CONTEXT_FIRST
00038 # define cuP_jargl(alops, argl, self) alops##prepend(argl, self)
00039 #else
00040 # define cuP_jargl(alops, argl, self) alops##append(argl, self)
00041 #endif
00042
00043 #define cuP_clos_formal(alops, argl) \
00044 cuP_jargl(alops, argl, cu_clos_self_t cuL_self)
00045 #define cuP_xargl(...) \
00046 cuP_jargl(cuPP_argl_, __VA_ARGS__, cu_clos_self_t cuL_self)
00047 #define cuP_xargl0() cu_clos_self_t cuL_self
00048
00049
00050
00051 #define cu_clop(val, res_t, ...) \
00052 res_t (**val)cuP_jargl(cuPP_argl_, (__VA_ARGS__), cu_clos_self_t)
00053 #define cu_clop0(val, res_t) \
00054 res_t (**val)(cu_clos_self_t)
00055 typedef void (**cu_clop_generic_t)();
00056
00057 #define cu_clop_null (NULL)
00058 #define cu_clop_is_null(clop) ((clop) == NULL)
00059
00060 #define cu_call(clop, ...) \
00061 ((**(clop))cuP_jargl(cuPP_argl_, (__VA_ARGS__), (cu_clos_self_t)(clop)))
00062 #define cu_call0(clop) \
00063 ((**(clop))cuP_jargl(cuPP_argl0_, (), ((cu_clos_self_t)(clop))))
00064
00065 #define cuP_clop_def(name, linkage, res_t, alops, xparl) \
00066 linkage res_t name##_fn cuP_clos_formal(alops, xparl); \
00067 linkage res_t (*name##_data) cuP_clos_formal(alops, xparl) = &name##_fn; \
00068 linkage res_t (**name) cuP_clos_formal(alops, xparl) \
00069 CU_ATTR_UNUSED = &name##_data; \
00070 linkage res_t name##_fn cuP_clos_formal(alops, xparl)
00071 #define cu_clop_ref(name) (&name##_data)
00072
00073 #define cu_clop_def(name, res_t, ...) \
00074 cuP_clop_def(name, static, res_t, cuPP_argl_, (__VA_ARGS__))
00075 #define cu_clop_def0(name, res_t) \
00076 cuP_clop_def(name, static, res_t, cuPP_argl0_, ())
00077 #define cu_clop_edef(name, res_t, ...) \
00078 cuP_clop_def(name, , res_t, cuPP_argl_, (__VA_ARGS__))
00079 #define cu_clop_edef0(name, res_t) \
00080 cuP_clop_def(name, , res_t, cuPP_argl0_, ())
00081
00082 #define cu_clop_call_fn(clop, ...) clop##_fn(__VA_ARGS__, NULL)
00083 #define cu_clop_call_fn0(clop) clop##_fn(NULL)
00084
00085
00086
00087 #define cuP_clos_dec(name, linkage, cargs, res_t, alops, parl) \
00088 typedef struct name##_s name##_t; \
00089 struct name##_s { \
00090 res_t (*cuL_fn) cuP_clos_formal(alops, parl); \
00091 cuPP_splice cargs \
00092 }; \
00093 \
00094 typedef res_t (**name##_clop_t) cuP_clos_formal(alops, parl); \
00095 \
00096 linkage res_t name##_fn cuP_jargl(alops, parl, name##_t *); \
00097 \
00098 CU_SINLINE void name##_init(name##_t *self) \
00099 { self->cuL_fn = (res_t (*)cuP_clos_formal(alops, parl))name##_fn;} \
00100 \
00101 CU_SINLINE name##_clop_t name##_prep(name##_t *self) \
00102 { name##_init(self); return &self->cuL_fn; } \
00103 \
00104 CU_SINLINE name##_clop_t name##_ref(name##_t *self) \
00105 { return &self->cuL_fn; }
00106
00107 #define cuP_clos_fun(name, linkage, res_t, alops, parl) \
00108 res_t name##_fn cuP_jargl(alops, parl, name##_t *cuL_self)
00109
00110 #define cu_clos_dec(name, prot, cargs) \
00111 cuP_clos_dec(name, static, cargs, prot) \
00112 CU_END_BOILERPLATE
00113
00114 #define cu_clos_edec(name, prot, cargs) \
00115 cuP_clos_dec(name, extern, cargs, prot) \
00116 CU_END_BOILERPLATE
00117
00118 #define cu_clos_fun(name, prot) cuP_clos_fun(name, static, prot)
00119 #define cu_clos_efun(name, prot) cuP_clos_fun(name, extern, prot)
00120
00121 #define cu_clos_def(name, prot, cargs) \
00122 cuP_clos_dec(name, static, cargs, prot) \
00123 cuP_clos_fun(name, static, prot)
00124
00125 #define cu_prot(res_t, ...) res_t, cuPP_argl_, (__VA_ARGS__)
00126 #define cu_prot0(res_t) res_t, cuPP_argl0_, ()
00127
00128 #define cu_clos_self(name) name##_t *self = cuL_self
00129
00130
00131
00132 #define cu_clof_fun(fn, res_t, ...) \
00133 static res_t fn cuP_jargl(cuPP_argl_,(__VA_ARGS__),cu_clos_self_t cuL_self)
00134 #define cu_clof_fun0(fn, res_t) \
00135 static res_t fn cuP_jargl(cuPP_argl0_, (), cu_clos_self_t cuL_self)
00136 #define cu_clof_decl(f, res_t, ...) \
00137 res_t (*f)cuP_jargl(cuPP_argl_, (__VA_ARGS__), cu_clos_self_t)
00138 #define cu_clof_decl0(f, res_t) \
00139 res_t (*f)cuP_jargl(cuPP_argl0_, (), cu_clos_self_t)
00140 #define cu_clof_self(name, field) \
00141 struct name *self = cu_ptr_context(struct name, field, cuL_self)
00142 #define cu_clof_init(obj, field, fn) ((obj)->field = (fn))
00143 #define cu_clof_ref(obj, field) &(obj)->field
00144
00145 CU_END_DECLARATIONS
00146
00147 #endif
00148
00149 #endif