Simbody

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-11 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 
00047 // Provide doxygen documentation for the SimTK namespace.
00048 
00057 // Define shared doxygen "modules" and sub-modules here. We'll put things 
00058 // in them at various places when appropriate.
00059 
00094 /*****************************/
00095 /* ANSI-C COMPATIBLE SECTION */
00096 /*****************************/
00097 
00098 /* Set up a few compile-time options that affect all SimTK Core headers. */
00099 
00107 #ifndef SimTK_DEFAULT_PRECISION
00108 #   define SimTK_DEFAULT_PRECISION 2
00109 #endif
00110 
00111 #if   (SimTK_DEFAULT_PRECISION == 1)
00112 
00113     typedef float SimTK_Real;
00114 #elif (SimTK_DEFAULT_PRECISION == 2)
00115 
00116     typedef double SimTK_Real;
00117 #elif (SimTK_DEFAULT_PRECISION == 4)
00118 
00119     typedef long double SimTK_Real;
00120 #else
00121     #error ILLEGAL VALUE FOR DEFAULT PRECISION
00122 #endif
00123 
00124 #ifndef NDEBUG
00125     #if defined(__cplusplus)
00126         #include <cstdio>
00127         #define SimTK_DEBUG(s) std::printf("DBG: " s)
00128         #define SimTK_DEBUG1(s,a1) std::printf("DBG: " s,a1)    
00129         #define SimTK_DEBUG2(s,a1,a2) std::printf("DBG: " s,a1,a2)  
00130         #define SimTK_DEBUG3(s,a1,a2,a3) std::printf("DBG: " s,a1,a2,a3)    
00131         #define SimTK_DEBUG4(s,a1,a2,a3,a4) std::printf("DBG: " s,a1,a2,a3,a4)
00132     #else
00133         #include <stdio.h>
00134         #define SimTK_DEBUG(s) printf("DBG: " s)
00135         #define SimTK_DEBUG1(s,a1) printf("DBG: " s,a1) 
00136         #define SimTK_DEBUG2(s,a1,a2) printf("DBG: " s,a1,a2)   
00137         #define SimTK_DEBUG3(s,a1,a2,a3) printf("DBG: " s,a1,a2,a3) 
00138         #define SimTK_DEBUG4(s,a1,a2,a3,a4) printf("DBG: " s,a1,a2,a3,a4)
00139     #endif
00140 #else
00141     #define SimTK_DEBUG(s)
00142     #define SimTK_DEBUG1(s,a1)
00143     #define SimTK_DEBUG2(s,a1,a2)
00144     #define SimTK_DEBUG3(s,a1,a2,a3)    
00145     #define SimTK_DEBUG4(s,a1,a2,a3,a4)
00146 #endif
00147 
00148 /*
00149  * Shared libraries are messy in Visual Studio. We have to distinguish three
00150  * cases:
00151  *   (1) this header is being used to build the SimTKcommon shared library (dllexport)
00152  *   (2) this header is being used by a *client* of the SimTKcommon shared
00153  *       library (dllimport)
00154  *   (3) we are building the SimTKcommon static library, or the client is
00155  *       being compiled with the expectation of linking with the
00156  *       SimTKcommon static library (nothing special needed)
00157  * In the CMake script for building this library, we define one of the symbols
00158  *     SimTK_SimTKCOMMON_BUILDING_{SHARED|STATIC}_LIBRARY
00159  * Client code normally has no special symbol defined, in which case we'll
00160  * assume it wants to use the shared library. However, if the client defines
00161  * the symbol SimTK_USE_STATIC_LIBRARIES we'll suppress the dllimport so
00162  * that the client code can be linked with static libraries. Note that
00163  * the client symbol is not library dependent, while the library symbols
00164  * affect only the SimTKcommon library, meaning that other libraries can
00165  * be clients of this one. However, we are assuming all-static or all-shared.
00166  */
00167 
00168 #ifdef _WIN32
00169     #ifdef _MSC_VER
00170     #pragma warning(disable:4231) /*need to use 'extern' template explicit instantiation*/
00171     #pragma warning(disable:4251) /*no DLL interface for type of member of exported class*/
00172     #pragma warning(disable:4275) /*no DLL interface for base class of exported class*/
00173     #pragma warning(disable:4345) /*warning about PODs being default-initialized*/
00174     #endif
00175     #if defined(SimTK_SimTKCOMMON_BUILDING_SHARED_LIBRARY)
00176         #define SimTK_SimTKCOMMON_EXPORT __declspec(dllexport)
00177         /* Keep MS VC++ quiet when it tries to instantiate incomplete template classes in a DLL. */
00178         #ifdef _MSC_VER
00179         #pragma warning(disable:4661)
00180         #endif
00181     #elif defined(SimTK_SimTKCOMMON_BUILDING_STATIC_LIBRARY) || defined(SimTK_USE_STATIC_LIBRARIES)
00182         #define SimTK_SimTKCOMMON_EXPORT
00183     #else
00184         #define SimTK_SimTKCOMMON_EXPORT __declspec(dllimport) /*i.e., a client of a shared library*/
00185     #endif
00186     /* VC++ tries to be secure by leaving bounds checking on for STL containers
00187      * even in Release mode. This macro exists to disable that feature and can
00188      * result in a considerable speedup.
00189      * CAUTION: every linked-together compilation unit must have this set the same
00190      * way. Everyone who properly includes this file first is fine; but as of this
00191      * writing Simmath's IpOpt doesn't do so.
00192      */
00193     /* (sherm 081204 disabling for now: doesn't work on VC++ 8 and is 
00194      * tricky on VC++ 9 because all libraries, including 3rd party, must
00195      * be built the same way). Better to use the SimTK::Array_<T> class in
00196      * place of the std::vector<T> class to get better performance.
00197      #ifdef NDEBUG
00198         #undef _SECURE_SCL
00199         #define _SECURE_SCL 0
00200      #endif
00201      */
00202 #else
00203     #define SimTK_SimTKCOMMON_EXPORT // Linux, Mac
00204 #endif
00205 
00206 /* Every SimTK Core library must provide these two routines, with the library
00207  * name appearing after the "version_" and "about_".
00208  */
00209 #if defined(__cplusplus)
00210 extern "C" {
00211 #endif
00212 
00213     SimTK_SimTKCOMMON_EXPORT void SimTK_version_SimTKcommon(int* major, int* minor, int* build);
00220     SimTK_SimTKCOMMON_EXPORT void SimTK_about_SimTKcommon(const char* key, int maxlen, char* value);
00221 #if defined(__cplusplus)
00222 }
00223 #endif
00224 
00225 
00226 /************************************/
00227 /* END OF ANSI-C COMPATIBLE SECTION */
00228 /************************************/
00229 
00230 #if defined(__cplusplus)
00231 
00232 #include <cstddef>
00233 #include <cassert>
00234 #include <cmath>
00235 #include <cfloat>
00236 #include <complex>
00237 #include <limits>
00238 #include <typeinfo>
00239 
00240 
00241 /* Currently (Microsoft VC++ 9) these C99-compatible floating point functions 
00242 are missing. We'll create them here and install them into namespace std.
00243 TODO: This should be removed when these are available. */
00244 #ifdef _MSC_VER
00245 namespace std {
00246 inline bool isfinite(float f) {return _finite(f) != 0;}
00247 inline bool isfinite(double d) {return _finite(d) != 0;}
00248 inline bool isfinite(long double l) {return _finite(l) != 0;}
00249 inline bool isnan(float f) {return _isnan(f) != 0;}
00250 inline bool isnan(double d) {return _isnan(d) != 0;}
00251 inline bool isnan(long double l) {return _isnan(l) != 0;}
00252 inline bool isinf(float f) {return std::abs(f)==std::numeric_limits<float>::infinity();}
00253 inline bool isinf(double d) {return std::abs(d)==std::numeric_limits<double>::infinity();}
00254 inline bool isinf(long double l) {return std::abs(l)==std::numeric_limits<double>::infinity();}
00255 inline bool signbit(float f) {return (*reinterpret_cast<unsigned*>(&f) & 0x80000000U) != 0;}
00256 inline bool signbit(double d) {return (*reinterpret_cast<unsigned long long*>(&d)
00257                                & 0x8000000000000000ULL) != 0;}
00258 inline bool signbit(long double l) {return (*reinterpret_cast<unsigned long long*>(&l)
00259                                     & 0x8000000000000000ULL) != 0;}
00260 }
00261 #endif
00262 
00263 
00264 namespace SimTK {
00265 
00266 
00267 // This utility answers the question "if I put this integral value in an int and then
00268 // get it back, will its value be the same?".
00269 inline bool canStoreInInt(bool)            {return true;}
00270 inline bool canStoreInInt(char)            {return true;}
00271 inline bool canStoreInInt(unsigned char)   {return true;}
00272 inline bool canStoreInInt(signed char)     {return true;}
00273 inline bool canStoreInInt(short)           {return true;}
00274 inline bool canStoreInInt(unsigned short)  {return true;}
00275 inline bool canStoreInInt(int)             {return true;}
00276 inline bool canStoreInInt(unsigned int  u) {return (unsigned int)(int(u)) == u;}
00277 inline bool canStoreInInt(long i)          {return long(int(i)) == i;}
00278 inline bool canStoreInInt(unsigned long u) {return (unsigned long)(int(u)) == u;}
00279 inline bool canStoreInInt(long long i)          {return (long long)(int(i)) == i;}
00280 inline bool canStoreInInt(unsigned long long u) {return (unsigned long long)(int(u)) == u;}
00281 
00282 // This utility answers the question "is this integral value a nonnegative number
00283 // that can be stored in an int?".
00284 inline bool canStoreInNonnegativeInt(bool)             {return true;}
00285 inline bool canStoreInNonnegativeInt(char c)           {return c >= 0;}
00286 inline bool canStoreInNonnegativeInt(unsigned char)    {return true;}
00287 inline bool canStoreInNonnegativeInt(signed char c)    {return c >= 0;}
00288 inline bool canStoreInNonnegativeInt(short s)          {return s >= 0;}
00289 inline bool canStoreInNonnegativeInt(unsigned short)   {return true;}
00290 inline bool canStoreInNonnegativeInt(int  i)           {return i >= 0;}
00291 inline bool canStoreInNonnegativeInt(long l)           {return canStoreInInt(l) && l >= 0;}
00292 inline bool canStoreInNonnegativeInt(long long l)      {return canStoreInInt(l) && l >= 0;}
00293 inline bool canStoreInNonnegativeInt(unsigned int  u)  {return canStoreInInt(u);}
00294 inline bool canStoreInNonnegativeInt(unsigned long u)  {return canStoreInInt(u);}
00295 inline bool canStoreInNonnegativeInt(unsigned long long u) {return canStoreInInt(u);}
00296 
00297 // This utility answers the question of whether an integer is suitable as a size
00298 // limited by the given maximum size. Signed types must be checked for being
00299 // nonegative; doing that with unsigned types leads to compiler warnings.
00300 
00301 // char can be signed or unsigned depending on the compiler; assume signed.
00302 inline bool isSizeInRange(char           sz, char           mx){return 0<=sz&&sz<=mx;}
00303 inline bool isSizeInRange(signed char    sz, signed char    mx){return 0<=sz&&sz<=mx;}
00304 inline bool isSizeInRange(short          sz, short          mx){return 0<=sz&&sz<=mx;}
00305 inline bool isSizeInRange(int            sz, int            mx){return 0<=sz&&sz<=mx;}
00306 inline bool isSizeInRange(long           sz, long           mx){return 0<=sz&&sz<=mx;}
00307 inline bool isSizeInRange(long long      sz, long long      mx){return 0<=sz&&sz<=mx;}
00308 inline bool isSizeInRange(unsigned char  sz, unsigned char  mx){return sz<=mx;}
00309 inline bool isSizeInRange(unsigned short sz, unsigned short mx){return sz<=mx;}
00310 inline bool isSizeInRange(unsigned int   sz, unsigned int   mx){return sz<=mx;}
00311 inline bool isSizeInRange(unsigned long  sz, unsigned long  mx){return sz<=mx;}
00312 inline bool isSizeInRange(unsigned long long sz, unsigned long long mx){return sz<=mx;}
00313 
00314 // This utility answers the question of whether an integer is suitable as an index
00315 // for an array limited by the given maximum size. Signed types must be checked for being
00316 // nonegative; doing that with unsigned types leads to compiler warnings. This is just
00317 // like the "size in range" check above except the maximum value allowed for an index
00318 // is one less that the size.
00319 
00320 // char can be signed or unsigned depending on the compiler; assume signed.
00321 inline bool isIndexInRange(char           ix, char           sz){return 0<=ix&&ix<sz;}
00322 inline bool isIndexInRange(signed char    ix, signed char    sz){return 0<=ix&&ix<sz;}
00323 inline bool isIndexInRange(short          ix, short          sz){return 0<=ix&&ix<sz;}
00324 inline bool isIndexInRange(int            ix, int            sz){return 0<=ix&&ix<sz;}
00325 inline bool isIndexInRange(long           ix, long           sz){return 0<=ix&&ix<sz;}
00326 inline bool isIndexInRange(long long      ix, long long      sz){return 0<=ix&&ix<sz;}
00327 inline bool isIndexInRange(unsigned char  ix, unsigned char  sz){return ix<sz;}
00328 inline bool isIndexInRange(unsigned short ix, unsigned short sz){return ix<sz;}
00329 inline bool isIndexInRange(unsigned int   ix, unsigned int   sz){return ix<sz;}
00330 inline bool isIndexInRange(unsigned long  ix, unsigned long  sz){return ix<sz;}
00331 inline bool isIndexInRange(unsigned long long ix, unsigned long long sz){return ix<sz;}
00332 
00333 // This utility answers the question: is this integral value nonnegative? The answer
00334 // is always true for unsigned types and you'll get a warning from some compilers if
00335 // you check.
00336 
00337 inline bool isNonnegative(bool)              {return true;}
00338 // char can be signed or unsigned depending on the compiler; assume signed.
00339 inline bool isNonnegative(char        n)     {return n>=0;}
00340 inline bool isNonnegative(signed char n)     {return n>=0;}
00341 inline bool isNonnegative(short       n)     {return n>=0;}
00342 inline bool isNonnegative(int         n)     {return n>=0;}
00343 inline bool isNonnegative(long        n)     {return n>=0;}
00344 inline bool isNonnegative(long long   n)     {return n>=0;}
00345 inline bool isNonnegative(unsigned char)     {return true;}
00346 inline bool isNonnegative(unsigned short)    {return true;}
00347 inline bool isNonnegative(unsigned int)      {return true;}
00348 inline bool isNonnegative(unsigned long)     {return true;}
00349 inline bool isNonnegative(unsigned long long){return true;}
00350 
00351 // A NaN-like value for unique index types created using the macro
00352 // SimTK_DEFINE_UNIQUE_INDEX_TYPE(). A unique, typed constant with
00353 // this numerical value is created for each index type.
00354 static const int InvalidIndex = -1111111111;
00355 }
00356 
00357 
00358 
00390 #define SimTK_DEFINE_UNIQUE_INDEX_TYPE(NAME)                   \
00391     SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,,,NAME)   \
00392     static const NAME Invalid ## NAME;
00393 
00396 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_INDEX_TYPE(EXPORT,NAME)     \
00397     SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,,,NAME) \
00398     static const NAME Invalid ## NAME;
00399 
00401 #define SimTK_DEFINE_UNIQUE_LOCAL_INDEX_TYPE(PARENT,NAME) \
00402     SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,PARENT,::,NAME)
00403 
00406 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,PARENT,SEP,NAME)   \
00407 class EXPORT NAME {                         \
00408     int ix;                                 \
00409 public:                                     \
00410     NAME() : ix(SimTK::InvalidIndex) { }       \
00411     explicit NAME(int i) : ix(i)      {assert(i>=0 || i==SimTK::InvalidIndex);} \
00412     explicit NAME(long l): ix((int)l) {assert(SimTK::canStoreInNonnegativeInt(l));}    \
00413     explicit NAME(unsigned int  u)  : ix((int)u)  {assert(SimTK::canStoreInInt(u));}   \
00414     explicit NAME(unsigned long ul) : ix((int)ul) {assert(SimTK::canStoreInInt(ul));}  \
00415     operator int() const {return ix;}               \
00416     bool isValid() const {return ix>=0;}            \
00417     bool isValidExtended() const {return ix>=-1;}   \
00418     void invalidate(){ix=SimTK::InvalidIndex;}      \
00419     \
00420     bool operator==(int  i) const {assert(isValidExtended() && isValidExtended(i)); return ix==i;}    \
00421     bool operator==(short s) const{assert(isValidExtended() && isValidExtended(s)); return ix==(int)s;}  \
00422     bool operator==(long l) const {assert(isValidExtended() && isValidExtended(l)); return ix==(int)l;}  \
00423     bool operator==(unsigned int  u)  const {assert(isValidExtended() && isValid(u)); return ix==(int)u;}   \
00424     bool operator==(unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix==(int)us;} \
00425     bool operator==(unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix==(int)ul;} \
00426     bool operator!=(int  i)           const {return !operator==(i);}    \
00427     bool operator!=(short s)          const {return !operator==(s);}    \
00428     bool operator!=(long l)           const {return !operator==(l);}    \
00429     bool operator!=(unsigned int  u)  const {return !operator==(u);}    \
00430     bool operator!=(unsigned long ul) const {return !operator==(ul);}   \
00431     \
00432     bool operator< (int  i) const {assert(isValidExtended() && isValidExtended(i)); return ix<i;}        \
00433     bool operator< (short s) const{assert(isValidExtended() && isValidExtended(s)); return ix<(int)s;}   \
00434     bool operator< (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix<(int)l;}   \
00435     bool operator< (unsigned int  u)  const {assert(isValidExtended() && isValid(u));  return ix<(int)u;}    \
00436     bool operator< (unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix<(int)us;}   \
00437     bool operator< (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix<(int)ul;}   \
00438     bool operator>=(int  i)           const {return !operator<(i);}    \
00439     bool operator>=(short s)          const {return !operator<(s);}    \
00440     bool operator>=(long l)           const {return !operator<(l);}    \
00441     bool operator>=(unsigned int  u)  const {return !operator<(u);}    \
00442     bool operator>=(unsigned short us)const {return !operator<(us);}   \
00443     bool operator>=(unsigned long ul) const {return !operator<(ul);}   \
00444     \
00445     bool operator> (int  i) const {assert(isValidExtended() && isValidExtended(i)); return ix>i;}        \
00446     bool operator> (short s) const{assert(isValidExtended() && isValidExtended(s)); return ix>(int)s;}   \
00447     bool operator> (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix>(int)l;}   \
00448     bool operator> (unsigned int  u)  const {assert(isValidExtended() && isValid(u));  return ix>(int)u;}    \
00449     bool operator> (unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix>(int)us;}   \
00450     bool operator> (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix>(int)ul;}   \
00451     bool operator<=(int  i)           const {return !operator>(i);}    \
00452     bool operator<=(short s)          const {return !operator>(s);}    \
00453     bool operator<=(long l)           const {return !operator>(l);}    \
00454     bool operator<=(unsigned int  u)  const {return !operator>(u);}    \
00455     bool operator<=(unsigned short us)const {return !operator>(us);}   \
00456     bool operator<=(unsigned long ul) const {return !operator>(ul);}   \
00457     \
00458     const NAME& operator++() {assert(isValid()); ++ix; return *this;}       /*prefix */   \
00459     NAME operator++(int)     {assert(isValid()); ++ix; return NAME(ix-1);}  /*postfix*/   \
00460     const NAME& operator--() {assert(isValid()); --ix; return *this;}       /*prefix */   \
00461     NAME operator--(int)     {assert(isValid()); --ix; return NAME(ix+1);}  /*postfix*/   \
00462     \
00463     NAME& operator+=(int i)  {assert(isValid() && isValidExtended(ix+i)); ix+=i; return *this;}     \
00464     NAME& operator-=(int i)  {assert(isValid() && isValidExtended(ix-i)); ix-=i; return *this;}     \
00465     NAME& operator+=(short s){assert(isValid() && SimTK::canStoreInInt(s) && isValidExtended(ix+(int)s)); ix+=(int)s; return *this;}     \
00466     NAME& operator-=(short s){assert(isValid() && SimTK::canStoreInInt(s) && isValidExtended(ix-(int)s)); ix-=(int)s; return *this;}     \
00467     NAME& operator+=(long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix+(int)l)); ix+=(int)l; return *this;}     \
00468     NAME& operator-=(long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix-(int)l)); ix-=(int)l; return *this;}     \
00469     NAME& operator+=(unsigned int  u)  {assert(isValid()&& SimTK::canStoreInInt(u)  && isValid(ix+(int)u));  ix+=(int)u;  return *this;}  \
00470     NAME& operator-=(unsigned int  u)  {assert(isValid()&& SimTK::canStoreInInt(u)  && isValidExtended(ix-(int)u));  ix-=(int)u;  return *this;}  \
00471     NAME& operator+=(unsigned short us){assert(isValid()&& SimTK::canStoreInInt(us) && isValid(ix+(int)us)); ix+=(int)us; return *this;}  \
00472     NAME& operator-=(unsigned short us){assert(isValid()&& SimTK::canStoreInInt(us) && isValidExtended(ix-(int)us)); ix-=(int)us; return *this;}  \
00473     NAME& operator+=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValid(ix+(int)ul)); ix+=(int)ul; return *this;}  \
00474     NAME& operator-=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValidExtended(ix-(int)ul)); ix-=(int)ul; return *this;}  \
00475     \
00476     static const NAME& Invalid() {static const NAME invalid; return invalid;}       \
00477     static bool isValid(int  i) {return i>=0;}                                      \
00478     static bool isValid(short s){return s>=0;}                                      \
00479     static bool isValid(long l) {return SimTK::canStoreInNonnegativeInt(l);}        \
00480     static bool isValid(unsigned int  u)  {return SimTK::canStoreInInt(u);}         \
00481     static bool isValid(unsigned short)   {return true;}                            \
00482     static bool isValid(unsigned long ul) {return SimTK::canStoreInInt(ul);}        \
00483     static bool isValidExtended(int  i) {return i>=-1;}                             \
00484     static bool isValidExtended(short s){return s>=-1;}                             \
00485     static bool isValidExtended(long l) {return SimTK::canStoreInInt(l) && l>=-1;}  \
00486     /* IndexTraits for use in Array_<T,X> with this as X; same as int */            \
00487     typedef int size_type;                                                  \
00488     typedef int difference_type;                                            \
00489     static size_type max_size() {return std::numeric_limits<int>::max();}   \
00490 };
00491 
00495 #define SimTK_DOWNCAST(Derived,Parent) \
00496     static bool isA(const Parent& p)                        \
00497         { return dynamic_cast<const Derived*>(&p) != 0; }   \
00498     static const Derived& downcast(const Parent& p)         \
00499         { return dynamic_cast<const Derived&>(p); }         \
00500     static Derived& updDowncast(Parent& p)                  \
00501         { return dynamic_cast<Derived&>(p); }               \
00502     static Derived& downcast(Parent& p)                     \
00503         { return dynamic_cast<Derived&>(p); }
00504 
00507 #define SimTK_DOWNCAST2(Derived,Helper,Parent) \
00508     static bool isA(const Parent& p)                                        \
00509         { return Helper::isA(p); }                                          \
00510     static const Derived& downcast(const Parent& p)                         \
00511         { return reinterpret_cast<const Derived&>(Helper::downcast(p)); }   \
00512     static Derived& updDowncast(Parent& p)                                  \
00513         { return reinterpret_cast<Derived&>(Helper::downcast(p)); }         \
00514     static Derived& downcast(Parent& p)                                     \
00515         { return reinterpret_cast<Derived&>(Helper::downcast(p)); }
00516 
00517 
00521 #define SimTK_PIMPL_DOWNCAST(Derived, Parent)           \
00522     static bool           isInstanceOf(const Parent&);  \
00523     static const Derived& downcast(const Parent&);      \
00524     static Derived&       updDowncast(Parent&)
00525 
00526 namespace SimTK {
00527     
00528 namespace Options { }
00529 namespace Exception { }
00530 
00533 typedef SimTK_Real              Real;
00536 typedef std::complex<Real>      Complex;
00538 typedef std::complex<float>     fComplex;
00540 typedef std::complex<float>     dComplex;
00541 
00544 struct Segment {
00545     Segment() : length(0), offset(0) { }
00546     explicit Segment(int l, int ofs=0) : length(l), offset(ofs) { 
00547         assert(l>=0 && ofs>=0);
00548     }
00549     // default copy, assignment, destructor
00550     int length;
00551     int offset;
00552 };  
00553 
00554 
00560 struct DontCopy {};
00564 struct TrustMe {};
00565 
00568 struct FalseType {};
00571 struct TrueType {};
00572 
00574 template <class L, class R> struct AndOpType {};
00575 template<> struct AndOpType<FalseType,FalseType> {typedef FalseType Result;};
00576 template<> struct AndOpType<FalseType,TrueType>  {typedef FalseType Result;};
00577 template<> struct AndOpType<TrueType, FalseType> {typedef FalseType Result;};
00578 template<> struct AndOpType<TrueType, TrueType>  {typedef TrueType  Result;};
00579 
00581 template <class L, class R> struct OrOpType {};
00582 template<> struct OrOpType<FalseType,FalseType> {typedef FalseType Result;};
00583 template<> struct OrOpType<FalseType,TrueType>  {typedef TrueType  Result;};
00584 template<> struct OrOpType<TrueType, FalseType> {typedef TrueType  Result;};
00585 template<> struct OrOpType<TrueType, TrueType>  {typedef TrueType  Result;};
00586 
00588 template <class L, class R> struct XorOpType {};
00589 template<> struct XorOpType<FalseType,FalseType> {typedef FalseType Result;};
00590 template<> struct XorOpType<FalseType,TrueType>  {typedef TrueType  Result;};
00591 template<> struct XorOpType<TrueType, FalseType> {typedef TrueType  Result;};
00592 template<> struct XorOpType<TrueType, TrueType>  {typedef FalseType Result;};
00593 
00595 template <class T> struct IsIntegralType {
00598     typedef FalseType Result;
00601     static const bool result = false;
00602 };
00605 #define SimTK_SPECIALIZE_INTEGRAL_TYPE(T)       \
00606     template<> struct IsIntegralType<T>         \
00607     {typedef TrueType Result; static const bool result = true;}
00608 
00609 SimTK_SPECIALIZE_INTEGRAL_TYPE(bool); 
00610 SimTK_SPECIALIZE_INTEGRAL_TYPE(char);
00611 // This causes problems when used with Qt which for some crazy
00612 // reason likes to make its own wchar_t rather than using the built in.
00613 // SimTK_SPECIALIZE_INTEGRAL_TYPE(wchar_t);
00614 SimTK_SPECIALIZE_INTEGRAL_TYPE(signed char);
00615 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned char);
00616 SimTK_SPECIALIZE_INTEGRAL_TYPE(short);
00617 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned short);
00618 SimTK_SPECIALIZE_INTEGRAL_TYPE(int);
00619 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned int); // a.k.a. "unsigned"
00620 SimTK_SPECIALIZE_INTEGRAL_TYPE(long);
00621 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned long);
00622 SimTK_SPECIALIZE_INTEGRAL_TYPE(long long);
00623 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned long long);
00624 
00626 template <class T> struct IsFloatingType {
00629     typedef FalseType Result;
00632     static const bool result = false;
00633 };
00636 #define SimTK_SPECIALIZE_FLOATING_TYPE(T)       \
00637     template<> struct IsFloatingType<T>         \
00638     {typedef TrueType Result; static const bool result = true;}
00639 
00640 SimTK_SPECIALIZE_FLOATING_TYPE(float); 
00641 SimTK_SPECIALIZE_FLOATING_TYPE(double); 
00642 SimTK_SPECIALIZE_FLOATING_TYPE(long double); 
00643 
00645 template <class T> struct IsVoidType {
00648     typedef FalseType Result;
00651     static const bool result = false;
00652 };
00653 template<> struct IsVoidType<void> 
00654 {typedef TrueType Result; static const bool result = true;};
00655 
00658 template <class T> struct IsArithmeticType {
00661     typedef OrOpType<typename IsIntegralType<T>::Result,
00662                      typename IsFloatingType<T>::Result>    Result;
00665     static const bool result = IsIntegralType<T>::result 
00666                             || IsFloatingType<T>::result;
00667 };
00668 
00669 // This struct's sole use is to allow us to define the typedef 
00670 // Is64BitPlatformType as equivalent to either TrueType or FalseType.
00671 template <bool is64Bit> struct Is64BitHelper {};
00672 template<> struct Is64BitHelper<true>  
00673 {typedef TrueType  Result; static const bool result = true;};
00674 template<> struct Is64BitHelper<false> 
00675 {typedef FalseType Result; static const bool result = false;};
00676 
00681 static const bool Is64BitPlatform = sizeof(size_t) > sizeof(int);
00682 typedef Is64BitHelper<Is64BitPlatform>::Result Is64BitPlatformType;
00683 
00684 
00688 template <class T> struct NiceTypeName {
00689     static const char* name() {return typeid(T).name();}
00690 };
00691 
00695 #define SimTK_NICETYPENAME_LITERAL(T)           \
00696 template <> struct NiceTypeName< T > {          \
00697     static const char* name() { return #T; }    \
00698 };
00699 
00700 // Some types for which we'd like to see nice type names.
00701 SimTK_NICETYPENAME_LITERAL(bool);            
00702 SimTK_NICETYPENAME_LITERAL(char); 
00703 // This causes problems when used with Qt which for some crazy
00704 // reason likes to make its own wchar_t rather than using the built in.
00705 // SimTK_NICETYPENAME_LITERAL(wchar_t);            
00706 SimTK_NICETYPENAME_LITERAL(signed char); 
00707 SimTK_NICETYPENAME_LITERAL(unsigned char);
00708 SimTK_NICETYPENAME_LITERAL(short);           
00709 SimTK_NICETYPENAME_LITERAL(unsigned short);  
00710 SimTK_NICETYPENAME_LITERAL(int); 
00711 SimTK_NICETYPENAME_LITERAL(unsigned); // preferred to "unsigned int"
00712 SimTK_NICETYPENAME_LITERAL(long);            
00713 SimTK_NICETYPENAME_LITERAL(unsigned long);   
00714 SimTK_NICETYPENAME_LITERAL(long long);
00715 SimTK_NICETYPENAME_LITERAL(unsigned long long);
00716 SimTK_NICETYPENAME_LITERAL(float);           
00717 SimTK_NICETYPENAME_LITERAL(double); 
00718 SimTK_NICETYPENAME_LITERAL(long double);
00719 SimTK_NICETYPENAME_LITERAL(std::complex<float>);
00720 SimTK_NICETYPENAME_LITERAL(std::complex<double>); 
00721 SimTK_NICETYPENAME_LITERAL(std::complex<long double>); 
00722 SimTK_NICETYPENAME_LITERAL(SimTK::FalseType);
00723 SimTK_NICETYPENAME_LITERAL(SimTK::TrueType); 
00724 
00725 } // namespace SimTK
00726 
00727 #endif /* C++ stuff */
00728 
00729 #endif /* SimTK_SimTKCOMMON_COMMON_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines