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 #ifdef _MSC_VER
00122 #pragma warning(disable:4231) // need to use 'extern' template explicit instantiation
00123 #endif
00124 #if defined(SimTK_SimTKCOMMON_BUILDING_SHARED_LIBRARY)
00125 #define SimTK_SimTKCOMMON_EXPORT __declspec(dllexport)
00126
00127 #ifdef _MSC_VER
00128 #pragma warning(disable:4661)
00129 #endif
00130 #elif defined(SimTK_SimTKCOMMON_BUILDING_STATIC_LIBRARY) || defined(SimTK_USE_STATIC_LIBRARIES)
00131 #define SimTK_SimTKCOMMON_EXPORT
00132 #else
00133 #define SimTK_SimTKCOMMON_EXPORT __declspec(dllimport) // i.e., a client of a shared library
00134 #endif
00135 #else
00136 #define SimTK_SimTKCOMMON_EXPORT // Linux, Mac
00137 #endif
00138
00139
00140
00141
00142 #if defined(__cplusplus)
00143 extern "C" {
00144 #endif
00145 SimTK_SimTKCOMMON_EXPORT void SimTK_version_SimTKcommon(int* major, int* minor, int* build);
00146 SimTK_SimTKCOMMON_EXPORT void SimTK_about_SimTKcommon(const char* key, int maxlen, char* value);
00147 #if defined(__cplusplus)
00148 }
00149 #endif
00150
00151
00152
00153
00154
00155 #if defined(__cplusplus)
00156
00157 #include <cstddef>
00158 #include <cassert>
00159 #include <complex>
00160 #include <limits>
00161
00190 namespace SimTK {
00191 static const int InvalidIndex = -1111111111;
00192 }
00193
00196 #define SimTK_DEFINE_UNIQUE_INDEX_TYPE(NAME) \
00197 SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,,,NAME) \
00198 static const NAME Invalid ## NAME;
00199
00202 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_INDEX_TYPE(EXPORT,NAME) \
00203 SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,,,NAME) \
00204 static const NAME Invalid ## NAME;
00205
00207 #define SimTK_DEFINE_UNIQUE_LOCAL_INDEX_TYPE(PARENT,NAME) \
00208 SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,PARENT,::,NAME)
00209
00212 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,PARENT,SEP,NAME) \
00213 class EXPORT NAME { \
00214 int ix; \
00215 public: \
00216 NAME() : ix(SimTK::InvalidIndex) { } \
00217 explicit NAME(int i) : ix(i) {assert(i>=0 || i==SimTK::InvalidIndex);} \
00218 explicit NAME(long l): ix((int)l) {assert(canStoreInNonnegativeInt(l));} \
00219 explicit NAME(unsigned int u) : ix((int)u) {assert(canStoreInInt(u));} \
00220 explicit NAME(unsigned long ul) : ix((int)ul) {assert(canStoreInInt(ul));} \
00221 operator int() const {return ix;} \
00222 bool isValid() const {return ix>=0;} \
00223 bool isValidExtended() const {return ix>=-1;} \
00224 void invalidate(){ix=SimTK::InvalidIndex;} \
00225 \
00226 bool operator==(int i) const {assert(isValidExtended() && isValidExtended(i)); return ix==i;} \
00227 bool operator==(long l) const {assert(isValidExtended() && isValidExtended(l)); return ix==(int)l;} \
00228 bool operator==(unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix==(int)u;} \
00229 bool operator==(unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix==(int)ul;} \
00230 bool operator!=(int i) const {return !operator==(i);} \
00231 bool operator!=(long l) const {return !operator==(l);} \
00232 bool operator!=(unsigned int u) const {return !operator==(u);} \
00233 bool operator!=(unsigned long ul) const {return !operator==(ul);} \
00234 \
00235 bool operator< (int i) const {assert(isValidExtended() && isValidExtended(i)); return ix<i;} \
00236 bool operator< (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix<(int)l;} \
00237 bool operator< (unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix<(int)u;} \
00238 bool operator< (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix<(int)ul;} \
00239 bool operator>=(int i) const {return !operator<(i);} \
00240 bool operator>=(long l) const {return !operator<(l);} \
00241 bool operator>=(unsigned int u) const {return !operator<(u);} \
00242 bool operator>=(unsigned long ul) const {return !operator<(ul);} \
00243 \
00244 bool operator> (int i) const {assert(isValidExtended() && isValidExtended(i)); return ix>i;} \
00245 bool operator> (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix>(int)l;} \
00246 bool operator> (unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix>(int)u;} \
00247 bool operator> (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix>(int)ul;} \
00248 bool operator<=(int i) const {return !operator>(i);} \
00249 bool operator<=(long l) const {return !operator>(l);} \
00250 bool operator<=(unsigned int u) const {return !operator>(u);} \
00251 bool operator<=(unsigned long ul) const {return !operator>(ul);} \
00252 \
00253 const NAME& operator++() {assert(isValid()); ++ix; return *this;} \
00254 NAME operator++(int) {assert(isValid()); ++ix; return NAME(ix-1);} \
00255 const NAME& operator--() {assert(isValid()); --ix; return *this;} \
00256 NAME operator--(int) {assert(isValid()); --ix; return NAME(ix+1);} \
00257 \
00258 NAME& operator+=(int i) {assert(isValid() && isValidExtended(ix+i)); ix+=i; return *this;} \
00259 NAME& operator-=(int i) {assert(isValid() && isValidExtended(ix-i)); ix-=i; return *this;} \
00260 NAME& operator+=(long l) {assert(isValid() && canStoreInInt(l) && isValidExtended(ix+(int)l)); ix+=(int)l; return *this;} \
00261 NAME& operator-=(long l) {assert(isValid() && canStoreInInt(l) && isValidExtended(ix-(int)l)); ix-=(int)l; return *this;} \
00262 NAME& operator+=(unsigned int u) {assert(isValid()&& canStoreInInt(u) && isValid(ix+(int)u)); ix+=(int)u; return *this;} \
00263 NAME& operator-=(unsigned int u) {assert(isValid()&& canStoreInInt(u) && isValidExtended(ix-(int)u)); ix-=(int)u; return *this;} \
00264 NAME& operator+=(unsigned long ul) {assert(isValid()&& canStoreInInt(ul) && isValid(ix+(int)ul)); ix+=(int)ul; return *this;} \
00265 NAME& operator-=(unsigned long ul) {assert(isValid()&& canStoreInInt(ul) && isValidExtended(ix-(int)ul)); ix-=(int)ul; return *this;} \
00266 \
00267 static const NAME& Invalid() {static const NAME invalid; return invalid;} \
00268 static bool isValid(int i) {return i>=0;} \
00269 static bool isValid(long l) {return canStoreInNonnegativeInt(l);} \
00270 static bool isValid(unsigned int u) {return canStoreInInt(u);} \
00271 static bool isValid(unsigned long ul) {return canStoreInInt(ul);} \
00272 static bool isValidExtended(int i) {return i>=-1;} \
00273 static bool isValidExtended(long l) {return canStoreInInt(l) && l>=-1;} \
00274 };
00275
00281 #define SimTK_DOWNCAST(Derived,Parent) \
00282 static bool isA(const Parent& p) \
00283 { return dynamic_cast<const Derived*>(&p) != 0; } \
00284 static const Derived& downcast(const Parent& p) \
00285 { return dynamic_cast<const Derived&>(p); } \
00286 static Derived& downcast(Parent& p) \
00287 { return dynamic_cast<Derived&>(p); }
00288
00293 #define SimTK_DOWNCAST2(Derived,Helper,Parent) \
00294 static bool isA(const Parent& p) \
00295 { return Helper::isA(p); } \
00296 static const Derived& downcast(const Parent& p) \
00297 { return reinterpret_cast<const Derived&>(Helper::downcast(p)); } \
00298 static Derived& downcast(Parent& p) \
00299 { return reinterpret_cast<Derived&>(Helper::downcast(p)); }
00300
00301
00302
00303
00304
00305 #define SimTK_PIMPL_DOWNCAST(Derived, Parent) \
00306 static bool isInstanceOf(const Parent&); \
00307 static const Derived& downcast(const Parent&); \
00308 static Derived& updDowncast(Parent&)
00309
00310 namespace SimTK {
00311
00312 namespace Options { }
00313 namespace Exception { }
00314
00315 typedef SimTK_Real Real;
00316 typedef std::complex<Real> Complex;
00317
00318 struct Segment {
00319 Segment() : length(0), offset(0) { }
00320 explicit Segment(int l, int ofs=0) : length(l), offset(ofs) {
00321 assert(l>=0 && ofs>=0);
00322 }
00323
00324 int length;
00325 int offset;
00326 };
00327
00328 template <class T> class TypeInfo {
00329 public:
00330 static const char* name() {return typeid(T).name();}
00331 };
00332
00333 #define SimTK_TYPEINFO_SPECIALIZE(T) \
00334 template <> class TypeInfo< T > { \
00335 public: \
00336 static const char* name() { return #T; } \
00337 };
00338
00339 SimTK_TYPEINFO_SPECIALIZE(bool); SimTK_TYPEINFO_SPECIALIZE(signed char);
00340 SimTK_TYPEINFO_SPECIALIZE(char); SimTK_TYPEINFO_SPECIALIZE(unsigned char);
00341 SimTK_TYPEINFO_SPECIALIZE(short); SimTK_TYPEINFO_SPECIALIZE(int);
00342 SimTK_TYPEINFO_SPECIALIZE(long);
00343 SimTK_TYPEINFO_SPECIALIZE(unsigned short); SimTK_TYPEINFO_SPECIALIZE(unsigned int);
00344 SimTK_TYPEINFO_SPECIALIZE(unsigned long);
00345 SimTK_TYPEINFO_SPECIALIZE(float); SimTK_TYPEINFO_SPECIALIZE(double);
00346 SimTK_TYPEINFO_SPECIALIZE(long double);
00347 SimTK_TYPEINFO_SPECIALIZE(std::complex<float>);
00348 SimTK_TYPEINFO_SPECIALIZE(std::complex<double>);
00349 SimTK_TYPEINFO_SPECIALIZE(std::complex<long double>);
00350
00351
00352 }
00353
00354 namespace SimTKimpl {
00355
00358 typedef void* (*IndexT)(void* tp, int n);
00359 typedef const void* (*IndexConstT)(const void* tp, int n);
00360 typedef void* (*CreateOneT)(const void* iptr);
00361 typedef void (*DestructOneT)(void*& tvptr);
00362 typedef void (*AssignArrayOfT)(void* dest, const void* src, int n);
00363 typedef void (*SetT)(void* dest, const void* valuep, int n);
00364 typedef void* (*CreateArrayOfT)(int n, const void* iptr);
00365 typedef void (*DestructArrayOfT)(void*& tvptr);
00367
00368 struct TypeManipulatorT {
00369 TypeManipulatorT(int z, IndexT it, IndexConstT ict,
00370 CreateOneT c1t, DestructOneT d1t, AssignArrayOfT aat, SetT st,
00371 CreateArrayOfT cat, DestructArrayOfT dat)
00372 : sizeOfT(z), indexT(it), indexConstT(ict),
00373 createOneT(c1t), destructOneT(d1t), assignArrayOfT(aat), setT(st),
00374 createArrayOfT(cat), destructArrayOfT(dat)
00375 { }
00376
00377 bool operator==(const TypeManipulatorT& t) const
00378 { return sizeOfT==t.sizeOfT && indexT==t.indexT; }
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 const int sizeOfT;
00390 const IndexT indexT;
00391 const IndexConstT indexConstT;
00392 const CreateOneT createOneT;
00393 const DestructOneT destructOneT;
00394 const AssignArrayOfT assignArrayOfT;
00395 const SetT setT;
00396 const CreateArrayOfT createArrayOfT;
00397 const DestructArrayOfT destructArrayOfT;
00398 };
00399
00414 template <class T> class MakeTypeManipulator {
00415 public:
00416 MakeTypeManipulator() { }
00417
00418
00419 static const TypeManipulatorT& getTypeManipulatorT() { return manipT; }
00420 static T& updAs(void* v)
00421 { assert(v); return *reinterpret_cast<T*>(v); }
00422 static const T& getAs(const void* v)
00423 { assert(v); return *reinterpret_cast<const T*>(v); }
00424
00425 private:
00431 static int sizeT() { return (int)sizeof(T); }
00432
00437 static void* indexT(void* tp, int n)
00438 { return (void*)(reinterpret_cast<T*>(tp) + n); }
00439 static const void* indexConstT(const void* tp, int n)
00440 { return (const void*)(reinterpret_cast<const T*>(tp) + n); }
00442
00446 static void* createOneT(const void* iptr=0)
00447 {
00448 T* tptr = new T;
00449 if (iptr) *tptr = *reinterpret_cast<const T*>(iptr);
00450 return tptr;
00451 }
00452
00455 static void destructOneT(void*& tvptr)
00456 {
00457 T* tptr = reinterpret_cast<T*>(tvptr);
00458 delete tptr;
00459 tvptr = 0;
00460 }
00461
00467 static void assignArrayOfT(void* dest, const void* src, int n)
00468 { assert(n>=0);
00469 if (n==0) return;
00470 assert(dest && src);
00471 assert(indexT(dest,n) < src || indexConstT(src,n) < dest);
00472 T* d = reinterpret_cast<T*>(dest);
00473 const T* s = reinterpret_cast<const T*>(src);
00474 for (int i=0; i < n; ++i) *d++ = *s++;
00475 }
00476
00481 static void setT(void* dest, const void* valuep, int n=1)
00482 { assert(n>=0);
00483 if (n==0) return;
00484 assert(dest && valuep);
00485 T* d = reinterpret_cast<T*>(dest);
00486 const T& v = *reinterpret_cast<const T*>(valuep);
00487 for (int i=0; i < n; ++i) *d++ = v;
00488 }
00489
00492 static void* createArrayOfT(int n, const void* iptr=0)
00493 { assert(n>=0);
00494 if (n == 0) return 0;
00495 T* tptr = new T[n];
00496 if (iptr) {
00497 const T& init = *reinterpret_cast<const T*>(iptr);
00498 for (int i=0; i < n; ++i) tptr[i] = init;
00499 }
00500 return tptr;
00501 }
00502
00507 static void destructArrayOfT(void*& tvptr)
00508 {
00509 T* tptr = reinterpret_cast<T*>(tvptr);
00510 delete[] tptr;
00511 tvptr = 0;
00512 }
00513
00514 private:
00515 static const TypeManipulatorT manipT;
00516 };
00517
00518 template <class T> const TypeManipulatorT
00519 MakeTypeManipulator<T>::manipT = TypeManipulatorT(
00520 (int)sizeof(T),indexT,indexConstT,
00521 createOneT, destructOneT, assignArrayOfT, setT,
00522 createArrayOfT, destructArrayOfT);
00523 }
00524
00525
00526 #endif
00527
00528 #endif