1
2 /******************************************************************************
3 * MODULE : basic.hpp
4 * DESCRIPTION: see basic.cpp
5 * COPYRIGHT : (C) 1999 Joris van der Hoeven
6 *******************************************************************************
7 * This software falls under the GNU general public license version 3 or later.
8 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
9 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
10 ******************************************************************************/
11
12 #ifndef BASIC_H
13 #define BASIC_H
14 #include "fast_alloc.hpp"
15 #include <math.h>
16
17 #ifdef HAVE_INTPTR_T
18 #ifdef HAVE_INTTYPES_H
19 #include <inttypes.h>
20 #endif
21 #ifdef HAVE_STDINT_H
22 #include <stdint.h>
23 #endif
24 #else
25 typedef long intptr_t;
26 #endif
27
28 #ifdef OS_WIN32
29 #define LESSGTR
30 #else
31 #define LESSGTR <>
32 #endif
33
34 #define TM_DEBUG(x)
35 typedef int SI;
36 typedef unsigned int SN;
37 typedef short HI;
38 typedef unsigned short HN;
39 typedef char QI;
40 typedef unsigned char QN;
41 #ifdef OS_WIN32
42 typedef __int64 DI;
43 typedef unsigned __int64 DN;
44 #else
45 typedef long long int DI;
46 typedef unsigned long long int DN;
47 #endif
48 typedef void* pointer;
49 typedef unsigned int color;
50 #define MAX_SI 0x7fffffff
51 #define MIN_SI 0x80000000
52
53 /******************************************************************************
54 * debugging
55 ******************************************************************************/
56
57 #if (defined OS_WIN32 || defined __SUNPRO_CC || defined __clang__)
58 #define STACK_NEW_ARRAY(name,T,size) T* name= tm_new_array<T> (size)
59 #define STACK_DELETE_ARRAY(name) tm_delete_array (name)
60 #else
61 #define STACK_NEW_ARRAY(name,T,size) T name[size]
62 #define STACK_DELETE_ARRAY(name)
63 #endif
64
65 enum { DEBUG_FLAG_AUTO, DEBUG_FLAG_VERBOSE, DEBUG_FLAG_EVENTS,
66 DEBUG_FLAG_STD, DEBUG_FLAG_IO, DEBUG_FLAG_BENCH,
67 DEBUG_FLAG_HISTORY, DEBUG_FLAG_QT, DEBUG_FLAG_QT_WIDGETS,
68 DEBUG_FLAG_KEYBOARD, DEBUG_FLAG_PACKRAT, DEBUG_FLAG_FLATTEN,
69 DEBUG_FLAG_CORRECT };
70 bool debug (int which, bool write_flag= false);
71 int debug_off ();
72 void debug_on (int status);
73 class string;
74 void debug_set (string s, bool flag);
75 bool debug_get (string s);
76 #define DEBUG_AUTO (debug (DEBUG_FLAG_AUTO))
77 #define DEBUG_VERBOSE (debug (DEBUG_FLAG_VERBOSE))
78 #define DEBUG_EVENTS (debug (DEBUG_FLAG_EVENTS))
79 #define DEBUG_STD (debug (DEBUG_FLAG_STD))
80 #define DEBUG_IO (debug (DEBUG_FLAG_IO))
81 #define DEBUG_BENCH (debug (DEBUG_FLAG_BENCH))
82 #define DEBUG_HISTORY (debug (DEBUG_FLAG_HISTORY))
83 #define DEBUG_QT (debug (DEBUG_FLAG_QT))
84 #define DEBUG_QT_WIDGETS (debug (DEBUG_FLAG_QT_WIDGETS))
85 #define DEBUG_KEYBOARD (debug (DEBUG_FLAG_KEYBOARD))
86 #define DEBUG_PACKRAT (debug (DEBUG_FLAG_PACKRAT))
87 #define DEBUG_FLATTEN (debug (DEBUG_FLAG_FLATTEN))
88 #define DEBUG_CORRECT (debug (DEBUG_FLAG_CORRECT))
89 #define DEBUG_AQUA (debug (DEBUG_FLAG_QT))
90 #define DEBUG_AQUA_WIDGETS (debug (DEBUG_FLAG_QT_WIDGETS))
91
92 #define USE_EXCEPTIONS
93 void tm_failure (const char* msg);
94 #ifdef USE_EXCEPTIONS
95 extern string the_exception;
96 void tm_throw (const char* msg);
97 void handle_exceptions ();
98 #define ASSERT(cond,msg) { if (!(cond)) tm_throw (msg); }
99 #define FAILED(msg) { tm_throw (msg); }
100 #else
101 #ifdef DEBUG_ASSERT
102 #include <assert.h>
103 #define ASSERT(cond,msg) { if (!(cond)) { tm_failure (msg); assert (cond); } }
104 #define FAILED(msg) { tm_failure (msg); assert (false); }
105 #else
106 #define ASSERT(cond,msg) { if (!(cond)) { tm_failure (msg); } }
107 #define FAILED(msg) { tm_failure (msg); }
108 #endif
109 #endif
110
111 class tree;
112 void debug_message (string channel, string msg);
113 void debug_formatted (string channel, tree msg);
114 tree get_debug_messages (string kind, int max_number);
115 void clear_debug_messages ();
116 void clear_debug_messages (string channel);
117
118 /******************************************************************************
119 * miscellaneous routines
120 ******************************************************************************/
121
min(SI i,SI j)122 inline SI min (SI i, SI j) { if (i<j) return i; else return j; }
max(SI i,SI j)123 inline SI max (SI i, SI j) { if (i>j) return i; else return j; }
min(DI i,DI j)124 inline DI min (DI i, DI j) { if (i<j) return i; else return j; }
max(DI i,DI j)125 inline DI max (DI i, DI j) { if (i>j) return i; else return j; }
min(double i,double j)126 inline double min (double i, double j) { if (i<j) return i; else return j; }
max(double i,double j)127 inline double max (double i, double j) { if (i>j) return i; else return j; }
hash(int i)128 inline int hash (int i) { return i; }
hash(long int i)129 inline int hash (long int i) { return (int) i; }
hash(DI i)130 inline int hash (DI i) { return (int) i; }
hash(unsigned int i)131 inline int hash (unsigned int i) { return i; }
hash(unsigned long int i)132 inline int hash (unsigned long int i) { return (int) i; }
hash(DN i)133 inline int hash (DN i) { return (int) i; }
hash(pointer ptr)134 inline int hash (pointer ptr) {
135 return ((int) ((intptr_t) ptr)) + (((int) ((intptr_t) ptr)) % 19); }
hash(float x)136 inline int hash (float x) {
137 union { int n; float d; } u;
138 u.d= x; return u.n & 0xffffffff; }
hash(double x)139 inline int hash (double x) {
140 union { DI n; double d; } u;
141 u.d= x; return (int) (u.n ^ (u.n >> 32)); }
copy(int x)142 inline int copy (int x) { return x; }
as_int(double x)143 inline SI as_int (double x) { return (SI) floor (x + 0.5); }
tm_round(double x)144 inline double tm_round (double x) { return floor (x + 0.5); }
145
146 enum display_control { INDENT, UNINDENT, HRULE, LF };
147 tm_ostream& operator << (tm_ostream& out, display_control ctrl);
148
149 bool gui_is_x ();
150 bool gui_is_qt ();
151 bool os_win32 ();
152 bool os_mingw ();
153 bool os_macos ();
154 bool use_macos_fonts ();
155 const char* default_look_and_feel ();
156
157 template<typename T>
158 struct type_helper {
159 static int id;
160 static T init;
init_valtype_helper161 static inline T init_val () { return T (); }
162 };
163
164 int new_type_identifier ();
165 template<typename T> int type_helper<T>::id = new_type_identifier ();
166 template<typename T> T type_helper<T>::init= T ();
167
168 #ifdef QTTEXMACS
169 //#define QT_CPU_FIX 1
170 #ifdef QT_CPU_FIX
171 void tm_wake_up ();
172 void tm_sleep ();
173 #endif
174 #endif
175
176 /******************************************************************************
177 * concrete and abstract base structures
178 ******************************************************************************/
179
180 extern int concrete_count;
181 struct concrete_struct {
182 int ref_count;
concrete_structconcrete_struct183 inline concrete_struct (): ref_count (1) { TM_DEBUG(concrete_count++); }
~concrete_structconcrete_struct184 virtual inline ~concrete_struct () { TM_DEBUG(concrete_count--); }
185 };
186
187 extern int abstract_count;
188 struct abstract_struct {
189 int ref_count;
abstract_structabstract_struct190 inline abstract_struct (): ref_count (0) { TM_DEBUG(abstract_count++); }
~abstract_structabstract_struct191 virtual inline ~abstract_struct () { TM_DEBUG(abstract_count--); }
192 };
193
194 /******************************************************************************
195 * indirect structures
196 ******************************************************************************/
197
198 #define INC_COUNT(R) { (R)->ref_count++; }
199 #define DEC_COUNT(R) { if(0==--((R)->ref_count)) { tm_delete (R);}}
200 //#define DEC_COUNT(R) { if(0==--((R)->ref_count)) { tm_delete (R); R=NULL;}}
201 #define INC_COUNT_NULL(R) { if ((R)!=NULL) (R)->ref_count++; }
202 /*#define DEC_COUNT_NULL(R) \
203 { if ((R)!=NULL && 0==--((R)->ref_count)) { tm_delete (R); } } */
204 #define DEC_COUNT_NULL(R) \
205 { if ((R)!=NULL && 0==--((R)->ref_count)) { tm_delete (R); R=NULL;} }
206
207 // concrete
208 #define CONCRETE(PTR) \
209 PTR##_rep *rep; \
210 public: \
211 inline PTR (const PTR&); \
212 inline ~PTR (); \
213 inline PTR##_rep* operator -> (); \
214 inline PTR& operator = (PTR x)
215 #define CONCRETE_CODE(PTR) \
216 inline PTR::PTR (const PTR& x): \
217 rep(x.rep) { INC_COUNT (this->rep); } \
218 inline PTR::~PTR () { DEC_COUNT (this->rep); } \
219 inline PTR##_rep* PTR::operator -> () { \
220 return rep; } \
221 inline PTR& PTR::operator = (PTR x) { \
222 INC_COUNT (x.rep); DEC_COUNT (this->rep); \
223 this->rep=x.rep; return *this; }
224
225 // definition for 1 parameter template classes
226 #define CONCRETE_TEMPLATE(PTR,T) \
227 PTR##_rep<T> *rep; \
228 public: \
229 inline PTR (const PTR<T>&); \
230 inline ~PTR (); \
231 inline PTR##_rep<T>* operator -> (); \
232 inline PTR<T>& operator = (PTR<T> x)
233 #define CONCRETE_TEMPLATE_CODE(PTR,TT,T) \
234 template<TT T> inline PTR<T>::PTR (const PTR<T>& x): \
235 rep(x.rep) { INC_COUNT (this->rep); } \
236 template<TT T> inline PTR<T>::~PTR() { DEC_COUNT (this->rep); } \
237 template<TT T> inline PTR##_rep<T>* PTR<T>::operator -> () { \
238 return this->rep; } \
239 template<TT T> inline PTR<T>& PTR<T>::operator = (PTR<T> x) { \
240 INC_COUNT (x.rep); DEC_COUNT (this->rep); \
241 this->rep=x.rep; return *this; }
242
243 // definition for 2 parameter template classes
244 #define CONCRETE_TEMPLATE_2(PTR,T1,T2) \
245 PTR##_rep<T1,T2> *rep; \
246 public: \
247 inline PTR (const PTR<T1,T2>&); \
248 inline ~PTR (); \
249 inline PTR##_rep<T1,T2>* operator -> (); \
250 inline PTR<T1,T2>& operator = (PTR<T1,T2> x)
251 #define CONCRETE_TEMPLATE_2_CODE(PTR,TT1,T1,TT2,T2) \
252 template<TT1 T1,TT2 T2> inline PTR<T1,T2>::PTR (const PTR<T1,T2>& x): \
253 rep(x.rep) { INC_COUNT (this->rep); } \
254 template<TT1 T1,TT2 T2> inline PTR<T1,T2>::~PTR () { DEC_COUNT(this->rep);} \
255 template<TT1 T1,TT2 T2> inline PTR##_rep<T1,T2>* PTR<T1,T2>::operator -> () \
256 { return this->rep; } \
257 template <TT1 T1,TT2 T2> \
258 inline PTR<T1,T2>& PTR<T1,T2>::operator = (PTR<T1,T2> x) { \
259 INC_COUNT (x.rep); DEC_COUNT (this->rep); \
260 this->rep=x.rep; return *this; }
261 // end concrete
262
263 // abstract
264 #define ABSTRACT(PTR) \
265 CONCRETE(PTR); \
266 inline PTR (PTR##_rep*)
267 #define ABSTRACT_CODE(PTR) \
268 CONCRETE_CODE(PTR) ; \
269 inline PTR::PTR (PTR##_rep* rep2): rep(rep2) { INC_COUNT (this->rep); }
270 #define ABSTRACT_TEMPLATE(PTR,T) \
271 CONCRETE_TEMPLATE(PTR,T); \
272 inline PTR (PTR##_rep<T>*)
273 #define ABSTRACT_TEMPLATE_CODE(PTR,TT,T) \
274 CONCRETE_TEMPLATE_CODE(PTR,TT,T); \
275 template<TT T> inline PTR<T>::PTR (PTR##_rep<T>* rep2): \
276 rep(rep2) { INC_COUNT (this->rep); }
277 // end abstract
278
279 /******************************************************************************
280 * null indirect structures
281 ******************************************************************************/
282
283 // concrete_null
284 #define CONCRETE_NULL(PTR) \
285 CONCRETE(PTR); \
286 inline PTR(); \
287 friend bool is_nil /*LESSGTR*/ (PTR x)
288 #define CONCRETE_NULL_CODE(PTR) \
289 inline PTR::PTR (): rep(NULL) {} \
290 inline PTR::PTR (const PTR& x): \
291 rep(x.rep) { INC_COUNT_NULL (this->rep); } \
292 inline PTR::~PTR() { DEC_COUNT_NULL (this->rep); } \
293 inline PTR##_rep* PTR::operator -> () { \
294 return this->rep; } \
295 inline PTR& PTR::operator = (PTR x) { \
296 INC_COUNT_NULL (x.rep); DEC_COUNT_NULL (this->rep); \
297 this->rep=x.rep; return *this; } \
298 inline bool is_nil (PTR x) { return x.rep==NULL; }
299 #define CONCRETE_NULL_TEMPLATE(PTR,T) \
300 CONCRETE_TEMPLATE(PTR,T); \
301 inline PTR(); \
302 friend bool is_nil LESSGTR (PTR<T> x)
303 #define CONCRETE_NULL_TEMPLATE_CODE(PTR,TT,T) \
304 template<TT T> inline PTR<T>::PTR (): rep(NULL) {} \
305 template<TT T> inline PTR<T>::PTR (const PTR<T>& x): \
306 rep(x.rep) { INC_COUNT_NULL (this->rep); } \
307 template<TT T> inline PTR<T>::~PTR () { DEC_COUNT_NULL (this->rep); } \
308 template<TT T> inline PTR##_rep<T>* PTR<T>::operator -> () { \
309 return this->rep; } \
310 template<TT T> inline PTR<T>& PTR<T>::operator = (PTR<T> x) { \
311 INC_COUNT_NULL (x.rep); DEC_COUNT_NULL (this->rep); \
312 this->rep=x.rep; return *this; } \
313 template<TT T> inline bool is_nil (PTR<T> x) { return x.rep==NULL; }
314
315 #define CONCRETE_NULL_TEMPLATE_2(PTR,T1,T2) \
316 CONCRETE_TEMPLATE_2(PTR,T1,T2); \
317 inline PTR(); \
318 friend bool is_nil LESSGTR (PTR<T1,T2> x)
319 #define CONCRETE_NULL_TEMPLATE_2_CODE(PTR,TT1,T1,TT2,T2) \
320 template<TT1 T1, TT2 T2> inline PTR<T1,T2>::PTR (): rep(NULL) {} \
321 template<TT1 T1, TT2 T2> inline PTR<T1,T2>::PTR (const PTR<T1,T2>& x): \
322 rep(x.rep) { INC_COUNT_NULL (this->rep); } \
323 template<TT1 T1, TT2 T2> inline PTR<T1,T2>::~PTR () { \
324 DEC_COUNT_NULL (this->rep); } \
325 template<TT1 T1, TT2 T2> PTR##_rep<T1,T2>* PTR<T1,T2>::operator -> () { \
326 return this->rep; } \
327 template<TT1 T1, TT2 T2> \
328 inline PTR<T1,T2>& PTR<T1,T2>::operator = (PTR<T1,T2> x) { \
329 INC_COUNT_NULL (x.rep); DEC_COUNT_NULL (this->rep); \
330 this->rep=x.rep; return *this; } \
331 template<TT1 T1, TT2 T2> inline bool is_nil (PTR<T1,T2> x) { \
332 return x.rep==NULL; }
333 // end concrete_null
334
335 // abstract_null
336 #define ABSTRACT_NULL(PTR) \
337 CONCRETE_NULL (PTR); \
338 inline PTR (PTR##_rep*)
339 #define ABSTRACT_NULL_CODE(PTR) \
340 CONCRETE_NULL_CODE (PTR); \
341 inline PTR::PTR (PTR##_rep* rep2): \
342 rep(rep2) { INC_COUNT_NULL (this->rep); }
343 #define ABSTRACT_NULL_TEMPLATE(PTR,T) \
344 CONCRETE_NULL_TEMPLATE (PTR,T); \
345 inline PTR (PTR##_rep<T>*)
346 #define ABSTRACT_NULL_TEMPLATE_CODE(PTR,TT,T) \
347 CONCRETE_NULL_TEMPLATE_CODE (PTR,TT,T); \
348 template<TT T> inline PTR<T>::PTR (PTR##_rep<T>* rep2): \
349 rep(rep2) { INC_COUNT (this->rep); }
350 #define ABSTRACT_NULL_TEMPLATE_2(PTR,T1,T2) \
351 CONCRETE_NULL_TEMPLATE_2 (PTR,T1,T2); \
352 inline PTR (PTR##_rep<T1,T2>*)
353 #define ABSTRACT_NULL_TEMPLATE_2_CODE(PTR,TT1,T1,TT2,T2) \
354 CONCRETE_NULL_TEMPLATE_2_CODE (PTR,TT1,T1,TT2,T2); \
355 template<TT1 T1,TT2 T2> inline PTR<T1,T2>::PTR (PTR##_rep<T1,T2>* rep2): \
356 rep(rep2) { INC_COUNT (this->rep); }
357 // end abstract_null
358
359 /******************************************************************************
360 * extensions
361 ******************************************************************************/
362
363 #define EXTEND(BASE,PTR) \
364 ABSTRACT(PTR); \
365 inline PTR(BASE&); \
366 inline operator BASE ()
367 #define EXTEND_CODE(BASE,PTR) \
368 ABSTRACT_CODE(PTR); \
369 inline PTR::PTR(BASE& x): \
370 rep(static_cast<PTR##_rep*>(x.rep)) { \
371 INC_COUNT (this->rep); } \
372 inline PTR::operator BASE () { return BASE (this->rep); }
373 // end extend
374
375 // extend_null
376 #define EXTEND_NULL(BASE,PTR) \
377 ABSTRACT_NULL(PTR); \
378 inline PTR(BASE&); \
379 inline operator BASE ()
380 #define EXTEND_NULL_CODE(BASE,PTR) \
381 ABSTRACT_NULL_CODE(PTR); \
382 inline PTR::PTR(BASE& x): \
383 rep(static_cast<PTR##_rep*>(x.rep)) { \
384 INC_COUNT_NULL(this->rep); } \
385 inline PTR::operator BASE () { return BASE (this->rep); }
386
387 #define EXTEND_NULL_TEMPLATE(BASE,PTR,T) \
388 ABSTRACT_NULL_TEMPLATE(PTR,T); \
389 inline PTR<T>(BASE&); \
390 inline operator BASE ()
391 #define EXTEND_NULL_TEMPLATE_CODE(BASE,PTR,TT,T) \
392 ABSTRACT_NULL_TEMPLATE_CODE(PTR,TT,T); \
393 template<TT T> inline PTR<T>::PTR(BASE& x): \
394 rep(static_cast<PTR##_rep<T>*>(x.rep)) { \
395 INC_COUNT_NULL(this->rep); } \
396 template<TT T> inline PTR<T>::operator BASE () { return BASE (this->rep); }
397 // end extend_null
398
399 #endif // defined BASIC_H
400