Simbody  3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
SimTKcommon/include/SimTKcommon/internal/common.h
Go to the documentation of this file.
1 #ifndef SimTK_SimTKCOMMON_COMMON_H_
2 #define SimTK_SimTKCOMMON_COMMON_H_
3 
4 /* -------------------------------------------------------------------------- *
5  * Simbody(tm): SimTKcommon *
6  * -------------------------------------------------------------------------- *
7  * This is part of the SimTK biosimulation toolkit originating from *
8  * Simbios, the NIH National Center for Physics-Based Simulation of *
9  * Biological Structures at Stanford, funded under the NIH Roadmap for *
10  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11  * *
12  * Portions copyright (c) 2005-14 Stanford University and the Authors. *
13  * Authors: Michael Sherman *
14  * Contributors: Chris Dembia *
15  * *
16  * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17  * not use this file except in compliance with the License. You may obtain a *
18  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19  * *
20  * Unless required by applicable law or agreed to in writing, software *
21  * distributed under the License is distributed on an "AS IS" BASIS, *
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23  * See the License for the specific language governing permissions and *
24  * limitations under the License. *
25  * -------------------------------------------------------------------------- */
26 
39 // Provide doxygen documentation for the SimTK namespace.
40 
49 // Define shared doxygen "modules" and sub-modules here. We'll put things
50 // in them at various places when appropriate.
51 
91 /*****************************/
92 /* ANSI-C COMPATIBLE SECTION */
93 /*****************************/
94 
95 /* Set up a few compile-time options that affect all SimTK Core headers. */
96 
104 #ifndef SimTK_DEFAULT_PRECISION
105 # define SimTK_DEFAULT_PRECISION 2
106 #endif
107 
108 #if (SimTK_DEFAULT_PRECISION == 1)
109 
110  typedef float SimTK_Real;
111 #elif (SimTK_DEFAULT_PRECISION == 2)
112 
113  typedef double SimTK_Real;
114 #elif (SimTK_DEFAULT_PRECISION == 4)
115 
116  typedef long double SimTK_Real;
117 #else
118  #error ILLEGAL VALUE FOR DEFAULT PRECISION
119 #endif
120 
121 #ifndef NDEBUG
122  #if defined(__cplusplus)
123  #include <cstdio>
124  #define SimTK_DEBUG(s) std::printf("DBG: " s)
125  #define SimTK_DEBUG1(s,a1) std::printf("DBG: " s,a1)
126  #define SimTK_DEBUG2(s,a1,a2) std::printf("DBG: " s,a1,a2)
127  #define SimTK_DEBUG3(s,a1,a2,a3) std::printf("DBG: " s,a1,a2,a3)
128  #define SimTK_DEBUG4(s,a1,a2,a3,a4) std::printf("DBG: " s,a1,a2,a3,a4)
129  #else
130  #include <stdio.h>
131  #define SimTK_DEBUG(s) printf("DBG: " s)
132  #define SimTK_DEBUG1(s,a1) printf("DBG: " s,a1)
133  #define SimTK_DEBUG2(s,a1,a2) printf("DBG: " s,a1,a2)
134  #define SimTK_DEBUG3(s,a1,a2,a3) printf("DBG: " s,a1,a2,a3)
135  #define SimTK_DEBUG4(s,a1,a2,a3,a4) printf("DBG: " s,a1,a2,a3,a4)
136  #endif
137 #else
138  #define SimTK_DEBUG(s)
139  #define SimTK_DEBUG1(s,a1)
140  #define SimTK_DEBUG2(s,a1,a2)
141  #define SimTK_DEBUG3(s,a1,a2,a3)
142  #define SimTK_DEBUG4(s,a1,a2,a3,a4)
143 #endif
144 
145 /*
146  * Shared libraries are messy in Visual Studio. We have to distinguish three
147  * cases:
148  * (1) this header is being used to build the SimTKcommon shared library (dllexport)
149  * (2) this header is being used by a *client* of the SimTKcommon shared
150  * library (dllimport)
151  * (3) we are building the SimTKcommon static library, or the client is
152  * being compiled with the expectation of linking with the
153  * SimTKcommon static library (nothing special needed)
154  * In the CMake script for building this library, we define one of the symbols
155  * SimTK_SimTKCOMMON_BUILDING_{SHARED|STATIC}_LIBRARY
156  * Client code normally has no special symbol defined, in which case we'll
157  * assume it wants to use the shared library. However, if the client defines
158  * the symbol SimTK_USE_STATIC_LIBRARIES we'll suppress the dllimport so
159  * that the client code can be linked with static libraries. Note that
160  * the client symbol is not library dependent, while the library symbols
161  * affect only the SimTKcommon library, meaning that other libraries can
162  * be clients of this one. However, we are assuming all-static or all-shared.
163  */
164 
165 #ifdef _WIN32
166  #ifdef _MSC_VER
167  #pragma warning(disable:4231) /*need to use 'extern' template explicit instantiation*/
168  #pragma warning(disable:4251) /*no DLL interface for type of member of exported class*/
169  #pragma warning(disable:4275) /*no DLL interface for base class of exported class*/
170  #pragma warning(disable:4345) /*warning about PODs being default-initialized*/
171  #endif
172  #if defined(SimTK_SimTKCOMMON_BUILDING_SHARED_LIBRARY)
173  #define SimTK_SimTKCOMMON_EXPORT __declspec(dllexport)
174  /* Keep MS VC++ quiet when it tries to instantiate incomplete template classes in a DLL. */
175  #ifdef _MSC_VER
176  #pragma warning(disable:4661)
177  #endif
178  #elif defined(SimTK_SimTKCOMMON_BUILDING_STATIC_LIBRARY) || defined(SimTK_USE_STATIC_LIBRARIES)
179  #define SimTK_SimTKCOMMON_EXPORT
180  #else
181  #define SimTK_SimTKCOMMON_EXPORT __declspec(dllimport) /*i.e., a client of a shared library*/
182  #endif
183  /* VC++ tries to be secure by leaving bounds checking on for STL containers
184  * even in Release mode. This macro exists to disable that feature and can
185  * result in a considerable speedup.
186  * CAUTION: every linked-together compilation unit must have this set the same
187  * way. Everyone who properly includes this file first is fine; but as of this
188  * writing Simmath's IpOpt doesn't do so.
189  * NOTE: Microsoft corrected this problem with VC10 -- the feature is
190  * disabled by default in that compiler and later.
191  */
192  /* (sherm 081204 disabling for now: doesn't work on VC++ 8 and is
193  * tricky on VC++ 9 because all libraries, including 3rd party, must
194  * be built the same way). Better to use the SimTK::Array_<T> class in
195  * place of the std::vector<T> class to get better performance.
196  #ifdef NDEBUG
197  #undef _SECURE_SCL
198  #define _SECURE_SCL 0
199  #endif
200  */
201 #else
202  #define SimTK_SimTKCOMMON_EXPORT // Linux, Mac
203 #endif
204 
205 /* Every SimTK Core library must provide these two routines, with the library
206  * name appearing after the "version_" and "about_".
207  */
208 #if defined(__cplusplus)
209 extern "C" {
210 #endif
211 
212  SimTK_SimTKCOMMON_EXPORT void SimTK_version_SimTKcommon(int* major, int* minor, int* build);
219  SimTK_SimTKCOMMON_EXPORT void SimTK_about_SimTKcommon(const char* key, int maxlen, char* value);
220 #if defined(__cplusplus)
221 }
222 #endif
223 
224 /************************************/
225 /* END OF ANSI-C COMPATIBLE SECTION */
226 /************************************/
227 
228 #if defined(__cplusplus)
229 
230 #include <cstddef>
231 #include <cassert>
232 #include <cstring>
233 #include <cmath>
234 #include <cfloat>
235 #include <complex>
236 #include <limits>
237 #include <typeinfo>
238 #include <algorithm>
239 
240 /* Transition macros for C++11 support. VC10 and VC11 have partial support for
241 C++11, early VC's do not. If using gcc or Clang, we check for C++11 support. */
242 #ifndef SWIG
243  #if _MSC_VER>=1700 || (defined(__GNUG__) && __cplusplus>=201103L)
244  /* VC11 or higher, OR using gcc or Clang and using C++11 */
245  #define OVERRIDE_11 override
246  #define FINAL_11 final
247  #elif _MSC_VER==1600 /* VC10 */
248  #define OVERRIDE_11 override
249  #define FINAL_11 sealed
250  #else /* gcc or Clang without C++11, or earlier VC */
251  #define OVERRIDE_11
252  #define FINAL_11
253  #endif
254 #else /* Swigging */
255  #define OVERRIDE_11
256  #define FINAL_11
257 #endif
258 
259 /* Be very careful with this macro -- don't use it unless you have measured
260 a performance improvement. You can end up with serious code bloat if you
261 override the compiler's judgement about when to inline, and that can cause
262 cache misses which ultimately reduce performance. */
263 #ifdef _MSC_VER
264  #define SimTK_FORCE_INLINE __forceinline
265 #else
266  #define SimTK_FORCE_INLINE __attribute__((always_inline))
267 #endif
268 
269 
270 /* In Microsoft VC++ 11 (2012) and earlier these C99-compatible floating
271 point functions are missing. We'll create them here and install them into
272 namespace std. They were added in VC++ 12 (2013). */
273 #if defined(_MSC_VER) && (_MSC_VER <= 1700) // VC++ 12 (2013, _MSC_VER=1800) added these
274 namespace std {
275 inline bool isfinite(float f) {return _finite(f) != 0;}
276 inline bool isfinite(double d) {return _finite(d) != 0;}
277 inline bool isfinite(long double l) {return _finite(l) != 0;}
278 inline bool isnan(float f) {return _isnan(f) != 0;}
279 inline bool isnan(double d) {return _isnan(d) != 0;}
280 inline bool isnan(long double l) {return _isnan(l) != 0;}
281 inline bool isinf(float f) {return std::abs(f)==std::numeric_limits<float>::infinity();}
282 inline bool isinf(double d) {return std::abs(d)==std::numeric_limits<double>::infinity();}
283 inline bool isinf(long double l) {return std::abs(l)==std::numeric_limits<double>::infinity();}
284 inline bool signbit(float f) {return (*reinterpret_cast<unsigned*>(&f) & 0x80000000U) != 0;}
285 inline bool signbit(double d) {return (*reinterpret_cast<unsigned long long*>(&d)
286  & 0x8000000000000000ULL) != 0;}
287 inline bool signbit(long double l) {return (*reinterpret_cast<unsigned long long*>(&l)
288  & 0x8000000000000000ULL) != 0;}
289 }
290 #endif
291 
292 
293 namespace SimTK {
294 
295 
296 // This utility answers the question "if I put this integral value in an int and then
297 // get it back, will its value be the same?".
298 inline bool canStoreInInt(bool) {return true;}
299 inline bool canStoreInInt(char) {return true;}
300 inline bool canStoreInInt(unsigned char) {return true;}
301 inline bool canStoreInInt(signed char) {return true;}
302 inline bool canStoreInInt(short) {return true;}
303 inline bool canStoreInInt(unsigned short) {return true;}
304 inline bool canStoreInInt(int) {return true;}
305 inline bool canStoreInInt(unsigned int u) {return (unsigned int)(int(u)) == u;}
306 inline bool canStoreInInt(long i) {return long(int(i)) == i;}
307 inline bool canStoreInInt(unsigned long u) {return (unsigned long)(int(u)) == u;}
308 inline bool canStoreInInt(long long i) {return (long long)(int(i)) == i;}
309 inline bool canStoreInInt(unsigned long long u) {return (unsigned long long)(int(u)) == u;}
310 
311 // This utility answers the question "is this integral value a nonnegative number
312 // that can be stored in an int?".
313 inline bool canStoreInNonnegativeInt(bool) {return true;}
314 inline bool canStoreInNonnegativeInt(char c) {return c >= 0;}
315 inline bool canStoreInNonnegativeInt(unsigned char) {return true;}
316 inline bool canStoreInNonnegativeInt(signed char c) {return c >= 0;}
317 inline bool canStoreInNonnegativeInt(short s) {return s >= 0;}
318 inline bool canStoreInNonnegativeInt(unsigned short) {return true;}
319 inline bool canStoreInNonnegativeInt(int i) {return i >= 0;}
320 inline bool canStoreInNonnegativeInt(long l) {return canStoreInInt(l) && l >= 0;}
321 inline bool canStoreInNonnegativeInt(long long l) {return canStoreInInt(l) && l >= 0;}
322 inline bool canStoreInNonnegativeInt(unsigned int u) {return canStoreInInt(u);}
323 inline bool canStoreInNonnegativeInt(unsigned long u) {return canStoreInInt(u);}
324 inline bool canStoreInNonnegativeInt(unsigned long long u) {return canStoreInInt(u);}
325 
326 // This utility answers the question of whether an integer is suitable as a size
327 // limited by the given maximum size. Signed types must be checked for being
328 // nonegative; doing that with unsigned types leads to compiler warnings.
329 
330 // char can be signed or unsigned depending on the compiler; assume signed.
331 inline bool isSizeInRange(char sz, char mx){return 0<=sz&&sz<=mx;}
332 inline bool isSizeInRange(signed char sz, signed char mx){return 0<=sz&&sz<=mx;}
333 inline bool isSizeInRange(short sz, short mx){return 0<=sz&&sz<=mx;}
334 inline bool isSizeInRange(int sz, int mx){return 0<=sz&&sz<=mx;}
335 inline bool isSizeInRange(long sz, long mx){return 0<=sz&&sz<=mx;}
336 inline bool isSizeInRange(long long sz, long long mx){return 0<=sz&&sz<=mx;}
337 inline bool isSizeInRange(unsigned char sz, unsigned char mx){return sz<=mx;}
338 inline bool isSizeInRange(unsigned short sz, unsigned short mx){return sz<=mx;}
339 inline bool isSizeInRange(unsigned int sz, unsigned int mx){return sz<=mx;}
340 inline bool isSizeInRange(unsigned long sz, unsigned long mx){return sz<=mx;}
341 inline bool isSizeInRange(unsigned long long sz, unsigned long long mx){return sz<=mx;}
342 
343 // This utility answers the question of whether an integer is suitable as an index
344 // for an array limited by the given maximum size. Signed types must be checked for being
345 // nonegative; doing that with unsigned types leads to compiler warnings. This is just
346 // like the "size in range" check above except the maximum value allowed for an index
347 // is one less that the size.
348 
349 // char can be signed or unsigned depending on the compiler; assume signed.
350 inline bool isIndexInRange(char ix, char sz){return 0<=ix&&ix<sz;}
351 inline bool isIndexInRange(signed char ix, signed char sz){return 0<=ix&&ix<sz;}
352 inline bool isIndexInRange(short ix, short sz){return 0<=ix&&ix<sz;}
353 inline bool isIndexInRange(int ix, int sz){return 0<=ix&&ix<sz;}
354 inline bool isIndexInRange(long ix, long sz){return 0<=ix&&ix<sz;}
355 inline bool isIndexInRange(long long ix, long long sz){return 0<=ix&&ix<sz;}
356 inline bool isIndexInRange(unsigned char ix, unsigned char sz){return ix<sz;}
357 inline bool isIndexInRange(unsigned short ix, unsigned short sz){return ix<sz;}
358 inline bool isIndexInRange(unsigned int ix, unsigned int sz){return ix<sz;}
359 inline bool isIndexInRange(unsigned long ix, unsigned long sz){return ix<sz;}
360 inline bool isIndexInRange(unsigned long long ix, unsigned long long sz){return ix<sz;}
361 
362 // This utility answers the question: is this integral value nonnegative? The answer
363 // is always true for unsigned types and you'll get a warning from some compilers if
364 // you check.
365 
366 inline bool isNonnegative(bool) {return true;}
367 // char can be signed or unsigned depending on the compiler; assume signed.
368 inline bool isNonnegative(char n) {return n>=0;}
369 inline bool isNonnegative(signed char n) {return n>=0;}
370 inline bool isNonnegative(short n) {return n>=0;}
371 inline bool isNonnegative(int n) {return n>=0;}
372 inline bool isNonnegative(long n) {return n>=0;}
373 inline bool isNonnegative(long long n) {return n>=0;}
374 inline bool isNonnegative(unsigned char) {return true;}
375 inline bool isNonnegative(unsigned short) {return true;}
376 inline bool isNonnegative(unsigned int) {return true;}
377 inline bool isNonnegative(unsigned long) {return true;}
378 inline bool isNonnegative(unsigned long long){return true;}
379 
380 // A NaN-like value for unique index types created using the macro
381 // SimTK_DEFINE_UNIQUE_INDEX_TYPE(). A unique, typed constant with
382 // this numerical value is created for each index type.
383 static const int InvalidIndex = -1111111111;
384 }
385 
386 
387 
419 #define SimTK_DEFINE_UNIQUE_INDEX_TYPE(NAME) \
420  SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,,,NAME) \
421  static const NAME Invalid ## NAME;
422 
425 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_INDEX_TYPE(EXPORT,NAME) \
426  SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,,,NAME) \
427  static const NAME Invalid ## NAME;
428 
430 #define SimTK_DEFINE_UNIQUE_LOCAL_INDEX_TYPE(PARENT,NAME) \
431  SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,PARENT,::,NAME)
432 
435 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,PARENT,SEP,NAME) \
436 class EXPORT NAME { \
437  int ix; \
438 public: \
439  NAME() : ix(SimTK::InvalidIndex) { } \
440  explicit NAME(int i) : ix(i) {assert(i>=0 || i==SimTK::InvalidIndex);} \
441  explicit NAME(long l): ix((int)l) {assert(SimTK::canStoreInNonnegativeInt(l));} \
442  explicit NAME(unsigned int u) : ix((int)u) {assert(SimTK::canStoreInInt(u));} \
443  explicit NAME(unsigned long ul) : ix((int)ul) {assert(SimTK::canStoreInInt(ul));} \
444  operator int() const {return ix;} \
445  bool isValid() const {return ix>=0;} \
446  bool isValidExtended() const {return ix>=-1;} \
447  void invalidate(){ix=SimTK::InvalidIndex;} \
448  \
449  bool operator==(int i) const {assert(isValidExtended() && isValidExtended(i)); return ix==i;} \
450  bool operator==(short s) const{assert(isValidExtended() && isValidExtended(s)); return ix==(int)s;} \
451  bool operator==(long l) const {assert(isValidExtended() && isValidExtended(l)); return ix==(int)l;} \
452  bool operator==(unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix==(int)u;} \
453  bool operator==(unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix==(int)us;} \
454  bool operator==(unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix==(int)ul;} \
455  bool operator!=(int i) const {return !operator==(i);} \
456  bool operator!=(short s) const {return !operator==(s);} \
457  bool operator!=(long l) const {return !operator==(l);} \
458  bool operator!=(unsigned int u) const {return !operator==(u);} \
459  bool operator!=(unsigned long ul) const {return !operator==(ul);} \
460  \
461  bool operator< (int i) const {assert(isValidExtended() && isValidExtended(i)); return ix<i;} \
462  bool operator< (short s) const{assert(isValidExtended() && isValidExtended(s)); return ix<(int)s;} \
463  bool operator< (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix<(int)l;} \
464  bool operator< (unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix<(int)u;} \
465  bool operator< (unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix<(int)us;} \
466  bool operator< (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix<(int)ul;} \
467  bool operator>=(int i) const {return !operator<(i);} \
468  bool operator>=(short s) const {return !operator<(s);} \
469  bool operator>=(long l) const {return !operator<(l);} \
470  bool operator>=(unsigned int u) const {return !operator<(u);} \
471  bool operator>=(unsigned short us)const {return !operator<(us);} \
472  bool operator>=(unsigned long ul) const {return !operator<(ul);} \
473  \
474  bool operator> (int i) const {assert(isValidExtended() && isValidExtended(i)); return ix>i;} \
475  bool operator> (short s) const{assert(isValidExtended() && isValidExtended(s)); return ix>(int)s;} \
476  bool operator> (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix>(int)l;} \
477  bool operator> (unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix>(int)u;} \
478  bool operator> (unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix>(int)us;} \
479  bool operator> (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix>(int)ul;} \
480  bool operator<=(int i) const {return !operator>(i);} \
481  bool operator<=(short s) const {return !operator>(s);} \
482  bool operator<=(long l) const {return !operator>(l);} \
483  bool operator<=(unsigned int u) const {return !operator>(u);} \
484  bool operator<=(unsigned short us)const {return !operator>(us);} \
485  bool operator<=(unsigned long ul) const {return !operator>(ul);} \
486  \
487  const NAME& operator++() {assert(isValid()); ++ix; return *this;} /*prefix */ \
488  NAME operator++(int) {assert(isValid()); ++ix; return NAME(ix-1);} /*postfix*/ \
489  const NAME& operator--() {assert(isValid()); --ix; return *this;} /*prefix */ \
490  NAME operator--(int) {assert(isValid()); --ix; return NAME(ix+1);} /*postfix*/ \
491  NAME next() const {assert(isValid()); return NAME(ix+1);} \
492  NAME prev() const {assert(isValid()); return NAME(ix-1);} /*might return -1*/ \
493  \
494  NAME& operator+=(int i) {assert(isValid() && isValidExtended(ix+i)); ix+=i; return *this;} \
495  NAME& operator-=(int i) {assert(isValid() && isValidExtended(ix-i)); ix-=i; return *this;} \
496  NAME& operator+=(short s){assert(isValid() && SimTK::canStoreInInt(s) && isValidExtended(ix+(int)s)); ix+=(int)s; return *this;} \
497  NAME& operator-=(short s){assert(isValid() && SimTK::canStoreInInt(s) && isValidExtended(ix-(int)s)); ix-=(int)s; return *this;} \
498  NAME& operator+=(long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix+(int)l)); ix+=(int)l; return *this;} \
499  NAME& operator-=(long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix-(int)l)); ix-=(int)l; return *this;} \
500  NAME& operator+=(unsigned int u) {assert(isValid()&& SimTK::canStoreInInt(u) && isValid(ix+(int)u)); ix+=(int)u; return *this;} \
501  NAME& operator-=(unsigned int u) {assert(isValid()&& SimTK::canStoreInInt(u) && isValidExtended(ix-(int)u)); ix-=(int)u; return *this;} \
502  NAME& operator+=(unsigned short us){assert(isValid()&& SimTK::canStoreInInt(us) && isValid(ix+(int)us)); ix+=(int)us; return *this;} \
503  NAME& operator-=(unsigned short us){assert(isValid()&& SimTK::canStoreInInt(us) && isValidExtended(ix-(int)us)); ix-=(int)us; return *this;} \
504  NAME& operator+=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValid(ix+(int)ul)); ix+=(int)ul; return *this;} \
505  NAME& operator-=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValidExtended(ix-(int)ul)); ix-=(int)ul; return *this;} \
506  \
507  static const NAME& Invalid() {static const NAME invalid; return invalid;} \
508  static bool isValid(int i) {return i>=0;} \
509  static bool isValid(short s){return s>=0;} \
510  static bool isValid(long l) {return SimTK::canStoreInNonnegativeInt(l);} \
511  static bool isValid(unsigned int u) {return SimTK::canStoreInInt(u);} \
512  static bool isValid(unsigned short) {return true;} \
513  static bool isValid(unsigned long ul) {return SimTK::canStoreInInt(ul);} \
514  static bool isValidExtended(int i) {return i>=-1;} \
515  static bool isValidExtended(short s){return s>=-1;} \
516  static bool isValidExtended(long l) {return SimTK::canStoreInInt(l) && l>=-1;} \
517  /* IndexTraits for use in Array_<T,X> with this as X; same as int */ \
518  typedef int size_type; \
519  typedef int difference_type; \
520  static size_type max_size() {return std::numeric_limits<int>::max();} \
521 };
522 
529 #ifndef NDEBUG
530  #define SimTK_DYNAMIC_CAST_DEBUG dynamic_cast // safe but slow
531 #else
532  #define SimTK_DYNAMIC_CAST_DEBUG static_cast // unsafe but fast
533 #endif
534 
538 #define SimTK_DOWNCAST(Derived,Parent) \
539  static bool isA(const Parent& p) \
540  { return dynamic_cast<const Derived*>(&p) != 0; } \
541  static const Derived& downcast(const Parent& p) \
542  { return SimTK_DYNAMIC_CAST_DEBUG<const Derived&>(p); } \
543  static Derived& updDowncast(Parent& p) \
544  { return SimTK_DYNAMIC_CAST_DEBUG<Derived&>(p); } \
545  static Derived& downcast(Parent& p) \
546  { return SimTK_DYNAMIC_CAST_DEBUG<Derived&>(p); }
547 
550 #define SimTK_DOWNCAST2(Derived,Helper,Parent) \
551  static bool isA(const Parent& p) \
552  { return Helper::isA(p); } \
553  static const Derived& downcast(const Parent& p) \
554  { return static_cast<const Derived&>(Helper::downcast(p)); } \
555  static Derived& updDowncast(Parent& p) \
556  { return static_cast<Derived&>(Helper::downcast(p)); } \
557  static Derived& downcast(Parent& p) \
558  { return static_cast<Derived&>(Helper::downcast(p)); }
559 
560 
564 #define SimTK_PIMPL_DOWNCAST(Derived, Parent) \
565  static bool isInstanceOf(const Parent&); \
566  static const Derived& downcast(const Parent&); \
567  static Derived& updDowncast(Parent&)
568 
569 namespace SimTK {
570 
573 namespace Exception { }
574 
577 typedef SimTK_Real Real;
580 typedef std::complex<Real> Complex;
582 typedef std::complex<float> fComplex;
584 typedef std::complex<double> dComplex;
585 
586 
587 // Forward declaration giving template defaults must come before any
588 // other declarations.
589 template <int M, class ELT=Real, int STRIDE=1> class Vec;
590 template <int N, class ELT=Real, int STRIDE=1> class Row;
591 template <int M, int N, class ELT=Real, int CS=M, int RS=1> class Mat;
592 template <int M, class ELT=Real, int RS=1> class SymMat;
593 
596 struct Segment {
597  Segment() : length(0), offset(0) { }
598  explicit Segment(int l, int ofs=0) : length(l), offset(ofs) {
599  assert(l>=0 && ofs>=0);
600  }
601  // default copy, assignment, destructor
602  int length;
603  int offset;
604 };
605 
606 
612 struct DontCopy {};
616 struct TrustMe {};
617 
620 struct FalseType {};
623 struct TrueType {};
624 
626 template <class L, class R> struct AndOpType {};
627 template<> struct AndOpType<FalseType,FalseType> {typedef FalseType Result;};
628 template<> struct AndOpType<FalseType,TrueType> {typedef FalseType Result;};
629 template<> struct AndOpType<TrueType, FalseType> {typedef FalseType Result;};
630 template<> struct AndOpType<TrueType, TrueType> {typedef TrueType Result;};
631 
633 template <class L, class R> struct OrOpType {};
634 template<> struct OrOpType<FalseType,FalseType> {typedef FalseType Result;};
635 template<> struct OrOpType<FalseType,TrueType> {typedef TrueType Result;};
636 template<> struct OrOpType<TrueType, FalseType> {typedef TrueType Result;};
637 template<> struct OrOpType<TrueType, TrueType> {typedef TrueType Result;};
638 
640 template <class L, class R> struct XorOpType {};
641 template<> struct XorOpType<FalseType,FalseType> {typedef FalseType Result;};
642 template<> struct XorOpType<FalseType,TrueType> {typedef TrueType Result;};
643 template<> struct XorOpType<TrueType, FalseType> {typedef TrueType Result;};
644 template<> struct XorOpType<TrueType, TrueType> {typedef FalseType Result;};
645 
647 template <class T> struct IsIntegralType {
650  typedef FalseType Result;
653  static const bool result = false;
654 };
657 #define SimTK_SPECIALIZE_INTEGRAL_TYPE(T) \
658  template<> struct IsIntegralType<T> \
659  {typedef TrueType Result; static const bool result = true;}
660 
663 // This causes problems when used with Qt which for some crazy
664 // reason likes to make its own wchar_t rather than using the built in.
665 // SimTK_SPECIALIZE_INTEGRAL_TYPE(wchar_t);
666 SimTK_SPECIALIZE_INTEGRAL_TYPE(signed char);
667 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned char);
669 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned short);
671 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned int); // a.k.a. "unsigned"
673 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned long);
675 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned long long);
676 
678 template <class T> struct IsFloatingType {
681  typedef FalseType Result;
684  static const bool result = false;
685 };
688 #define SimTK_SPECIALIZE_FLOATING_TYPE(T) \
689  template<> struct IsFloatingType<T> \
690  {typedef TrueType Result; static const bool result = true;}
691 
694 SimTK_SPECIALIZE_FLOATING_TYPE(long double);
695 
697 template <class T> struct IsVoidType {
700  typedef FalseType Result;
703  static const bool result = false;
704 };
705 template<> struct IsVoidType<void>
706 {typedef TrueType Result; static const bool result = true;};
707 
710 template <class T> struct IsArithmeticType {
717  static const bool result = IsIntegralType<T>::result
719 };
720 
721 // This struct's sole use is to allow us to define the typedef
722 // Is64BitPlatformType as equivalent to either TrueType or FalseType.
723 template <bool is64Bit> struct Is64BitHelper {};
724 template<> struct Is64BitHelper<true>
725 {typedef TrueType Result; static const bool result = true;};
726 template<> struct Is64BitHelper<false>
727 {typedef FalseType Result; static const bool result = false;};
728 
733 static const bool Is64BitPlatform = sizeof(size_t) > sizeof(int);
735 
736 
740 SimTK_SimTKCOMMON_EXPORT std::string demangle(const char* name);
741 
745 template <class T> struct NiceTypeName {
749  static const char* name() {return typeid(T).name();}
753  static std::string namestr() {return demangle(name());}
754 };
755 
756 } // namespace SimTK
757 
764 #define SimTK_NICETYPENAME_LITERAL(T) \
765 namespace SimTK { \
766  template <> struct NiceTypeName< T > { \
767  static std::string namestr() { return #T; } \
768  static const char* name() { return #T; } \
769  }; \
770 }
771 
772 // Some types for which we'd like to see nice type names.
775 // This causes problems when used with Qt which for some crazy
776 // reason likes to make its own wchar_t rather than using the built in.
777 // SimTK_NICETYPENAME_LITERAL(wchar_t);
778 SimTK_NICETYPENAME_LITERAL(signed char);
779 SimTK_NICETYPENAME_LITERAL(unsigned char);
781 SimTK_NICETYPENAME_LITERAL(unsigned short);
783 SimTK_NICETYPENAME_LITERAL(unsigned); // preferred to "unsigned int"
785 SimTK_NICETYPENAME_LITERAL(unsigned long);
786 SimTK_NICETYPENAME_LITERAL(long long);
787 SimTK_NICETYPENAME_LITERAL(unsigned long long);
790 SimTK_NICETYPENAME_LITERAL(long double);
791 SimTK_NICETYPENAME_LITERAL(std::string);
792 SimTK_NICETYPENAME_LITERAL(std::complex<float>);
793 SimTK_NICETYPENAME_LITERAL(std::complex<double>);
794 SimTK_NICETYPENAME_LITERAL(std::complex<long double>);
797 
798 
799 #endif /* C++ stuff */
800 
801 #endif /* SimTK_SimTKCOMMON_COMMON_H_ */
This is an operator for exclusive or-ing compile-time truth types.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:640
#define SimTK_SimTKCOMMON_EXPORT
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:202
OrOpType< typename IsIntegralType< T >::Result, typename IsFloatingType< T >::Result > Result
This typedef is TrueType if the template type T is one of the integral; or floating point types...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:714
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:630
This is a special type used for causing invocation of a particular constructor or method overload tha...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:612
bool canStoreInNonnegativeInt(bool)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:313
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37
bool canStoreInInt(bool)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:298
std::complex< Real > Complex
This is the default complex type for SimTK, with precision for the real and imaginary parts set to th...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:580
Segment()
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:597
static std::string namestr()
The default implementation of namestr() attempts to return a nicely demangled type name on all platfo...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:753
STL namespace.
static const int InvalidIndex
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:383
double SimTK_Real
This type is for use in C; in C++ use SimTK::Real instead.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:113
This is a small, fixed-size symmetric or Hermitian matrix designed for no-overhead inline computation...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:592
SimTK_Real Real
This is the default compiled-in floating point type for SimTK, either float or double.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:577
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:627
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:706
Compile-time type test: is this the void type?.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:697
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:636
This is a compile-time equivalent of "false", used in compile-time condition checking in templatized ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:620
Is64BitHelper< Is64BitPlatform >::Result Is64BitPlatformType
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:734
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:634
bool isIndexInRange(char ix, char sz)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:350
Segment(int l, int ofs=0)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:598
static const char * name()
The default implementation of name() here returns the raw result from typeid(T).name() which will be ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:749
FalseType Result
This typedef is TrueType if the template type T is "void"; otherwise it is FalseType.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:700
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:637
This is an operator for or-ing compile-time truth types.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:633
std::string demangle(const char *name)
Attempt to demangle a type name as returned by typeid.name(), with the result hopefully suitable for ...
static const bool result
This compile-time constant bool is true if the template type T is "void" otherwise it is false...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:703
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:644
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:642
Compile-time test: is this one of the built-in "arithmetic" types, meaning an integral or floating ty...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:710
static const bool result
This compile-time constant bool is true if the template type T is a floating point type otherwise it ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:684
void SimTK_about_SimTKcommon(const char *key, int maxlen, char *value)
Obtain "about" information for the currently-loaded SimTKcommon library.
void SimTK_version_SimTKcommon(int *major, int *minor, int *build)
Obtain version information for the currently-loaded SimTKcommon library.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:723
This is a compile-time equivalent of "true", used in compile-time condition checking in templatized i...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:623
SimTK_SPECIALIZE_INTEGRAL_TYPE(bool)
This is a special type used for forcing invocation of a particularly dangerous constructor or method ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:616
Compile-time type test: is this one of the built-in integral types?.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:647
std::complex< double > dComplex
An abbreviation for std::complex for consistency with others.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:584
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:727
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:641
This is a fixed-length row vector designed for no-overhead inline computation.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:590
Compile-time type test: is this one of the built-in floating point types?.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:678
FalseType Result
This typedef is TrueType if the template type T is an integral type; otherwise it is FalseType...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:650
FalseType Result
This typedef is TrueType if the template type T is a floating point type; otherwise it is FalseType...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:681
RowVectorBase< typename CNT< ELEM >::TAbs > abs(const RowVectorBase< ELEM > &v)
Definition: VectorMath.h:120
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:628
static const bool result
This compile-time constant bool is true if the template type T is one of the integral or floating poi...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:717
This class represents a small matrix whose size is known at compile time, containing elements of any ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:591
std::complex< float > fComplex
An abbreviation for std::complex for consistency with others.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:582
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:643
In case you don't like the name you get from typeid(), you can specialize this class to provide a nic...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:745
This is a fixed-length column vector designed for no-overhead inline computation. ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:589
A convenient struct for anything requiring an offset and length to specify a segment of some larger s...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:596
static const bool Is64BitPlatform
Compile-time test: this typedef will be TrueType if this is a 64-bit platform, meaning that the size ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:733
int length
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:602
SimTK_SPECIALIZE_FLOATING_TYPE(float)
This is an operator for and-ing compile-time truth types.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:626
int offset
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:603
#define SimTK_NICETYPENAME_LITERAL(T)
This specializes the name of a type to be exactly the text you use to specify it, rather than whateve...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:764
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:725
bool isSizeInRange(char sz, char mx)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:331
static const bool result
This compile-time constant bool is true if the template type T is an integral type otherwise it is fa...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:653
bool isNonnegative(bool)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:366
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:635
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:629