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
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 #ifndef SimTK_DEFAULT_PRECISION
00062 # define SimTK_DEFAULT_PRECISION 2
00063 #endif
00064
00065
00066 #if (SimTK_DEFAULT_PRECISION == 1)
00067 typedef float SimTK_Real;
00068 #elif (SimTK_DEFAULT_PRECISION == 2)
00069 typedef double SimTK_Real;
00070 #elif (SimTK_DEFAULT_PRECISION == 4)
00071 typedef long double SimTK_Real;
00072 #else
00073 #error ILLEGAL VALUE FOR DEFAULT PRECISION
00074 #endif
00075
00076 #ifndef NDEBUG
00077 #if defined(__cplusplus)
00078 #include <cstdio>
00079 #define SimTK_DEBUG(s) std::printf("DBG: " s)
00080 #define SimTK_DEBUG1(s,a1) std::printf("DBG: " s,a1)
00081 #define SimTK_DEBUG2(s,a1,a2) std::printf("DBG: " s,a1,a2)
00082 #define SimTK_DEBUG3(s,a1,a2,a3) std::printf("DBG: " s,a1,a2,a3)
00083 #define SimTK_DEBUG4(s,a1,a2,a3,a4) std::printf("DBG: " s,a1,a2,a3,a4)
00084 #else
00085 #include <stdio.h>
00086 #define SimTK_DEBUG(s) printf("DBG: " s)
00087 #define SimTK_DEBUG1(s,a1) printf("DBG: " s,a1)
00088 #define SimTK_DEBUG2(s,a1,a2) printf("DBG: " s,a1,a2)
00089 #define SimTK_DEBUG3(s,a1,a2,a3) printf("DBG: " s,a1,a2,a3)
00090 #define SimTK_DEBUG4(s,a1,a2,a3,a4) printf("DBG: " s,a1,a2,a3,a4)
00091 #endif
00092 #else
00093 #define SimTK_DEBUG(s)
00094 #define SimTK_DEBUG1(s,a1)
00095 #define SimTK_DEBUG2(s,a1,a2)
00096 #define SimTK_DEBUG3(s,a1,a2,a3)
00097 #define SimTK_DEBUG4(s,a1,a2,a3,a4)
00098 #endif
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 #ifdef WIN32
00121 #if defined(SimTK_SimTKCOMMON_BUILDING_SHARED_LIBRARY)
00122 #define SimTK_SimTKCOMMON_EXPORT __declspec(dllexport)
00123 #elif defined(SimTK_SimTKCOMMON_BUILDING_STATIC_LIBRARY) || defined(SimTK_USE_STATIC_LIBRARIES)
00124 #define SimTK_SimTKCOMMON_EXPORT
00125 #else
00126 #define SimTK_SimTKCOMMON_EXPORT __declspec(dllimport) // i.e., a client of a shared library
00127 #endif
00128 #else
00129 #define SimTK_SimTKCOMMON_EXPORT // Linux, Mac
00130 #endif
00131
00132
00133
00134
00135 #if defined(__cplusplus)
00136 extern "C" {
00137 #endif
00138 SimTK_SimTKCOMMON_EXPORT void SimTK_version_SimTKcommon(int* major, int* minor, int* build);
00139 SimTK_SimTKCOMMON_EXPORT void SimTK_about_SimTKcommon(const char* key, int maxlen, char* value);
00140 #if defined(__cplusplus)
00141 }
00142 #endif
00143
00144
00145
00146
00147
00148 #if defined(__cplusplus)
00149
00150 #include <cstddef>
00151 #include <cassert>
00152 #include <complex>
00153 #include <limits>
00154
00183 namespace SimTK {
00184 static const int InvalidIndex = -1111111111;
00185 }
00186
00189 #define SimTK_DEFINE_UNIQUE_INDEX_TYPE(NAME) \
00190 SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,,,NAME) \
00191 static const NAME Invalid ## NAME;
00192
00195 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_INDEX_TYPE(EXPORT,NAME) \
00196 SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,,,NAME) \
00197 static const NAME Invalid ## NAME;
00198
00200 #define SimTK_DEFINE_UNIQUE_LOCAL_INDEX_TYPE(PARENT,NAME) \
00201 SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,PARENT,::,NAME)
00202
00205 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,PARENT,SEP,NAME) \
00206 class EXPORT NAME { \
00207 int ix; \
00208 public: \
00209 NAME() : ix(SimTK::InvalidIndex) { } \
00210 explicit NAME(int i) : ix(i) {assert(i>=0 || i==SimTK::InvalidIndex);} \
00211 explicit NAME(long l): ix((int)l) {assert(canStoreInNonnegativeInt(l));} \
00212 explicit NAME(unsigned int u) : ix((int)u) {assert(canStoreInInt(u));} \
00213 explicit NAME(unsigned long ul) : ix((int)ul) {assert(canStoreInInt(ul));} \
00214 operator int() const {return ix;} \
00215 bool isValid() const {return ix>=0;} \
00216 bool isValidExtended() const {return ix>=-1;} \
00217 void invalidate(){ix=SimTK::InvalidIndex;} \
00218 \
00219 bool operator==(int i) const {assert(isValidExtended() && isValidExtended(i)); return ix==i;} \
00220 bool operator==(long l) const {assert(isValidExtended() && isValidExtended(l)); return ix==(int)l;} \
00221 bool operator==(unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix==(int)u;} \
00222 bool operator==(unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix==(int)ul;} \
00223 bool operator!=(int i) const {return !operator==(i);} \
00224 bool operator!=(long l) const {return !operator==(l);} \
00225 bool operator!=(unsigned int u) const {return !operator==(u);} \
00226 bool operator!=(unsigned long ul) const {return !operator==(ul);} \
00227 \
00228 bool operator< (int i) const {assert(isValidExtended() && isValidExtended(i)); return ix<i;} \
00229 bool operator< (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix<(int)l;} \
00230 bool operator< (unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix<(int)u;} \
00231 bool operator< (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix<(int)ul;} \
00232 bool operator>=(int i) const {return !operator<(i);} \
00233 bool operator>=(long l) const {return !operator<(l);} \
00234 bool operator>=(unsigned int u) const {return !operator<(u);} \
00235 bool operator>=(unsigned long ul) const {return !operator<(ul);} \
00236 \
00237 bool operator> (int i) const {assert(isValidExtended() && isValidExtended(i)); return ix>i;} \
00238 bool operator> (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix>(int)l;} \
00239 bool operator> (unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix>(int)u;} \
00240 bool operator> (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix>(int)ul;} \
00241 bool operator<=(int i) const {return !operator>(i);} \
00242 bool operator<=(long l) const {return !operator>(l);} \
00243 bool operator<=(unsigned int u) const {return !operator>(u);} \
00244 bool operator<=(unsigned long ul) const {return !operator>(ul);} \
00245 \
00246 const NAME& operator++() {assert(isValid()); ++ix; return *this;} \
00247 NAME operator++(int) {assert(isValid()); ++ix; return NAME(ix-1);} \
00248 const NAME& operator--() {assert(isValid()); --ix; return *this;} \
00249 NAME operator--(int) {assert(isValid()); --ix; return NAME(ix+1);} \
00250 \
00251 NAME& operator+=(int i) {assert(isValid() && isValidExtended(ix+i)); ix+=i; return *this;} \
00252 NAME& operator-=(int i) {assert(isValid() && isValidExtended(ix-i)); ix-=i; return *this;} \
00253 NAME& operator+=(long l) {assert(isValid() && canStoreInInt(l) && isValidExtended(ix+(int)l)); ix+=(int)l; return *this;} \
00254 NAME& operator-=(long l) {assert(isValid() && canStoreInInt(l) && isValidExtended(ix-(int)l)); ix-=(int)l; return *this;} \
00255 NAME& operator+=(unsigned int u) {assert(isValid()&& canStoreInInt(u) && isValid(ix+(int)u)); ix+=(int)u; return *this;} \
00256 NAME& operator-=(unsigned int u) {assert(isValid()&& canStoreInInt(u) && isValidExtended(ix-(int)u)); ix-=(int)u; return *this;} \
00257 NAME& operator+=(unsigned long ul) {assert(isValid()&& canStoreInInt(ul) && isValid(ix+(int)ul)); ix+=(int)ul; return *this;} \
00258 NAME& operator-=(unsigned long ul) {assert(isValid()&& canStoreInInt(ul) && isValidExtended(ix-(int)ul)); ix-=(int)ul; return *this;} \
00259 \
00260 static const NAME& Invalid() {static const NAME invalid; return invalid;} \
00261 static bool isValid(int i) {return i>=0;} \
00262 static bool isValid(long l) {return canStoreInNonnegativeInt(l);} \
00263 static bool isValid(unsigned int u) {return canStoreInInt(u);} \
00264 static bool isValid(unsigned long ul) {return canStoreInInt(ul);} \
00265 static bool isValidExtended(int i) {return i>=-1;} \
00266 static bool isValidExtended(long l) {return canStoreInInt(l) && l>=-1;} \
00267 };
00268
00274 #define SimTK_DOWNCAST(Derived,Parent) \
00275 static bool isA(const Parent& p) \
00276 { return dynamic_cast<const Derived*>(&p) != 0; } \
00277 static const Derived& downcast(const Parent& p) \
00278 { return dynamic_cast<const Derived&>(p); } \
00279 static Derived& downcast(Parent& p) \
00280 { return dynamic_cast<Derived&>(p); }
00281
00286 #define SimTK_DOWNCAST2(Derived,Helper,Parent) \
00287 static bool isA(const Parent& p) \
00288 { return Helper::isA(p); } \
00289 static const Derived& downcast(const Parent& p) \
00290 { return reinterpret_cast<const Derived&>(Helper::downcast(p)); } \
00291 static Derived& downcast(Parent& p) \
00292 { return reinterpret_cast<Derived&>(Helper::downcast(p)); }
00293
00294
00295
00296
00297
00298 #define SimTK_PIMPL_DOWNCAST(Derived, Parent) \
00299 static bool isInstanceOf(const Parent&); \
00300 static const Derived& downcast(const Parent&); \
00301 static Derived& updDowncast(Parent&)
00302
00303 namespace SimTK {
00304
00305 namespace Options { }
00306 namespace Exception { }
00307
00308 typedef SimTK_Real Real;
00309 typedef std::complex<Real> Complex;
00310
00311 struct Segment {
00312 Segment() : length(0), offset(0) { }
00313 explicit Segment(int l, int ofs=0) : length(l), offset(ofs) {
00314 assert(l>=0 && ofs>=0);
00315 }
00316
00317 int length;
00318 int offset;
00319 };
00320
00321 template <class T> class TypeInfo {
00322 public:
00323 static const char* name() {return typeid(T).name();}
00324 };
00325
00326 #define SimTK_TYPEINFO_SPECIALIZE(T) \
00327 template <> class TypeInfo< T > { \
00328 public: \
00329 static const char* name() { return #T; } \
00330 };
00331
00332 SimTK_TYPEINFO_SPECIALIZE(bool); SimTK_TYPEINFO_SPECIALIZE(signed char);
00333 SimTK_TYPEINFO_SPECIALIZE(char); SimTK_TYPEINFO_SPECIALIZE(unsigned char);
00334 SimTK_TYPEINFO_SPECIALIZE(short); SimTK_TYPEINFO_SPECIALIZE(int);
00335 SimTK_TYPEINFO_SPECIALIZE(long);
00336 SimTK_TYPEINFO_SPECIALIZE(unsigned short); SimTK_TYPEINFO_SPECIALIZE(unsigned int);
00337 SimTK_TYPEINFO_SPECIALIZE(unsigned long);
00338 SimTK_TYPEINFO_SPECIALIZE(float); SimTK_TYPEINFO_SPECIALIZE(double);
00339 SimTK_TYPEINFO_SPECIALIZE(long double);
00340 SimTK_TYPEINFO_SPECIALIZE(std::complex<float>);
00341 SimTK_TYPEINFO_SPECIALIZE(std::complex<double>);
00342 SimTK_TYPEINFO_SPECIALIZE(std::complex<long double>);
00343
00344
00345 }
00346
00347 namespace SimTKimpl {
00348
00351 typedef void* (*IndexT)(void* tp, int n);
00352 typedef const void* (*IndexConstT)(const void* tp, int n);
00353 typedef void* (*CreateOneT)(const void* iptr);
00354 typedef void (*DestructOneT)(void*& tvptr);
00355 typedef void (*AssignArrayOfT)(void* dest, const void* src, int n);
00356 typedef void (*SetT)(void* dest, const void* valuep, int n);
00357 typedef void* (*CreateArrayOfT)(int n, const void* iptr);
00358 typedef void (*DestructArrayOfT)(void*& tvptr);
00360
00361 struct TypeManipulatorT {
00362 TypeManipulatorT(int z, IndexT it, IndexConstT ict,
00363 CreateOneT c1t, DestructOneT d1t, AssignArrayOfT aat, SetT st,
00364 CreateArrayOfT cat, DestructArrayOfT dat)
00365 : sizeOfT(z), indexT(it), indexConstT(ict),
00366 createOneT(c1t), destructOneT(d1t), assignArrayOfT(aat), setT(st),
00367 createArrayOfT(cat), destructArrayOfT(dat)
00368 { }
00369
00370 bool operator==(const TypeManipulatorT& t) const
00371 { return sizeOfT==t.sizeOfT && indexT==t.indexT; }
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 const int sizeOfT;
00383 const IndexT indexT;
00384 const IndexConstT indexConstT;
00385 const CreateOneT createOneT;
00386 const DestructOneT destructOneT;
00387 const AssignArrayOfT assignArrayOfT;
00388 const SetT setT;
00389 const CreateArrayOfT createArrayOfT;
00390 const DestructArrayOfT destructArrayOfT;
00391 };
00392
00407 template <class T> class MakeTypeManipulator {
00408 public:
00409 MakeTypeManipulator() { }
00410
00411
00412 static const TypeManipulatorT& getTypeManipulatorT() { return manipT; }
00413 static T& updAs(void* v)
00414 { assert(v); return *reinterpret_cast<T*>(v); }
00415 static const T& getAs(const void* v)
00416 { assert(v); return *reinterpret_cast<const T*>(v); }
00417
00418 private:
00424 static int sizeT() { return (int)sizeof(T); }
00425
00430 static void* indexT(void* tp, int n)
00431 { return (void*)(reinterpret_cast<T*>(tp) + n); }
00432 static const void* indexConstT(const void* tp, int n)
00433 { return (const void*)(reinterpret_cast<const T*>(tp) + n); }
00435
00439 static void* createOneT(const void* iptr=0)
00440 {
00441 T* tptr = new T;
00442 if (iptr) *tptr = *reinterpret_cast<const T*>(iptr);
00443 return tptr;
00444 }
00445
00448 static void destructOneT(void*& tvptr)
00449 {
00450 T* tptr = reinterpret_cast<T*>(tvptr);
00451 delete tptr;
00452 tvptr = 0;
00453 }
00454
00460 static void assignArrayOfT(void* dest, const void* src, int n)
00461 { assert(n>=0);
00462 if (n==0) return;
00463 assert(dest && src);
00464 assert(indexT(dest,n) < src || indexConstT(src,n) < dest);
00465 T* d = reinterpret_cast<T*>(dest);
00466 const T* s = reinterpret_cast<const T*>(src);
00467 for (int i=0; i < n; ++i) *d++ = *s++;
00468 }
00469
00474 static void setT(void* dest, const void* valuep, int n=1)
00475 { assert(n>=0);
00476 if (n==0) return;
00477 assert(dest && valuep);
00478 T* d = reinterpret_cast<T*>(dest);
00479 const T& v = *reinterpret_cast<const T*>(valuep);
00480 for (int i=0; i < n; ++i) *d++ = v;
00481 }
00482
00485 static void* createArrayOfT(int n, const void* iptr=0)
00486 { assert(n>=0);
00487 if (n == 0) return 0;
00488 T* tptr = new T[n];
00489 if (iptr) {
00490 const T& init = *reinterpret_cast<const T*>(iptr);
00491 for (int i=0; i < n; ++i) tptr[i] = init;
00492 }
00493 return tptr;
00494 }
00495
00500 static void destructArrayOfT(void*& tvptr)
00501 {
00502 T* tptr = reinterpret_cast<T*>(tvptr);
00503 delete[] tptr;
00504 tvptr = 0;
00505 }
00506
00507 private:
00508 static const TypeManipulatorT manipT;
00509 };
00510
00511 template <class T> const TypeManipulatorT
00512 MakeTypeManipulator<T>::manipT = TypeManipulatorT(
00513 (int)sizeof(T),indexT,indexConstT,
00514 createOneT, destructOneT, assignArrayOfT, setT,
00515 createArrayOfT, destructArrayOfT);
00516 }
00517
00518
00519 #endif
00520
00521 #endif