Simbody
3.5
|
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_ */