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