Back to index

texmacs  1.0.7.15
basic.hpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : basic.hpp
00004 * DESCRIPTION: see basic.cpp
00005 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #ifndef BASIC_H
00013 #define BASIC_H
00014 #include "fast_alloc.hpp"
00015 #include <math.h>
00016 
00017 #ifdef HAVE_INTPTR_T
00018 #ifdef OS_SUN
00019 #include <inttypes.h>
00020 #else
00021 #include <stdint.h>
00022 #endif
00023 #else
00024 typedef long intptr_t;
00025 #endif
00026 
00027 #ifdef OS_WIN32
00028 #define LESSGTR
00029 #else
00030 #define LESSGTR <>
00031 #endif
00032 
00033 #define TM_DEBUG(x)
00034 typedef int SI;
00035 typedef unsigned int SN;
00036 typedef short HI;
00037 typedef unsigned short HN;
00038 typedef char QI;
00039 typedef unsigned char QN;
00040 #ifdef OS_WIN32
00041 typedef __int64 DI;
00042 #else
00043 typedef long long int DI;
00044 #endif
00045 typedef void* pointer;
00046 
00047 /******************************************************************************
00048 * debugging
00049 ******************************************************************************/
00050 
00051 #if (defined OS_WIN32 || defined __SUNPRO_CC)
00052 #define STACK_NEW_ARRAY(name,T,size) T* name= tm_new_array<T> (size)
00053 #define STACK_DELETE_ARRAY(name) tm_delete_array (name)
00054 #else
00055 #define STACK_NEW_ARRAY(name,T,size) T name[size]
00056 #define STACK_DELETE_ARRAY(name)
00057 #endif
00058 
00059 enum { DEBUG_FLAG_AUTO, DEBUG_FLAG_VERBOSE, DEBUG_FLAG_EVENTS,
00060        DEBUG_FLAG_STD, DEBUG_FLAG_IO, DEBUG_FLAG_BENCH,
00061        DEBUG_FLAG_HISTORY, DEBUG_FLAG_QT, DEBUG_FLAG_KEYBOARD,
00062        DEBUG_FLAG_PACKRAT, DEBUG_FLAG_FLATTEN, DEBUG_FLAG_CORRECT };
00063 bool debug (int which, bool write_flag= false);
00064 int  debug_off ();
00065 void debug_on (int status);
00066 class string;
00067 void debug_set (string s, bool flag);
00068 bool debug_get (string s);
00069 #define DEBUG_AUTO (debug (DEBUG_FLAG_AUTO))
00070 #define DEBUG_VERBOSE (debug (DEBUG_FLAG_VERBOSE))
00071 #define DEBUG_EVENTS (debug (DEBUG_FLAG_EVENTS))
00072 #define DEBUG_STD (debug (DEBUG_FLAG_STD))
00073 #define DEBUG_IO (debug (DEBUG_FLAG_IO))
00074 #define DEBUG_BENCH (debug (DEBUG_FLAG_BENCH))
00075 #define DEBUG_HISTORY (debug (DEBUG_FLAG_HISTORY))
00076 #define DEBUG_QT (debug (DEBUG_FLAG_QT))
00077 #define DEBUG_KEYBOARD (debug (DEBUG_FLAG_KEYBOARD))
00078 #define DEBUG_PACKRAT (debug (DEBUG_FLAG_PACKRAT))
00079 #define DEBUG_FLATTEN (debug (DEBUG_FLAG_FLATTEN))
00080 #define DEBUG_CORRECT (debug (DEBUG_FLAG_CORRECT))
00081 
00082 void tm_failure (const char* msg);
00083 #ifdef DEBUG_ASSERT
00084 #include <assert.h>
00085 #define ASSERT(cond,msg) { if (!(cond)) { tm_failure (msg); assert (cond); } }
00086 #define FAILED(msg) { tm_failure (msg); assert (false); }
00087 #else
00088 #define ASSERT(cond,msg) { if (!(cond)) { tm_failure (msg); } }
00089 #define FAILED(msg) { tm_failure (msg); }
00090 #endif
00091 
00092 /******************************************************************************
00093 * miscellaneous routines
00094 ******************************************************************************/
00095 
00096 inline SI min (SI i, SI j) { if (i<j) return i; else return j; }
00097 inline SI max (SI i, SI j) { if (i>j) return i; else return j; }
00098 inline DI min (DI i, DI j) { if (i<j) return i; else return j; }
00099 inline DI max (DI i, DI j) { if (i>j) return i; else return j; }
00100 inline double min (double i, double j) { if (i<j) return i; else return j; }
00101 inline double max (double i, double j) { if (i>j) return i; else return j; }
00102 inline int hash (int i) { return i; }
00103 inline int hash (pointer ptr) {
00104   return ((int) ((intptr_t) ptr)) + (((int) ((intptr_t) ptr)) % 19); }
00105 inline int copy (int x) { return x; }
00106 inline SI as_int (double x) { return (SI) floor (x + 0.5); }
00107 
00108 enum display_control { INDENT, UNINDENT, HRULE, LF };
00109 tm_ostream& operator << (tm_ostream& out, display_control ctrl);
00110 
00111 bool gui_is_x ();
00112 bool gui_is_qt ();
00113 bool os_win32 ();
00114 bool os_mingw ();
00115 bool os_macos ();
00116 bool use_macos_fonts ();
00117 const char* default_look_and_feel ();
00118 
00119 template<typename T>
00120 struct type_helper {
00121   static int id;
00122   static T   init;
00123 };
00124 
00125 int new_type_identifier ();
00126 template<typename T> int type_helper<T>::id  = new_type_identifier ();
00127 template<typename T> T   type_helper<T>::init= T ();
00128 
00129 /******************************************************************************
00130 * concrete and abstract base structures
00131 ******************************************************************************/
00132 
00133 extern int concrete_count;
00134 struct concrete_struct {
00135   int ref_count;
00136   inline concrete_struct (): ref_count (1) { TM_DEBUG(concrete_count++); }
00137   virtual inline ~concrete_struct () { TM_DEBUG(concrete_count--); }
00138 };
00139 
00140 extern int abstract_count;
00141 struct abstract_struct {
00142   int ref_count;
00143   inline abstract_struct (): ref_count (0) { TM_DEBUG(abstract_count++); }
00144   virtual inline ~abstract_struct () { TM_DEBUG(abstract_count--); }
00145 };
00146 
00147 /******************************************************************************
00148 * indirect structures
00149 ******************************************************************************/
00150 
00151 #define INC_COUNT(R)      { (R)->ref_count++; }
00152 #define DEC_COUNT(R)      { if(0==--((R)->ref_count)) tm_delete (R); }
00153 #define INC_COUNT_NULL(R) { if ((R)!=NULL) (R)->ref_count++; }
00154 #define DEC_COUNT_NULL(R) { if ((R)!=NULL && 0==--((R)->ref_count)) tm_delete (R); }
00155 
00156 // concrete
00157 #define CONCRETE(PTR)               \
00158   PTR##_rep *rep;                   \
00159 public:                             \
00160   inline PTR (const PTR&);          \
00161   inline ~PTR ();                   \
00162   inline PTR##_rep* operator -> (); \
00163   inline PTR& operator = (PTR x)
00164 #define CONCRETE_CODE(PTR)                       \
00165   inline PTR::PTR (const PTR& x):                \
00166     rep(x.rep) { INC_COUNT (this->rep); }        \
00167   inline PTR::~PTR () { DEC_COUNT (this->rep); } \
00168   inline PTR##_rep* PTR::operator -> () {        \
00169     return rep; }                                \
00170   inline PTR& PTR::operator = (PTR x) {          \
00171     INC_COUNT (x.rep); DEC_COUNT (this->rep);    \
00172     this->rep=x.rep; return *this; }
00173 
00174 // definition for 1 parameter template classes
00175 #define CONCRETE_TEMPLATE(PTR,T)      \
00176   PTR##_rep<T> *rep;                  \
00177 public:                               \
00178   inline PTR (const PTR<T>&);         \
00179   inline ~PTR ();                     \
00180   inline PTR##_rep<T>* operator -> (); \
00181   inline PTR<T>& operator = (PTR<T> x)
00182 #define CONCRETE_TEMPLATE_CODE(PTR,TT,T)                          \
00183   template<TT T> inline PTR<T>::PTR (const PTR<T>& x):            \
00184     rep(x.rep) { INC_COUNT (this->rep); }                         \
00185   template<TT T> inline PTR<T>::~PTR() { DEC_COUNT (this->rep); } \
00186   template<TT T> inline PTR##_rep<T>* PTR<T>::operator -> () {    \
00187     return this->rep; }                                           \
00188   template<TT T> inline PTR<T>& PTR<T>::operator = (PTR<T> x) {   \
00189     INC_COUNT (x.rep); DEC_COUNT (this->rep);                     \
00190     this->rep=x.rep; return *this; }
00191 
00192 // definition for 2 parameter template classes
00193 #define CONCRETE_TEMPLATE_2(PTR,T1,T2)     \
00194   PTR##_rep<T1,T2> *rep;                   \
00195 public:                                    \
00196   inline PTR (const PTR<T1,T2>&);          \
00197   inline ~PTR ();                          \
00198   inline PTR##_rep<T1,T2>* operator -> (); \
00199   inline PTR<T1,T2>& operator = (PTR<T1,T2> x)
00200 #define CONCRETE_TEMPLATE_2_CODE(PTR,TT1,T1,TT2,T2)                           \
00201   template<TT1 T1,TT2 T2> inline PTR<T1,T2>::PTR (const PTR<T1,T2>& x):       \
00202     rep(x.rep) { INC_COUNT (this->rep); }                                     \
00203   template<TT1 T1,TT2 T2> inline PTR<T1,T2>::~PTR () { DEC_COUNT(this->rep);} \
00204   template<TT1 T1,TT2 T2> inline PTR##_rep<T1,T2>* PTR<T1,T2>::operator -> () \
00205     { return this->rep; }                                                     \
00206   template <TT1 T1,TT2 T2>                                                    \
00207   inline PTR<T1,T2>& PTR<T1,T2>::operator = (PTR<T1,T2> x) {                  \
00208     INC_COUNT (x.rep); DEC_COUNT (this->rep);                                 \
00209     this->rep=x.rep; return *this; }
00210 // end concrete
00211 
00212 // abstract
00213 #define ABSTRACT(PTR) \
00214   CONCRETE(PTR);      \
00215   inline PTR (PTR##_rep*)
00216 #define ABSTRACT_CODE(PTR) \
00217   CONCRETE_CODE(PTR) ;     \
00218   inline PTR::PTR (PTR##_rep* rep2): rep(rep2) { INC_COUNT (this->rep); }
00219 #define ABSTRACT_TEMPLATE(PTR,T) \
00220   CONCRETE_TEMPLATE(PTR,T);      \
00221   inline PTR (PTR##_rep<T>*)
00222 #define ABSTRACT_TEMPLATE_CODE(PTR,TT,T)                  \
00223   CONCRETE_TEMPLATE_CODE(PTR,TT,T);                       \
00224   template<TT T> inline PTR<T>::PTR (PTR##_rep<T>* rep2): \
00225     rep(rep2) { INC_COUNT (this->rep); }
00226 // end abstract
00227 
00228 /******************************************************************************
00229 * null indirect structures
00230 ******************************************************************************/
00231 
00232 // concrete_null
00233 #define CONCRETE_NULL(PTR) \
00234   CONCRETE(PTR);           \
00235   inline PTR();            \
00236   friend bool is_nil /*LESSGTR*/ (PTR x)
00237 #define CONCRETE_NULL_CODE(PTR)                         \
00238   inline PTR::PTR (): rep(NULL) {}                      \
00239   inline PTR::PTR (const PTR& x):                       \
00240     rep(x.rep) { INC_COUNT_NULL (this->rep); }          \
00241   inline PTR::~PTR() { DEC_COUNT_NULL (this->rep); }    \
00242   inline PTR##_rep* PTR::operator -> () {               \
00243     return this->rep; }                                 \
00244   inline PTR& PTR::operator = (PTR x) {                 \
00245     INC_COUNT_NULL (x.rep); DEC_COUNT_NULL (this->rep); \
00246     this->rep=x.rep; return *this; }                    \
00247   inline bool is_nil (PTR x) { return x.rep==NULL; }
00248 #define CONCRETE_NULL_TEMPLATE(PTR,T) \
00249   CONCRETE_TEMPLATE(PTR,T);           \
00250   inline PTR();                       \
00251   friend bool is_nil LESSGTR (PTR<T> x)
00252 #define CONCRETE_NULL_TEMPLATE_CODE(PTR,TT,T)                           \
00253   template<TT T> inline PTR<T>::PTR (): rep(NULL) {}                    \
00254   template<TT T> inline PTR<T>::PTR (const PTR<T>& x):                  \
00255     rep(x.rep) { INC_COUNT_NULL (this->rep); }                          \
00256   template<TT T> inline PTR<T>::~PTR () { DEC_COUNT_NULL (this->rep); } \
00257   template<TT T> inline PTR##_rep<T>* PTR<T>::operator -> () {          \
00258     return this->rep; }                                                 \
00259   template<TT T> inline PTR<T>& PTR<T>::operator = (PTR<T> x) {         \
00260     INC_COUNT_NULL (x.rep); DEC_COUNT_NULL (this->rep);                 \
00261     this->rep=x.rep; return *this; }                                    \
00262   template<TT T> inline bool is_nil (PTR<T> x) { return x.rep==NULL; }
00263 
00264 #define CONCRETE_NULL_TEMPLATE_2(PTR,T1,T2) \
00265   CONCRETE_TEMPLATE_2(PTR,T1,T2);           \
00266   inline PTR();                             \
00267   friend bool is_nil LESSGTR (PTR<T1,T2> x)
00268 #define CONCRETE_NULL_TEMPLATE_2_CODE(PTR,TT1,T1,TT2,T2)                  \
00269   template<TT1 T1, TT2 T2> inline PTR<T1,T2>::PTR (): rep(NULL) {}        \
00270   template<TT1 T1, TT2 T2> inline PTR<T1,T2>::PTR (const PTR<T1,T2>& x):  \
00271     rep(x.rep) { INC_COUNT_NULL (this->rep); }                            \
00272   template<TT1 T1, TT2 T2> inline PTR<T1,T2>::~PTR () {                   \
00273     DEC_COUNT_NULL (this->rep); }                                         \
00274   template<TT1 T1, TT2 T2> PTR##_rep<T1,T2>* PTR<T1,T2>::operator -> () { \
00275     return this->rep; }                                                   \
00276   template<TT1 T1, TT2 T2>                                                \
00277   inline PTR<T1,T2>& PTR<T1,T2>::operator = (PTR<T1,T2> x) {              \
00278     INC_COUNT_NULL (x.rep); DEC_COUNT_NULL (this->rep);                   \
00279     this->rep=x.rep; return *this; }                                      \
00280   template<TT1 T1, TT2 T2> inline bool is_nil (PTR<T1,T2> x) {               \
00281     return x.rep==NULL; }
00282 // end concrete_null
00283 
00284 // abstract_null
00285 #define ABSTRACT_NULL(PTR) \
00286   CONCRETE_NULL (PTR);     \
00287   inline PTR (PTR##_rep*)
00288 #define ABSTRACT_NULL_CODE(PTR)      \
00289   CONCRETE_NULL_CODE (PTR);          \
00290   inline PTR::PTR (PTR##_rep* rep2): \
00291     rep(rep2) { INC_COUNT_NULL (this->rep); }
00292 #define ABSTRACT_NULL_TEMPLATE(PTR,T) \
00293   CONCRETE_NULL_TEMPLATE (PTR,T);     \
00294   inline PTR (PTR##_rep<T>*)
00295 #define ABSTRACT_NULL_TEMPLATE_CODE(PTR,TT,T)              \
00296   CONCRETE_NULL_TEMPLATE_CODE (PTR,TT,T);                  \
00297   template<TT T> inline PTR<T>::PTR (PTR##_rep<T>* rep2):  \
00298     rep(rep2) { INC_COUNT (this->rep); }
00299 #define ABSTRACT_NULL_TEMPLATE_2(PTR,T1,T2) \
00300   CONCRETE_NULL_TEMPLATE_2 (PTR,T1,T2);     \
00301   inline PTR (PTR##_rep<T1,T2>*)
00302 #define ABSTRACT_NULL_TEMPLATE_2_CODE(PTR,TT1,T1,TT2,T2)                    \
00303   CONCRETE_NULL_TEMPLATE_2_CODE (PTR,TT1,T1,TT2,T2);                          \
00304   template<TT1 T1,TT2 T2> inline PTR<T1,T2>::PTR (PTR##_rep<T1,T2>* rep2):  \
00305     rep(rep2) { INC_COUNT (this->rep); }
00306 // end abstract_null
00307 
00308 /******************************************************************************
00309 * extensions
00310 ******************************************************************************/
00311 
00312 #define EXTEND(BASE,PTR) \
00313   ABSTRACT(PTR);         \
00314   inline PTR(BASE&);     \
00315   inline operator BASE ()
00316 #define EXTEND_CODE(BASE,PTR)             \
00317   ABSTRACT_CODE(PTR);                     \
00318   inline PTR::PTR(BASE& x):               \
00319     rep(static_cast<PTR##_rep*>(x.rep)) { \
00320     INC_COUNT (this->rep); }              \
00321   inline PTR::operator BASE () { return BASE (this->rep); }
00322 // end extend
00323 
00324 // extend_null
00325 #define EXTEND_NULL(BASE,PTR) \
00326   ABSTRACT_NULL(PTR);         \
00327   inline PTR(BASE&);          \
00328   inline operator BASE ()
00329 #define EXTEND_NULL_CODE(BASE,PTR)        \
00330   ABSTRACT_NULL_CODE(PTR);                \
00331   inline PTR::PTR(BASE& x):               \
00332     rep(static_cast<PTR##_rep*>(x.rep)) { \
00333     INC_COUNT_NULL(this->rep); }          \
00334   inline PTR::operator BASE () { return BASE (this->rep); }
00335 
00336 #define EXTEND_NULL_TEMPLATE(BASE,PTR,T) \
00337   ABSTRACT_NULL_TEMPLATE(PTR,T);         \
00338   inline PTR<T>(BASE&);                  \
00339   inline operator BASE ()
00340 #define EXTEND_NULL_TEMPLATE_CODE(BASE,PTR,TT,T) \
00341   ABSTRACT_NULL_TEMPLATE_CODE(PTR,TT,T);         \
00342   template<TT T> inline PTR<T>::PTR(BASE& x):    \
00343     rep(static_cast<PTR##_rep<T>*>(x.rep)) {     \
00344     INC_COUNT_NULL(this->rep); }                 \
00345   template<TT T> inline PTR<T>::operator BASE () { return BASE (this->rep); }
00346 // end extend_null
00347 
00348 #endif // defined BASIC_H