Simbody  3.5
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 
172  /* Until VS2015 struct timespec was missing from <ctime> so is faked here
173  if needed. However, note that it is also defined in the pthread.h header on
174  Windows, so the guard symbol must match here to avoid a duplicate declaration.
175  TODO: there is a potential problem here since VS2015's struct timespec
176  doesn't appear to match pthread's definition. */
177  #ifndef HAVE_STRUCT_TIMESPEC
178  #define HAVE_STRUCT_TIMESPEC 1
179  #if _MSC_VER < 1900
180  struct timespec {
181  long tv_sec; // TODO: this should be time_t but must fix in pthreads too
182  long tv_nsec;
183  };
184  #endif
185  #endif /* HAVE_STRUCT_TIMESPEC */
186  #endif
187 
188  #if defined(SimTK_SimTKCOMMON_BUILDING_SHARED_LIBRARY)
189  #define SimTK_SimTKCOMMON_EXPORT __declspec(dllexport)
190  /* Keep MS VC++ quiet when it tries to instantiate incomplete template classes in a DLL. */
191  #ifdef _MSC_VER
192  #pragma warning(disable:4661)
193  #endif
194  #elif defined(SimTK_SimTKCOMMON_BUILDING_STATIC_LIBRARY) || defined(SimTK_USE_STATIC_LIBRARIES)
195  #define SimTK_SimTKCOMMON_EXPORT
196  #else
197  #define SimTK_SimTKCOMMON_EXPORT __declspec(dllimport) /*i.e., a client of a shared library*/
198  #endif
199  /* VC++ tries to be secure by leaving bounds checking on for STL containers
200  * even in Release mode. This macro exists to disable that feature and can
201  * result in a considerable speedup.
202  * CAUTION: every linked-together compilation unit must have this set the same
203  * way. Everyone who properly includes this file first is fine; but as of this
204  * writing Simmath's IpOpt doesn't do so.
205  * NOTE: Microsoft corrected this problem with VC10 -- the feature is
206  * disabled by default in that compiler and later.
207  */
208  /* (sherm 081204 disabling for now: doesn't work on VC++ 8 and is
209  * tricky on VC++ 9 because all libraries, including 3rd party, must
210  * be built the same way). Better to use the SimTK::Array_<T> class in
211  * place of the std::vector<T> class to get better performance.
212  #ifdef NDEBUG
213  #undef _SECURE_SCL
214  #define _SECURE_SCL 0
215  #endif
216  */
217 #else
218  #define SimTK_SimTKCOMMON_EXPORT // Linux, Mac
219 #endif
220 
221 /* Every SimTK Core library must provide these two routines, with the library
222  * name appearing after the "version_" and "about_".
223  */
224 #if defined(__cplusplus)
225 extern "C" {
226 #endif
227 
228  SimTK_SimTKCOMMON_EXPORT void SimTK_version_SimTKcommon(int* major, int* minor, int* build);
235  SimTK_SimTKCOMMON_EXPORT void SimTK_about_SimTKcommon(const char* key, int maxlen, char* value);
236 #if defined(__cplusplus)
237 }
238 #endif
239 
240 /************************************/
241 /* END OF ANSI-C COMPATIBLE SECTION */
242 /************************************/
243 
244 #if defined(__cplusplus)
245 
246 #include <cstddef>
247 #include <cassert>
248 #include <cstring>
249 #include <cmath>
250 #include <cfloat>
251 #include <complex>
252 #include <limits>
253 #include <typeinfo>
254 #include <algorithm>
255 
256 /* Transition macros for C++11 support. VC10 and VC11 have partial support for
257 C++11, early VC's do not. If using gcc or Clang, we check for C++11 support. */
258 #ifndef SWIG
259  #if _MSC_VER>=1700 || (defined(__GNUG__) && __cplusplus>=201103L)
260  /* VC11 or higher, OR using gcc or Clang and using C++11 */
261  #define OVERRIDE_11 override
262  #define FINAL_11 final
263  #elif _MSC_VER==1600 /* VC10 */
264  #define OVERRIDE_11 override
265  #define FINAL_11 sealed
266  #else /* gcc or Clang without C++11, or earlier VC */
267  #define OVERRIDE_11
268  #define FINAL_11
269  #endif
270 #else /* Swigging */
271  #define OVERRIDE_11
272  #define FINAL_11
273 #endif
274 
275 /* Be very careful with this macro -- don't use it unless you have measured
276 a performance improvement. You can end up with serious code bloat if you
277 override the compiler's judgement about when to inline, and that can cause
278 cache misses which ultimately reduce performance. */
279 #ifdef _MSC_VER
280  #define SimTK_FORCE_INLINE __forceinline
281 #else
282  #define SimTK_FORCE_INLINE __attribute__((always_inline))
283 #endif
284 
285 
286 /* In Microsoft VC++ 11 (2012) and earlier these C99-compatible floating
287 point functions are missing. We'll create them here and install them into
288 namespace std. They were added in VC++ 12 (2013). */
289 #if defined(_MSC_VER) && (_MSC_VER <= 1700) // VC++ 12 (2013, _MSC_VER=1800) added these
290 namespace std {
291 inline bool isfinite(float f) {return _finite(f) != 0;}
292 inline bool isfinite(double d) {return _finite(d) != 0;}
293 inline bool isfinite(long double l) {return _finite(l) != 0;}
294 inline bool isnan(float f) {return _isnan(f) != 0;}
295 inline bool isnan(double d) {return _isnan(d) != 0;}
296 inline bool isnan(long double l) {return _isnan(l) != 0;}
297 inline bool isinf(float f) {return std::abs(f)==std::numeric_limits<float>::infinity();}
298 inline bool isinf(double d) {return std::abs(d)==std::numeric_limits<double>::infinity();}
299 inline bool isinf(long double l) {return std::abs(l)==std::numeric_limits<double>::infinity();}
300 inline bool signbit(float f) {return (*reinterpret_cast<unsigned*>(&f) & 0x80000000U) != 0;}
301 inline bool signbit(double d) {return (*reinterpret_cast<unsigned long long*>(&d)
302  & 0x8000000000000000ULL) != 0;}
303 inline bool signbit(long double l) {return (*reinterpret_cast<unsigned long long*>(&l)
304  & 0x8000000000000000ULL) != 0;}
305 }
306 #endif
307 
308 
309 namespace SimTK {
310 
311 
312 // This utility answers the question "if I put this integral value in an int and then
313 // get it back, will its value be the same?".
314 inline bool canStoreInInt(bool) {return true;}
315 inline bool canStoreInInt(char) {return true;}
316 inline bool canStoreInInt(unsigned char) {return true;}
317 inline bool canStoreInInt(signed char) {return true;}
318 inline bool canStoreInInt(short) {return true;}
319 inline bool canStoreInInt(unsigned short) {return true;}
320 inline bool canStoreInInt(int) {return true;}
321 inline bool canStoreInInt(unsigned int u) {return (unsigned int)(int(u)) == u;}
322 inline bool canStoreInInt(long i) {return long(int(i)) == i;}
323 inline bool canStoreInInt(unsigned long u) {return (unsigned long)(int(u)) == u;}
324 inline bool canStoreInInt(long long i) {return (long long)(int(i)) == i;}
325 inline bool canStoreInInt(unsigned long long u) {return (unsigned long long)(int(u)) == u;}
326 
327 // This utility answers the question "is this integral value a nonnegative number
328 // that can be stored in an int?".
329 inline bool canStoreInNonnegativeInt(bool) {return true;}
330 inline bool canStoreInNonnegativeInt(char c) {return c >= 0;}
331 inline bool canStoreInNonnegativeInt(unsigned char) {return true;}
332 inline bool canStoreInNonnegativeInt(signed char c) {return c >= 0;}
333 inline bool canStoreInNonnegativeInt(short s) {return s >= 0;}
334 inline bool canStoreInNonnegativeInt(unsigned short) {return true;}
335 inline bool canStoreInNonnegativeInt(int i) {return i >= 0;}
336 inline bool canStoreInNonnegativeInt(long l) {return canStoreInInt(l) && l >= 0;}
337 inline bool canStoreInNonnegativeInt(long long l) {return canStoreInInt(l) && l >= 0;}
338 inline bool canStoreInNonnegativeInt(unsigned int u) {return canStoreInInt(u);}
339 inline bool canStoreInNonnegativeInt(unsigned long u) {return canStoreInInt(u);}
340 inline bool canStoreInNonnegativeInt(unsigned long long u) {return canStoreInInt(u);}
341 
342 // This utility answers the question of whether an integer is suitable as a size
343 // limited by the given maximum size. Signed types must be checked for being
344 // nonegative; doing that with unsigned types leads to compiler warnings.
345 
346 // char can be signed or unsigned depending on the compiler; assume signed.
347 inline bool isSizeInRange(char sz, char mx){return 0<=sz&&sz<=mx;}
348 inline bool isSizeInRange(signed char sz, signed char mx){return 0<=sz&&sz<=mx;}
349 inline bool isSizeInRange(short sz, short mx){return 0<=sz&&sz<=mx;}
350 inline bool isSizeInRange(int sz, int mx){return 0<=sz&&sz<=mx;}
351 inline bool isSizeInRange(long sz, long mx){return 0<=sz&&sz<=mx;}
352 inline bool isSizeInRange(long long sz, long long mx){return 0<=sz&&sz<=mx;}
353 inline bool isSizeInRange(unsigned char sz, unsigned char mx){return sz<=mx;}
354 inline bool isSizeInRange(unsigned short sz, unsigned short mx){return sz<=mx;}
355 inline bool isSizeInRange(unsigned int sz, unsigned int mx){return sz<=mx;}
356 inline bool isSizeInRange(unsigned long sz, unsigned long mx){return sz<=mx;}
357 inline bool isSizeInRange(unsigned long long sz, unsigned long long mx){return sz<=mx;}
358 
359 // This utility answers the question of whether an integer is suitable as an index
360 // for an array limited by the given maximum size. Signed types must be checked for being
361 // nonegative; doing that with unsigned types leads to compiler warnings. This is just
362 // like the "size in range" check above except the maximum value allowed for an index
363 // is one less that the size.
364 
365 // char can be signed or unsigned depending on the compiler; assume signed.
366 inline bool isIndexInRange(char ix, char sz){return 0<=ix&&ix<sz;}
367 inline bool isIndexInRange(signed char ix, signed char sz){return 0<=ix&&ix<sz;}
368 inline bool isIndexInRange(short ix, short sz){return 0<=ix&&ix<sz;}
369 inline bool isIndexInRange(int ix, int sz){return 0<=ix&&ix<sz;}
370 inline bool isIndexInRange(long ix, long sz){return 0<=ix&&ix<sz;}
371 inline bool isIndexInRange(long long ix, long long sz){return 0<=ix&&ix<sz;}
372 inline bool isIndexInRange(unsigned char ix, unsigned char sz){return ix<sz;}
373 inline bool isIndexInRange(unsigned short ix, unsigned short sz){return ix<sz;}
374 inline bool isIndexInRange(unsigned int ix, unsigned int sz){return ix<sz;}
375 inline bool isIndexInRange(unsigned long ix, unsigned long sz){return ix<sz;}
376 inline bool isIndexInRange(unsigned long long ix, unsigned long long sz){return ix<sz;}
377 
378 // This utility answers the question: is this integral value nonnegative? The answer
379 // is always true for unsigned types and you'll get a warning from some compilers if
380 // you check.
381 
382 inline bool isNonnegative(bool) {return true;}
383 // char can be signed or unsigned depending on the compiler; assume signed.
384 inline bool isNonnegative(char n) {return n>=0;}
385 inline bool isNonnegative(signed char n) {return n>=0;}
386 inline bool isNonnegative(short n) {return n>=0;}
387 inline bool isNonnegative(int n) {return n>=0;}
388 inline bool isNonnegative(long n) {return n>=0;}
389 inline bool isNonnegative(long long n) {return n>=0;}
390 inline bool isNonnegative(unsigned char) {return true;}
391 inline bool isNonnegative(unsigned short) {return true;}
392 inline bool isNonnegative(unsigned int) {return true;}
393 inline bool isNonnegative(unsigned long) {return true;}
394 inline bool isNonnegative(unsigned long long){return true;}
395 
396 // A NaN-like value for unique index types created using the macro
397 // SimTK_DEFINE_UNIQUE_INDEX_TYPE(). A unique, typed constant with
398 // this numerical value is created for each index type.
399 static const int InvalidIndex = -1111111111;
400 }
401 
402 
403 
435 #define SimTK_DEFINE_UNIQUE_INDEX_TYPE(NAME) \
436  SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,,,NAME) \
437  static const NAME Invalid ## NAME;
438 
441 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_INDEX_TYPE(EXPORT,NAME) \
442  SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,,,NAME) \
443  static const NAME Invalid ## NAME;
444 
446 #define SimTK_DEFINE_UNIQUE_LOCAL_INDEX_TYPE(PARENT,NAME) \
447  SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,PARENT,::,NAME)
448 
451 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,PARENT,SEP,NAME) \
452 class EXPORT NAME { \
453  int ix; \
454 public: \
455  NAME() : ix(SimTK::InvalidIndex) { } \
456  explicit NAME(int i) : ix(i) {assert(i>=0 || i==SimTK::InvalidIndex);} \
457  explicit NAME(long l): ix((int)l) {assert(SimTK::canStoreInNonnegativeInt(l));} \
458  explicit NAME(unsigned int u) : ix((int)u) {assert(SimTK::canStoreInInt(u));} \
459  explicit NAME(unsigned long ul) : ix((int)ul) {assert(SimTK::canStoreInInt(ul));} \
460  operator int() const {return ix;} \
461  bool isValid() const {return ix>=0;} \
462  bool isValidExtended() const {return ix>=-1;} \
463  void invalidate(){ix=SimTK::InvalidIndex;} \
464  \
465  bool operator==(int i) const {assert(isValidExtended() && isValidExtended(i)); return ix==i;} \
466  bool operator==(short s) const{assert(isValidExtended() && isValidExtended(s)); return ix==(int)s;} \
467  bool operator==(long l) const {assert(isValidExtended() && isValidExtended(l)); return ix==(int)l;} \
468  bool operator==(unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix==(int)u;} \
469  bool operator==(unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix==(int)us;} \
470  bool operator==(unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix==(int)ul;} \
471  bool operator!=(int i) const {return !operator==(i);} \
472  bool operator!=(short s) const {return !operator==(s);} \
473  bool operator!=(long l) const {return !operator==(l);} \
474  bool operator!=(unsigned int u) const {return !operator==(u);} \
475  bool operator!=(unsigned long ul) const {return !operator==(ul);} \
476  \
477  bool operator< (int i) const {assert(isValidExtended() && isValidExtended(i)); return ix<i;} \
478  bool operator< (short s) const{assert(isValidExtended() && isValidExtended(s)); return ix<(int)s;} \
479  bool operator< (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix<(int)l;} \
480  bool operator< (unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix<(int)u;} \
481  bool operator< (unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix<(int)us;} \
482  bool operator< (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix<(int)ul;} \
483  bool operator>=(int i) const {return !operator<(i);} \
484  bool operator>=(short s) const {return !operator<(s);} \
485  bool operator>=(long l) const {return !operator<(l);} \
486  bool operator>=(unsigned int u) const {return !operator<(u);} \
487  bool operator>=(unsigned short us)const {return !operator<(us);} \
488  bool operator>=(unsigned long ul) const {return !operator<(ul);} \
489  \
490  bool operator> (int i) const {assert(isValidExtended() && isValidExtended(i)); return ix>i;} \
491  bool operator> (short s) const{assert(isValidExtended() && isValidExtended(s)); return ix>(int)s;} \
492  bool operator> (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix>(int)l;} \
493  bool operator> (unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix>(int)u;} \
494  bool operator> (unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix>(int)us;} \
495  bool operator> (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix>(int)ul;} \
496  bool operator<=(int i) const {return !operator>(i);} \
497  bool operator<=(short s) const {return !operator>(s);} \
498  bool operator<=(long l) const {return !operator>(l);} \
499  bool operator<=(unsigned int u) const {return !operator>(u);} \
500  bool operator<=(unsigned short us)const {return !operator>(us);} \
501  bool operator<=(unsigned long ul) const {return !operator>(ul);} \
502  \
503  const NAME& operator++() {assert(isValid()); ++ix; return *this;} /*prefix */ \
504  NAME operator++(int) {assert(isValid()); ++ix; return NAME(ix-1);} /*postfix*/ \
505  const NAME& operator--() {assert(isValid()); --ix; return *this;} /*prefix */ \
506  NAME operator--(int) {assert(isValid()); --ix; return NAME(ix+1);} /*postfix*/ \
507  NAME next() const {assert(isValid()); return NAME(ix+1);} \
508  NAME prev() const {assert(isValid()); return NAME(ix-1);} /*might return -1*/ \
509  \
510  NAME& operator+=(int i) {assert(isValid() && isValidExtended(ix+i)); ix+=i; return *this;} \
511  NAME& operator-=(int i) {assert(isValid() && isValidExtended(ix-i)); ix-=i; return *this;} \
512  NAME& operator+=(short s){assert(isValid() && SimTK::canStoreInInt(s) && isValidExtended(ix+(int)s)); ix+=(int)s; return *this;} \
513  NAME& operator-=(short s){assert(isValid() && SimTK::canStoreInInt(s) && isValidExtended(ix-(int)s)); ix-=(int)s; return *this;} \
514  NAME& operator+=(long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix+(int)l)); ix+=(int)l; return *this;} \
515  NAME& operator-=(long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix-(int)l)); ix-=(int)l; return *this;} \
516  NAME& operator+=(unsigned int u) {assert(isValid()&& SimTK::canStoreInInt(u) && isValid(ix+(int)u)); ix+=(int)u; return *this;} \
517  NAME& operator-=(unsigned int u) {assert(isValid()&& SimTK::canStoreInInt(u) && isValidExtended(ix-(int)u)); ix-=(int)u; return *this;} \
518  NAME& operator+=(unsigned short us){assert(isValid()&& SimTK::canStoreInInt(us) && isValid(ix+(int)us)); ix+=(int)us; return *this;} \
519  NAME& operator-=(unsigned short us){assert(isValid()&& SimTK::canStoreInInt(us) && isValidExtended(ix-(int)us)); ix-=(int)us; return *this;} \
520  NAME& operator+=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValid(ix+(int)ul)); ix+=(int)ul; return *this;} \
521  NAME& operator-=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValidExtended(ix-(int)ul)); ix-=(int)ul; return *this;} \
522  \
523  static const NAME& Invalid() {static const NAME invalid; return invalid;} \
524  static bool isValid(int i) {return i>=0;} \
525  static bool isValid(short s){return s>=0;} \
526  static bool isValid(long l) {return SimTK::canStoreInNonnegativeInt(l);} \
527  static bool isValid(unsigned int u) {return SimTK::canStoreInInt(u);} \
528  static bool isValid(unsigned short) {return true;} \
529  static bool isValid(unsigned long ul) {return SimTK::canStoreInInt(ul);} \
530  static bool isValidExtended(int i) {return i>=-1;} \
531  static bool isValidExtended(short s){return s>=-1;} \
532  static bool isValidExtended(long l) {return SimTK::canStoreInInt(l) && l>=-1;} \
533  /* IndexTraits for use in Array_<T,X> with this as X; same as int */ \
534  typedef int size_type; \
535  typedef int difference_type; \
536  static size_type max_size() {return std::numeric_limits<int>::max();} \
537 };
538 
545 #ifndef NDEBUG
546  #define SimTK_DYNAMIC_CAST_DEBUG dynamic_cast // safe but slow
547 #else
548  #define SimTK_DYNAMIC_CAST_DEBUG static_cast // unsafe but fast
549 #endif
550 
554 #define SimTK_DOWNCAST(Derived,Parent) \
555  static bool isA(const Parent& p) \
556  { return dynamic_cast<const Derived*>(&p) != 0; } \
557  static const Derived& downcast(const Parent& p) \
558  { return SimTK_DYNAMIC_CAST_DEBUG<const Derived&>(p); } \
559  static Derived& updDowncast(Parent& p) \
560  { return SimTK_DYNAMIC_CAST_DEBUG<Derived&>(p); } \
561  static Derived& downcast(Parent& p) \
562  { return SimTK_DYNAMIC_CAST_DEBUG<Derived&>(p); }
563 
566 #define SimTK_DOWNCAST2(Derived,Helper,Parent) \
567  static bool isA(const Parent& p) \
568  { return Helper::isA(p); } \
569  static const Derived& downcast(const Parent& p) \
570  { return static_cast<const Derived&>(Helper::downcast(p)); } \
571  static Derived& updDowncast(Parent& p) \
572  { return static_cast<Derived&>(Helper::downcast(p)); } \
573  static Derived& downcast(Parent& p) \
574  { return static_cast<Derived&>(Helper::downcast(p)); }
575 
576 
580 #define SimTK_PIMPL_DOWNCAST(Derived, Parent) \
581  static bool isInstanceOf(const Parent&); \
582  static const Derived& downcast(const Parent&); \
583  static Derived& updDowncast(Parent&)
584 
585 namespace SimTK {
586 
589 namespace Exception { }
590 
593 typedef SimTK_Real Real;
596 typedef std::complex<Real> Complex;
598 typedef std::complex<float> fComplex;
600 typedef std::complex<double> dComplex;
601 
602 
603 // Forward declaration giving template defaults must come before any
604 // other declarations.
605 template <int M, class ELT=Real, int STRIDE=1> class Vec;
606 template <int N, class ELT=Real, int STRIDE=1> class Row;
607 template <int M, int N, class ELT=Real, int CS=M, int RS=1> class Mat;
608 template <int M, class ELT=Real, int RS=1> class SymMat;
609 
612 struct Segment {
613  Segment() : length(0), offset(0) { }
614  explicit Segment(int l, int ofs=0) : length(l), offset(ofs) {
615  assert(l>=0 && ofs>=0);
616  }
617  // default copy, assignment, destructor
618  int length;
619  int offset;
620 };
621 
622 
628 struct DontCopy {};
632 struct TrustMe {};
633 
636 struct FalseType {};
639 struct TrueType {};
640 
642 template <class L, class R> struct AndOpType {};
643 template<> struct AndOpType<FalseType,FalseType> {typedef FalseType Result;};
644 template<> struct AndOpType<FalseType,TrueType> {typedef FalseType Result;};
645 template<> struct AndOpType<TrueType, FalseType> {typedef FalseType Result;};
646 template<> struct AndOpType<TrueType, TrueType> {typedef TrueType Result;};
647 
649 template <class L, class R> struct OrOpType {};
650 template<> struct OrOpType<FalseType,FalseType> {typedef FalseType Result;};
651 template<> struct OrOpType<FalseType,TrueType> {typedef TrueType Result;};
652 template<> struct OrOpType<TrueType, FalseType> {typedef TrueType Result;};
653 template<> struct OrOpType<TrueType, TrueType> {typedef TrueType Result;};
654 
656 template <class L, class R> struct XorOpType {};
657 template<> struct XorOpType<FalseType,FalseType> {typedef FalseType Result;};
658 template<> struct XorOpType<FalseType,TrueType> {typedef TrueType Result;};
659 template<> struct XorOpType<TrueType, FalseType> {typedef TrueType Result;};
660 template<> struct XorOpType<TrueType, TrueType> {typedef FalseType Result;};
661 
663 template <class T> struct IsIntegralType {
666  typedef FalseType Result;
669  static const bool result = false;
670 };
673 #define SimTK_SPECIALIZE_INTEGRAL_TYPE(T) \
674  template<> struct IsIntegralType<T> \
675  {typedef TrueType Result; static const bool result = true;}
676 
679 // This causes problems when used with Qt which for some crazy
680 // reason likes to make its own wchar_t rather than using the built in.
681 // SimTK_SPECIALIZE_INTEGRAL_TYPE(wchar_t);
682 SimTK_SPECIALIZE_INTEGRAL_TYPE(signed char);
683 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned char);
685 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned short);
687 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned int); // a.k.a. "unsigned"
689 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned long);
691 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned long long);
692 
694 template <class T> struct IsFloatingType {
697  typedef FalseType Result;
700  static const bool result = false;
701 };
704 #define SimTK_SPECIALIZE_FLOATING_TYPE(T) \
705  template<> struct IsFloatingType<T> \
706  {typedef TrueType Result; static const bool result = true;}
707 
710 SimTK_SPECIALIZE_FLOATING_TYPE(long double);
711 
713 template <class T> struct IsVoidType {
716  typedef FalseType Result;
719  static const bool result = false;
720 };
721 template<> struct IsVoidType<void>
722 {typedef TrueType Result; static const bool result = true;};
723 
726 template <class T> struct IsArithmeticType {
733  static const bool result = IsIntegralType<T>::result
735 };
736 
737 // This struct's sole use is to allow us to define the typedef
738 // Is64BitPlatformType as equivalent to either TrueType or FalseType.
739 template <bool is64Bit> struct Is64BitHelper {};
740 template<> struct Is64BitHelper<true>
741 {typedef TrueType Result; static const bool result = true;};
742 template<> struct Is64BitHelper<false>
743 {typedef FalseType Result; static const bool result = false;};
744 
749 static const bool Is64BitPlatform = sizeof(size_t) > sizeof(int);
751 
752 
756 SimTK_SimTKCOMMON_EXPORT std::string demangle(const char* name);
757 
761 template <class T> struct NiceTypeName {
765  static const char* name() {return typeid(T).name();}
769  static std::string namestr() {return demangle(name());}
770 };
771 
772 } // namespace SimTK
773 
780 #define SimTK_NICETYPENAME_LITERAL(T) \
781 namespace SimTK { \
782  template <> struct NiceTypeName< T > { \
783  static std::string namestr() { return #T; } \
784  static const char* name() { return #T; } \
785  }; \
786 }
787 
788 // Some types for which we'd like to see nice type names.
791 // This causes problems when used with Qt which for some crazy
792 // reason likes to make its own wchar_t rather than using the built in.
793 // SimTK_NICETYPENAME_LITERAL(wchar_t);
794 SimTK_NICETYPENAME_LITERAL(signed char);
795 SimTK_NICETYPENAME_LITERAL(unsigned char);
797 SimTK_NICETYPENAME_LITERAL(unsigned short);
799 SimTK_NICETYPENAME_LITERAL(unsigned); // preferred to "unsigned int"
801 SimTK_NICETYPENAME_LITERAL(unsigned long);
802 SimTK_NICETYPENAME_LITERAL(long long);
803 SimTK_NICETYPENAME_LITERAL(unsigned long long);
806 SimTK_NICETYPENAME_LITERAL(long double);
807 SimTK_NICETYPENAME_LITERAL(std::string);
808 SimTK_NICETYPENAME_LITERAL(std::complex<float>);
809 SimTK_NICETYPENAME_LITERAL(std::complex<double>);
810 SimTK_NICETYPENAME_LITERAL(std::complex<long double>);
813 
814 
815 #endif /* C++ stuff */
816 
817 #endif /* SimTK_SimTKCOMMON_COMMON_H_ */
This is an operator for exclusive or-ing compile-time truth types.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:656
#define SimTK_SimTKCOMMON_EXPORT
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:218
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:730
This is a small, fixed-size symmetric or Hermitian matrix designed for no-overhead inline computation...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:608
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:646
This is a special type used for causing invocation of a particular constructor or method overload tha...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:628
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37
#define SimTK_SPECIALIZE_INTEGRAL_TYPE(T)
This macro must be invoked once for each of the built-in integral types to specialize the IsIntegralT...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:673
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:596
Segment()
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:613
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:769
STL namespace.
static const int InvalidIndex
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:399
double SimTK_Real
This type is for use in C; in C++ use SimTK::Real instead.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:113
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:593
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:643
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:722
Compile-time type test: is this the void type?.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:713
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:652
This is a compile-time equivalent of "false", used in compile-time condition checking in templatized ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:636
Is64BitHelper< Is64BitPlatform >::Result Is64BitPlatformType
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:750
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:650
Segment(int l, int ofs=0)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:614
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:765
This is a fixed-length column vector designed for no-overhead inline computation. ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:605
FalseType Result
This typedef is TrueType if the template type T is "void"; otherwise it is FalseType.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:716
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:653
This is an operator for or-ing compile-time truth types.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:649
std::string demangle(const char *name)
Attempt to demangle a type name as returned by typeid.name(), with the result hopefully suitable for ...
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:660
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:658
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:726
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:739
This is a compile-time equivalent of "true", used in compile-time condition checking in templatized i...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:639
This is a special type used for forcing invocation of a particularly dangerous constructor or method ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:632
Compile-time type test: is this one of the built-in integral types?.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:663
std::complex< double > dComplex
An abbreviation for std::complex<double> for consistency with others.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:600
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:743
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:657
#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:780
Compile-time type test: is this one of the built-in floating point types?.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:694
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:666
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:697
RowVectorBase< typename CNT< ELEM >::TAbs > abs(const RowVectorBase< ELEM > &v)
Definition: VectorMath.h:120
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:644
This is a fixed-length row vector designed for no-overhead inline computation.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:606
bool isNonnegative(unsigned long long)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:394
std::complex< float > fComplex
An abbreviation for std::complex<float> for consistency with others.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:598
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:659
In case you don&#39;t like the name you get from typeid(), you can specialize this class to provide a nic...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:761
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:612
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:749
int length
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:618
#define SimTK_SPECIALIZE_FLOATING_TYPE(T)
This macro must be invoked once for each of the built-in floating point types to specialize the IsFlo...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:704
This class represents a small matrix whose size is known at compile time, containing elements of any ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:607
bool canStoreInInt(unsigned long long u)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:325
bool isSizeInRange(unsigned long long sz, unsigned long long mx)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:357
This is an operator for and-ing compile-time truth types.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:642
int offset
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:619
bool canStoreInNonnegativeInt(unsigned long long u)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:340
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:741
bool isIndexInRange(unsigned long long ix, unsigned long long sz)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:376
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:651
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:645