Simbody
3.4 (development)
|
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_ */