Simbody  3.4 (development)
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-12 Stanford University and the Authors.        *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
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 <cmath>
00233 #include <cfloat>
00234 #include <complex>
00235 #include <limits>
00236 #include <typeinfo>
00237 
00238 /* Transition macros for C++11 support. VC10 and VC11 have partial support for
00239 C++11, early VC's do not. Currently we're assuming no support from gcc. */
00240 #ifndef SWIG
00241     #if _MSC_VER>=1700 /* VC11 or higher */
00242         #define OVERRIDE_11  override
00243         #define FINAL_11     final
00244     #elif _MSC_VER==1600 /* VC10 */
00245         #define OVERRIDE_11  override
00246         #define FINAL_11     sealed
00247     #else /* gcc or earlier VC */
00248         #define OVERRIDE_11
00249         #define FINAL_11
00250     #endif
00251 #else /* Swigging */
00252     #define OVERRIDE_11
00253     #define FINAL_11
00254 #endif
00255 
00256 
00257 /* Currently (Microsoft VC++ 9) these C99-compatible floating point functions 
00258 are missing. We'll create them here and install them into namespace std.
00259 TODO: This should be removed when these are available. */
00260 #ifdef _MSC_VER
00261 namespace std {
00262 inline bool isfinite(float f) {return _finite(f) != 0;}
00263 inline bool isfinite(double d) {return _finite(d) != 0;}
00264 inline bool isfinite(long double l) {return _finite(l) != 0;}
00265 inline bool isnan(float f) {return _isnan(f) != 0;}
00266 inline bool isnan(double d) {return _isnan(d) != 0;}
00267 inline bool isnan(long double l) {return _isnan(l) != 0;}
00268 inline bool isinf(float f) {return std::abs(f)==std::numeric_limits<float>::infinity();}
00269 inline bool isinf(double d) {return std::abs(d)==std::numeric_limits<double>::infinity();}
00270 inline bool isinf(long double l) {return std::abs(l)==std::numeric_limits<double>::infinity();}
00271 inline bool signbit(float f) {return (*reinterpret_cast<unsigned*>(&f) & 0x80000000U) != 0;}
00272 inline bool signbit(double d) {return (*reinterpret_cast<unsigned long long*>(&d)
00273                                & 0x8000000000000000ULL) != 0;}
00274 inline bool signbit(long double l) {return (*reinterpret_cast<unsigned long long*>(&l)
00275                                     & 0x8000000000000000ULL) != 0;}
00276 }
00277 #endif
00278 
00279 
00280 namespace SimTK {
00281 
00282 
00283 // This utility answers the question "if I put this integral value in an int and then
00284 // get it back, will its value be the same?".
00285 inline bool canStoreInInt(bool)            {return true;}
00286 inline bool canStoreInInt(char)            {return true;}
00287 inline bool canStoreInInt(unsigned char)   {return true;}
00288 inline bool canStoreInInt(signed char)     {return true;}
00289 inline bool canStoreInInt(short)           {return true;}
00290 inline bool canStoreInInt(unsigned short)  {return true;}
00291 inline bool canStoreInInt(int)             {return true;}
00292 inline bool canStoreInInt(unsigned int  u) {return (unsigned int)(int(u)) == u;}
00293 inline bool canStoreInInt(long i)          {return long(int(i)) == i;}
00294 inline bool canStoreInInt(unsigned long u) {return (unsigned long)(int(u)) == u;}
00295 inline bool canStoreInInt(long long i)          {return (long long)(int(i)) == i;}
00296 inline bool canStoreInInt(unsigned long long u) {return (unsigned long long)(int(u)) == u;}
00297 
00298 // This utility answers the question "is this integral value a nonnegative number
00299 // that can be stored in an int?".
00300 inline bool canStoreInNonnegativeInt(bool)             {return true;}
00301 inline bool canStoreInNonnegativeInt(char c)           {return c >= 0;}
00302 inline bool canStoreInNonnegativeInt(unsigned char)    {return true;}
00303 inline bool canStoreInNonnegativeInt(signed char c)    {return c >= 0;}
00304 inline bool canStoreInNonnegativeInt(short s)          {return s >= 0;}
00305 inline bool canStoreInNonnegativeInt(unsigned short)   {return true;}
00306 inline bool canStoreInNonnegativeInt(int  i)           {return i >= 0;}
00307 inline bool canStoreInNonnegativeInt(long l)           {return canStoreInInt(l) && l >= 0;}
00308 inline bool canStoreInNonnegativeInt(long long l)      {return canStoreInInt(l) && l >= 0;}
00309 inline bool canStoreInNonnegativeInt(unsigned int  u)  {return canStoreInInt(u);}
00310 inline bool canStoreInNonnegativeInt(unsigned long u)  {return canStoreInInt(u);}
00311 inline bool canStoreInNonnegativeInt(unsigned long long u) {return canStoreInInt(u);}
00312 
00313 // This utility answers the question of whether an integer is suitable as a size
00314 // limited by the given maximum size. Signed types must be checked for being
00315 // nonegative; doing that with unsigned types leads to compiler warnings.
00316 
00317 // char can be signed or unsigned depending on the compiler; assume signed.
00318 inline bool isSizeInRange(char           sz, char           mx){return 0<=sz&&sz<=mx;}
00319 inline bool isSizeInRange(signed char    sz, signed char    mx){return 0<=sz&&sz<=mx;}
00320 inline bool isSizeInRange(short          sz, short          mx){return 0<=sz&&sz<=mx;}
00321 inline bool isSizeInRange(int            sz, int            mx){return 0<=sz&&sz<=mx;}
00322 inline bool isSizeInRange(long           sz, long           mx){return 0<=sz&&sz<=mx;}
00323 inline bool isSizeInRange(long long      sz, long long      mx){return 0<=sz&&sz<=mx;}
00324 inline bool isSizeInRange(unsigned char  sz, unsigned char  mx){return sz<=mx;}
00325 inline bool isSizeInRange(unsigned short sz, unsigned short mx){return sz<=mx;}
00326 inline bool isSizeInRange(unsigned int   sz, unsigned int   mx){return sz<=mx;}
00327 inline bool isSizeInRange(unsigned long  sz, unsigned long  mx){return sz<=mx;}
00328 inline bool isSizeInRange(unsigned long long sz, unsigned long long mx){return sz<=mx;}
00329 
00330 // This utility answers the question of whether an integer is suitable as an index
00331 // for an array limited by the given maximum size. Signed types must be checked for being
00332 // nonegative; doing that with unsigned types leads to compiler warnings. This is just
00333 // like the "size in range" check above except the maximum value allowed for an index
00334 // is one less that the size.
00335 
00336 // char can be signed or unsigned depending on the compiler; assume signed.
00337 inline bool isIndexInRange(char           ix, char           sz){return 0<=ix&&ix<sz;}
00338 inline bool isIndexInRange(signed char    ix, signed char    sz){return 0<=ix&&ix<sz;}
00339 inline bool isIndexInRange(short          ix, short          sz){return 0<=ix&&ix<sz;}
00340 inline bool isIndexInRange(int            ix, int            sz){return 0<=ix&&ix<sz;}
00341 inline bool isIndexInRange(long           ix, long           sz){return 0<=ix&&ix<sz;}
00342 inline bool isIndexInRange(long long      ix, long long      sz){return 0<=ix&&ix<sz;}
00343 inline bool isIndexInRange(unsigned char  ix, unsigned char  sz){return ix<sz;}
00344 inline bool isIndexInRange(unsigned short ix, unsigned short sz){return ix<sz;}
00345 inline bool isIndexInRange(unsigned int   ix, unsigned int   sz){return ix<sz;}
00346 inline bool isIndexInRange(unsigned long  ix, unsigned long  sz){return ix<sz;}
00347 inline bool isIndexInRange(unsigned long long ix, unsigned long long sz){return ix<sz;}
00348 
00349 // This utility answers the question: is this integral value nonnegative? The answer
00350 // is always true for unsigned types and you'll get a warning from some compilers if
00351 // you check.
00352 
00353 inline bool isNonnegative(bool)              {return true;}
00354 // char can be signed or unsigned depending on the compiler; assume signed.
00355 inline bool isNonnegative(char        n)     {return n>=0;}
00356 inline bool isNonnegative(signed char n)     {return n>=0;}
00357 inline bool isNonnegative(short       n)     {return n>=0;}
00358 inline bool isNonnegative(int         n)     {return n>=0;}
00359 inline bool isNonnegative(long        n)     {return n>=0;}
00360 inline bool isNonnegative(long long   n)     {return n>=0;}
00361 inline bool isNonnegative(unsigned char)     {return true;}
00362 inline bool isNonnegative(unsigned short)    {return true;}
00363 inline bool isNonnegative(unsigned int)      {return true;}
00364 inline bool isNonnegative(unsigned long)     {return true;}
00365 inline bool isNonnegative(unsigned long long){return true;}
00366 
00367 // A NaN-like value for unique index types created using the macro
00368 // SimTK_DEFINE_UNIQUE_INDEX_TYPE(). A unique, typed constant with
00369 // this numerical value is created for each index type.
00370 static const int InvalidIndex = -1111111111;
00371 }
00372 
00373 
00374 
00406 #define SimTK_DEFINE_UNIQUE_INDEX_TYPE(NAME)                   \
00407     SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,,,NAME)   \
00408     static const NAME Invalid ## NAME;
00409 
00412 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_INDEX_TYPE(EXPORT,NAME)     \
00413     SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,,,NAME) \
00414     static const NAME Invalid ## NAME;
00415 
00417 #define SimTK_DEFINE_UNIQUE_LOCAL_INDEX_TYPE(PARENT,NAME) \
00418     SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,PARENT,::,NAME)
00419 
00422 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,PARENT,SEP,NAME)   \
00423 class EXPORT NAME {                         \
00424     int ix;                                 \
00425 public:                                     \
00426     NAME() : ix(SimTK::InvalidIndex) { }       \
00427     explicit NAME(int i) : ix(i)      {assert(i>=0 || i==SimTK::InvalidIndex);} \
00428     explicit NAME(long l): ix((int)l) {assert(SimTK::canStoreInNonnegativeInt(l));}    \
00429     explicit NAME(unsigned int  u)  : ix((int)u)  {assert(SimTK::canStoreInInt(u));}   \
00430     explicit NAME(unsigned long ul) : ix((int)ul) {assert(SimTK::canStoreInInt(ul));}  \
00431     operator int() const {return ix;}               \
00432     bool isValid() const {return ix>=0;}            \
00433     bool isValidExtended() const {return ix>=-1;}   \
00434     void invalidate(){ix=SimTK::InvalidIndex;}      \
00435     \
00436     bool operator==(int  i) const {assert(isValidExtended() && isValidExtended(i)); return ix==i;}    \
00437     bool operator==(short s) const{assert(isValidExtended() && isValidExtended(s)); return ix==(int)s;}  \
00438     bool operator==(long l) const {assert(isValidExtended() && isValidExtended(l)); return ix==(int)l;}  \
00439     bool operator==(unsigned int  u)  const {assert(isValidExtended() && isValid(u)); return ix==(int)u;}   \
00440     bool operator==(unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix==(int)us;} \
00441     bool operator==(unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix==(int)ul;} \
00442     bool operator!=(int  i)           const {return !operator==(i);}    \
00443     bool operator!=(short s)          const {return !operator==(s);}    \
00444     bool operator!=(long l)           const {return !operator==(l);}    \
00445     bool operator!=(unsigned int  u)  const {return !operator==(u);}    \
00446     bool operator!=(unsigned long ul) const {return !operator==(ul);}   \
00447     \
00448     bool operator< (int  i) const {assert(isValidExtended() && isValidExtended(i)); return ix<i;}        \
00449     bool operator< (short s) const{assert(isValidExtended() && isValidExtended(s)); return ix<(int)s;}   \
00450     bool operator< (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix<(int)l;}   \
00451     bool operator< (unsigned int  u)  const {assert(isValidExtended() && isValid(u));  return ix<(int)u;}    \
00452     bool operator< (unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix<(int)us;}   \
00453     bool operator< (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix<(int)ul;}   \
00454     bool operator>=(int  i)           const {return !operator<(i);}    \
00455     bool operator>=(short s)          const {return !operator<(s);}    \
00456     bool operator>=(long l)           const {return !operator<(l);}    \
00457     bool operator>=(unsigned int  u)  const {return !operator<(u);}    \
00458     bool operator>=(unsigned short us)const {return !operator<(us);}   \
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     const NAME& operator++() {assert(isValid()); ++ix; return *this;}       /*prefix */   \
00475     NAME operator++(int)     {assert(isValid()); ++ix; return NAME(ix-1);}  /*postfix*/   \
00476     const NAME& operator--() {assert(isValid()); --ix; return *this;}       /*prefix */   \
00477     NAME operator--(int)     {assert(isValid()); --ix; return NAME(ix+1);}  /*postfix*/   \
00478     NAME next() const {assert(isValid()); return NAME(ix+1);}                             \
00479     NAME prev() const {assert(isValid()); return NAME(ix-1);} /*might return -1*/         \
00480     \
00481     NAME& operator+=(int i)  {assert(isValid() && isValidExtended(ix+i)); ix+=i; return *this;}     \
00482     NAME& operator-=(int i)  {assert(isValid() && isValidExtended(ix-i)); ix-=i; return *this;}     \
00483     NAME& operator+=(short s){assert(isValid() && SimTK::canStoreInInt(s) && isValidExtended(ix+(int)s)); ix+=(int)s; return *this;}     \
00484     NAME& operator-=(short s){assert(isValid() && SimTK::canStoreInInt(s) && isValidExtended(ix-(int)s)); ix-=(int)s; return *this;}     \
00485     NAME& operator+=(long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix+(int)l)); ix+=(int)l; return *this;}     \
00486     NAME& operator-=(long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix-(int)l)); ix-=(int)l; return *this;}     \
00487     NAME& operator+=(unsigned int  u)  {assert(isValid()&& SimTK::canStoreInInt(u)  && isValid(ix+(int)u));  ix+=(int)u;  return *this;}  \
00488     NAME& operator-=(unsigned int  u)  {assert(isValid()&& SimTK::canStoreInInt(u)  && isValidExtended(ix-(int)u));  ix-=(int)u;  return *this;}  \
00489     NAME& operator+=(unsigned short us){assert(isValid()&& SimTK::canStoreInInt(us) && isValid(ix+(int)us)); ix+=(int)us; return *this;}  \
00490     NAME& operator-=(unsigned short us){assert(isValid()&& SimTK::canStoreInInt(us) && isValidExtended(ix-(int)us)); ix-=(int)us; return *this;}  \
00491     NAME& operator+=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValid(ix+(int)ul)); ix+=(int)ul; return *this;}  \
00492     NAME& operator-=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValidExtended(ix-(int)ul)); ix-=(int)ul; return *this;}  \
00493     \
00494     static const NAME& Invalid() {static const NAME invalid; return invalid;}       \
00495     static bool isValid(int  i) {return i>=0;}                                      \
00496     static bool isValid(short s){return s>=0;}                                      \
00497     static bool isValid(long l) {return SimTK::canStoreInNonnegativeInt(l);}        \
00498     static bool isValid(unsigned int  u)  {return SimTK::canStoreInInt(u);}         \
00499     static bool isValid(unsigned short)   {return true;}                            \
00500     static bool isValid(unsigned long ul) {return SimTK::canStoreInInt(ul);}        \
00501     static bool isValidExtended(int  i) {return i>=-1;}                             \
00502     static bool isValidExtended(short s){return s>=-1;}                             \
00503     static bool isValidExtended(long l) {return SimTK::canStoreInInt(l) && l>=-1;}  \
00504     /* IndexTraits for use in Array_<T,X> with this as X; same as int */            \
00505     typedef int size_type;                                                  \
00506     typedef int difference_type;                                            \
00507     static size_type max_size() {return std::numeric_limits<int>::max();}   \
00508 };
00509 
00516 #ifndef NDEBUG
00517     #define SimTK_DYNAMIC_CAST_DEBUG dynamic_cast   // safe but slow
00518 #else
00519     #define SimTK_DYNAMIC_CAST_DEBUG static_cast    // unsafe but fast
00520 #endif
00521 
00525 #define SimTK_DOWNCAST(Derived,Parent)                          \
00526     static bool isA(const Parent& p)                            \
00527         { return dynamic_cast<const Derived*>(&p) != 0; }       \
00528     static const Derived& downcast(const Parent& p)             \
00529         { return SimTK_DYNAMIC_CAST_DEBUG<const Derived&>(p); } \
00530     static Derived& updDowncast(Parent& p)                      \
00531         { return SimTK_DYNAMIC_CAST_DEBUG<Derived&>(p); }       \
00532     static Derived& downcast(Parent& p)                         \
00533         { return SimTK_DYNAMIC_CAST_DEBUG<Derived&>(p); }
00534 
00537 #define SimTK_DOWNCAST2(Derived,Helper,Parent)                          \
00538     static bool isA(const Parent& p)                                    \
00539         { return Helper::isA(p); }                                      \
00540     static const Derived& downcast(const Parent& p)                     \
00541         { return static_cast<const Derived&>(Helper::downcast(p)); }    \
00542     static Derived& updDowncast(Parent& p)                              \
00543         { return static_cast<Derived&>(Helper::downcast(p)); }          \
00544     static Derived& downcast(Parent& p)                                 \
00545         { return static_cast<Derived&>(Helper::downcast(p)); }
00546 
00547 
00551 #define SimTK_PIMPL_DOWNCAST(Derived, Parent)           \
00552     static bool           isInstanceOf(const Parent&);  \
00553     static const Derived& downcast(const Parent&);      \
00554     static Derived&       updDowncast(Parent&)
00555 
00556 namespace SimTK {
00557 
00560 namespace Exception { }
00561 
00564 typedef SimTK_Real              Real;
00567 typedef std::complex<Real>      Complex;
00569 typedef std::complex<float>     fComplex;
00571 typedef std::complex<float>     dComplex;
00572 
00573 
00574 // Forward declaration giving template defaults must come before any
00575 // other declarations.
00576 template <int M, class E=Real, int STRIDE=1>              class Vec;
00577 template <int N, class E=Real, int STRIDE=1>              class Row; 
00578 template <int M, int N, class E=Real, int CS=M, int RS=1> class Mat; // col & row spacing
00579 template <int M, class E=Real, int RS=1>                  class SymMat;
00580 
00581 
00584 struct Segment {
00585     Segment() : length(0), offset(0) { }
00586     explicit Segment(int l, int ofs=0) : length(l), offset(ofs) { 
00587         assert(l>=0 && ofs>=0);
00588     }
00589     // default copy, assignment, destructor
00590     int length;
00591     int offset;
00592 };  
00593 
00594 
00600 struct DontCopy {};
00604 struct TrustMe {};
00605 
00608 struct FalseType {};
00611 struct TrueType {};
00612 
00614 template <class L, class R> struct AndOpType {};
00615 template<> struct AndOpType<FalseType,FalseType> {typedef FalseType Result;};
00616 template<> struct AndOpType<FalseType,TrueType>  {typedef FalseType Result;};
00617 template<> struct AndOpType<TrueType, FalseType> {typedef FalseType Result;};
00618 template<> struct AndOpType<TrueType, TrueType>  {typedef TrueType  Result;};
00619 
00621 template <class L, class R> struct OrOpType {};
00622 template<> struct OrOpType<FalseType,FalseType> {typedef FalseType Result;};
00623 template<> struct OrOpType<FalseType,TrueType>  {typedef TrueType  Result;};
00624 template<> struct OrOpType<TrueType, FalseType> {typedef TrueType  Result;};
00625 template<> struct OrOpType<TrueType, TrueType>  {typedef TrueType  Result;};
00626 
00628 template <class L, class R> struct XorOpType {};
00629 template<> struct XorOpType<FalseType,FalseType> {typedef FalseType Result;};
00630 template<> struct XorOpType<FalseType,TrueType>  {typedef TrueType  Result;};
00631 template<> struct XorOpType<TrueType, FalseType> {typedef TrueType  Result;};
00632 template<> struct XorOpType<TrueType, TrueType>  {typedef FalseType Result;};
00633 
00635 template <class T> struct IsIntegralType {
00638     typedef FalseType Result;
00641     static const bool result = false;
00642 };
00645 #define SimTK_SPECIALIZE_INTEGRAL_TYPE(T)       \
00646     template<> struct IsIntegralType<T>         \
00647     {typedef TrueType Result; static const bool result = true;}
00648 
00649 SimTK_SPECIALIZE_INTEGRAL_TYPE(bool); 
00650 SimTK_SPECIALIZE_INTEGRAL_TYPE(char);
00651 // This causes problems when used with Qt which for some crazy
00652 // reason likes to make its own wchar_t rather than using the built in.
00653 // SimTK_SPECIALIZE_INTEGRAL_TYPE(wchar_t);
00654 SimTK_SPECIALIZE_INTEGRAL_TYPE(signed char);
00655 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned char);
00656 SimTK_SPECIALIZE_INTEGRAL_TYPE(short);
00657 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned short);
00658 SimTK_SPECIALIZE_INTEGRAL_TYPE(int);
00659 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned int); // a.k.a. "unsigned"
00660 SimTK_SPECIALIZE_INTEGRAL_TYPE(long);
00661 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned long);
00662 SimTK_SPECIALIZE_INTEGRAL_TYPE(long long);
00663 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned long long);
00664 
00666 template <class T> struct IsFloatingType {
00669     typedef FalseType Result;
00672     static const bool result = false;
00673 };
00676 #define SimTK_SPECIALIZE_FLOATING_TYPE(T)       \
00677     template<> struct IsFloatingType<T>         \
00678     {typedef TrueType Result; static const bool result = true;}
00679 
00680 SimTK_SPECIALIZE_FLOATING_TYPE(float); 
00681 SimTK_SPECIALIZE_FLOATING_TYPE(double); 
00682 SimTK_SPECIALIZE_FLOATING_TYPE(long double); 
00683 
00685 template <class T> struct IsVoidType {
00688     typedef FalseType Result;
00691     static const bool result = false;
00692 };
00693 template<> struct IsVoidType<void> 
00694 {typedef TrueType Result; static const bool result = true;};
00695 
00698 template <class T> struct IsArithmeticType {
00701     typedef OrOpType<typename IsIntegralType<T>::Result,
00702                      typename IsFloatingType<T>::Result>    Result;
00705     static const bool result = IsIntegralType<T>::result 
00706                             || IsFloatingType<T>::result;
00707 };
00708 
00709 // This struct's sole use is to allow us to define the typedef 
00710 // Is64BitPlatformType as equivalent to either TrueType or FalseType.
00711 template <bool is64Bit> struct Is64BitHelper {};
00712 template<> struct Is64BitHelper<true>  
00713 {typedef TrueType  Result; static const bool result = true;};
00714 template<> struct Is64BitHelper<false> 
00715 {typedef FalseType Result; static const bool result = false;};
00716 
00721 static const bool Is64BitPlatform = sizeof(size_t) > sizeof(int);
00722 typedef Is64BitHelper<Is64BitPlatform>::Result Is64BitPlatformType;
00723 
00724 
00728 template <class T> struct NiceTypeName {
00729     static const char* name() {return typeid(T).name();}
00730 };
00731 
00735 #define SimTK_NICETYPENAME_LITERAL(T)           \
00736 template <> struct NiceTypeName< T > {          \
00737     static const char* name() { return #T; }    \
00738 };
00739 
00740 // Some types for which we'd like to see nice type names.
00741 SimTK_NICETYPENAME_LITERAL(bool);            
00742 SimTK_NICETYPENAME_LITERAL(char); 
00743 // This causes problems when used with Qt which for some crazy
00744 // reason likes to make its own wchar_t rather than using the built in.
00745 // SimTK_NICETYPENAME_LITERAL(wchar_t);            
00746 SimTK_NICETYPENAME_LITERAL(signed char); 
00747 SimTK_NICETYPENAME_LITERAL(unsigned char);
00748 SimTK_NICETYPENAME_LITERAL(short);           
00749 SimTK_NICETYPENAME_LITERAL(unsigned short);  
00750 SimTK_NICETYPENAME_LITERAL(int); 
00751 SimTK_NICETYPENAME_LITERAL(unsigned); // preferred to "unsigned int"
00752 SimTK_NICETYPENAME_LITERAL(long);            
00753 SimTK_NICETYPENAME_LITERAL(unsigned long);   
00754 SimTK_NICETYPENAME_LITERAL(long long);
00755 SimTK_NICETYPENAME_LITERAL(unsigned long long);
00756 SimTK_NICETYPENAME_LITERAL(float);           
00757 SimTK_NICETYPENAME_LITERAL(double); 
00758 SimTK_NICETYPENAME_LITERAL(long double);
00759 SimTK_NICETYPENAME_LITERAL(std::string);
00760 SimTK_NICETYPENAME_LITERAL(std::complex<float>);
00761 SimTK_NICETYPENAME_LITERAL(std::complex<double>); 
00762 SimTK_NICETYPENAME_LITERAL(std::complex<long double>); 
00763 SimTK_NICETYPENAME_LITERAL(SimTK::FalseType);
00764 SimTK_NICETYPENAME_LITERAL(SimTK::TrueType); 
00765 
00766 } // namespace SimTK
00767 
00768 #endif /* C++ stuff */
00769 
00770 #endif /* SimTK_SimTKCOMMON_COMMON_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines