]> www.ginac.de Git - cln.git/blob - src/base/cl_macros.h
* Removed internal gmp/ directory and other traces of it like $GMP_INCLUDES.
[cln.git] / src / base / cl_macros.h
1 // CLN internal macros
2
3 #ifndef _CL_MACROS_H
4 #define _CL_MACROS_H
5
6 // Concatenation of macroexpanded tokens.
7 // Example:
8 //   #undef x
9 //   #define y 16
10 //   CONCAT(x,y)        ==>  'x16' (not 'xy' !)
11   #define CONCAT_(xxx,yyy)  xxx##yyy
12   #define CONCAT3_(aaa,bbb,ccc)  aaa##bbb##ccc
13   #define CONCAT4_(aaa,bbb,ccc,ddd)  aaa##bbb##ccc##ddd
14   #define CONCAT5_(aaa,bbb,ccc,ddd,eee)  aaa##bbb##ccc##ddd##eee
15   #define CONCAT6_(aaa,bbb,ccc,ddd,eee,fff)  aaa##bbb##ccc##ddd##eee##fff
16   #define CONCAT7_(aaa,bbb,ccc,ddd,eee,fff,ggg)  aaa##bbb##ccc##ddd##eee##fff##ggg
17   #define CONCAT(xxx,yyy)  CONCAT_(xxx,yyy)
18   #define CONCAT3(aaa,bbb,ccc)  CONCAT3_(aaa,bbb,ccc)
19   #define CONCAT4(aaa,bbb,ccc,ddd)  CONCAT4_(aaa,bbb,ccc,ddd)
20   #define CONCAT5(aaa,bbb,ccc,ddd,eee)  CONCAT5_(aaa,bbb,ccc,ddd,eee)
21   #define CONCAT6(aaa,bbb,ccc,ddd,eee,fff)  CONCAT6_(aaa,bbb,ccc,ddd,eee,fff)
22   #define CONCAT7(aaa,bbb,ccc,ddd,eee,fff,ggg)  CONCAT7_(aaa,bbb,ccc,ddd,eee,fff,ggg)
23
24 // Convert tokens to strings.
25 // STRING(token)  ==>  "token"
26   #define STRING(token) #token
27   #define STRINGIFY(token) STRING(token)
28
29 // Declare functions that don't return.
30 // nonreturning_function(extern,exit,(void)); == extern void exit (void);
31   #ifdef __GNUC__
32     #if (__GNUC__ >= 3) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 90))
33       #define nonreturning_function(storclass,funname,arguments)  \
34         storclass void funname arguments __attribute__((__noreturn__))
35     #else
36       #define nonreturning_function(storclass,funname,arguments)  \
37         typedef void CONCAT3(funname,_function_,__LINE__) arguments; \
38         storclass __volatile__ CONCAT3(funname,_function_,__LINE__) funname
39     #endif
40   #else
41     #define nonreturning_function(storclass,funname,arguments)  \
42       storclass void funname arguments
43   #endif
44
45 // Declaration of variables.
46   #define var
47
48 // `if' with more than one clause:
49 // if (cond1) ... {elif (condi) ...} [else ...]
50   #define elif  else if
51
52 // Endless loop, leave with  break;  or return...;
53   #define loop  while (1)
54
55 // Reversed end condition.
56 // Allows   until (expression) statement
57 // and      do statement until (expression);
58   #define until(expression)  while(!(expression))
59
60 // Boolean values.
61   #define FALSE  0
62   #define TRUE   1
63
64 // Ignore a value (instead of assigning it to a variable).
65 // unused ...
66   #if defined(__GNUC__) || defined(__KCC) // avoid a gcc warning "statement with no effect"
67     #define unused  (void)
68   #else
69     #define unused
70   #endif
71
72 // Denotes a point where control flow can never arrive.
73 // NOTREACHED
74   #define NOTREACHED  cl_notreached_abort(__FILE__,__LINE__);
75   nonreturning_function(extern,cl_notreached_abort, (const char* filename, int lineno));
76
77 // Check an arithmetic expression.
78 // ASSERT(expr)
79   #define ASSERT(expr)  { if (!(expr)) { NOTREACHED } }
80
81 // alloca()
82   #if defined(__GNUC__) && !defined(__riscos) && !defined(__convex__)
83     #undef alloca
84     #define alloca  __builtin_alloca
85   #elif defined(_MSC_VER)
86     #include <malloc.h>
87     #define alloca  _alloca
88   #elif defined(HAVE_ALLOCA_H) || defined(__riscos)
89     #include <alloca.h>
90     #ifndef alloca // Sometimes `alloca' is defined as a macro...
91       #if defined(__osf__)
92         extern "C" char* alloca (int size);
93       #else
94         extern "C" void* alloca (int size);
95       #endif
96     #endif
97   #elif defined(_AIX)
98     #pragma alloca // AIX requires this to be the first thing in the file.
99   #elif defined(WATCOM)
100     #include <malloc.h> // defines `alloca' as a macro
101   #elif !defined(NO_ALLOCA)
102     extern "C" void* alloca (int size);
103   #endif
104
105 // NULL pointer.
106   #undef NULL
107   #define NULL  0
108
109 // Bit number n (0<=n<32)
110   #define bit(n)  (1L<<(n))
111 // Bit number n (0<n<=32) mod 2^32
112   #define bitm(n)  (2L<<((n)-1))
113 // Test bit n in x, n constant, x a cl_uint:
114   #if !(defined(__sparc__) || defined(__sparc64__))
115     #define bit_test(x,n)  ((x) & bit(n))
116   #else
117     // On Sparcs long constants are slower than shifts.
118     #if !defined(__GNUC__)
119       #define bit_test(x,n)  \
120         ((n)<12 ? ((x) & bit(n)) : ((sint32)((uint32)(x) << (31-(n))) < 0))
121     #else // gcc optimizes boolean expressions better this way:
122       #define bit_test(x,n)  \
123         (   ( ((n)<12) && ((x) & bit(n)) )                           \
124          || ( ((n)>=12) && ((sint32)((uint32)(x) << (31-(n))) < 0) ) \
125         )
126     #endif
127   #endif
128 // minus bit number n (0<=n<32)
129   #define minus_bit(n)  (-1L<<(n))
130 // minus bit number n (0<n<=32) mod 2^32
131   #define minus_bitm(n)  (-2L<<((n)-1))
132
133 // Return 2^n, n a constant expression.
134 // Same as bit(n), but undefined if n<0 or n>=long_bitsize.
135   #define bitc(n)  (1UL << (((n) >= 0 && (n) < long_bitsize) ? (n) : 0))
136
137 // floor(a,b) for a>=0, b>0 returns floor(a/b).
138 // b should be a constant expression.
139   #define floor(a_from_floor,b_from_floor)  ((a_from_floor) / (b_from_floor))
140 // Save the macro in case we need to include <math.h>.
141   #define cln_floor(a_from_floor,b_from_floor)  ((a_from_floor) / (b_from_floor))
142
143 // ceiling(a,b) for a>=0, b>0 returns ceiling(a/b) = floor((a+b-1)/b).
144 // b should be a constant expression.
145   #define ceiling(a_from_ceiling,b_from_ceiling)  \
146     (((a_from_ceiling) + (b_from_ceiling) - 1) / (b_from_ceiling))
147
148 // round_down(a,b) decreases a>=0 such that it becomes divisible by b>0.
149 // b should be a constant expression.
150   #define round_down(a_from_round,b_from_round)  \
151     (floor(a_from_round,b_from_round)*(b_from_round))
152
153 // round_up(a,b) increases a>=0 such that it becomes divisible by b>0.
154 // b should be a constant expression.
155   #define round_up(a_from_round,b_from_round)  \
156     (ceiling(a_from_round,b_from_round)*(b_from_round))
157
158 // We never call malloc(0), so no need to handle it.
159   #define __MALLOC_0_RETURNS_NULL
160
161 // Loop which executes a statement a given number of times.
162 // dotimesC(countvar,count,statement);
163 // countvar must be of type `uintC'. It is modified!
164   #define dotimesC(countvar_from_dotimesC,count_from_dotimesC,statement_from_dotimesC)  \
165     { countvar_from_dotimesC = (count_from_dotimesC);         \
166       until (countvar_from_dotimesC==0)                       \
167         {statement_from_dotimesC; countvar_from_dotimesC--; } \
168     }
169   #define dotimespC(countvar_from_dotimespC,count_from_dotimespC,statement_from_dotimespC)  \
170     { countvar_from_dotimespC = (count_from_dotimespC);                   \
171       do {statement_from_dotimespC} until (--countvar_from_dotimespC==0); \
172     }
173
174 // doconsttimes(count,statement);
175 // führt statement count mal aus (count mal der Code!),
176 // wobei count eine constant-expression >=0, <=8 ist.
177   #define doconsttimes(count_from_doconsttimes,statement_from_doconsttimes)  \
178     { if (0 < (count_from_doconsttimes)) { statement_from_doconsttimes; } \
179       if (1 < (count_from_doconsttimes)) { statement_from_doconsttimes; } \
180       if (2 < (count_from_doconsttimes)) { statement_from_doconsttimes; } \
181       if (3 < (count_from_doconsttimes)) { statement_from_doconsttimes; } \
182       if (4 < (count_from_doconsttimes)) { statement_from_doconsttimes; } \
183       if (5 < (count_from_doconsttimes)) { statement_from_doconsttimes; } \
184       if (6 < (count_from_doconsttimes)) { statement_from_doconsttimes; } \
185       if (7 < (count_from_doconsttimes)) { statement_from_doconsttimes; } \
186     }
187
188 // DOCONSTTIMES(count,macroname);
189 // ruft count mal den Macro macroname auf (count mal der Code!),
190 // wobei count eine constant-expression >=0, <=8 ist.
191 // Dabei bekommt macroname der Reihe nach die Werte 0,...,count-1 übergeben.
192   #define DOCONSTTIMES(count_from_DOCONSTTIMES,macroname_from_DOCONSTTIMES)  \
193     { if (0 < (count_from_DOCONSTTIMES)) { macroname_from_DOCONSTTIMES((0 < (count_from_DOCONSTTIMES) ? 0 : 0)); } \
194       if (1 < (count_from_DOCONSTTIMES)) { macroname_from_DOCONSTTIMES((1 < (count_from_DOCONSTTIMES) ? 1 : 0)); } \
195       if (2 < (count_from_DOCONSTTIMES)) { macroname_from_DOCONSTTIMES((2 < (count_from_DOCONSTTIMES) ? 2 : 0)); } \
196       if (3 < (count_from_DOCONSTTIMES)) { macroname_from_DOCONSTTIMES((3 < (count_from_DOCONSTTIMES) ? 3 : 0)); } \
197       if (4 < (count_from_DOCONSTTIMES)) { macroname_from_DOCONSTTIMES((4 < (count_from_DOCONSTTIMES) ? 4 : 0)); } \
198       if (5 < (count_from_DOCONSTTIMES)) { macroname_from_DOCONSTTIMES((5 < (count_from_DOCONSTTIMES) ? 5 : 0)); } \
199       if (6 < (count_from_DOCONSTTIMES)) { macroname_from_DOCONSTTIMES((6 < (count_from_DOCONSTTIMES) ? 6 : 0)); } \
200       if (7 < (count_from_DOCONSTTIMES)) { macroname_from_DOCONSTTIMES((7 < (count_from_DOCONSTTIMES) ? 7 : 0)); } \
201     }
202
203 // AT_INITIALIZATION(id) { ... }
204 // executes the given code at initialization time of the file.
205 // The id is something unique.
206   #define AT_INITIALIZATION(id)  \
207     class CONCAT3(INIT_CLASS_,id,__LINE__) {                            \
208       public: CONCAT3(INIT_CLASS_,id,__LINE__) (void);                  \
209     } CONCAT4(INIT_CLASS_,id,__LINE__,_DUMMY);                          \
210     inline CONCAT3(INIT_CLASS_,id,__LINE__)::CONCAT3(INIT_CLASS_,id,__LINE__) (void)
211
212 // AT_DESTRUCTION(id) { ... }
213 // executes the given code at destruction time of the file.
214 // The id is something unique.
215   #define AT_DESTRUCTION(id)  \
216     class CONCAT3(DESTR_CLASS_,id,__LINE__) {                           \
217       public: ~CONCAT3(DESTR_CLASS_,id,__LINE__) (void);                \
218     } CONCAT4(DESTR_CLASS_,id,__LINE__,_DUMMY);                         \
219     CONCAT3(DESTR_CLASS_,id,__LINE__)::~CONCAT3(DESTR_CLASS_,id,__LINE__) (void)
220
221 // Inside a class definition:
222 // Overload `new' so that a class object can be allocated anywhere.
223 #if !((defined(__rs6000__) || defined(__alpha__)) && !defined(__GNUC__))
224 #define ALLOCATE_ANYWHERE(classname)  \
225     /* Ability to place an object at a given address. */                \
226 public:                                                                 \
227     void* operator new (size_t size) { return cl_malloc_hook(size); }   \
228     void* operator new (size_t size, classname* ptr) { unused size; return ptr; } \
229     void operator delete (void* ptr) { cl_free_hook(ptr); }
230 #else
231 // For some compilers, work around template problem with "classname".
232 #define ALLOCATE_ANYWHERE(classname)  \
233     /* Ability to place an object at a given address. */                \
234 public:                                                                 \
235     void* operator new (size_t size) { return cl_malloc_hook(size); }   \
236     void* operator new (size_t size, void* ptr) { unused size; return ptr; } \
237     void operator delete (void* ptr) { cl_free_hook(ptr); }
238 #endif
239
240 // init1(type, object) (value);
241 // initializes `object' with `value', by calling `type''s constructor.
242 // (The identifiers `init' and `Init' are already in use by <streambuf.h>,
243 // it's a shame!)
244 #define init1(type,lvalue)  (void) new (&(lvalue)) type
245
246 // MAYBE_INLINE normally expands to nothing.
247 // Useful for including the implementation of some file inline into another.
248   #define MAYBE_INLINE
249   #define MAYBE_INLINE2
250
251 #endif /* _CL_MACROS_H */