Simbody  3.7
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-15 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 #else
115  #error ILLEGAL VALUE FOR DEFAULT PRECISION
116 #endif
117 
118 #ifndef NDEBUG
119  #if defined(__cplusplus)
120  #include <cstdio>
121  #define SimTK_DEBUG(s) std::printf("DBG: " s)
122  #define SimTK_DEBUG1(s,a1) std::printf("DBG: " s,a1)
123  #define SimTK_DEBUG2(s,a1,a2) std::printf("DBG: " s,a1,a2)
124  #define SimTK_DEBUG3(s,a1,a2,a3) std::printf("DBG: " s,a1,a2,a3)
125  #define SimTK_DEBUG4(s,a1,a2,a3,a4) std::printf("DBG: " s,a1,a2,a3,a4)
126  #else
127  #include <stdio.h>
128  #define SimTK_DEBUG(s) printf("DBG: " s)
129  #define SimTK_DEBUG1(s,a1) printf("DBG: " s,a1)
130  #define SimTK_DEBUG2(s,a1,a2) printf("DBG: " s,a1,a2)
131  #define SimTK_DEBUG3(s,a1,a2,a3) printf("DBG: " s,a1,a2,a3)
132  #define SimTK_DEBUG4(s,a1,a2,a3,a4) printf("DBG: " s,a1,a2,a3,a4)
133  #endif
134 #else
135  #define SimTK_DEBUG(s)
136  #define SimTK_DEBUG1(s,a1)
137  #define SimTK_DEBUG2(s,a1,a2)
138  #define SimTK_DEBUG3(s,a1,a2,a3)
139  #define SimTK_DEBUG4(s,a1,a2,a3,a4)
140 #endif
141 
142 /*
143  * Shared libraries are messy in Visual Studio. We have to distinguish three
144  * cases:
145  * (1) this header is being used to build the SimTKcommon shared library (dllexport)
146  * (2) this header is being used by a *client* of the SimTKcommon shared
147  * library (dllimport)
148  * (3) we are building the SimTKcommon static library, or the client is
149  * being compiled with the expectation of linking with the
150  * SimTKcommon static library (nothing special needed)
151  * In the CMake script for building this library, we define one of the symbols
152  * SimTK_SimTKCOMMON_BUILDING_{SHARED|STATIC}_LIBRARY
153  * Client code normally has no special symbol defined, in which case we'll
154  * assume it wants to use the shared library. However, if the client defines
155  * the symbol SimTK_USE_STATIC_LIBRARIES we'll suppress the dllimport so
156  * that the client code can be linked with static libraries. Note that
157  * the client symbol is not library dependent, while the library symbols
158  * affect only the SimTKcommon library, meaning that other libraries can
159  * be clients of this one. However, we are assuming all-static or all-shared.
160  */
161 
162 #ifdef _WIN32
163  #ifdef _MSC_VER
164  #pragma warning(disable:4231) /*need to use 'extern' template explicit instantiation*/
165  #pragma warning(disable:4251) /*no DLL interface for type of member of exported class*/
166  #pragma warning(disable:4275) /*no DLL interface for base class of exported class*/
167  #pragma warning(disable:4345) /*warning about PODs being default-initialized*/
168 
169 
170  /* Until VS2015 struct timespec was missing from <ctime> so is faked here
171  if needed. When Simbody used pthreads and provided its own pthread.h for
172  Windows, we had to avoid a duplicate declaration with timespec in pthread.h
173  via the HAVE_STRUCT_TIMESPEC guard. In 2018, we removed pthread.h, but we
174  left in the HAVE_STRUCT_TIMESPEC guard in case a third party defines
175  timespec.
176  TODO: there is a potential problem here since VS2015's struct timespec
177  doesn't appear to match pthread's definition. */
178  #ifndef HAVE_STRUCT_TIMESPEC
179  #define HAVE_STRUCT_TIMESPEC 1
180  #if _MSC_VER < 1900
181  struct timespec {
182  long tv_sec; /* TODO(sherm1,chrisdembia) should be time_t? */
183  long tv_nsec;
184  };
185  #endif
186  #endif /* HAVE_STRUCT_TIMESPEC */
187  #endif
188  #if defined(SimTK_SimTKCOMMON_BUILDING_SHARED_LIBRARY)
189  #ifdef _MSC_VER
190  #define SimTK_SimTKCOMMON_EXPORT __declspec(dllexport)
191  /* Keep MS VC++ quiet when it tries to instantiate incomplete template classes in a DLL. */
192  #pragma warning(disable:4661)
193  #else
194  #define SimTK_SimTKCOMMON_EXPORT
195  #endif
196  #elif defined(SimTK_SimTKCOMMON_BUILDING_STATIC_LIBRARY) || defined(SimTK_USE_STATIC_LIBRARIES)
197  #define SimTK_SimTKCOMMON_EXPORT
198  #else
199  #ifdef _MSC_VER
200  #define SimTK_SimTKCOMMON_EXPORT __declspec(dllimport) /*i.e., a client of a shared library*/
201  #else
202  #define SimTK_SimTKCOMMON_EXPORT
203  #endif
204  #endif
205  /* VC++ tries to be secure by leaving bounds checking on for STL containers
206  * even in Release mode. This macro exists to disable that feature and can
207  * result in a considerable speedup.
208  * CAUTION: every linked-together compilation unit must have this set the same
209  * way. Everyone who properly includes this file first is fine; but as of this
210  * writing Simmath's IpOpt doesn't do so.
211  * NOTE: Microsoft corrected this problem with VC10 -- the feature is
212  * disabled by default in that compiler and later.
213  */
214  /* (sherm 081204 disabling for now: doesn't work on VC++ 8 and is
215  * tricky on VC++ 9 because all libraries, including 3rd party, must
216  * be built the same way). Better to use the SimTK::Array_<T> class in
217  * place of the std::vector<T> class to get better performance.
218  #ifdef NDEBUG
219  #undef _SECURE_SCL
220  #define _SECURE_SCL 0
221  #endif
222  */
223 #else
224  #define SimTK_SimTKCOMMON_EXPORT // Linux, Mac
225 #endif
226 
227 /* Every SimTK Core library must provide these two routines, with the library
228  * name appearing after the "version_" and "about_".
229  */
230 #if defined(__cplusplus)
231 extern "C" {
232 #endif
233 
234  SimTK_SimTKCOMMON_EXPORT void SimTK_version_SimTKcommon(int* major, int* minor, int* build);
241  SimTK_SimTKCOMMON_EXPORT void SimTK_about_SimTKcommon(const char* key, int maxlen, char* value);
242 #if defined(__cplusplus)
243 }
244 #endif
245 
246 /************************************/
247 /* END OF ANSI-C COMPATIBLE SECTION */
248 /************************************/
249 
250 #if defined(__cplusplus)
251 
252 #include <cstddef>
253 #include <cassert>
254 #include <cstring>
255 #include <cmath>
256 #include <cfloat>
257 #include <complex>
258 #include <limits>
259 #include <typeinfo>
260 #include <algorithm>
261 
262 /* Be very careful with this macro -- don't use it unless you have measured
263 a performance improvement. You can end up with serious code bloat if you
264 override the compiler's judgement about when to inline, and that can cause
265 cache misses which ultimately reduce performance. */
266 #ifdef _MSC_VER
267  #define SimTK_FORCE_INLINE __forceinline
268 #else
269  #define SimTK_FORCE_INLINE __attribute__((always_inline)) inline
270 #endif
271 
272 /* Microsoft added noexcept in VS2015 */
273 #if defined(_MSC_VER) && _MSC_VER < 1900
274  #define NOEXCEPT_11 throw()
275 #else
276  #define NOEXCEPT_11 noexcept
277 #endif
278 
279 /* C++14 introduces a standard way to mark deprecated declarations. Before
280 that we can use non-standard compiler hacks. */
281 #ifndef SWIG
282  #if __cplusplus >= 201402L
283  /* C++14 */
284  #define DEPRECATED_14(MSG) [[deprecated(MSG)]]
285  #elif _MSC_VER
286  /* VC++ just says warning C4996 so add "DEPRECATED" to the message. */
287  #define DEPRECATED_14(MSG) __declspec(deprecated("DEPRECATED: " MSG))
288  #else /* gcc or clang */
289  #define DEPRECATED_14(MSG) __attribute__((deprecated(MSG)))
290  #endif
291 #else /* Swigging */
292  #define DEPRECATED_14(MSG)
293 #endif
294 
295 /* These macros are deprecated, leftover from before C++11 was available.
296 Don't use them. Sorry, can't use the DEPRECATED_14 macro here! */
297 #define OVERRIDE_11 override
298 #define FINAL_11 final
299 
300 namespace SimTK {
301 
302 
303 // This utility answers the question "if I put this integral value in an int and then
304 // get it back, will its value be the same?".
305 inline bool canStoreInInt(bool) {return true;}
306 inline bool canStoreInInt(char) {return true;}
307 inline bool canStoreInInt(unsigned char) {return true;}
308 inline bool canStoreInInt(signed char) {return true;}
309 inline bool canStoreInInt(short) {return true;}
310 inline bool canStoreInInt(unsigned short) {return true;}
311 inline bool canStoreInInt(int) {return true;}
312 inline bool canStoreInInt(unsigned int u) {return (unsigned int)(int(u)) == u;}
313 inline bool canStoreInInt(long i) {return long(int(i)) == i;}
314 inline bool canStoreInInt(unsigned long u) {return (unsigned long)(int(u)) == u;}
315 inline bool canStoreInInt(long long i) {return (long long)(int(i)) == i;}
316 inline bool canStoreInInt(unsigned long long u) {return (unsigned long long)(int(u)) == u;}
317 
318 // This utility answers the question "is this integral value a nonnegative number
319 // that can be stored in an int?".
320 inline bool canStoreInNonnegativeInt(bool) {return true;}
321 inline bool canStoreInNonnegativeInt(char c) {return c >= 0;}
322 inline bool canStoreInNonnegativeInt(unsigned char) {return true;}
323 inline bool canStoreInNonnegativeInt(signed char c) {return c >= 0;}
324 inline bool canStoreInNonnegativeInt(short s) {return s >= 0;}
325 inline bool canStoreInNonnegativeInt(unsigned short) {return true;}
326 inline bool canStoreInNonnegativeInt(int i) {return i >= 0;}
327 inline bool canStoreInNonnegativeInt(long l) {return canStoreInInt(l) && l >= 0;}
328 inline bool canStoreInNonnegativeInt(long long l) {return canStoreInInt(l) && l >= 0;}
329 inline bool canStoreInNonnegativeInt(unsigned int u) {return canStoreInInt(u);}
330 inline bool canStoreInNonnegativeInt(unsigned long u) {return canStoreInInt(u);}
331 inline bool canStoreInNonnegativeInt(unsigned long long u) {return canStoreInInt(u);}
332 
333 // This utility answers the question of whether an integer is suitable as a size
334 // limited by the given maximum size. Signed types must be checked for being
335 // nonegative; doing that with unsigned types leads to compiler warnings.
336 
337 // char can be signed or unsigned depending on the compiler; assume signed.
338 inline bool isSizeInRange(char sz, char mx){return 0<=sz&&sz<=mx;}
339 inline bool isSizeInRange(signed char sz, signed char mx){return 0<=sz&&sz<=mx;}
340 inline bool isSizeInRange(short sz, short mx){return 0<=sz&&sz<=mx;}
341 inline bool isSizeInRange(int sz, int mx){return 0<=sz&&sz<=mx;}
342 inline bool isSizeInRange(long sz, long mx){return 0<=sz&&sz<=mx;}
343 inline bool isSizeInRange(long long sz, long long mx){return 0<=sz&&sz<=mx;}
344 inline bool isSizeInRange(unsigned char sz, unsigned char mx){return sz<=mx;}
345 inline bool isSizeInRange(unsigned short sz, unsigned short mx){return sz<=mx;}
346 inline bool isSizeInRange(unsigned int sz, unsigned int mx){return sz<=mx;}
347 inline bool isSizeInRange(unsigned long sz, unsigned long mx){return sz<=mx;}
348 inline bool isSizeInRange(unsigned long long sz, unsigned long long mx){return sz<=mx;}
349 
350 // This utility answers the question of whether an integer is suitable as an index
351 // for an array limited by the given maximum size. Signed types must be checked for being
352 // nonegative; doing that with unsigned types leads to compiler warnings. This is just
353 // like the "size in range" check above except the maximum value allowed for an index
354 // is one less that the size.
355 
356 // char can be signed or unsigned depending on the compiler; assume signed.
357 inline bool isIndexInRange(char ix, char sz){return 0<=ix&&ix<sz;}
358 inline bool isIndexInRange(signed char ix, signed char sz){return 0<=ix&&ix<sz;}
359 inline bool isIndexInRange(short ix, short sz){return 0<=ix&&ix<sz;}
360 inline bool isIndexInRange(int ix, int sz){return 0<=ix&&ix<sz;}
361 inline bool isIndexInRange(long ix, long sz){return 0<=ix&&ix<sz;}
362 inline bool isIndexInRange(long long ix, long long sz){return 0<=ix&&ix<sz;}
363 inline bool isIndexInRange(unsigned char ix, unsigned char sz){return ix<sz;}
364 inline bool isIndexInRange(unsigned short ix, unsigned short sz){return ix<sz;}
365 inline bool isIndexInRange(unsigned int ix, unsigned int sz){return ix<sz;}
366 inline bool isIndexInRange(unsigned long ix, unsigned long sz){return ix<sz;}
367 inline bool isIndexInRange(unsigned long long ix, unsigned long long sz){return ix<sz;}
368 
369 // This utility answers the question: is this integral value nonnegative? The answer
370 // is always true for unsigned types and you'll get a warning from some compilers if
371 // you check.
372 
373 inline bool isNonnegative(bool) {return true;}
374 // char can be signed or unsigned depending on the compiler; assume signed.
375 inline bool isNonnegative(char n) {return n>=0;}
376 inline bool isNonnegative(signed char n) {return n>=0;}
377 inline bool isNonnegative(short n) {return n>=0;}
378 inline bool isNonnegative(int n) {return n>=0;}
379 inline bool isNonnegative(long n) {return n>=0;}
380 inline bool isNonnegative(long long n) {return n>=0;}
381 inline bool isNonnegative(unsigned char) {return true;}
382 inline bool isNonnegative(unsigned short) {return true;}
383 inline bool isNonnegative(unsigned int) {return true;}
384 inline bool isNonnegative(unsigned long) {return true;}
385 inline bool isNonnegative(unsigned long long){return true;}
386 
387 // A NaN-like value for unique index types created using the macro
388 // SimTK_DEFINE_UNIQUE_INDEX_TYPE(). A unique, typed constant with
389 // this numerical value is created for each index type.
390 static const int InvalidIndex = -1111111111;
391 }
392 
393 
394 
426 #define SimTK_DEFINE_UNIQUE_INDEX_TYPE(NAME) \
427  SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,,,NAME) \
428  static const NAME Invalid ## NAME;
429 
432 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_INDEX_TYPE(EXPORT,NAME) \
433  SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,,,NAME) \
434  static const NAME Invalid ## NAME;
435 
437 #define SimTK_DEFINE_UNIQUE_LOCAL_INDEX_TYPE(PARENT,NAME) \
438  SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,PARENT,::,NAME)
439 
442 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,PARENT,SEP,NAME) \
443 class EXPORT NAME { \
444  int ix; \
445 public: \
446  NAME() : ix(SimTK::InvalidIndex) { } \
447  explicit NAME(int i) : ix(i) {assert(i>=0 || i==SimTK::InvalidIndex);} \
448  explicit NAME(long l): ix((int)l) {assert(SimTK::canStoreInNonnegativeInt(l));} \
449  explicit NAME(long long l): ix((int)l) {assert(SimTK::canStoreInNonnegativeInt(l));} \
450  explicit NAME(unsigned int u) : ix((int)u) {assert(SimTK::canStoreInInt(u));} \
451  explicit NAME(unsigned long ul) : ix((int)ul) {assert(SimTK::canStoreInInt(ul));} \
452  explicit NAME(unsigned long long ul) : ix((int)ul) {assert(SimTK::canStoreInInt(ul));} \
453  operator int() const {return ix;} \
454  bool isValid() const {return ix>=0;} \
455  bool isValidExtended() const {return ix>=-1;} \
456  void invalidate(){clear();} \
457  void clear(){ix=SimTK::InvalidIndex;} \
458  \
459  bool operator==(int i) const {assert(isValidExtended() && isValidExtended(i)); return ix==i;} \
460  bool operator==(short s) const{assert(isValidExtended() && isValidExtended(s)); return ix==(int)s;} \
461  bool operator==(long l) const {assert(isValidExtended() && isValidExtended(l)); return ix==(int)l;} \
462  bool operator==(long long l) const {assert(isValidExtended() && isValidExtended(l)); return ix==(int)l;} \
463  bool operator==(unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix==(int)u;} \
464  bool operator==(unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix==(int)us;} \
465  bool operator==(unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix==(int)ul;} \
466  bool operator==(unsigned long 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!=(long long l) const {return !operator==(l);} \
471  bool operator!=(unsigned int u) const {return !operator==(u);} \
472  bool operator!=(unsigned long ul) const {return !operator==(ul);} \
473  bool operator!=(unsigned long long ul) const {return !operator==(ul);} \
474  \
475  bool operator< (int i) const {assert(isValidExtended() && isValidExtended(i)); return ix<i;} \
476  bool operator< (short s) const{assert(isValidExtended() && isValidExtended(s)); return ix<(int)s;} \
477  bool operator< (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix<(int)l;} \
478  bool operator< (long long l) const {assert(isValidExtended() && isValidExtended(l)); return ix<(int)l;} \
479  bool operator< (unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix<(int)u;} \
480  bool operator< (unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix<(int)us;} \
481  bool operator< (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix<(int)ul;} \
482  bool operator< (unsigned long 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>=(long long l) const {return !operator<(l);} \
487  bool operator>=(unsigned int u) const {return !operator<(u);} \
488  bool operator>=(unsigned short us)const {return !operator<(us);} \
489  bool operator>=(unsigned long ul) const {return !operator<(ul);} \
490  bool operator>=(unsigned long long ul) const {return !operator<(ul);} \
491  \
492  bool operator> (int i) const {assert(isValidExtended() && isValidExtended(i)); return ix>i;} \
493  bool operator> (short s) const{assert(isValidExtended() && isValidExtended(s)); return ix>(int)s;} \
494  bool operator> (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix>(int)l;} \
495  bool operator> (long long l) const {assert(isValidExtended() && isValidExtended(l)); return ix>(int)l;} \
496  bool operator> (unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix>(int)u;} \
497  bool operator> (unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix>(int)us;} \
498  bool operator> (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix>(int)ul;} \
499  bool operator> (unsigned long long ul) const {assert(isValidExtended() && isValid(ul)); return ix>(int)ul;} \
500  bool operator<=(int i) const {return !operator>(i);} \
501  bool operator<=(short s) const {return !operator>(s);} \
502  bool operator<=(long l) const {return !operator>(l);} \
503  bool operator<=(long long l) const {return !operator>(l);} \
504  bool operator<=(unsigned int u) const {return !operator>(u);} \
505  bool operator<=(unsigned short us)const {return !operator>(us);} \
506  bool operator<=(unsigned long ul) const {return !operator>(ul);} \
507  bool operator<=(unsigned long long ul) const {return !operator>(ul);} \
508  \
509  const NAME& operator++() {assert(isValid()); ++ix; return *this;} /*prefix */ \
510  NAME operator++(int) {assert(isValid()); ++ix; return NAME(ix-1);} /*postfix*/ \
511  const NAME& operator--() {assert(isValid()); --ix; return *this;} /*prefix */ \
512  NAME operator--(int) {assert(isValid()); --ix; return NAME(ix+1);} /*postfix*/ \
513  NAME next() const {assert(isValid()); return NAME(ix+1);} \
514  NAME prev() const {assert(isValid()); return NAME(ix-1);} /*might return -1*/ \
515  \
516  NAME& operator+=(int i) {assert(isValid() && isValidExtended(ix+i)); ix+=i; return *this;} \
517  NAME& operator-=(int i) {assert(isValid() && isValidExtended(ix-i)); ix-=i; return *this;} \
518  NAME& operator+=(short s){assert(isValid() && SimTK::canStoreInInt(s) && isValidExtended(ix+(int)s)); ix+=(int)s; return *this;} \
519  NAME& operator-=(short s){assert(isValid() && SimTK::canStoreInInt(s) && isValidExtended(ix-(int)s)); ix-=(int)s; return *this;} \
520  NAME& operator+=(long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix+(int)l)); ix+=(int)l; return *this;} \
521  NAME& operator-=(long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix-(int)l)); ix-=(int)l; return *this;} \
522  NAME& operator+=(long long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix+(int)l)); ix+=(int)l; return *this;} \
523  NAME& operator-=(long long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix-(int)l)); ix-=(int)l; return *this;} \
524  NAME& operator+=(unsigned int u) {assert(isValid()&& SimTK::canStoreInInt(u) && isValid(ix+(int)u)); ix+=(int)u; return *this;} \
525  NAME& operator-=(unsigned int u) {assert(isValid()&& SimTK::canStoreInInt(u) && isValidExtended(ix-(int)u)); ix-=(int)u; return *this;} \
526  NAME& operator+=(unsigned short us){assert(isValid()&& SimTK::canStoreInInt(us) && isValid(ix+(int)us)); ix+=(int)us; return *this;} \
527  NAME& operator-=(unsigned short us){assert(isValid()&& SimTK::canStoreInInt(us) && isValidExtended(ix-(int)us)); ix-=(int)us; return *this;} \
528  NAME& operator+=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValid(ix+(int)ul)); ix+=(int)ul; return *this;} \
529  NAME& operator-=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValidExtended(ix-(int)ul)); ix-=(int)ul; return *this;} \
530  NAME& operator+=(unsigned long long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValid(ix+(int)ul)); ix+=(int)ul; return *this;} \
531  NAME& operator-=(unsigned long long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValidExtended(ix-(int)ul)); ix-=(int)ul; return *this;} \
532  \
533  static const NAME& Invalid() {static const NAME invalid; return invalid;} \
534  static bool isValid(int i) {return i>=0;} \
535  static bool isValid(short s){return s>=0;} \
536  static bool isValid(long l) {return SimTK::canStoreInNonnegativeInt(l);} \
537  static bool isValid(long long l) {return SimTK::canStoreInNonnegativeInt(l);} \
538  static bool isValid(unsigned int u) {return SimTK::canStoreInInt(u);} \
539  static bool isValid(unsigned short) {return true;} \
540  static bool isValid(unsigned long ul) {return SimTK::canStoreInInt(ul);} \
541  static bool isValid(unsigned long long ul) {return SimTK::canStoreInInt(ul);} \
542  static bool isValidExtended(int i) {return i>=-1;} \
543  static bool isValidExtended(short s){return s>=-1;} \
544  static bool isValidExtended(long l) {return SimTK::canStoreInInt(l) && l>=-1;} \
545  static bool isValidExtended(long long l) {return SimTK::canStoreInInt(l) && l>=-1;} \
546  /* IndexTraits for use in Array_<T,X> with this as X; same as int */ \
547  typedef int size_type; \
548  typedef int difference_type; \
549  static size_type max_size() {return std::numeric_limits<int>::max();} \
550 };
551 
558 #ifndef NDEBUG
559  #define SimTK_DYNAMIC_CAST_DEBUG dynamic_cast // safe but slow
560 #else
561  #define SimTK_DYNAMIC_CAST_DEBUG static_cast // unsafe but fast
562 #endif
563 
567 #define SimTK_DOWNCAST(Derived,Parent) \
568  static bool isA(const Parent& p) \
569  { return dynamic_cast<const Derived*>(&p) != 0; } \
570  static const Derived& downcast(const Parent& p) \
571  { return SimTK_DYNAMIC_CAST_DEBUG<const Derived&>(p); } \
572  static Derived& updDowncast(Parent& p) \
573  { return SimTK_DYNAMIC_CAST_DEBUG<Derived&>(p); } \
574  static Derived& downcast(Parent& p) \
575  { return SimTK_DYNAMIC_CAST_DEBUG<Derived&>(p); }
576 
579 #define SimTK_DOWNCAST2(Derived,Helper,Parent) \
580  static bool isA(const Parent& p) \
581  { return Helper::isA(p); } \
582  static const Derived& downcast(const Parent& p) \
583  { return static_cast<const Derived&>(Helper::downcast(p)); } \
584  static Derived& updDowncast(Parent& p) \
585  { return static_cast<Derived&>(Helper::downcast(p)); } \
586  static Derived& downcast(Parent& p) \
587  { return static_cast<Derived&>(Helper::downcast(p)); }
588 
589 
593 #define SimTK_PIMPL_DOWNCAST(Derived, Parent) \
594  static bool isInstanceOf(const Parent&); \
595  static const Derived& downcast(const Parent&); \
596  static Derived& updDowncast(Parent&)
597 
598 namespace SimTK {
599 
602 namespace Exception { }
603 
606 typedef SimTK_Real Real;
609 typedef std::complex<Real> Complex;
611 typedef std::complex<float> fComplex;
613 typedef std::complex<double> dComplex;
614 
615 
616 // Forward declaration giving template defaults must come before any
617 // other declarations.
618 template <int M, class ELT=Real, int STRIDE=1> class Vec;
619 template <int N, class ELT=Real, int STRIDE=1> class Row;
620 template <int M, int N, class ELT=Real, int CS=M, int RS=1> class Mat;
621 template <int M, class ELT=Real, int RS=1> class SymMat;
622 
625 struct Segment {
626  Segment() : length(0), offset(0) { }
627  explicit Segment(int l, int ofs=0) : length(l), offset(ofs) {
628  assert(l>=0 && ofs>=0);
629  }
630  // default copy, assignment, destructor
631  int length;
632  int offset;
633 };
634 
635 // These next four methods supply the missing relational operators for any
636 // types L and R where L==R and L<R have been defined. This is like the
637 // operators in the std::rel_ops namespace, except that those require both
638 // types to be the same.
639 
640 template<class L, class R> inline
641 bool operator!=(const L& left, const R& right)
642 { // test for inequality, in terms of equality
643  return !(left == right);
644 }
645 
646 template<class L, class R> inline
647 bool operator>(const L& left, const R& right)
648 { // test if left > right, in terms of operator<
649  return right < left;
650 }
651 
652 template<class L, class R> inline
653 bool operator<=(const L& left, const R& right)
654 { // test if left <= right, in terms of operator<
655  return !(right < left);
656 }
657 
658 template<class L, class R> inline
659 bool operator>=(const L& left, const R& right)
660 { // test if left >= right, in terms of operator<
661  return !(left < right);
662 }
663 
664 
670 struct DontCopy {};
674 struct TrustMe {};
675 
678 struct FalseType {};
681 struct TrueType {};
682 
684 template <class L, class R> struct AndOpType {};
685 template<> struct AndOpType<FalseType,FalseType> {typedef FalseType Result;};
686 template<> struct AndOpType<FalseType,TrueType> {typedef FalseType Result;};
687 template<> struct AndOpType<TrueType, FalseType> {typedef FalseType Result;};
688 template<> struct AndOpType<TrueType, TrueType> {typedef TrueType Result;};
689 
691 template <class L, class R> struct OrOpType {};
692 template<> struct OrOpType<FalseType,FalseType> {typedef FalseType Result;};
693 template<> struct OrOpType<FalseType,TrueType> {typedef TrueType Result;};
694 template<> struct OrOpType<TrueType, FalseType> {typedef TrueType Result;};
695 template<> struct OrOpType<TrueType, TrueType> {typedef TrueType Result;};
696 
698 template <class L, class R> struct XorOpType {};
699 template<> struct XorOpType<FalseType,FalseType> {typedef FalseType Result;};
700 template<> struct XorOpType<FalseType,TrueType> {typedef TrueType Result;};
701 template<> struct XorOpType<TrueType, FalseType> {typedef TrueType Result;};
702 template<> struct XorOpType<TrueType, TrueType> {typedef FalseType Result;};
703 
705 template <class T> struct IsIntegralType {
708  typedef FalseType Result;
711  static const bool result = false;
712 };
715 #define SimTK_SPECIALIZE_INTEGRAL_TYPE(T) \
716  template<> struct IsIntegralType<T> \
717  {typedef TrueType Result; static const bool result = true;}
718 
721 // This causes problems when used with Qt which for some crazy
722 // reason likes to make its own wchar_t rather than using the built in.
723 // SimTK_SPECIALIZE_INTEGRAL_TYPE(wchar_t);
724 SimTK_SPECIALIZE_INTEGRAL_TYPE(signed char);
725 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned char);
727 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned short);
729 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned int); // a.k.a. "unsigned"
731 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned long);
733 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned long long);
734 
736 template <class T> struct IsFloatingType {
739  typedef FalseType Result;
742  static const bool result = false;
743 };
746 #define SimTK_SPECIALIZE_FLOATING_TYPE(T) \
747  template<> struct IsFloatingType<T> \
748  {typedef TrueType Result; static const bool result = true;}
749 
752 
754 template <class T> struct IsVoidType {
757  typedef FalseType Result;
760  static const bool result = false;
761 };
762 template<> struct IsVoidType<void>
763 {typedef TrueType Result; static const bool result = true;};
764 
767 template <class T> struct IsArithmeticType {
774  static const bool result = IsIntegralType<T>::result
776 };
777 
778 // This struct's sole use is to allow us to define the typedef
779 // Is64BitPlatformType as equivalent to either TrueType or FalseType.
780 template <bool is64Bit> struct Is64BitHelper {};
781 template<> struct Is64BitHelper<true>
782 {typedef TrueType Result; static const bool result = true;};
783 template<> struct Is64BitHelper<false>
784 {typedef FalseType Result; static const bool result = false;};
785 
790 // We use a constexpr function to avoid a bug in SWIG.
791 constexpr bool detect64BitPlatform() { return (sizeof(size_t) > sizeof(int)); }
792 static const bool Is64BitPlatform = detect64BitPlatform();
794 
795 
801 std::string demangle(const char* name);
802 
811 std::string canonicalizeTypeName(std::string&& demangledTypeName);
812 
815 inline std::string canonicalizeTypeName(const std::string& demangledTypeName)
816 { return canonicalizeTypeName(std::string(demangledTypeName)); }
817 
824 std::string encodeTypeNameForXML(std::string&& canonicalizedTypeName);
825 
828 inline std::string encodeTypeNameForXML(const std::string& niceTypeName)
829 { return encodeTypeNameForXML(std::string(niceTypeName)); }
830 
836 std::string decodeXMLTypeName(std::string&& xmlTypeName);
837 
840 inline std::string decodeXMLTypeName(const std::string& xmlTypeName)
841 { return decodeXMLTypeName(std::string(xmlTypeName)); }
842 
858 template <class T> struct NiceTypeName {
862  static const char* name() {return typeid(T).name();}
867  static const std::string& namestr() {
868  static const std::string canonical =
870  return canonical;
871  }
874  static const std::string& xmlstr() {
875  static const std::string xml = encodeTypeNameForXML(namestr());
876  return xml;
877  }
878 };
879 
880 } // namespace SimTK
881 
888 #define SimTK_NICETYPENAME_LITERAL(T) \
889 namespace SimTK { \
890 template <> struct NiceTypeName< T > { \
891  static const char* name() { return #T; } \
892  static const std::string& namestr() { \
893  static const std::string str(#T); \
894  return str; \
895  } \
896  static const std::string& xmlstr() { \
897  static const std::string xml = encodeTypeNameForXML(namestr()); \
898  return xml; \
899  } \
900 }; \
901 }
902 
903 // Some types for which we'd like to see nice type names.
906 // This causes problems when used with Qt which for some crazy
907 // reason likes to make its own wchar_t rather than using the built in.
908 // SimTK_NICETYPENAME_LITERAL(wchar_t);
909 SimTK_NICETYPENAME_LITERAL(signed char);
910 SimTK_NICETYPENAME_LITERAL(unsigned char);
912 SimTK_NICETYPENAME_LITERAL(unsigned short);
914 SimTK_NICETYPENAME_LITERAL(unsigned); // preferred to "unsigned int"
916 SimTK_NICETYPENAME_LITERAL(unsigned long);
917 SimTK_NICETYPENAME_LITERAL(long long);
918 SimTK_NICETYPENAME_LITERAL(unsigned long long);
921 SimTK_NICETYPENAME_LITERAL(long double);
922 SimTK_NICETYPENAME_LITERAL(std::string);
923 SimTK_NICETYPENAME_LITERAL(std::complex<float>);
924 SimTK_NICETYPENAME_LITERAL(std::complex<double>);
925 SimTK_NICETYPENAME_LITERAL(std::complex<long double>);
928 
929 
930 #endif /* C++ stuff */
931 
932 #endif /* SimTK_SimTKCOMMON_COMMON_H_ */
bool operator<=(const L &left, const R &right)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:653
This is an operator for exclusive or-ing compile-time truth types.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:698
#define SimTK_SimTKCOMMON_EXPORT
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:224
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:771
std::string canonicalizeTypeName(std::string &&demangledTypeName)
Given a compiler-dependent demangled type name string as returned by SimTK::demangle(), attempt to form a canonicalized representation that will be the same for any compiler.
This is a small, fixed-size symmetric or Hermitian matrix designed for no-overhead inline computation...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:621
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:688
This is a special type used for causing invocation of a particular constructor or method overload tha...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:670
bool canStoreInNonnegativeInt(bool)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:320
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:305
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:609
Segment()
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:626
static const std::string & namestr()
The default implementation of namestr() attempts to return a nicely demangled and canonicalized type ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:867
static const int InvalidIndex
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:390
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:606
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:685
Compile-time type test: is this the void type?.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:754
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:694
This is a compile-time equivalent of "false", used in compile-time condition checking in templatized ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:678
Is64BitHelper< Is64BitPlatform >::Result Is64BitPlatformType
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:793
std::string encodeTypeNameForXML(const std::string &niceTypeName)
Same, but takes an lvalue reference so has to copy the input.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:828
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:692
bool isIndexInRange(char ix, char sz)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:357
Segment(int l, int ofs=0)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:627
static const char * name()
The default implementation of name() here returns the raw result from `typeid(T). ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:862
std::string canonicalizeTypeName(const std::string &demangledTypeName)
Same, but takes an lvalue reference so has to copy the input.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:815
This is a fixed-length column vector designed for no-overhead inline computation. ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:618
FalseType Result
This typedef is TrueType if the template type T is "void"; otherwise it is FalseType.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:757
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:695
This is an operator for or-ing compile-time truth types.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:691
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:760
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:702
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:700
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:767
constexpr bool detect64BitPlatform()
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:791
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:742
void SimTK_about_SimTKcommon(const char *key, int maxlen, char *value)
Obtain "about" information for the currently-loaded SimTKcommon library.
static const std::string & xmlstr()
The default implementation of xmlstr() takes the output of namestr() and invokes SimTK::encodeTypeNam...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:874
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:780
This is a compile-time equivalent of "true", used in compile-time condition checking in templatized i...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:681
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:674
Compile-time type test: is this one of the built-in integral types?.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:705
std::complex< double > dComplex
An abbreviation for std::complex<double> for consistency with others.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:613
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:699
Compile-time type test: is this one of the built-in floating point types?.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:736
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:708
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:739
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:686
std::string encodeTypeNameForXML(std::string &&canonicalizedTypeName)
Given a canonicalized type name, produce a modified version that is better-suited to use as an XML at...
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:774
This is a fixed-length row vector designed for no-overhead inline computation.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:619
std::string demangle(const char *name)
Attempt to demangle a type name as returned by typeid.name(), with the result hopefully suitable for ...
std::complex< float > fComplex
An abbreviation for std::complex<float> for consistency with others.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:611
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:701
Obtain human-readable and XML-usable names for arbitrarily-complicated C++ types. ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:858
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:625
static const bool Is64BitPlatform
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:792
int length
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:631
bool operator!=(const L &left, const R &right)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:641
This class represents a small matrix whose size is known at compile time, containing elements of any ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:620
bool operator>(const L &left, const R &right)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:647
SimTK_SPECIALIZE_FLOATING_TYPE(float)
bool operator>=(const L &left, const R &right)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:659
This is an operator for and-ing compile-time truth types.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:684
int offset
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:632
#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:888
bool isSizeInRange(char sz, char mx)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:338
std::string decodeXMLTypeName(const std::string &xmlTypeName)
Same, but takes an lvalue reference so has to copy the input.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:840
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:711
bool isNonnegative(bool)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:373
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:693
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:687