00001 #ifndef SimTK_SimTKCOMMON_COMMON_H_
00002 #define SimTK_SimTKCOMMON_COMMON_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00048
00049
00060
00061
00062
00085
00086
00087
00088
00089
00090
00098 #ifndef SimTK_DEFAULT_PRECISION
00099 # define SimTK_DEFAULT_PRECISION 2
00100 #endif
00101
00102 #if (SimTK_DEFAULT_PRECISION == 1)
00103
00104 typedef float SimTK_Real;
00105 #elif (SimTK_DEFAULT_PRECISION == 2)
00106
00107 typedef double SimTK_Real;
00108 #elif (SimTK_DEFAULT_PRECISION == 4)
00109
00110 typedef long double SimTK_Real;
00111 #else
00112 #error ILLEGAL VALUE FOR DEFAULT PRECISION
00113 #endif
00114
00115 #ifndef NDEBUG
00116 #if defined(__cplusplus)
00117 #include <cstdio>
00118 #define SimTK_DEBUG(s) std::printf("DBG: " s)
00119 #define SimTK_DEBUG1(s,a1) std::printf("DBG: " s,a1)
00120 #define SimTK_DEBUG2(s,a1,a2) std::printf("DBG: " s,a1,a2)
00121 #define SimTK_DEBUG3(s,a1,a2,a3) std::printf("DBG: " s,a1,a2,a3)
00122 #define SimTK_DEBUG4(s,a1,a2,a3,a4) std::printf("DBG: " s,a1,a2,a3,a4)
00123 #else
00124 #include <stdio.h>
00125 #define SimTK_DEBUG(s) printf("DBG: " s)
00126 #define SimTK_DEBUG1(s,a1) printf("DBG: " s,a1)
00127 #define SimTK_DEBUG2(s,a1,a2) printf("DBG: " s,a1,a2)
00128 #define SimTK_DEBUG3(s,a1,a2,a3) printf("DBG: " s,a1,a2,a3)
00129 #define SimTK_DEBUG4(s,a1,a2,a3,a4) printf("DBG: " s,a1,a2,a3,a4)
00130 #endif
00131 #else
00132 #define SimTK_DEBUG(s)
00133 #define SimTK_DEBUG1(s,a1)
00134 #define SimTK_DEBUG2(s,a1,a2)
00135 #define SimTK_DEBUG3(s,a1,a2,a3)
00136 #define SimTK_DEBUG4(s,a1,a2,a3,a4)
00137 #endif
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 #ifdef _WIN32
00160 #ifdef _MSC_VER
00161 #pragma warning(disable:4231) // need to use 'extern' template explicit instantiation
00162 #pragma warning(disable:4251) // no DLL interface for type of member of exported class
00163 #endif
00164 #if defined(SimTK_SimTKCOMMON_BUILDING_SHARED_LIBRARY)
00165 #define SimTK_SimTKCOMMON_EXPORT __declspec(dllexport)
00166
00167 #ifdef _MSC_VER
00168 #pragma warning(disable:4661)
00169 #endif
00170 #elif defined(SimTK_SimTKCOMMON_BUILDING_STATIC_LIBRARY) || defined(SimTK_USE_STATIC_LIBRARIES)
00171 #define SimTK_SimTKCOMMON_EXPORT
00172 #else
00173 #define SimTK_SimTKCOMMON_EXPORT __declspec(dllimport) // i.e., a client of a shared library
00174 #endif
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 #else
00191 #define SimTK_SimTKCOMMON_EXPORT // Linux, Mac
00192 #endif
00193
00194
00195
00196
00197 #if defined(__cplusplus)
00198 extern "C" {
00199 #endif
00200
00201 SimTK_SimTKCOMMON_EXPORT void SimTK_version_SimTKcommon(int* major, int* minor, int* build);
00208 SimTK_SimTKCOMMON_EXPORT void SimTK_about_SimTKcommon(const char* key, int maxlen, char* value);
00209 #if defined(__cplusplus)
00210 }
00211 #endif
00212
00213
00214
00215
00216
00217 #if defined(__cplusplus)
00218
00219 #include <cstddef>
00220 #include <cassert>
00221 #include <cmath>
00222 #include <cfloat>
00223 #include <complex>
00224 #include <limits>
00225 #include <typeinfo>
00226
00227
00228
00229
00230
00231
00232 #ifdef _MSC_VER
00233 namespace std {
00234 inline bool isfinite(float f) {return _finite(f) != 0;}
00235 inline bool isfinite(double d) {return _finite(d) != 0;}
00236 inline bool isfinite(long double l) {return _finite(l) != 0;}
00237 inline bool isnan(float f) {return _isnan(f) != 0;}
00238 inline bool isnan(double d) {return _isnan(d) != 0;}
00239 inline bool isnan(long double l) {return _isnan(l) != 0;}
00240 inline bool isinf(float f) {return std::abs(f)==std::numeric_limits<float>::infinity();}
00241 inline bool isinf(double d) {return std::abs(d)==std::numeric_limits<double>::infinity();}
00242 inline bool isinf(long double l) {return std::abs(l)==std::numeric_limits<double>::infinity();}
00243 inline bool signbit(float f) {return (*reinterpret_cast<unsigned*>(&f) & 0x80000000U) != 0;}
00244 inline bool signbit(double d) {return (*reinterpret_cast<unsigned long long*>(&d)
00245 & 0x8000000000000000ULL) != 0;}
00246 inline bool signbit(long double l) {return (*reinterpret_cast<unsigned long long*>(&l)
00247 & 0x8000000000000000ULL) != 0;}
00248 }
00249 #endif
00250
00251
00252 namespace SimTK {
00253
00254
00255 inline bool canStoreInInt(char) {return true;}
00256 inline bool canStoreInInt(unsigned char) {return true;}
00257 inline bool canStoreInInt(signed char) {return true;}
00258 inline bool canStoreInInt(short) {return true;}
00259 inline bool canStoreInInt(unsigned short) {return true;}
00260 inline bool canStoreInInt(int) {return true;}
00261 inline bool canStoreInInt(unsigned int u) {return (unsigned int)(int(u)) == u;}
00262 inline bool canStoreInInt(long i) {return long(int(i)) == i;}
00263 inline bool canStoreInInt(unsigned long u) {return (unsigned long)(int(u)) == u;}
00264
00265
00266
00267 inline bool canStoreInNonnegativeInt(char c) {return c >= 0;}
00268 inline bool canStoreInNonnegativeInt(unsigned char c) {return true;}
00269 inline bool canStoreInNonnegativeInt(signed char c) {return c >= 0;}
00270 inline bool canStoreInNonnegativeInt(short s) {return s >= 0;}
00271 inline bool canStoreInNonnegativeInt(unsigned short s) {return true;}
00272 inline bool canStoreInNonnegativeInt(int i) {return i >= 0;}
00273 inline bool canStoreInNonnegativeInt(long l) {return canStoreInInt(l) && l >= 0;}
00274 inline bool canStoreInNonnegativeInt(unsigned int u) {return canStoreInInt(u);}
00275 inline bool canStoreInNonnegativeInt(unsigned long u) {return canStoreInInt(u);}
00276
00277
00278
00279
00280 static const int InvalidIndex = -1111111111;
00281 }
00282
00312
00313
00314 #define SimTK_DEFINE_UNIQUE_INDEX_TYPE(NAME) \
00315 SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,,,NAME) \
00316 static const NAME Invalid ## NAME;
00317
00320 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_INDEX_TYPE(EXPORT,NAME) \
00321 SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,,,NAME) \
00322 static const NAME Invalid ## NAME;
00323
00325 #define SimTK_DEFINE_UNIQUE_LOCAL_INDEX_TYPE(PARENT,NAME) \
00326 SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,PARENT,::,NAME)
00327
00330 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,PARENT,SEP,NAME) \
00331 class EXPORT NAME { \
00332 int ix; \
00333 public: \
00334 NAME() : ix(SimTK::InvalidIndex) { } \
00335 explicit NAME(int i) : ix(i) {assert(i>=0 || i==SimTK::InvalidIndex);} \
00336 explicit NAME(long l): ix((int)l) {assert(SimTK::canStoreInNonnegativeInt(l));} \
00337 explicit NAME(unsigned int u) : ix((int)u) {assert(SimTK::canStoreInInt(u));} \
00338 explicit NAME(unsigned long ul) : ix((int)ul) {assert(SimTK::canStoreInInt(ul));} \
00339 operator int() const {return ix;} \
00340 bool isValid() const {return ix>=0;} \
00341 bool isValidExtended() const {return ix>=-1;} \
00342 void invalidate(){ix=SimTK::InvalidIndex;} \
00343 \
00344 bool operator==(int i) const {assert(isValidExtended() && isValidExtended(i)); return ix==i;} \
00345 bool operator==(long l) const {assert(isValidExtended() && isValidExtended(l)); return ix==(int)l;} \
00346 bool operator==(unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix==(int)u;} \
00347 bool operator==(unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix==(int)ul;} \
00348 bool operator!=(int i) const {return !operator==(i);} \
00349 bool operator!=(long l) const {return !operator==(l);} \
00350 bool operator!=(unsigned int u) const {return !operator==(u);} \
00351 bool operator!=(unsigned long ul) const {return !operator==(ul);} \
00352 \
00353 bool operator< (int i) const {assert(isValidExtended() && isValidExtended(i)); return ix<i;} \
00354 bool operator< (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix<(int)l;} \
00355 bool operator< (unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix<(int)u;} \
00356 bool operator< (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix<(int)ul;} \
00357 bool operator>=(int i) const {return !operator<(i);} \
00358 bool operator>=(long l) const {return !operator<(l);} \
00359 bool operator>=(unsigned int u) const {return !operator<(u);} \
00360 bool operator>=(unsigned long ul) const {return !operator<(ul);} \
00361 \
00362 bool operator> (int i) const {assert(isValidExtended() && isValidExtended(i)); return ix>i;} \
00363 bool operator> (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix>(int)l;} \
00364 bool operator> (unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix>(int)u;} \
00365 bool operator> (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix>(int)ul;} \
00366 bool operator<=(int i) const {return !operator>(i);} \
00367 bool operator<=(long l) const {return !operator>(l);} \
00368 bool operator<=(unsigned int u) const {return !operator>(u);} \
00369 bool operator<=(unsigned long ul) const {return !operator>(ul);} \
00370 \
00371 const NAME& operator++() {assert(isValid()); ++ix; return *this;} \
00372 NAME operator++(int) {assert(isValid()); ++ix; return NAME(ix-1);} \
00373 const NAME& operator--() {assert(isValid()); --ix; return *this;} \
00374 NAME operator--(int) {assert(isValid()); --ix; return NAME(ix+1);} \
00375 \
00376 NAME& operator+=(int i) {assert(isValid() && isValidExtended(ix+i)); ix+=i; return *this;} \
00377 NAME& operator-=(int i) {assert(isValid() && isValidExtended(ix-i)); ix-=i; return *this;} \
00378 NAME& operator+=(long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix+(int)l)); ix+=(int)l; return *this;} \
00379 NAME& operator-=(long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix-(int)l)); ix-=(int)l; return *this;} \
00380 NAME& operator+=(unsigned int u) {assert(isValid()&& SimTK::canStoreInInt(u) && isValid(ix+(int)u)); ix+=(int)u; return *this;} \
00381 NAME& operator-=(unsigned int u) {assert(isValid()&& SimTK::canStoreInInt(u) && isValidExtended(ix-(int)u)); ix-=(int)u; return *this;} \
00382 NAME& operator+=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValid(ix+(int)ul)); ix+=(int)ul; return *this;} \
00383 NAME& operator-=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValidExtended(ix-(int)ul)); ix-=(int)ul; return *this;} \
00384 \
00385 static const NAME& Invalid() {static const NAME invalid; return invalid;} \
00386 static bool isValid(int i) {return i>=0;} \
00387 static bool isValid(long l) {return SimTK::canStoreInNonnegativeInt(l);} \
00388 static bool isValid(unsigned int u) {return SimTK::canStoreInInt(u);} \
00389 static bool isValid(unsigned long ul) {return SimTK::canStoreInInt(ul);} \
00390 static bool isValidExtended(int i) {return i>=-1;} \
00391 static bool isValidExtended(long l) {return SimTK::canStoreInInt(l) && l>=-1;} \
00392 };
00393
00399 #define SimTK_DOWNCAST(Derived,Parent) \
00400 static bool isA(const Parent& p) \
00401 { return dynamic_cast<const Derived*>(&p) != 0; } \
00402 static const Derived& downcast(const Parent& p) \
00403 { return dynamic_cast<const Derived&>(p); } \
00404 static Derived& updDowncast(Parent& p) \
00405 { return dynamic_cast<Derived&>(p); } \
00406 static Derived& downcast(Parent& p) \
00407 { return dynamic_cast<Derived&>(p); }
00408
00413 #define SimTK_DOWNCAST2(Derived,Helper,Parent) \
00414 static bool isA(const Parent& p) \
00415 { return Helper::isA(p); } \
00416 static const Derived& downcast(const Parent& p) \
00417 { return reinterpret_cast<const Derived&>(Helper::downcast(p)); } \
00418 static Derived& updDowncast(Parent& p) \
00419 { return reinterpret_cast<Derived&>(Helper::downcast(p)); } \
00420 static Derived& downcast(Parent& p) \
00421 { return reinterpret_cast<Derived&>(Helper::downcast(p)); }
00422
00423
00424
00425
00426
00427 #define SimTK_PIMPL_DOWNCAST(Derived, Parent) \
00428 static bool isInstanceOf(const Parent&); \
00429 static const Derived& downcast(const Parent&); \
00430 static Derived& updDowncast(Parent&)
00431
00432 namespace SimTK {
00433
00434 namespace Options { }
00435 namespace Exception { }
00436
00440 typedef SimTK_Real Real;
00444 typedef std::complex<Real> Complex;
00445
00448 struct Segment {
00449 Segment() : length(0), offset(0) { }
00450 explicit Segment(int l, int ofs=0) : length(l), offset(ofs) {
00451 assert(l>=0 && ofs>=0);
00452 }
00453
00454 int length;
00455 int offset;
00456 };
00457
00458 template <class T> class TypeInfo {
00459 public:
00460 static const char* name() {return typeid(T).name();}
00461 };
00462
00463 #define SimTK_TYPEINFO_SPECIALIZE(T) \
00464 template <> class TypeInfo< T > { \
00465 public: \
00466 static const char* name() { return #T; } \
00467 };
00468
00469 SimTK_TYPEINFO_SPECIALIZE(bool); SimTK_TYPEINFO_SPECIALIZE(signed char);
00470 SimTK_TYPEINFO_SPECIALIZE(char); SimTK_TYPEINFO_SPECIALIZE(unsigned char);
00471 SimTK_TYPEINFO_SPECIALIZE(short); SimTK_TYPEINFO_SPECIALIZE(int);
00472 SimTK_TYPEINFO_SPECIALIZE(long);
00473 SimTK_TYPEINFO_SPECIALIZE(unsigned short); SimTK_TYPEINFO_SPECIALIZE(unsigned int);
00474 SimTK_TYPEINFO_SPECIALIZE(unsigned long);
00475 SimTK_TYPEINFO_SPECIALIZE(float); SimTK_TYPEINFO_SPECIALIZE(double);
00476 SimTK_TYPEINFO_SPECIALIZE(long double);
00477 SimTK_TYPEINFO_SPECIALIZE(std::complex<float>);
00478 SimTK_TYPEINFO_SPECIALIZE(std::complex<double>);
00479 SimTK_TYPEINFO_SPECIALIZE(std::complex<long double>);
00480
00481
00482 }
00483
00484 namespace SimTKimpl {
00485
00488 typedef void* (*IndexT)(void* tp, int n);
00489 typedef const void* (*IndexConstT)(const void* tp, int n);
00490 typedef void* (*CreateOneT)(const void* iptr);
00491 typedef void (*DestructOneT)(void*& tvptr);
00492 typedef void (*AssignArrayOfT)(void* dest, const void* src, int n);
00493 typedef void (*SetT)(void* dest, const void* valuep, int n);
00494 typedef void* (*CreateArrayOfT)(int n, const void* iptr);
00495 typedef void (*DestructArrayOfT)(void*& tvptr);
00497
00498 struct TypeManipulatorT {
00499 TypeManipulatorT(int z, IndexT it, IndexConstT ict,
00500 CreateOneT c1t, DestructOneT d1t, AssignArrayOfT aat, SetT st,
00501 CreateArrayOfT cat, DestructArrayOfT dat)
00502 : sizeOfT(z), indexT(it), indexConstT(ict),
00503 createOneT(c1t), destructOneT(d1t), assignArrayOfT(aat), setT(st),
00504 createArrayOfT(cat), destructArrayOfT(dat)
00505 { }
00506
00507 bool operator==(const TypeManipulatorT& t) const
00508 { return sizeOfT==t.sizeOfT && indexT==t.indexT; }
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519 const int sizeOfT;
00520 const IndexT indexT;
00521 const IndexConstT indexConstT;
00522 const CreateOneT createOneT;
00523 const DestructOneT destructOneT;
00524 const AssignArrayOfT assignArrayOfT;
00525 const SetT setT;
00526 const CreateArrayOfT createArrayOfT;
00527 const DestructArrayOfT destructArrayOfT;
00528 };
00529
00544 template <class T> class MakeTypeManipulator {
00545 public:
00546 MakeTypeManipulator() { }
00547
00548
00549 static const TypeManipulatorT& getTypeManipulatorT() { return manipT; }
00550 static T& updAs(void* v)
00551 { assert(v); return *reinterpret_cast<T*>(v); }
00552 static const T& getAs(const void* v)
00553 { assert(v); return *reinterpret_cast<const T*>(v); }
00554
00555 private:
00561 static int sizeT() { return (int)sizeof(T); }
00562
00567 static void* indexT(void* tp, int n)
00568 { return (void*)(reinterpret_cast<T*>(tp) + n); }
00569 static const void* indexConstT(const void* tp, int n)
00570 { return (const void*)(reinterpret_cast<const T*>(tp) + n); }
00572
00576 static void* createOneT(const void* iptr=0)
00577 {
00578 T* tptr = new T;
00579 if (iptr) *tptr = *reinterpret_cast<const T*>(iptr);
00580 return tptr;
00581 }
00582
00585 static void destructOneT(void*& tvptr)
00586 {
00587 T* tptr = reinterpret_cast<T*>(tvptr);
00588 delete tptr;
00589 tvptr = 0;
00590 }
00591
00597 static void assignArrayOfT(void* dest, const void* src, int n)
00598 { assert(n>=0);
00599 if (n==0) return;
00600 assert(dest && src);
00601 assert(indexT(dest,n) < src || indexConstT(src,n) < dest);
00602 T* d = reinterpret_cast<T*>(dest);
00603 const T* s = reinterpret_cast<const T*>(src);
00604 for (int i=0; i < n; ++i) *d++ = *s++;
00605 }
00606
00611 static void setT(void* dest, const void* valuep, int n=1)
00612 { assert(n>=0);
00613 if (n==0) return;
00614 assert(dest && valuep);
00615 T* d = reinterpret_cast<T*>(dest);
00616 const T& v = *reinterpret_cast<const T*>(valuep);
00617 for (int i=0; i < n; ++i) *d++ = v;
00618 }
00619
00622 static void* createArrayOfT(int n, const void* iptr=0)
00623 { assert(n>=0);
00624 if (n == 0) return 0;
00625 T* tptr = new T[n];
00626 if (iptr) {
00627 const T& init = *reinterpret_cast<const T*>(iptr);
00628 for (int i=0; i < n; ++i) tptr[i] = init;
00629 }
00630 return tptr;
00631 }
00632
00637 static void destructArrayOfT(void*& tvptr)
00638 {
00639 T* tptr = reinterpret_cast<T*>(tvptr);
00640 delete[] tptr;
00641 tvptr = 0;
00642 }
00643
00644 private:
00645 static const TypeManipulatorT manipT;
00646 };
00647
00648 template <class T> const TypeManipulatorT
00649 MakeTypeManipulator<T>::manipT = TypeManipulatorT(
00650 (int)sizeof(T),indexT,indexConstT,
00651 createOneT, destructOneT, assignArrayOfT, setT,
00652 createArrayOfT, destructArrayOfT);
00653 }
00654
00655
00656 #endif
00657
00658 #endif