7 #include "cln/exception.h"
9 // Concatenation of macroexpanded tokens.
13 // CONCAT(x,y) ==> 'x16' (not 'xy' !)
14 #define CONCAT_(xxx,yyy) xxx##yyy
15 #define CONCAT3_(aaa,bbb,ccc) aaa##bbb##ccc
16 #define CONCAT4_(aaa,bbb,ccc,ddd) aaa##bbb##ccc##ddd
17 #define CONCAT5_(aaa,bbb,ccc,ddd,eee) aaa##bbb##ccc##ddd##eee
18 #define CONCAT6_(aaa,bbb,ccc,ddd,eee,fff) aaa##bbb##ccc##ddd##eee##fff
19 #define CONCAT7_(aaa,bbb,ccc,ddd,eee,fff,ggg) aaa##bbb##ccc##ddd##eee##fff##ggg
20 #define CONCAT(xxx,yyy) CONCAT_(xxx,yyy)
21 #define CONCAT3(aaa,bbb,ccc) CONCAT3_(aaa,bbb,ccc)
22 #define CONCAT4(aaa,bbb,ccc,ddd) CONCAT4_(aaa,bbb,ccc,ddd)
23 #define CONCAT5(aaa,bbb,ccc,ddd,eee) CONCAT5_(aaa,bbb,ccc,ddd,eee)
24 #define CONCAT6(aaa,bbb,ccc,ddd,eee,fff) CONCAT6_(aaa,bbb,ccc,ddd,eee,fff)
25 #define CONCAT7(aaa,bbb,ccc,ddd,eee,fff,ggg) CONCAT7_(aaa,bbb,ccc,ddd,eee,fff,ggg)
27 // Convert tokens to strings.
28 // STRING(token) ==> "token"
29 #define STRING(token) #token
30 #define STRINGIFY(token) STRING(token)
32 // Declare functions that don't return.
33 // nonreturning_function(extern,exit,(void)); == extern void exit (void);
35 #if (__GNUC__ >= 3) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 9))
36 #define nonreturning_function(storclass,funname,arguments) \
37 storclass void funname arguments __attribute__((__noreturn__))
39 #define nonreturning_function(storclass,funname,arguments) \
40 typedef void CONCAT3(funname,_function_,__LINE__) arguments; \
41 storclass __volatile__ CONCAT3(funname,_function_,__LINE__) funname
44 #define nonreturning_function(storclass,funname,arguments) \
45 storclass void funname arguments
48 // Declaration of variables.
51 // `if' with more than one clause:
52 // if (cond1) ... {elif (condi) ...} [else ...]
55 // Endless loop, leave with break; or return...;
56 #define loop while (1)
58 // Reversed end condition.
59 // Allows until (expression) statement
60 // and do statement until (expression);
61 #define until(expression) while(!(expression))
67 // Ignore a value (instead of assigning it to a variable).
69 #if defined(__GNUC__) || defined(__KCC) // avoid a gcc warning "statement with no effect"
75 // Denotes a point where control flow can never arrive.
77 #define NOTREACHED throw notreached_exception(__FILE__,__LINE__);
79 // Check an arithmetic expression.
81 #define ASSERT(expr) { if (!(expr)) { NOTREACHED } }
84 #if defined(__GNUC__) && !defined(__riscos) && !defined(__convex__)
86 #define alloca __builtin_alloca
87 #elif defined(_MSC_VER)
89 #define alloca _alloca
90 #elif defined(HAVE_ALLOCA_H) || defined(__riscos)
92 #ifndef alloca // Sometimes `alloca' is defined as a macro...
94 extern "C" char* alloca (int size);
96 extern "C" void* alloca (size_t size);
100 #pragma alloca // AIX requires this to be the first thing in the file.
101 #elif defined(WATCOM)
102 #include <malloc.h> // defines `alloca' as a macro
103 #elif !defined(NO_ALLOCA)
104 extern "C" void* alloca (size_t size);
111 // Bit number n (0<=n<32 or 0<=n<64)
112 #ifdef HAVE_FAST_LONGLONG
113 #define bit(n) (1LL<<(n))
115 #define bit(n) (1L<<(n))
117 // Bit number n (0<n<=32) mod 2^32
118 #ifdef HAVE_FAST_LONGLONG
119 #define bitm(n) (2LL<<((n)-1))
121 #define bitm(n) (2L<<((n)-1))
123 // Test bit n in x, n constant, x a cl_uint:
124 #if !(defined(__sparc__) || defined(__sparc64__))
125 #define bit_test(x,n) ((x) & bit(n))
127 // On Sparcs long constants are slower than shifts.
128 #if !defined(__GNUC__)
129 #define bit_test(x,n) \
130 ((n)<12 ? ((x) & bit(n)) : ((sint32)((uint32)(x) << (31-(n))) < 0))
131 #else // gcc optimizes boolean expressions better this way:
132 #define bit_test(x,n) \
133 ( ( ((n)<12) && ((x) & bit(n)) ) \
134 || ( ((n)>=12) && ((sint32)((uint32)(x) << (31-(n))) < 0) ) \
138 // minus bit number n (0<=n<32 or 0<=n<64)
139 #ifdef HAVE_FAST_LONGLONG
140 #define minus_bit(n) (-1LL<<(n))
142 #define minus_bit(n) (-1L<<(n))
144 // minus bit number n (0<n<=32) mod 2^32
145 #ifdef HAVE_FAST_LONGLONG
146 #define minus_bitm(n) (-2LL<<((n)-1))
148 #define minus_bitm(n) (-2L<<((n)-1))
151 // Return 2^n, n a constant expression.
152 // Same as bit(n), but undefined if n<0 or n>={long_}long_bitsize.
153 #if defined(HAVE_FAST_LONGLONG) || defined(intQsize)
154 #define bitc(n) (1ULL << (((n) >= 0 && (n) < long_long_bitsize) ? (n) : 0))
156 #define bitc(n) (1UL << (((n) >= 0 && (n) < long_bitsize) ? (n) : 0))
159 // floor(a,b) for a>=0, b>0 returns floor(a/b).
160 // b should be a constant expression.
161 #define floor(a_from_floor,b_from_floor) ((a_from_floor) / (b_from_floor))
162 // Save the macro in case we need to include <cmath>.
163 #define cln_floor(a_from_floor,b_from_floor) ((a_from_floor) / (b_from_floor))
165 // ceiling(a,b) for a>=0, b>0 returns ceiling(a/b) = floor((a+b-1)/b).
166 // b should be a constant expression.
167 #define ceiling(a_from_ceiling,b_from_ceiling) \
168 (((a_from_ceiling) + (b_from_ceiling) - 1) / (b_from_ceiling))
170 // round_down(a,b) decreases a>=0 such that it becomes divisible by b>0.
171 // b should be a constant expression.
172 #define round_down(a_from_round,b_from_round) \
173 (floor(a_from_round,b_from_round)*(b_from_round))
175 // round_up(a,b) increases a>=0 such that it becomes divisible by b>0.
176 // b should be a constant expression.
177 #define round_up(a_from_round,b_from_round) \
178 (ceiling(a_from_round,b_from_round)*(b_from_round))
180 // We never call malloc(0), so no need to handle it.
181 #define __MALLOC_0_RETURNS_NULL
183 // Loop which executes a statement a given number of times.
184 // dotimesC(countvar,count,statement);
185 // countvar must be of type `uintC'. It is modified!
186 #define dotimesC(countvar_from_dotimesC,count_from_dotimesC,statement_from_dotimesC) \
187 { countvar_from_dotimesC = (count_from_dotimesC); \
188 until (countvar_from_dotimesC==0) \
189 {statement_from_dotimesC; countvar_from_dotimesC--; } \
191 #define dotimespC(countvar_from_dotimespC,count_from_dotimespC,statement_from_dotimespC) \
192 { countvar_from_dotimespC = (count_from_dotimespC); \
193 do {statement_from_dotimespC} until (--countvar_from_dotimespC==0); \
196 // doconsttimes(count,statement);
197 // führt statement count mal aus (count mal der Code!),
198 // wobei count eine constant-expression >=0, <=8 ist.
199 #define doconsttimes(count_from_doconsttimes,statement_from_doconsttimes) \
200 { if (0 < (count_from_doconsttimes)) { statement_from_doconsttimes; } \
201 if (1 < (count_from_doconsttimes)) { statement_from_doconsttimes; } \
202 if (2 < (count_from_doconsttimes)) { statement_from_doconsttimes; } \
203 if (3 < (count_from_doconsttimes)) { statement_from_doconsttimes; } \
204 if (4 < (count_from_doconsttimes)) { statement_from_doconsttimes; } \
205 if (5 < (count_from_doconsttimes)) { statement_from_doconsttimes; } \
206 if (6 < (count_from_doconsttimes)) { statement_from_doconsttimes; } \
207 if (7 < (count_from_doconsttimes)) { statement_from_doconsttimes; } \
210 // DOCONSTTIMES(count,macroname);
211 // ruft count mal den Macro macroname auf (count mal der Code!),
212 // wobei count eine constant-expression >=0, <=8 ist.
213 // Dabei bekommt macroname der Reihe nach die Werte 0,...,count-1 übergeben.
214 #define DOCONSTTIMES(count_from_DOCONSTTIMES,macroname_from_DOCONSTTIMES) \
215 { if (0 < (count_from_DOCONSTTIMES)) { macroname_from_DOCONSTTIMES((0 < (count_from_DOCONSTTIMES) ? 0 : 0)); } \
216 if (1 < (count_from_DOCONSTTIMES)) { macroname_from_DOCONSTTIMES((1 < (count_from_DOCONSTTIMES) ? 1 : 0)); } \
217 if (2 < (count_from_DOCONSTTIMES)) { macroname_from_DOCONSTTIMES((2 < (count_from_DOCONSTTIMES) ? 2 : 0)); } \
218 if (3 < (count_from_DOCONSTTIMES)) { macroname_from_DOCONSTTIMES((3 < (count_from_DOCONSTTIMES) ? 3 : 0)); } \
219 if (4 < (count_from_DOCONSTTIMES)) { macroname_from_DOCONSTTIMES((4 < (count_from_DOCONSTTIMES) ? 4 : 0)); } \
220 if (5 < (count_from_DOCONSTTIMES)) { macroname_from_DOCONSTTIMES((5 < (count_from_DOCONSTTIMES) ? 5 : 0)); } \
221 if (6 < (count_from_DOCONSTTIMES)) { macroname_from_DOCONSTTIMES((6 < (count_from_DOCONSTTIMES) ? 6 : 0)); } \
222 if (7 < (count_from_DOCONSTTIMES)) { macroname_from_DOCONSTTIMES((7 < (count_from_DOCONSTTIMES) ? 7 : 0)); } \
225 // AT_INITIALIZATION(id) { ... }
226 // executes the given code at initialization time of the file.
227 // The id is something unique.
228 #define AT_INITIALIZATION(id) \
229 class CONCAT3(INIT_CLASS_,id,__LINE__) { \
230 public: CONCAT3(INIT_CLASS_,id,__LINE__) (void); \
231 } CONCAT4(INIT_CLASS_,id,__LINE__,_DUMMY); \
232 inline CONCAT3(INIT_CLASS_,id,__LINE__)::CONCAT3(INIT_CLASS_,id,__LINE__) (void)
234 // AT_DESTRUCTION(id) { ... }
235 // executes the given code at destruction time of the file.
236 // The id is something unique.
237 #define AT_DESTRUCTION(id) \
238 class CONCAT3(DESTR_CLASS_,id,__LINE__) { \
239 public: ~CONCAT3(DESTR_CLASS_,id,__LINE__) (void); \
240 } CONCAT4(DESTR_CLASS_,id,__LINE__,_DUMMY); \
241 CONCAT3(DESTR_CLASS_,id,__LINE__)::~CONCAT3(DESTR_CLASS_,id,__LINE__) (void)
243 // Inside a class definition:
244 // Overload `new' so that a class object can be allocated anywhere.
245 #if !((defined(__rs6000__) || defined(__alpha__)) && !defined(__GNUC__))
246 #define ALLOCATE_ANYWHERE(classname) \
247 /* Ability to place an object at a given address. */ \
249 void* operator new (size_t size) { return malloc_hook(size); } \
250 void* operator new (size_t size, classname* ptr) { unused size; return ptr; } \
251 void operator delete (void* ptr) { free_hook(ptr); }
253 // For some compilers, work around template problem with "classname".
254 #define ALLOCATE_ANYWHERE(classname) \
255 /* Ability to place an object at a given address. */ \
257 void* operator new (size_t size) { return malloc_hook(size); } \
258 void* operator new (size_t size, void* ptr) { unused size; return ptr; } \
259 void operator delete (void* ptr) { free_hook(ptr); }
262 // init1(type, object) (value);
263 // initializes `object' with `value', by calling `type''s constructor.
264 // (The identifiers `init' and `Init' are already in use by <streambuf.h>,
266 #define init1(type,lvalue) (void) new (&(lvalue)) type
268 #include "base/cl_maybe_inline.h"
270 #endif /* _CL_MACROS_H */