|
ORTS
|
00001 #ifndef Global_H 00002 #define Global_H 00003 00004 // $Id: Global.H 6634 2008-01-20 19:59:11Z furtak $ 00005 00006 // This is an ORTS file (c) Michael Buro, licensed under the GPL 00007 00008 // general global definitions and useful macros 00009 00010 #include "All.H" 00011 #include "Vector.H" 00012 00013 #if 1 00014 00015 typedef int8_t sint1; 00016 typedef uint8_t uint1; 00017 typedef int16_t sint2; 00018 typedef uint16_t uint2; 00019 typedef int32_t sint4; 00020 typedef uint32_t uint4; 00021 typedef int64_t sint8; 00022 typedef uint64_t uint8; 00023 00024 typedef intptr_t sintptr; 00025 typedef uintptr_t uintptr; 00026 00027 #else 00028 00029 // old 00030 00031 typedef signed char sint1; 00032 typedef unsigned char uint1; 00033 typedef signed short sint2; 00034 typedef unsigned short uint2; 00035 typedef signed int sint4; 00036 typedef unsigned int uint4; 00037 typedef float real4; 00038 typedef double real8; 00039 typedef long double realC; 00040 typedef signed long long sint8; 00041 typedef unsigned long long uint8; 00042 00043 #endif 00044 00045 typedef float real4; 00046 typedef double real8; 00047 typedef long double realC; 00048 00049 typedef void* vptr; 00050 typedef char* cptr; 00051 00052 typedef const void* cvptr; 00053 typedef const char* ccptr; 00054 00055 typedef const void* const cvptrc; 00056 typedef const char* const ccptrc; 00057 00058 const sint1 min_sint1 = 0x80; 00059 const sint1 max_sint1 = 0x7F; 00060 const uint1 min_uint1 = 0x00; 00061 const uint1 max_uint1 = 0xFF; 00062 const sint2 min_sint2 = 0x8000; 00063 const sint2 max_sint2 = 0x7FFF; 00064 const uint2 min_uint2 = 0x0000; 00065 const uint2 max_uint2 = 0xFFFF; 00066 const sint4 min_sint4 = 0x80000000; 00067 const sint4 max_sint4 = 0x7FFFFFFF; 00068 const uint4 min_uint4 = 0x00000000; 00069 const uint4 max_uint4 = 0xFFFFFFFF; 00070 const sint8 min_sint8 = 0x8000000000000000LL; 00071 const sint8 max_sint8 = 0x7FFFFFFFFFFFFFFFLL; 00072 const uint8 min_uint8 = 0x0000000000000000LL; 00073 const uint8 max_uint8 = 0xFFFFFFFFFFFFFFFFLL; 00074 //const sintptr min_sintptr = INTPTR_MIN; 00075 //const sintptr max_sintptr = INTPTR_MAX; 00076 //const uintptr min_uintptr = 0; 00077 //const uintptr max_uintptr = UINTPTR_MAX; 00078 00079 BOOST_STATIC_ASSERT(sizeof(sint1) == 1); 00080 BOOST_STATIC_ASSERT(min_sint1 < 0); 00081 BOOST_STATIC_ASSERT(max_sint1 > 0); 00082 BOOST_STATIC_ASSERT(sizeof(uint1) == 1); 00083 BOOST_STATIC_ASSERT(min_uint1 == 0); 00084 BOOST_STATIC_ASSERT(max_uint1 > 0); 00085 BOOST_STATIC_ASSERT(sizeof(sint2) == 2); 00086 BOOST_STATIC_ASSERT(min_sint2 < 0); 00087 BOOST_STATIC_ASSERT(max_sint2 > 0); 00088 BOOST_STATIC_ASSERT(sizeof(uint2) == 2); 00089 BOOST_STATIC_ASSERT(min_uint2 == 0); 00090 BOOST_STATIC_ASSERT(max_uint2 > 0); 00091 BOOST_STATIC_ASSERT(sizeof(sint4) == 4); 00092 BOOST_STATIC_ASSERT(min_sint4 < 0); 00093 BOOST_STATIC_ASSERT(max_sint4 > 0); 00094 BOOST_STATIC_ASSERT(sizeof(uint4) == 4); 00095 BOOST_STATIC_ASSERT(min_uint4 == 0); 00096 BOOST_STATIC_ASSERT(max_uint4 > 0); 00097 BOOST_STATIC_ASSERT(sizeof(sint8) == 8); 00098 BOOST_STATIC_ASSERT(min_sint8 < 0); 00099 BOOST_STATIC_ASSERT(max_sint8 > 0); 00100 BOOST_STATIC_ASSERT(sizeof(uint8) == 8); 00101 BOOST_STATIC_ASSERT(min_uint8 == 0LL); 00102 BOOST_STATIC_ASSERT(max_uint8 > 0LL); 00103 00104 BOOST_STATIC_ASSERT(sizeof(sintptr) >= 4); 00105 BOOST_STATIC_ASSERT(sizeof(uintptr) >= 4); 00106 00107 class ExitException 00108 { 00109 private: 00110 std::string sReason; 00111 public: 00112 std::string* get_reason() { return &sReason; }; 00113 ExitException(std::string s) : sReason(s) { } 00114 }; 00115 00116 // WINDOWS COMPATIBILITY 00117 00118 #ifdef GCC 00119 # define PACKED_STRUCT __attribute__((packed)) 00120 # define PATH_SEP '/' 00121 00122 struct StringHash 00123 { 00124 size_t operator()( const std::string& x ) const 00125 { 00126 return EXT_NAMESPACE::hash< const char* >()( x.c_str() ); 00127 } 00128 }; 00129 00130 #else 00131 # define rint(x) int(real4(x)+0.5) 00132 # define PACKED_STRUCT 00133 # define PATH_SEP '\\' 00134 # ifndef M_PI 00135 # define M_PI 3.14159265358979323846 00136 # define M_PI_2 1.57079632679489661923 00137 # define M_PI_4 0.78539816339744830962 00138 # define M_1_PI 0.31830988618379067154 00139 # define M_2_PI 0.63661977236758134308 00140 # define M_SQRT2 1.41421356237309504880 00141 # define M_SQRT1_2 0.70710678118654752440 00142 # define srand48(n) srand((n)) 00143 # endif 00144 00145 struct StringHash : public EXT_NAMESPACE::hash_compare<std::string> 00146 { 00147 }; 00148 00149 #endif 00150 00151 #if defined GCC && defined __MINGW32__ 00152 # define srand48(n) srand((n)) 00153 #endif 00154 00155 #ifndef GCC 00156 #include "direct.h" 00157 #define getcwd _getcwd 00158 #define chdir _chdir 00159 #endif 00160 00161 // frequently used for loops 00162 // ..._DYN evaluates upper bound in each loop 00163 // ... evaluates it only once at the loop start 00164 00165 #define FOREVER for (;;) 00166 00167 // important: 2 statements => put { } around FOR in if/else/while/for blocks 00168 #define FOR(i, n) typeof(n) _=(n); for (i=0; i < _; ++i) 00169 #define FOR_DYN(i, n) for (i=0; i < (n); ++i) 00170 00171 #define FORS(i, n) for (sint4 i=0, _=(n); i < _; ++i) 00172 #define FORS_DYN(i, n) for (sint4 i=0; i < (n); ++i) 00173 00174 #define FORU(i, n) for (uint4 i=0, _=(n); i < _; ++i) 00175 #define FORU_DYN(i, n) for (uint4 i=0; i < (n); ++i) 00176 00177 #define FORS_REV(i, n) for (sint4 i=(n)-1; i >= 0; --i) 00178 00179 // infers the upper bound type 00180 #define FORT(i, n) for (typeof(n) i=0, _=(n); i < _; ++i) 00181 #define FORT_DYN(i, n) for (typeof(n) i=0; i < (n); ++i) 00182 00183 00184 // these are macros that traverse STL containers 00185 00186 // assumes container does not change 00187 #define FORALL(CONT,i) \ 00188 for (typeof((CONT).begin()) i = (CONT).begin(), _ = (CONT).end(); i != _; ++i) 00189 00190 // no increment, dynamic end 00191 #define FORALL_NI(CONT,i) \ 00192 for (typeof((CONT).begin()) i = (CONT).begin(); i != (CONT).end();) 00193 00194 // assumes container does not change and defines iterator outside of loop (B=BREAK) 00195 // ATTENTION: two lines of code => { } may be necessary! 00196 #define FORALL_B(CONT,i) \ 00197 typeof((CONT).begin()) i = (CONT).begin(); \ 00198 for (typeof((CONT).begin()) _ = (CONT).end(); i != _; ++i) \ 00199 00200 // container may change 00201 #define FORALL_DYN(CONT,i) \ 00202 for (typeof((CONT).begin()) i = (CONT).begin(); i != (CONT).end(); ++i) 00203 00204 // reverse traversal 00205 // container does not change 00206 #define FORALL_REV(CONT,i) \ 00207 for (typeof((CONT).rbegin()) i = (CONT).rbegin(), _ = (CONT).rend(); i != _; ++i) 00208 00209 // reverse traversal 00210 // assumes container does not change (BREAK version) 00211 // ATTENTION: two lines of code => { } may be necessary! 00212 #define FORALL_REV_B(CONT,i) \ 00213 typeof((CONT).rbegin()) i = (CONT).rbegin(); \ 00214 for (typeof((CONT).rbegin()) _ = (CONT).rend(); i != _; ++i) 00215 00216 // container may change 00217 #define FORALL_REV_DYN(CONT,i) \ 00218 for (typeof((CONT).rbegin()) i = (CONT).rbegin(); i != (CONT).rend(); ++i) 00219 00220 #define FIND(cont, it, elem) typeof(cont.find(elem)) it = cont.find(elem); 00221 00222 #define errstr std::cerr 00223 #define ABORT assert(0==1) 00224 00225 #if defined(__GNUC__) 00226 #define ERR(s) {\ 00227 std::stringstream ss; ss << __FILE__ << " " << __FUNCTION__ \ 00228 << "() (line " << __LINE__ << "): " << s; \ 00229 errstr << "ERROR: " << ss.str() << std::endl; \ 00230 throw ExitException(std::string(ss.str())); \ 00231 } 00232 00233 #define ERR2(s1, s2) {\ 00234 std::stringstream ss; ss << __FILE__ << " " << __FUNCTION__ \ 00235 << "() (line " << __LINE__ << "): " << s1 << " " << s2 ; \ 00236 errstr << "ERROR: " << ss.str() << std::endl; \ 00237 throw ExitException(std::string(ss.str())); \ 00238 } 00239 00240 #else 00241 #define ERR(s) {\ 00242 std::stringstream ss; ss << __FILE__ \ 00243 << " () (line " << __LINE__ << "): " << s; \ 00244 errstr << "ERROR: " << ss.str() << std::endl; \ 00245 throw ExitException(std::string(ss.str())); \ 00246 } 00247 00248 #define ERR2(s1, s2) {\ 00249 std::stringstream ss; ss << __FILE__ \ 00250 << " () (line " << __LINE__ << "): " << s1 << " " << s2 ; \ 00251 errstr << "ERROR: " << ss.str() << std::endl; \ 00252 throw ExitException(std::string(ss.str())); \ 00253 } 00254 00255 #endif 00256 00257 #define REM(x) errstr << "REMARK: " << x << std::endl; 00258 #define REM2(x,y) errstr << "REMARK: " << (x) << " " << (y) << std::endl; 00259 00260 inline sint4 my_round(real4 x) { return sint4(rint(x)); } 00261 00262 inline sint4 mult(sint4 x, sint4 y) 00263 { 00264 #ifdef GCC 00265 assert(::llabs(sint8(x)*sint8(y)) < 2000000000); 00266 #endif 00267 return x*y; 00268 } 00269 00270 inline sint8 mult(const sint8 x, const sint8 y) 00271 { 00272 assert(fabs(real8(x)*real8(y)) < 1e18); 00273 return x*y; 00274 } 00275 00276 inline uint4 square(const uint4& x) { 00277 assert(x <= 65535); 00278 return x*x; 00279 } 00280 00281 inline sint4 square(const sint4& x) { 00282 assert(abs(x) <= 46340); 00283 return x*x; 00284 } 00285 00286 inline sint8 square(const sint8& x) { 00287 #ifdef GCC 00288 assert(::llabs(x) <= 3037000499LL); 00289 #endif 00290 return x*x; 00291 } 00292 00293 inline real4 square(const real4& x) { 00294 assert(fabs(x) <= 1.84391e19); 00295 return x*x; 00296 } 00297 00298 inline real8 square(const real8& x) { 00299 assert(fabs(x) <= 1.0e150L); 00300 return x*x; 00301 } 00302 00303 template<class T> T sign(T &x) { 00304 if (x > 0) return +1; 00305 if (x < 0) return -1; 00306 return 0; 00307 } 00308 00309 template< class T> 00310 inline std::string to_string(const T & Value) 00311 { 00312 std::stringstream streamOut; 00313 streamOut << Value; 00314 return streamOut.str(); 00315 } 00316 00317 #if 0 00318 // defined in STL 00319 template <class T> void swap(T& x, T&y) { 00320 T temp = x; x = y; y = temp; 00321 } 00322 #endif 00323 00324 00325 // check whether memory ranges do not overlap (for memcpy) 00326 // ATTENTION: beware of side effects! 00327 #define NO_OVERLAP(p,q,n) assert((p)+(n) <= (q) || (p) >= (q)+(n)); 00328 00329 // SYSTEM DEPENDENT 00330 00331 #if 0 00332 # ifdef __i386__ 00333 # if __GNUC__ 00334 # define FLOAT_TO_INT(in,out) \ 00335 __asm__ __volatile__ ("fistpl %0" : "=m" (out) : "t" (in) : "st") ; 00336 # else // !__GNUC__ ( && __i386__) 00337 # define FLOAT_TO_INT(in,out) out = rint(in) 00338 # endif // __GNUC__ 00339 00340 # else // __i386__ 00341 # define FLOAT_TO_INT(in,out) out = rint(in) 00342 # endif // __i386__ 00343 #endif 00344 00345 00346 #if defined(__i386__) && __GNUC__ && !defined(__CYGWIN__) 00347 00348 #include <fenv.h> 00349 00350 #define FAST_ROUND 1 00351 00352 #define ROUND_REAL8_TO_SINT4(in,out) \ 00353 __asm__ __volatile__ ("fistpl %0" : "=m" (out) : "t" (in) : "st") ; 00354 00355 #define ROUND_TO_NEAREST fesetround(FE_TONEAREST) 00356 #define ROUND_DOWNWARD fesetround(FE_DOWNWARD) 00357 #define ROUND_UPWARD fesetround(FE_UPWARD) 00358 #define ROUND_TOWARD_0 fesetround(FE_TOWARDZERO) 00359 #define ROUND_DEFAULT fesetround(FE_TONEAREST) 00360 00361 #define ASSERT_DEFAULT assert(fegetround() == FE_TONEAREST) 00362 00363 #else 00364 00365 #define FAST_ROUND 0 00366 #define ROUND_REAL8_TO_SINT4(in,out) out = (int)rint(in) 00367 00368 #endif 00369 00370 extern std::string sanitize_path(const std::string &fp); 00371 00372 extern char *alloc_sprintf(const char *fmt, ...); 00373 extern char *alloc_sprintf(const char *fmt, va_list ap); 00374 extern std::ostream &form(std::ostream& os, const char* fmt, ... ); 00375 extern std::ostream &form(std::ostream& os, const char* fmt, va_list ap); 00376 00377 // tokenize string into parts separated by a delimiter 00378 // creates empty strings for consecutive delimters 00379 extern void tokenize(const std::string& str, 00380 Vector<std::string>& tokens, 00381 const std::string& delimiters = " "); 00382 00383 extern bool gdb; // set to -gdb option in main() 00384 00385 // requires the above definitions 00386 // but we need this here to give every function access to random 00387 00388 #include "Typeof.H" 00389 00390 #endif