Simbody  3.5
common.h
Go to the documentation of this file.
00001 #ifndef SimTK_SimTKCOMMON_COMMON_H_
00002 #define SimTK_SimTKCOMMON_COMMON_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                       Simbody(tm): SimTKcommon                             *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK 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/home/simbody.  *
00011  *                                                                            *
00012  * Portions copyright (c) 2005-14 Stanford University and the Authors.        *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors: Chris Dembia                                                 *
00015  *                                                                            *
00016  * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
00017  * not use this file except in compliance with the License. You may obtain a  *
00018  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
00019  *                                                                            *
00020  * Unless required by applicable law or agreed to in writing, software        *
00021  * distributed under the License is distributed on an "AS IS" BASIS,          *
00022  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
00023  * See the License for the specific language governing permissions and        *
00024  * limitations under the License.                                             *
00025  * -------------------------------------------------------------------------- */
00026 
00039 // Provide doxygen documentation for the SimTK namespace.
00040 
00049 // Define shared doxygen "modules" and sub-modules here. We'll put things 
00050 // in them at various places when appropriate.
00051 
00091 /*****************************/
00092 /* ANSI-C COMPATIBLE SECTION */
00093 /*****************************/
00094 
00095 /* Set up a few compile-time options that affect all SimTK Core headers. */
00096 
00104 #ifndef SimTK_DEFAULT_PRECISION
00105 #   define SimTK_DEFAULT_PRECISION 2
00106 #endif
00107 
00108 #if   (SimTK_DEFAULT_PRECISION == 1)
00109 
00110     typedef float SimTK_Real;
00111 #elif (SimTK_DEFAULT_PRECISION == 2)
00112 
00113     typedef double SimTK_Real;
00114 #elif (SimTK_DEFAULT_PRECISION == 4)
00115 
00116     typedef long double SimTK_Real;
00117 #else
00118     #error ILLEGAL VALUE FOR DEFAULT PRECISION
00119 #endif
00120 
00121 #ifndef NDEBUG
00122     #if defined(__cplusplus)
00123         #include <cstdio>
00124         #define SimTK_DEBUG(s) std::printf("DBG: " s)
00125         #define SimTK_DEBUG1(s,a1) std::printf("DBG: " s,a1)    
00126         #define SimTK_DEBUG2(s,a1,a2) std::printf("DBG: " s,a1,a2)    
00127         #define SimTK_DEBUG3(s,a1,a2,a3) std::printf("DBG: " s,a1,a2,a3)    
00128         #define SimTK_DEBUG4(s,a1,a2,a3,a4) std::printf("DBG: " s,a1,a2,a3,a4)
00129     #else
00130         #include <stdio.h>
00131         #define SimTK_DEBUG(s) printf("DBG: " s)
00132         #define SimTK_DEBUG1(s,a1) printf("DBG: " s,a1)    
00133         #define SimTK_DEBUG2(s,a1,a2) printf("DBG: " s,a1,a2)    
00134         #define SimTK_DEBUG3(s,a1,a2,a3) printf("DBG: " s,a1,a2,a3)    
00135         #define SimTK_DEBUG4(s,a1,a2,a3,a4) printf("DBG: " s,a1,a2,a3,a4)
00136     #endif
00137 #else
00138     #define SimTK_DEBUG(s)
00139     #define SimTK_DEBUG1(s,a1)
00140     #define SimTK_DEBUG2(s,a1,a2)
00141     #define SimTK_DEBUG3(s,a1,a2,a3)    
00142     #define SimTK_DEBUG4(s,a1,a2,a3,a4)
00143 #endif
00144 
00145 /*
00146  * Shared libraries are messy in Visual Studio. We have to distinguish three
00147  * cases:
00148  *   (1) this header is being used to build the SimTKcommon shared library (dllexport)
00149  *   (2) this header is being used by a *client* of the SimTKcommon shared
00150  *       library (dllimport)
00151  *   (3) we are building the SimTKcommon static library, or the client is
00152  *       being compiled with the expectation of linking with the
00153  *       SimTKcommon static library (nothing special needed)
00154  * In the CMake script for building this library, we define one of the symbols
00155  *     SimTK_SimTKCOMMON_BUILDING_{SHARED|STATIC}_LIBRARY
00156  * Client code normally has no special symbol defined, in which case we'll
00157  * assume it wants to use the shared library. However, if the client defines
00158  * the symbol SimTK_USE_STATIC_LIBRARIES we'll suppress the dllimport so
00159  * that the client code can be linked with static libraries. Note that
00160  * the client symbol is not library dependent, while the library symbols
00161  * affect only the SimTKcommon library, meaning that other libraries can
00162  * be clients of this one. However, we are assuming all-static or all-shared.
00163  */
00164 
00165 #ifdef _WIN32
00166     #ifdef _MSC_VER
00167     #pragma warning(disable:4231) /*need to use 'extern' template explicit instantiation*/
00168     #pragma warning(disable:4251) /*no DLL interface for type of member of exported class*/
00169     #pragma warning(disable:4275) /*no DLL interface for base class of exported class*/
00170     #pragma warning(disable:4345) /*warning about PODs being default-initialized*/
00171     #endif
00172     #if defined(SimTK_SimTKCOMMON_BUILDING_SHARED_LIBRARY)
00173         #define SimTK_SimTKCOMMON_EXPORT __declspec(dllexport)
00174         /* Keep MS VC++ quiet when it tries to instantiate incomplete template classes in a DLL. */
00175         #ifdef _MSC_VER
00176         #pragma warning(disable:4661)
00177         #endif
00178     #elif defined(SimTK_SimTKCOMMON_BUILDING_STATIC_LIBRARY) || defined(SimTK_USE_STATIC_LIBRARIES)
00179         #define SimTK_SimTKCOMMON_EXPORT
00180     #else
00181         #define SimTK_SimTKCOMMON_EXPORT __declspec(dllimport) /*i.e., a client of a shared library*/
00182     #endif
00183     /* VC++ tries to be secure by leaving bounds checking on for STL containers
00184      * even in Release mode. This macro exists to disable that feature and can
00185      * result in a considerable speedup.
00186      * CAUTION: every linked-together compilation unit must have this set the same
00187      * way. Everyone who properly includes this file first is fine; but as of this
00188      * writing Simmath's IpOpt doesn't do so.
00189      * NOTE: Microsoft corrected this problem with VC10 -- the feature is 
00190      * disabled by default in that compiler and later.
00191      */
00192     /* (sherm 081204 disabling for now: doesn't work on VC++ 8 and is 
00193      * tricky on VC++ 9 because all libraries, including 3rd party, must
00194      * be built the same way). Better to use the SimTK::Array_<T> class in
00195      * place of the std::vector<T> class to get better performance.
00196      #ifdef NDEBUG
00197          #undef _SECURE_SCL
00198          #define _SECURE_SCL 0
00199      #endif
00200      */
00201 #else
00202     #define SimTK_SimTKCOMMON_EXPORT // Linux, Mac
00203 #endif
00204 
00205 /* Every SimTK Core library must provide these two routines, with the library
00206  * name appearing after the "version_" and "about_".
00207  */
00208 #if defined(__cplusplus)
00209 extern "C" {
00210 #endif
00211 
00212     SimTK_SimTKCOMMON_EXPORT void SimTK_version_SimTKcommon(int* major, int* minor, int* build);
00219     SimTK_SimTKCOMMON_EXPORT void SimTK_about_SimTKcommon(const char* key, int maxlen, char* value);
00220 #if defined(__cplusplus)
00221 }
00222 #endif
00223 
00224 /************************************/
00225 /* END OF ANSI-C COMPATIBLE SECTION */
00226 /************************************/
00227 
00228 #if defined(__cplusplus)
00229 
00230 #include <cstddef>
00231 #include <cassert>
00232 #include <cstring>
00233 #include <cmath>
00234 #include <cfloat>
00235 #include <complex>
00236 #include <limits>
00237 #include <typeinfo>
00238 #include <algorithm>
00239 
00240 /* Transition macros for C++11 support. VC10 and VC11 have partial support for
00241 C++11, early VC's do not. If using gcc or Clang, we check for C++11 support. */
00242 #ifndef SWIG
00243     #if _MSC_VER>=1700 || (defined(__GNUG__) && __cplusplus>=201103L)
00244         /* VC11 or higher, OR using gcc or Clang and using C++11 */
00245         #define OVERRIDE_11  override
00246         #define FINAL_11     final
00247     #elif _MSC_VER==1600 /* VC10 */
00248         #define OVERRIDE_11  override
00249         #define FINAL_11     sealed
00250     #else /* gcc or Clang without C++11, or earlier VC */
00251         #define OVERRIDE_11
00252         #define FINAL_11
00253     #endif
00254 #else /* Swigging */
00255     #define OVERRIDE_11
00256     #define FINAL_11
00257 #endif
00258 
00259 /* Be very careful with this macro -- don't use it unless you have measured
00260 a performance improvement. You can end up with serious code bloat if you 
00261 override the compiler's judgement about when to inline, and that can cause
00262 cache misses which ultimately reduce performance. */
00263 #ifdef _MSC_VER
00264     #define SimTK_FORCE_INLINE __forceinline
00265 #else
00266     #define SimTK_FORCE_INLINE __attribute__((always_inline))
00267 #endif
00268 
00269 
00270 /* In Microsoft VC++ 11 (2012) and earlier these C99-compatible floating 
00271 point functions are missing. We'll create them here and install them into 
00272 namespace std. They were added in VC++ 12 (2013). */
00273 #if defined(_MSC_VER) && (_MSC_VER <= 1700) // VC++ 12 (2013, _MSC_VER=1800) added these
00274 namespace std {
00275 inline bool isfinite(float f) {return _finite(f) != 0;}
00276 inline bool isfinite(double d) {return _finite(d) != 0;}
00277 inline bool isfinite(long double l) {return _finite(l) != 0;}
00278 inline bool isnan(float f) {return _isnan(f) != 0;}
00279 inline bool isnan(double d) {return _isnan(d) != 0;}
00280 inline bool isnan(long double l) {return _isnan(l) != 0;}
00281 inline bool isinf(float f) {return std::abs(f)==std::numeric_limits<float>::infinity();}
00282 inline bool isinf(double d) {return std::abs(d)==std::numeric_limits<double>::infinity();}
00283 inline bool isinf(long double l) {return std::abs(l)==std::numeric_limits<double>::infinity();}
00284 inline bool signbit(float f) {return (*reinterpret_cast<unsigned*>(&f) & 0x80000000U) != 0;}
00285 inline bool signbit(double d) {return (*reinterpret_cast<unsigned long long*>(&d)
00286                                 & 0x8000000000000000ULL) != 0;}
00287 inline bool signbit(long double l) {return (*reinterpret_cast<unsigned long long*>(&l)
00288                                     & 0x8000000000000000ULL) != 0;}
00289 }
00290 #endif
00291 
00292 
00293 namespace SimTK {
00294 
00295 
00296 // This utility answers the question "if I put this integral value in an int and then
00297 // get it back, will its value be the same?".
00298 inline bool canStoreInInt(bool)            {return true;}
00299 inline bool canStoreInInt(char)            {return true;}
00300 inline bool canStoreInInt(unsigned char)   {return true;}
00301 inline bool canStoreInInt(signed char)     {return true;}
00302 inline bool canStoreInInt(short)           {return true;}
00303 inline bool canStoreInInt(unsigned short)  {return true;}
00304 inline bool canStoreInInt(int)             {return true;}
00305 inline bool canStoreInInt(unsigned int  u) {return (unsigned int)(int(u)) == u;}
00306 inline bool canStoreInInt(long i)          {return long(int(i)) == i;}
00307 inline bool canStoreInInt(unsigned long u) {return (unsigned long)(int(u)) == u;}
00308 inline bool canStoreInInt(long long i)          {return (long long)(int(i)) == i;}
00309 inline bool canStoreInInt(unsigned long long u) {return (unsigned long long)(int(u)) == u;}
00310 
00311 // This utility answers the question "is this integral value a nonnegative number
00312 // that can be stored in an int?".
00313 inline bool canStoreInNonnegativeInt(bool)             {return true;}
00314 inline bool canStoreInNonnegativeInt(char c)           {return c >= 0;}
00315 inline bool canStoreInNonnegativeInt(unsigned char)    {return true;}
00316 inline bool canStoreInNonnegativeInt(signed char c)    {return c >= 0;}
00317 inline bool canStoreInNonnegativeInt(short s)          {return s >= 0;}
00318 inline bool canStoreInNonnegativeInt(unsigned short)   {return true;}
00319 inline bool canStoreInNonnegativeInt(int  i)           {return i >= 0;}
00320 inline bool canStoreInNonnegativeInt(long l)           {return canStoreInInt(l) && l >= 0;}
00321 inline bool canStoreInNonnegativeInt(long long l)      {return canStoreInInt(l) && l >= 0;}
00322 inline bool canStoreInNonnegativeInt(unsigned int  u)  {return canStoreInInt(u);}
00323 inline bool canStoreInNonnegativeInt(unsigned long u)  {return canStoreInInt(u);}
00324 inline bool canStoreInNonnegativeInt(unsigned long long u) {return canStoreInInt(u);}
00325 
00326 // This utility answers the question of whether an integer is suitable as a size
00327 // limited by the given maximum size. Signed types must be checked for being
00328 // nonegative; doing that with unsigned types leads to compiler warnings.
00329 
00330 // char can be signed or unsigned depending on the compiler; assume signed.
00331 inline bool isSizeInRange(char           sz, char           mx){return 0<=sz&&sz<=mx;}
00332 inline bool isSizeInRange(signed char    sz, signed char    mx){return 0<=sz&&sz<=mx;}
00333 inline bool isSizeInRange(short          sz, short          mx){return 0<=sz&&sz<=mx;}
00334 inline bool isSizeInRange(int            sz, int            mx){return 0<=sz&&sz<=mx;}
00335 inline bool isSizeInRange(long           sz, long           mx){return 0<=sz&&sz<=mx;}
00336 inline bool isSizeInRange(long long      sz, long long      mx){return 0<=sz&&sz<=mx;}
00337 inline bool isSizeInRange(unsigned char  sz, unsigned char  mx){return sz<=mx;}
00338 inline bool isSizeInRange(unsigned short sz, unsigned short mx){return sz<=mx;}
00339 inline bool isSizeInRange(unsigned int   sz, unsigned int   mx){return sz<=mx;}
00340 inline bool isSizeInRange(unsigned long  sz, unsigned long  mx){return sz<=mx;}
00341 inline bool isSizeInRange(unsigned long long sz, unsigned long long mx){return sz<=mx;}
00342 
00343 // This utility answers the question of whether an integer is suitable as an index
00344 // for an array limited by the given maximum size. Signed types must be checked for being
00345 // nonegative; doing that with unsigned types leads to compiler warnings. This is just
00346 // like the "size in range" check above except the maximum value allowed for an index
00347 // is one less that the size.
00348 
00349 // char can be signed or unsigned depending on the compiler; assume signed.
00350 inline bool isIndexInRange(char           ix, char           sz){return 0<=ix&&ix<sz;}
00351 inline bool isIndexInRange(signed char    ix, signed char    sz){return 0<=ix&&ix<sz;}
00352 inline bool isIndexInRange(short          ix, short          sz){return 0<=ix&&ix<sz;}
00353 inline bool isIndexInRange(int            ix, int            sz){return 0<=ix&&ix<sz;}
00354 inline bool isIndexInRange(long           ix, long           sz){return 0<=ix&&ix<sz;}
00355 inline bool isIndexInRange(long long      ix, long long      sz){return 0<=ix&&ix<sz;}
00356 inline bool isIndexInRange(unsigned char  ix, unsigned char  sz){return ix<sz;}
00357 inline bool isIndexInRange(unsigned short ix, unsigned short sz){return ix<sz;}
00358 inline bool isIndexInRange(unsigned int   ix, unsigned int   sz){return ix<sz;}
00359 inline bool isIndexInRange(unsigned long  ix, unsigned long  sz){return ix<sz;}
00360 inline bool isIndexInRange(unsigned long long ix, unsigned long long sz){return ix<sz;}
00361 
00362 // This utility answers the question: is this integral value nonnegative? The answer
00363 // is always true for unsigned types and you'll get a warning from some compilers if
00364 // you check.
00365 
00366 inline bool isNonnegative(bool)              {return true;}
00367 // char can be signed or unsigned depending on the compiler; assume signed.
00368 inline bool isNonnegative(char        n)     {return n>=0;}
00369 inline bool isNonnegative(signed char n)     {return n>=0;}
00370 inline bool isNonnegative(short       n)     {return n>=0;}
00371 inline bool isNonnegative(int         n)     {return n>=0;}
00372 inline bool isNonnegative(long        n)     {return n>=0;}
00373 inline bool isNonnegative(long long   n)     {return n>=0;}
00374 inline bool isNonnegative(unsigned char)     {return true;}
00375 inline bool isNonnegative(unsigned short)    {return true;}
00376 inline bool isNonnegative(unsigned int)      {return true;}
00377 inline bool isNonnegative(unsigned long)     {return true;}
00378 inline bool isNonnegative(unsigned long long){return true;}
00379 
00380 // A NaN-like value for unique index types created using the macro
00381 // SimTK_DEFINE_UNIQUE_INDEX_TYPE(). A unique, typed constant with
00382 // this numerical value is created for each index type.
00383 static const int InvalidIndex = -1111111111;
00384 }
00385 
00386 
00387 
00419 #define SimTK_DEFINE_UNIQUE_INDEX_TYPE(NAME)                   \
00420     SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,,,NAME)   \
00421     static const NAME Invalid ## NAME;
00422 
00425 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_INDEX_TYPE(EXPORT,NAME)     \
00426     SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,,,NAME) \
00427     static const NAME Invalid ## NAME;
00428 
00430 #define SimTK_DEFINE_UNIQUE_LOCAL_INDEX_TYPE(PARENT,NAME) \
00431     SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,PARENT,::,NAME)
00432 
00435 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,PARENT,SEP,NAME)   \
00436 class EXPORT NAME {                         \
00437     int ix;                                 \
00438 public:                                     \
00439     NAME() : ix(SimTK::InvalidIndex) { }       \
00440     explicit NAME(int i) : ix(i)      {assert(i>=0 || i==SimTK::InvalidIndex);} \
00441     explicit NAME(long l): ix((int)l) {assert(SimTK::canStoreInNonnegativeInt(l));}    \
00442     explicit NAME(unsigned int  u)  : ix((int)u)  {assert(SimTK::canStoreInInt(u));}   \
00443     explicit NAME(unsigned long ul) : ix((int)ul) {assert(SimTK::canStoreInInt(ul));}  \
00444     operator int() const {return ix;}               \
00445     bool isValid() const {return ix>=0;}            \
00446     bool isValidExtended() const {return ix>=-1;}   \
00447     void invalidate(){ix=SimTK::InvalidIndex;}      \
00448     \
00449     bool operator==(int  i) const {assert(isValidExtended() && isValidExtended(i)); return ix==i;}    \
00450     bool operator==(short s) const{assert(isValidExtended() && isValidExtended(s)); return ix==(int)s;}  \
00451     bool operator==(long l) const {assert(isValidExtended() && isValidExtended(l)); return ix==(int)l;}  \
00452     bool operator==(unsigned int  u)  const {assert(isValidExtended() && isValid(u)); return ix==(int)u;}   \
00453     bool operator==(unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix==(int)us;} \
00454     bool operator==(unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix==(int)ul;} \
00455     bool operator!=(int  i)           const {return !operator==(i);}    \
00456     bool operator!=(short s)          const {return !operator==(s);}    \
00457     bool operator!=(long l)           const {return !operator==(l);}    \
00458     bool operator!=(unsigned int  u)  const {return !operator==(u);}    \
00459     bool operator!=(unsigned long ul) const {return !operator==(ul);}   \
00460     \
00461     bool operator< (int  i) const {assert(isValidExtended() && isValidExtended(i)); return ix<i;}        \
00462     bool operator< (short s) const{assert(isValidExtended() && isValidExtended(s)); return ix<(int)s;}   \
00463     bool operator< (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix<(int)l;}   \
00464     bool operator< (unsigned int  u)  const {assert(isValidExtended() && isValid(u));  return ix<(int)u;}    \
00465     bool operator< (unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix<(int)us;}   \
00466     bool operator< (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix<(int)ul;}   \
00467     bool operator>=(int  i)           const {return !operator<(i);}    \
00468     bool operator>=(short s)          const {return !operator<(s);}    \
00469     bool operator>=(long l)           const {return !operator<(l);}    \
00470     bool operator>=(unsigned int  u)  const {return !operator<(u);}    \
00471     bool operator>=(unsigned short us)const {return !operator<(us);}   \
00472     bool operator>=(unsigned long ul) const {return !operator<(ul);}   \
00473     \
00474     bool operator> (int  i) const {assert(isValidExtended() && isValidExtended(i)); return ix>i;}        \
00475     bool operator> (short s) const{assert(isValidExtended() && isValidExtended(s)); return ix>(int)s;}   \
00476     bool operator> (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix>(int)l;}   \
00477     bool operator> (unsigned int  u)  const {assert(isValidExtended() && isValid(u));  return ix>(int)u;}    \
00478     bool operator> (unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix>(int)us;}   \
00479     bool operator> (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix>(int)ul;}   \
00480     bool operator<=(int  i)           const {return !operator>(i);}    \
00481     bool operator<=(short s)          const {return !operator>(s);}    \
00482     bool operator<=(long l)           const {return !operator>(l);}    \
00483     bool operator<=(unsigned int  u)  const {return !operator>(u);}    \
00484     bool operator<=(unsigned short us)const {return !operator>(us);}   \
00485     bool operator<=(unsigned long ul) const {return !operator>(ul);}   \
00486     \
00487     const NAME& operator++() {assert(isValid()); ++ix; return *this;}       /*prefix */   \
00488     NAME operator++(int)     {assert(isValid()); ++ix; return NAME(ix-1);}  /*postfix*/   \
00489     const NAME& operator--() {assert(isValid()); --ix; return *this;}       /*prefix */   \
00490     NAME operator--(int)     {assert(isValid()); --ix; return NAME(ix+1);}  /*postfix*/   \
00491     NAME next() const {assert(isValid()); return NAME(ix+1);}                             \
00492     NAME prev() const {assert(isValid()); return NAME(ix-1);} /*might return -1*/         \
00493     \
00494     NAME& operator+=(int i)  {assert(isValid() && isValidExtended(ix+i)); ix+=i; return *this;}     \
00495     NAME& operator-=(int i)  {assert(isValid() && isValidExtended(ix-i)); ix-=i; return *this;}     \
00496     NAME& operator+=(short s){assert(isValid() && SimTK::canStoreInInt(s) && isValidExtended(ix+(int)s)); ix+=(int)s; return *this;}     \
00497     NAME& operator-=(short s){assert(isValid() && SimTK::canStoreInInt(s) && isValidExtended(ix-(int)s)); ix-=(int)s; return *this;}     \
00498     NAME& operator+=(long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix+(int)l)); ix+=(int)l; return *this;}     \
00499     NAME& operator-=(long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix-(int)l)); ix-=(int)l; return *this;}     \
00500     NAME& operator+=(unsigned int  u)  {assert(isValid()&& SimTK::canStoreInInt(u)  && isValid(ix+(int)u));  ix+=(int)u;  return *this;}  \
00501     NAME& operator-=(unsigned int  u)  {assert(isValid()&& SimTK::canStoreInInt(u)  && isValidExtended(ix-(int)u));  ix-=(int)u;  return *this;}  \
00502     NAME& operator+=(unsigned short us){assert(isValid()&& SimTK::canStoreInInt(us) && isValid(ix+(int)us)); ix+=(int)us; return *this;}  \
00503     NAME& operator-=(unsigned short us){assert(isValid()&& SimTK::canStoreInInt(us) && isValidExtended(ix-(int)us)); ix-=(int)us; return *this;}  \
00504     NAME& operator+=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValid(ix+(int)ul)); ix+=(int)ul; return *this;}  \
00505     NAME& operator-=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValidExtended(ix-(int)ul)); ix-=(int)ul; return *this;}  \
00506     \
00507     static const NAME& Invalid() {static const NAME invalid; return invalid;}       \
00508     static bool isValid(int  i) {return i>=0;}                                      \
00509     static bool isValid(short s){return s>=0;}                                      \
00510     static bool isValid(long l) {return SimTK::canStoreInNonnegativeInt(l);}        \
00511     static bool isValid(unsigned int  u)  {return SimTK::canStoreInInt(u);}         \
00512     static bool isValid(unsigned short)   {return true;}                            \
00513     static bool isValid(unsigned long ul) {return SimTK::canStoreInInt(ul);}        \
00514     static bool isValidExtended(int  i) {return i>=-1;}                             \
00515     static bool isValidExtended(short s){return s>=-1;}                             \
00516     static bool isValidExtended(long l) {return SimTK::canStoreInInt(l) && l>=-1;}  \
00517     /* IndexTraits for use in Array_<T,X> with this as X; same as int */            \
00518     typedef int size_type;                                                  \
00519     typedef int difference_type;                                            \
00520     static size_type max_size() {return std::numeric_limits<int>::max();}   \
00521 };
00522 
00529 #ifndef NDEBUG
00530     #define SimTK_DYNAMIC_CAST_DEBUG dynamic_cast   // safe but slow
00531 #else
00532     #define SimTK_DYNAMIC_CAST_DEBUG static_cast    // unsafe but fast
00533 #endif
00534 
00538 #define SimTK_DOWNCAST(Derived,Parent)                          \
00539     static bool isA(const Parent& p)                            \
00540         { return dynamic_cast<const Derived*>(&p) != 0; }       \
00541     static const Derived& downcast(const Parent& p)             \
00542         { return SimTK_DYNAMIC_CAST_DEBUG<const Derived&>(p); } \
00543     static Derived& updDowncast(Parent& p)                      \
00544         { return SimTK_DYNAMIC_CAST_DEBUG<Derived&>(p); }        \
00545     static Derived& downcast(Parent& p)                         \
00546         { return SimTK_DYNAMIC_CAST_DEBUG<Derived&>(p); }
00547 
00550 #define SimTK_DOWNCAST2(Derived,Helper,Parent)                          \
00551     static bool isA(const Parent& p)                                    \
00552         { return Helper::isA(p); }                                      \
00553     static const Derived& downcast(const Parent& p)                     \
00554         { return static_cast<const Derived&>(Helper::downcast(p)); }    \
00555     static Derived& updDowncast(Parent& p)                                \
00556         { return static_cast<Derived&>(Helper::downcast(p)); }            \
00557     static Derived& downcast(Parent& p)                                 \
00558         { return static_cast<Derived&>(Helper::downcast(p)); }
00559 
00560 
00564 #define SimTK_PIMPL_DOWNCAST(Derived, Parent)           \
00565     static bool           isInstanceOf(const Parent&);  \
00566     static const Derived& downcast(const Parent&);      \
00567     static Derived&       updDowncast(Parent&)
00568 
00569 namespace SimTK {
00570 
00573 namespace Exception { }
00574 
00577 typedef SimTK_Real              Real;
00580 typedef std::complex<Real>      Complex;
00582 typedef std::complex<float>     fComplex;
00584 typedef std::complex<double>    dComplex;
00585 
00586 
00587 // Forward declaration giving template defaults must come before any
00588 // other declarations.
00589 template <int M, class ELT=Real, int STRIDE=1>              class Vec;
00590 template <int N, class ELT=Real, int STRIDE=1>              class Row; 
00591 template <int M, int N, class ELT=Real, int CS=M, int RS=1> class Mat;
00592 template <int M, class ELT=Real, int RS=1>                  class SymMat;
00593 
00596 struct Segment {
00597     Segment() : length(0), offset(0) { }
00598     explicit Segment(int l, int ofs=0) : length(l), offset(ofs) { 
00599         assert(l>=0 && ofs>=0);
00600     }
00601     // default copy, assignment, destructor
00602     int length;
00603     int offset;
00604 };  
00605 
00606 
00612 struct DontCopy {};
00616 struct TrustMe {};
00617 
00620 struct FalseType {};
00623 struct TrueType {};
00624 
00626 template <class L, class R> struct AndOpType {};
00627 template<> struct AndOpType<FalseType,FalseType> {typedef FalseType Result;};
00628 template<> struct AndOpType<FalseType,TrueType>  {typedef FalseType Result;};
00629 template<> struct AndOpType<TrueType, FalseType> {typedef FalseType Result;};
00630 template<> struct AndOpType<TrueType, TrueType>  {typedef TrueType  Result;};
00631 
00633 template <class L, class R> struct OrOpType {};
00634 template<> struct OrOpType<FalseType,FalseType> {typedef FalseType Result;};
00635 template<> struct OrOpType<FalseType,TrueType>  {typedef TrueType  Result;};
00636 template<> struct OrOpType<TrueType, FalseType> {typedef TrueType  Result;};
00637 template<> struct OrOpType<TrueType, TrueType>  {typedef TrueType  Result;};
00638 
00640 template <class L, class R> struct XorOpType {};
00641 template<> struct XorOpType<FalseType,FalseType> {typedef FalseType Result;};
00642 template<> struct XorOpType<FalseType,TrueType>  {typedef TrueType  Result;};
00643 template<> struct XorOpType<TrueType, FalseType> {typedef TrueType  Result;};
00644 template<> struct XorOpType<TrueType, TrueType>  {typedef FalseType Result;};
00645 
00647 template <class T> struct IsIntegralType {
00650     typedef FalseType Result;
00653     static const bool result = false;
00654 };
00657 #define SimTK_SPECIALIZE_INTEGRAL_TYPE(T)       \
00658     template<> struct IsIntegralType<T>         \
00659     {typedef TrueType Result; static const bool result = true;}
00660 
00661 SimTK_SPECIALIZE_INTEGRAL_TYPE(bool); 
00662 SimTK_SPECIALIZE_INTEGRAL_TYPE(char);
00663 // This causes problems when used with Qt which for some crazy
00664 // reason likes to make its own wchar_t rather than using the built in.
00665 // SimTK_SPECIALIZE_INTEGRAL_TYPE(wchar_t);
00666 SimTK_SPECIALIZE_INTEGRAL_TYPE(signed char);
00667 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned char);
00668 SimTK_SPECIALIZE_INTEGRAL_TYPE(short);
00669 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned short);
00670 SimTK_SPECIALIZE_INTEGRAL_TYPE(int);
00671 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned int); // a.k.a. "unsigned"
00672 SimTK_SPECIALIZE_INTEGRAL_TYPE(long);
00673 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned long);
00674 SimTK_SPECIALIZE_INTEGRAL_TYPE(long long);
00675 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned long long);
00676 
00678 template <class T> struct IsFloatingType {
00681     typedef FalseType Result;
00684     static const bool result = false;
00685 };
00688 #define SimTK_SPECIALIZE_FLOATING_TYPE(T)       \
00689     template<> struct IsFloatingType<T>         \
00690     {typedef TrueType Result; static const bool result = true;}
00691 
00692 SimTK_SPECIALIZE_FLOATING_TYPE(float); 
00693 SimTK_SPECIALIZE_FLOATING_TYPE(double); 
00694 SimTK_SPECIALIZE_FLOATING_TYPE(long double); 
00695 
00697 template <class T> struct IsVoidType {
00700     typedef FalseType Result;
00703     static const bool result = false;
00704 };
00705 template<> struct IsVoidType<void> 
00706 {typedef TrueType Result; static const bool result = true;};
00707 
00710 template <class T> struct IsArithmeticType {
00713     typedef OrOpType<typename IsIntegralType<T>::Result,
00714                      typename IsFloatingType<T>::Result>    Result;
00717     static const bool result = IsIntegralType<T>::result 
00718                             || IsFloatingType<T>::result;
00719 };
00720 
00721 // This struct's sole use is to allow us to define the typedef 
00722 // Is64BitPlatformType as equivalent to either TrueType or FalseType.
00723 template <bool is64Bit> struct Is64BitHelper {};
00724 template<> struct Is64BitHelper<true>  
00725 {typedef TrueType  Result; static const bool result = true;};
00726 template<> struct Is64BitHelper<false> 
00727 {typedef FalseType Result; static const bool result = false;};
00728 
00733 static const bool Is64BitPlatform = sizeof(size_t) > sizeof(int);
00734 typedef Is64BitHelper<Is64BitPlatform>::Result Is64BitPlatformType;
00735 
00736 
00740 SimTK_SimTKCOMMON_EXPORT std::string demangle(const char* name);
00741 
00745 template <class T> struct NiceTypeName {
00749     static const char* name() {return typeid(T).name();}
00753     static std::string namestr() {return demangle(name());}
00754 };
00755 
00756 } // namespace SimTK
00757 
00764 #define SimTK_NICETYPENAME_LITERAL(T)               \
00765 namespace SimTK {                                   \
00766     template <> struct NiceTypeName< T > {          \
00767         static std::string namestr() { return #T; } \
00768         static const char* name() { return #T; }    \
00769     };                                              \
00770 }
00771 
00772 // Some types for which we'd like to see nice type names.
00773 SimTK_NICETYPENAME_LITERAL(bool);            
00774 SimTK_NICETYPENAME_LITERAL(char); 
00775 // This causes problems when used with Qt which for some crazy
00776 // reason likes to make its own wchar_t rather than using the built in.
00777 // SimTK_NICETYPENAME_LITERAL(wchar_t);            
00778 SimTK_NICETYPENAME_LITERAL(signed char); 
00779 SimTK_NICETYPENAME_LITERAL(unsigned char);
00780 SimTK_NICETYPENAME_LITERAL(short);           
00781 SimTK_NICETYPENAME_LITERAL(unsigned short);  
00782 SimTK_NICETYPENAME_LITERAL(int); 
00783 SimTK_NICETYPENAME_LITERAL(unsigned); // preferred to "unsigned int"
00784 SimTK_NICETYPENAME_LITERAL(long);            
00785 SimTK_NICETYPENAME_LITERAL(unsigned long);   
00786 SimTK_NICETYPENAME_LITERAL(long long);
00787 SimTK_NICETYPENAME_LITERAL(unsigned long long);
00788 SimTK_NICETYPENAME_LITERAL(float);           
00789 SimTK_NICETYPENAME_LITERAL(double); 
00790 SimTK_NICETYPENAME_LITERAL(long double);
00791 SimTK_NICETYPENAME_LITERAL(std::string);
00792 SimTK_NICETYPENAME_LITERAL(std::complex<float>);
00793 SimTK_NICETYPENAME_LITERAL(std::complex<double>); 
00794 SimTK_NICETYPENAME_LITERAL(std::complex<long double>); 
00795 SimTK_NICETYPENAME_LITERAL(SimTK::FalseType);
00796 SimTK_NICETYPENAME_LITERAL(SimTK::TrueType); 
00797 
00798 
00799 #endif /* C++ stuff */
00800 
00801 #endif /* SimTK_SimTKCOMMON_COMMON_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines