common.h

Go to the documentation of this file.
00001 #ifndef SimTK_SimTKCOMMON_COMMON_H_
00002 #define SimTK_SimTKCOMMON_COMMON_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                      SimTK Core: SimTKcommon                               *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK Core biosimulation toolkit originating from      *
00008  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00009  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00010  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
00011  *                                                                            *
00012  * Portions copyright (c) 2005-7 Stanford University and the Authors.         *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Permission is hereby granted, free of charge, to any person obtaining a    *
00017  * copy of this software and associated documentation files (the "Software"), *
00018  * to deal in the Software without restriction, including without limitation  *
00019  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
00020  * and/or sell copies of the Software, and to permit persons to whom the      *
00021  * Software is furnished to do so, subject to the following conditions:       *
00022  *                                                                            *
00023  * The above copyright notice and this permission notice shall be included in *
00024  * all copies or substantial portions of the Software.                        *
00025  *                                                                            *
00026  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
00027  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
00028  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
00029  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
00030  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
00031  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
00032  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
00033  * -------------------------------------------------------------------------- */
00034 
00048 /*****************************/
00049 /* ANSI-C COMPATIBLE SECTION */
00050 /*****************************/
00051 
00052 /* Set up a few compile-time options that affect all SimTK Core headers. */
00053 
00054 /* 
00055  * This compile-time constant determines the default precision used everywhere
00056  * in SimTK Core code. Wherever a SimTK::Real, SimTK::Vector, SimTK::Matrix,
00057  * etc. appears with no precision specified, it will have this underlying precision.
00058  * We use 1==float, 2==double, 4==long double. Any other value will cause
00059  * a compile time error. The default is 2.
00060  */
00061 #ifndef SimTK_DEFAULT_PRECISION
00062 #   define SimTK_DEFAULT_PRECISION 2
00063 #endif
00064 
00065 /* This type is for use in C. In C++ use SimTK::Real instead. */
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  * Shared libraries are messy in Visual Studio. We have to distinguish three
00102  * cases:
00103  *   (1) this header is being used to build the SimTKcommon shared library (dllexport)
00104  *   (2) this header is being used by a *client* of the SimTKcommon shared
00105  *       library (dllimport)
00106  *   (3) we are building the SimTKcommon static library, or the client is
00107  *       being compiled with the expectation of linking with the
00108  *       SimTKcommon static library (nothing special needed)
00109  * In the CMake script for building this library, we define one of the symbols
00110  *     SimTK_SimTKCOMMON_BUILDING_{SHARED|STATIC}_LIBRARY
00111  * Client code normally has no special symbol defined, in which case we'll
00112  * assume it wants to use the shared library. However, if the client defines
00113  * the symbol SimTK_USE_STATIC_LIBRARIES we'll suppress the dllimport so
00114  * that the client code can be linked with static libraries. Note that
00115  * the client symbol is not library dependent, while the library symbols
00116  * affect only the SimTKcommon library, meaning that other libraries can
00117  * be clients of this one. However, we are assuming all-static or all-shared.
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 /* Every SimTK Core library must provide these two routines, with the library
00133  * name appearing after the "version_" and "about_".
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 /* END OF ANSI-C COMPATIBLE SECTION */
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;}       /*prefix */   \
00247     NAME operator++(int)     {assert(isValid()); ++ix; return NAME(ix-1);}  /*postfix*/   \
00248     const NAME& operator--() {assert(isValid()); --ix; return *this;}       /*prefix */   \
00249     NAME operator--(int)     {assert(isValid()); --ix; return NAME(ix+1);}  /*postfix*/   \
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 // Similar to the above but for private implementation abstract classes, that
00296 // is, abstract class hierarchies where the virtual function table is 
00297 // hidden on the library side.
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     // default copy, assignment, destructor
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 // Built-in types
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 } // namespace SimTK
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     // THESE MUST NEVER CHANGE ORDER! This is effectively a compiler-independent
00374     // virtual function table. The first entry is a size in bytes and the rest have
00375     // type "pointer to function" so all the data should have a very predictable
00376     // and stable layout in memory.
00377     //
00378     // This is the one place in the SimTK API where the client
00379     // side and library side must agree on the physical layout of the class. 
00380     // It is safe to add new entries to the end of this list, but inserting earlier,
00381     // deleting or reordering anything already here will break binary compatibility.
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     // default copy, assignment, destructor
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 /*static*/ 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 } // namespace SimTKimpl
00517 
00518 
00519 #endif /* C++ stuff */
00520 
00521 #endif /* SimTK_SimTKCOMMON_COMMON_H_ */

Generated on Thu Feb 28 01:34:28 2008 for SimTKcommon by  doxygen 1.4.7