SimTKcommon/internal/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-10 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 // Provide doxygen documentation for the SimTK namespace.
00049 
00060 // Define shared doxygen "modules" and sub-modules here. We'll put things 
00061 // in them at various places when appropriate.
00062 
00085 /*****************************/
00086 /* ANSI-C COMPATIBLE SECTION */
00087 /*****************************/
00088 
00089 /* Set up a few compile-time options that affect all SimTK Core headers. */
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  * Shared libraries are messy in Visual Studio. We have to distinguish three
00141  * cases:
00142  *   (1) this header is being used to build the SimTKcommon shared library (dllexport)
00143  *   (2) this header is being used by a *client* of the SimTKcommon shared
00144  *       library (dllimport)
00145  *   (3) we are building the SimTKcommon static library, or the client is
00146  *       being compiled with the expectation of linking with the
00147  *       SimTKcommon static library (nothing special needed)
00148  * In the CMake script for building this library, we define one of the symbols
00149  *     SimTK_SimTKCOMMON_BUILDING_{SHARED|STATIC}_LIBRARY
00150  * Client code normally has no special symbol defined, in which case we'll
00151  * assume it wants to use the shared library. However, if the client defines
00152  * the symbol SimTK_USE_STATIC_LIBRARIES we'll suppress the dllimport so
00153  * that the client code can be linked with static libraries. Note that
00154  * the client symbol is not library dependent, while the library symbols
00155  * affect only the SimTKcommon library, meaning that other libraries can
00156  * be clients of this one. However, we are assuming all-static or all-shared.
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     #pragma warning(disable:4275) /*no DLL interface for base class of exported class*/
00164     #pragma warning(disable:4345) /*warning about PODs being default-initialized*/
00165     #endif
00166     #if defined(SimTK_SimTKCOMMON_BUILDING_SHARED_LIBRARY)
00167         #define SimTK_SimTKCOMMON_EXPORT __declspec(dllexport)
00168         /* Keep MS VC++ quiet when it tries to instantiate incomplete template classes in a DLL. */
00169         #ifdef _MSC_VER
00170         #pragma warning(disable:4661)
00171         #endif
00172     #elif defined(SimTK_SimTKCOMMON_BUILDING_STATIC_LIBRARY) || defined(SimTK_USE_STATIC_LIBRARIES)
00173         #define SimTK_SimTKCOMMON_EXPORT
00174     #else
00175         #define SimTK_SimTKCOMMON_EXPORT __declspec(dllimport) /*i.e., a client of a shared library*/
00176     #endif
00177     /* VC++ tries to be secure by leaving bounds checking on for STL containers
00178      * even in Release mode. This macro exists to disable that feature and can
00179      * result in a considerable speedup.
00180      * CAUTION: every linked-together compilation unit must have this set the same
00181      * way. Everyone who properly includes this file first is fine; but as of this
00182      * writing Simmath's IpOpt doesn't do so.
00183      */
00184     /* (sherm 081204 disabling for now: doesn't work on VC++ 8 and is 
00185      * tricky on VC++ 9 because all libraries, including 3rd party, must
00186      * be built the same way). Better to use the SimTK::Array_<T> class in
00187      * place of the std::vector<T> class to get better performance.
00188      #ifdef NDEBUG
00189         #undef _SECURE_SCL
00190         #define _SECURE_SCL 0
00191      #endif
00192      */
00193 #else
00194     #define SimTK_SimTKCOMMON_EXPORT // Linux, Mac
00195 #endif
00196 
00197 /* Every SimTK Core library must provide these two routines, with the library
00198  * name appearing after the "version_" and "about_".
00199  */
00200 #if defined(__cplusplus)
00201 extern "C" {
00202 #endif
00203 
00204     SimTK_SimTKCOMMON_EXPORT void SimTK_version_SimTKcommon(int* major, int* minor, int* build);
00211     SimTK_SimTKCOMMON_EXPORT void SimTK_about_SimTKcommon(const char* key, int maxlen, char* value);
00212 #if defined(__cplusplus)
00213 }
00214 #endif
00215 
00216 /************************************/
00217 /* END OF ANSI-C COMPATIBLE SECTION */
00218 /************************************/
00219 
00220 #if defined(__cplusplus)
00221 
00222 #include <cstddef>
00223 #include <cassert>
00224 #include <cmath>
00225 #include <cfloat>
00226 #include <complex>
00227 #include <limits>
00228 #include <typeinfo>
00229 
00230 
00231 /* Currently (Microsoft VC++ 9) these C99-compatible floating point functions 
00232 are missing. We'll create them here and install them into namespace std.
00233 TODO: This should be removed when these are available. */
00234 #ifdef _MSC_VER
00235 namespace std {
00236 inline bool isfinite(float f) {return _finite(f) != 0;}
00237 inline bool isfinite(double d) {return _finite(d) != 0;}
00238 inline bool isfinite(long double l) {return _finite(l) != 0;}
00239 inline bool isnan(float f) {return _isnan(f) != 0;}
00240 inline bool isnan(double d) {return _isnan(d) != 0;}
00241 inline bool isnan(long double l) {return _isnan(l) != 0;}
00242 inline bool isinf(float f) {return std::abs(f)==std::numeric_limits<float>::infinity();}
00243 inline bool isinf(double d) {return std::abs(d)==std::numeric_limits<double>::infinity();}
00244 inline bool isinf(long double l) {return std::abs(l)==std::numeric_limits<double>::infinity();}
00245 inline bool signbit(float f) {return (*reinterpret_cast<unsigned*>(&f) & 0x80000000U) != 0;}
00246 inline bool signbit(double d) {return (*reinterpret_cast<unsigned long long*>(&d)
00247                                & 0x8000000000000000ULL) != 0;}
00248 inline bool signbit(long double l) {return (*reinterpret_cast<unsigned long long*>(&l)
00249                                     & 0x8000000000000000ULL) != 0;}
00250 }
00251 #endif
00252 
00253 
00254 namespace SimTK {
00255 // This utility answers the question "if I put this integral value in an int and then
00256 // get it back, will its value be the same?".
00257 inline bool canStoreInInt(bool)            {return true;}
00258 inline bool canStoreInInt(char)            {return true;}
00259 inline bool canStoreInInt(unsigned char)   {return true;}
00260 inline bool canStoreInInt(signed char)     {return true;}
00261 inline bool canStoreInInt(short)           {return true;}
00262 inline bool canStoreInInt(unsigned short)  {return true;}
00263 inline bool canStoreInInt(int)             {return true;}
00264 inline bool canStoreInInt(unsigned int  u) {return (unsigned int)(int(u)) == u;}
00265 inline bool canStoreInInt(long i)          {return long(int(i)) == i;}
00266 inline bool canStoreInInt(unsigned long u) {return (unsigned long)(int(u)) == u;}
00267 inline bool canStoreInInt(long long i)          {return (long long)(int(i)) == i;}
00268 inline bool canStoreInInt(unsigned long long u) {return (unsigned long long)(int(u)) == u;}
00269 
00270 // This utility answers the question "is this integral value a nonnegative number
00271 // that can be stored in an int?".
00272 inline bool canStoreInNonnegativeInt(bool)             {return true;}
00273 inline bool canStoreInNonnegativeInt(char c)           {return c >= 0;}
00274 inline bool canStoreInNonnegativeInt(unsigned char c)  {return true;}
00275 inline bool canStoreInNonnegativeInt(signed char c)    {return c >= 0;}
00276 inline bool canStoreInNonnegativeInt(short s)          {return s >= 0;}
00277 inline bool canStoreInNonnegativeInt(unsigned short s) {return true;}
00278 inline bool canStoreInNonnegativeInt(int  i)           {return i >= 0;}
00279 inline bool canStoreInNonnegativeInt(long l)           {return canStoreInInt(l) && l >= 0;}
00280 inline bool canStoreInNonnegativeInt(long long l)      {return canStoreInInt(l) && l >= 0;}
00281 inline bool canStoreInNonnegativeInt(unsigned int  u)  {return canStoreInInt(u);}
00282 inline bool canStoreInNonnegativeInt(unsigned long u)  {return canStoreInInt(u);}
00283 inline bool canStoreInNonnegativeInt(unsigned long long u) {return canStoreInInt(u);}
00284 
00285 // This utility answers the question of whether an integer is suitable as a size
00286 // limited by the given maximum size. Signed types must be checked for being
00287 // nonegative; doing that with unsigned types leads to compiler warnings.
00288 
00289 // char can be signed or unsigned depending on the compiler; assume signed.
00290 inline bool isSizeInRange(char           sz, char           mx){return 0<=sz&&sz<=mx;}
00291 inline bool isSizeInRange(signed char    sz, signed char    mx){return 0<=sz&&sz<=mx;}
00292 inline bool isSizeInRange(short          sz, short          mx){return 0<=sz&&sz<=mx;}
00293 inline bool isSizeInRange(int            sz, int            mx){return 0<=sz&&sz<=mx;}
00294 inline bool isSizeInRange(long           sz, long           mx){return 0<=sz&&sz<=mx;}
00295 inline bool isSizeInRange(long long      sz, long long      mx){return 0<=sz&&sz<=mx;}
00296 inline bool isSizeInRange(unsigned char  sz, unsigned char  mx){return sz<=mx;}
00297 inline bool isSizeInRange(unsigned short sz, unsigned short mx){return sz<=mx;}
00298 inline bool isSizeInRange(unsigned int   sz, unsigned int   mx){return sz<=mx;}
00299 inline bool isSizeInRange(unsigned long  sz, unsigned long  mx){return sz<=mx;}
00300 inline bool isSizeInRange(unsigned long long sz, unsigned long long mx){return sz<=mx;}
00301 
00302 // This utility answers the question of whether an integer is suitable as an index
00303 // for an array limited by the given maximum size. Signed types must be checked for being
00304 // nonegative; doing that with unsigned types leads to compiler warnings. This is just
00305 // like the "size in range" check above except the maximum value allowed for an index
00306 // is one less that the size.
00307 
00308 // char can be signed or unsigned depending on the compiler; assume signed.
00309 inline bool isIndexInRange(char           ix, char           sz){return 0<=ix&&ix<sz;}
00310 inline bool isIndexInRange(signed char    ix, signed char    sz){return 0<=ix&&ix<sz;}
00311 inline bool isIndexInRange(short          ix, short          sz){return 0<=ix&&ix<sz;}
00312 inline bool isIndexInRange(int            ix, int            sz){return 0<=ix&&ix<sz;}
00313 inline bool isIndexInRange(long           ix, long           sz){return 0<=ix&&ix<sz;}
00314 inline bool isIndexInRange(long long      ix, long long      sz){return 0<=ix&&ix<sz;}
00315 inline bool isIndexInRange(unsigned char  ix, unsigned char  sz){return ix<sz;}
00316 inline bool isIndexInRange(unsigned short ix, unsigned short sz){return ix<sz;}
00317 inline bool isIndexInRange(unsigned int   ix, unsigned int   sz){return ix<sz;}
00318 inline bool isIndexInRange(unsigned long  ix, unsigned long  sz){return ix<sz;}
00319 inline bool isIndexInRange(unsigned long long ix, unsigned long long sz){return ix<sz;}
00320 
00321 // This utility answers the question: is this integral value nonnegative? The answer
00322 // is always true for unsigned types and you'll get a warning from some compilers if
00323 // you check.
00324 
00325 inline bool isNonnegative(bool           n){return true;}
00326 // char can be signed or unsigned depending on the compiler; assume signed.
00327 inline bool isNonnegative(char           n){return n>=0;}
00328 inline bool isNonnegative(signed char    n){return n>=0;}
00329 inline bool isNonnegative(short          n){return n>=0;}
00330 inline bool isNonnegative(int            n){return n>=0;}
00331 inline bool isNonnegative(long           n){return n>=0;}
00332 inline bool isNonnegative(long long      n){return n>=0;}
00333 inline bool isNonnegative(unsigned char  n){return true;}
00334 inline bool isNonnegative(unsigned short n){return true;}
00335 inline bool isNonnegative(unsigned int   n){return true;}
00336 inline bool isNonnegative(unsigned long  n){return true;}
00337 inline bool isNonnegative(unsigned long long n){return true;}
00338 
00339 // A NaN-like value for unique index types created using the macro
00340 // SimTK_DEFINE_UNIQUE_INDEX_TYPE(). A unique, typed constant with
00341 // this numerical value is created for each index type.
00342 static const int InvalidIndex = -1111111111;
00343 }
00344 
00376 #define SimTK_DEFINE_UNIQUE_INDEX_TYPE(NAME)                   \
00377     SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,,,NAME)   \
00378     static const NAME Invalid ## NAME;
00379 
00382 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_INDEX_TYPE(EXPORT,NAME)     \
00383     SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,,,NAME) \
00384     static const NAME Invalid ## NAME;
00385 
00387 #define SimTK_DEFINE_UNIQUE_LOCAL_INDEX_TYPE(PARENT,NAME) \
00388     SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,PARENT,::,NAME)
00389 
00392 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,PARENT,SEP,NAME)   \
00393 class EXPORT NAME {                         \
00394     int ix;                                 \
00395 public:                                     \
00396     NAME() : ix(SimTK::InvalidIndex) { }       \
00397     explicit NAME(int i) : ix(i)      {assert(i>=0 || i==SimTK::InvalidIndex);} \
00398     explicit NAME(long l): ix((int)l) {assert(SimTK::canStoreInNonnegativeInt(l));}    \
00399     explicit NAME(unsigned int  u)  : ix((int)u)  {assert(SimTK::canStoreInInt(u));}   \
00400     explicit NAME(unsigned long ul) : ix((int)ul) {assert(SimTK::canStoreInInt(ul));}  \
00401     operator int() const {return ix;}               \
00402     bool isValid() const {return ix>=0;}            \
00403     bool isValidExtended() const {return ix>=-1;}   \
00404     void invalidate(){ix=SimTK::InvalidIndex;}      \
00405     \
00406     bool operator==(int  i) const {assert(isValidExtended() && isValidExtended(i)); return ix==i;}    \
00407     bool operator==(short s) const{assert(isValidExtended() && isValidExtended(s)); return ix==(int)s;}  \
00408     bool operator==(long l) const {assert(isValidExtended() && isValidExtended(l)); return ix==(int)l;}  \
00409     bool operator==(unsigned int  u)  const {assert(isValidExtended() && isValid(u)); return ix==(int)u;}   \
00410     bool operator==(unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix==(int)us;} \
00411     bool operator==(unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix==(int)ul;} \
00412     bool operator!=(int  i)           const {return !operator==(i);}    \
00413     bool operator!=(short s)          const {return !operator==(s);}    \
00414     bool operator!=(long l)           const {return !operator==(l);}    \
00415     bool operator!=(unsigned int  u)  const {return !operator==(u);}    \
00416     bool operator!=(unsigned long ul) const {return !operator==(ul);}   \
00417     \
00418     bool operator< (int  i) const {assert(isValidExtended() && isValidExtended(i)); return ix<i;}        \
00419     bool operator< (short s) const{assert(isValidExtended() && isValidExtended(s)); return ix<(int)s;}   \
00420     bool operator< (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix<(int)l;}   \
00421     bool operator< (unsigned int  u)  const {assert(isValidExtended() && isValid(u));  return ix<(int)u;}    \
00422     bool operator< (unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix<(int)us;}   \
00423     bool operator< (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix<(int)ul;}   \
00424     bool operator>=(int  i)           const {return !operator<(i);}    \
00425     bool operator>=(short s)          const {return !operator<(s);}    \
00426     bool operator>=(long l)           const {return !operator<(l);}    \
00427     bool operator>=(unsigned int  u)  const {return !operator<(u);}    \
00428     bool operator>=(unsigned short us)const {return !operator<(us);}   \
00429     bool operator>=(unsigned long ul) const {return !operator<(ul);}   \
00430     \
00431     bool operator> (int  i) const {assert(isValidExtended() && isValidExtended(i)); return ix>i;}        \
00432     bool operator> (short s) const{assert(isValidExtended() && isValidExtended(s)); return ix>(int)s;}   \
00433     bool operator> (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix>(int)l;}   \
00434     bool operator> (unsigned int  u)  const {assert(isValidExtended() && isValid(u));  return ix>(int)u;}    \
00435     bool operator> (unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix>(int)us;}   \
00436     bool operator> (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix>(int)ul;}   \
00437     bool operator<=(int  i)           const {return !operator>(i);}    \
00438     bool operator<=(short s)          const {return !operator>(s);}    \
00439     bool operator<=(long l)           const {return !operator>(l);}    \
00440     bool operator<=(unsigned int  u)  const {return !operator>(u);}    \
00441     bool operator<=(unsigned short us)const {return !operator>(us);}   \
00442     bool operator<=(unsigned long ul) const {return !operator>(ul);}   \
00443     \
00444     const NAME& operator++() {assert(isValid()); ++ix; return *this;}       /*prefix */   \
00445     NAME operator++(int)     {assert(isValid()); ++ix; return NAME(ix-1);}  /*postfix*/   \
00446     const NAME& operator--() {assert(isValid()); --ix; return *this;}       /*prefix */   \
00447     NAME operator--(int)     {assert(isValid()); --ix; return NAME(ix+1);}  /*postfix*/   \
00448     \
00449     NAME& operator+=(int i)  {assert(isValid() && isValidExtended(ix+i)); ix+=i; return *this;}     \
00450     NAME& operator-=(int i)  {assert(isValid() && isValidExtended(ix-i)); ix-=i; return *this;}     \
00451     NAME& operator+=(short s){assert(isValid() && SimTK::canStoreInInt(s) && isValidExtended(ix+(int)s)); ix+=(int)s; return *this;}     \
00452     NAME& operator-=(short s){assert(isValid() && SimTK::canStoreInInt(s) && isValidExtended(ix-(int)s)); ix-=(int)s; return *this;}     \
00453     NAME& operator+=(long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix+(int)l)); ix+=(int)l; return *this;}     \
00454     NAME& operator-=(long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix-(int)l)); ix-=(int)l; return *this;}     \
00455     NAME& operator+=(unsigned int  u)  {assert(isValid()&& SimTK::canStoreInInt(u)  && isValid(ix+(int)u));  ix+=(int)u;  return *this;}  \
00456     NAME& operator-=(unsigned int  u)  {assert(isValid()&& SimTK::canStoreInInt(u)  && isValidExtended(ix-(int)u));  ix-=(int)u;  return *this;}  \
00457     NAME& operator+=(unsigned short us){assert(isValid()&& SimTK::canStoreInInt(us) && isValid(ix+(int)us)); ix+=(int)us; return *this;}  \
00458     NAME& operator-=(unsigned short us){assert(isValid()&& SimTK::canStoreInInt(us) && isValidExtended(ix-(int)us)); ix-=(int)us; return *this;}  \
00459     NAME& operator+=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValid(ix+(int)ul)); ix+=(int)ul; return *this;}  \
00460     NAME& operator-=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValidExtended(ix-(int)ul)); ix-=(int)ul; return *this;}  \
00461     \
00462     static const NAME& Invalid() {static const NAME invalid; return invalid;}       \
00463     static bool isValid(int  i) {return i>=0;}                                      \
00464     static bool isValid(short s){return s>=0;}                                      \
00465     static bool isValid(long l) {return SimTK::canStoreInNonnegativeInt(l);}        \
00466     static bool isValid(unsigned int  u)  {return SimTK::canStoreInInt(u);}         \
00467     static bool isValid(unsigned short)   {return true;}                            \
00468     static bool isValid(unsigned long ul) {return SimTK::canStoreInInt(ul);}        \
00469     static bool isValidExtended(int  i) {return i>=-1;}                             \
00470     static bool isValidExtended(short s){return s>=-1;}                             \
00471     static bool isValidExtended(long l) {return SimTK::canStoreInInt(l) && l>=-1;}  \
00472     /* IndexTraits for use in Array_<T,X> with this as X; same as int */            \
00473     typedef int size_type;                                                  \
00474     typedef int difference_type;                                            \
00475     static size_type max_size() {return std::numeric_limits<int>::max();}   \
00476 };
00477 
00481 #define SimTK_DOWNCAST(Derived,Parent) \
00482     static bool isA(const Parent& p)                        \
00483         { return dynamic_cast<const Derived*>(&p) != 0; }   \
00484     static const Derived& downcast(const Parent& p)         \
00485         { return dynamic_cast<const Derived&>(p); }         \
00486     static Derived& updDowncast(Parent& p)                  \
00487         { return dynamic_cast<Derived&>(p); }               \
00488     static Derived& downcast(Parent& p)                     \
00489         { return dynamic_cast<Derived&>(p); }
00490 
00493 #define SimTK_DOWNCAST2(Derived,Helper,Parent) \
00494     static bool isA(const Parent& p)                                        \
00495         { return Helper::isA(p); }                                          \
00496     static const Derived& downcast(const Parent& p)                         \
00497         { return reinterpret_cast<const Derived&>(Helper::downcast(p)); }   \
00498     static Derived& updDowncast(Parent& p)                                  \
00499         { return reinterpret_cast<Derived&>(Helper::downcast(p)); }         \
00500     static Derived& downcast(Parent& p)                                     \
00501         { return reinterpret_cast<Derived&>(Helper::downcast(p)); }
00502 
00503 
00507 #define SimTK_PIMPL_DOWNCAST(Derived, Parent)           \
00508     static bool           isInstanceOf(const Parent&);  \
00509     static const Derived& downcast(const Parent&);      \
00510     static Derived&       updDowncast(Parent&)
00511 
00512 namespace SimTK {
00513     
00514 namespace Options { }
00515 namespace Exception { }
00516 
00519 typedef SimTK_Real              Real;
00522 typedef std::complex<Real>      Complex;
00523 
00526 struct Segment {
00527     Segment() : length(0), offset(0) { }
00528     explicit Segment(int l, int ofs=0) : length(l), offset(ofs) { 
00529         assert(l>=0 && ofs>=0);
00530     }
00531     // default copy, assignment, destructor
00532     int length;
00533     int offset;
00534 };  
00535 
00536 
00542 struct DontCopy {};
00546 struct TrustMe {};
00547 
00550 struct FalseType {};
00553 struct TrueType {};
00554 
00556 template <class L, class R> struct AndOpType {};
00557 template<> struct AndOpType<FalseType,FalseType> {typedef FalseType Result;};
00558 template<> struct AndOpType<FalseType,TrueType>  {typedef FalseType Result;};
00559 template<> struct AndOpType<TrueType, FalseType> {typedef FalseType Result;};
00560 template<> struct AndOpType<TrueType, TrueType>  {typedef TrueType  Result;};
00561 
00563 template <class L, class R> struct OrOpType {};
00564 template<> struct OrOpType<FalseType,FalseType> {typedef FalseType Result;};
00565 template<> struct OrOpType<FalseType,TrueType>  {typedef TrueType  Result;};
00566 template<> struct OrOpType<TrueType, FalseType> {typedef TrueType  Result;};
00567 template<> struct OrOpType<TrueType, TrueType>  {typedef TrueType  Result;};
00568 
00570 template <class L, class R> struct XorOpType {};
00571 template<> struct XorOpType<FalseType,FalseType> {typedef FalseType Result;};
00572 template<> struct XorOpType<FalseType,TrueType>  {typedef TrueType  Result;};
00573 template<> struct XorOpType<TrueType, FalseType> {typedef TrueType  Result;};
00574 template<> struct XorOpType<TrueType, TrueType>  {typedef FalseType Result;};
00575 
00577 template <class T> struct IsIntegralType {
00580     typedef FalseType Result;
00583     static const bool result = false;
00584 };
00587 #define SimTK_SPECIALIZE_INTEGRAL_TYPE(T)       \
00588     template<> struct IsIntegralType<T>         \
00589     {typedef TrueType Result; static const bool result = true;}
00590 
00591 SimTK_SPECIALIZE_INTEGRAL_TYPE(bool); 
00592 SimTK_SPECIALIZE_INTEGRAL_TYPE(char);
00593 SimTK_SPECIALIZE_INTEGRAL_TYPE(wchar_t);
00594 SimTK_SPECIALIZE_INTEGRAL_TYPE(signed char);
00595 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned char);
00596 SimTK_SPECIALIZE_INTEGRAL_TYPE(short);
00597 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned short);
00598 SimTK_SPECIALIZE_INTEGRAL_TYPE(int);
00599 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned int); // a.k.a. "unsigned"
00600 SimTK_SPECIALIZE_INTEGRAL_TYPE(long);
00601 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned long);
00602 SimTK_SPECIALIZE_INTEGRAL_TYPE(long long);
00603 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned long long);
00604 
00606 template <class T> struct IsFloatingType {
00609     typedef FalseType Result;
00612     static const bool result = false;
00613 };
00616 #define SimTK_SPECIALIZE_FLOATING_TYPE(T)       \
00617     template<> struct IsFloatingType<T>         \
00618     {typedef TrueType Result; static const bool result = true;}
00619 
00620 SimTK_SPECIALIZE_FLOATING_TYPE(float); 
00621 SimTK_SPECIALIZE_FLOATING_TYPE(double); 
00622 SimTK_SPECIALIZE_FLOATING_TYPE(long double); 
00623 
00625 template <class T> struct IsVoidType {
00628     typedef FalseType Result;
00631     static const bool result = false;
00632 };
00633 template<> struct IsVoidType<void> 
00634 {typedef TrueType Result; static const bool result = true;};
00635 
00638 template <class T> struct IsArithmeticType {
00641     typedef OrOpType<typename IsIntegralType<T>::Result,
00642                      typename IsFloatingType<T>::Result>    Result;
00645     static const bool result = IsIntegralType<T>::result 
00646                             || IsFloatingType<T>::result;
00647 };
00648 
00649 // This struct's sole use is to allow us to define the typedef 
00650 // Is64BitPlatformType as equivalent to either TrueType or FalseType.
00651 template <bool is64Bit> struct Is64BitHelper {};
00652 template<> struct Is64BitHelper<true>  
00653 {typedef TrueType  Result; static const bool result = true;};
00654 template<> struct Is64BitHelper<false> 
00655 {typedef FalseType Result; static const bool result = false;};
00656 
00661 static const bool Is64BitPlatform = sizeof(size_t) > sizeof(int);
00662 typedef Is64BitHelper<Is64BitPlatform>::Result Is64BitPlatformType;
00663 
00664 
00668 template <class T> struct NiceTypeName {
00669     static const char* name() {return typeid(T).name();}
00670 };
00671 
00675 #define SimTK_NICETYPENAME_LITERAL(T)           \
00676 template <> struct NiceTypeName< T > {          \
00677     static const char* name() { return #T; }    \
00678 };
00679 
00680 // Some types for which we'd like to see nice type names.
00681 SimTK_NICETYPENAME_LITERAL(bool);            
00682 SimTK_NICETYPENAME_LITERAL(char);            
00683 SimTK_NICETYPENAME_LITERAL(wchar_t);            
00684 SimTK_NICETYPENAME_LITERAL(signed char); 
00685 SimTK_NICETYPENAME_LITERAL(unsigned char);
00686 SimTK_NICETYPENAME_LITERAL(short);           
00687 SimTK_NICETYPENAME_LITERAL(unsigned short);  
00688 SimTK_NICETYPENAME_LITERAL(int); 
00689 SimTK_NICETYPENAME_LITERAL(unsigned); // preferred to "unsigned int"
00690 SimTK_NICETYPENAME_LITERAL(long);            
00691 SimTK_NICETYPENAME_LITERAL(unsigned long);   
00692 SimTK_NICETYPENAME_LITERAL(long long);
00693 SimTK_NICETYPENAME_LITERAL(unsigned long long);
00694 SimTK_NICETYPENAME_LITERAL(float);           
00695 SimTK_NICETYPENAME_LITERAL(double); 
00696 SimTK_NICETYPENAME_LITERAL(long double);
00697 SimTK_NICETYPENAME_LITERAL(std::complex<float>);
00698 SimTK_NICETYPENAME_LITERAL(std::complex<double>); 
00699 SimTK_NICETYPENAME_LITERAL(std::complex<long double>); 
00700 SimTK_NICETYPENAME_LITERAL(SimTK::FalseType);
00701 SimTK_NICETYPENAME_LITERAL(SimTK::TrueType); 
00702 
00703 } // namespace SimTK
00704 
00705 #endif /* C++ stuff */
00706 
00707 #endif /* SimTK_SimTKCOMMON_COMMON_H_ */

Generated on Thu Aug 12 16:37:05 2010 for SimTKcore by  doxygen 1.6.1