Simbody  3.8
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)
110  typedef float SimTK_Real;
111 #elif (SimTK_DEFAULT_PRECISION == 2)
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
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==(const NAME& other) const {assert(isValidExtended() && isValidExtended(other)); return ix == other.ix; } \
460  bool operator==(int i) const {assert(isValidExtended() && isValidExtended(i)); return ix==i;} \
461  bool operator==(short s) const{assert(isValidExtended() && isValidExtended(s)); return ix==(int)s;} \
462  bool operator==(long l) const {assert(isValidExtended() && isValidExtended(l)); return ix==(int)l;} \
463  bool operator==(long 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==(unsigned long long ul) const {assert(isValidExtended() && isValid(ul)); return ix==(int)ul;} \
468  bool operator!=(int i) const {return !operator==(i);} \
469  bool operator!=(short s) const {return !operator==(s);} \
470  bool operator!=(long l) const {return !operator==(l);} \
471  bool operator!=(long long l) const {return !operator==(l);} \
472  bool operator!=(unsigned int u) const {return !operator==(u);} \
473  bool operator!=(unsigned long ul) const {return !operator==(ul);} \
474  bool operator!=(unsigned long long ul) const {return !operator==(ul);} \
475  \
476  bool operator< (int i) const {assert(isValidExtended() && isValidExtended(i)); return ix<i;} \
477  bool operator< (short s) const{assert(isValidExtended() && isValidExtended(s)); return ix<(int)s;} \
478  bool operator< (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix<(int)l;} \
479  bool operator< (long 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< (unsigned long long ul) const {assert(isValidExtended() && isValid(ul)); return ix<(int)ul;} \
484  bool operator>=(int i) const {return !operator<(i);} \
485  bool operator>=(short s) const {return !operator<(s);} \
486  bool operator>=(long l) const {return !operator<(l);} \
487  bool operator>=(long long l) const {return !operator<(l);} \
488  bool operator>=(unsigned int u) const {return !operator<(u);} \
489  bool operator>=(unsigned short us)const {return !operator<(us);} \
490  bool operator>=(unsigned long ul) const {return !operator<(ul);} \
491  bool operator>=(unsigned long long ul) const {return !operator<(ul);} \
492  \
493  bool operator> (int i) const {assert(isValidExtended() && isValidExtended(i)); return ix>i;} \
494  bool operator> (short s) const{assert(isValidExtended() && isValidExtended(s)); return ix>(int)s;} \
495  bool operator> (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix>(int)l;} \
496  bool operator> (long long l) const {assert(isValidExtended() && isValidExtended(l)); return ix>(int)l;} \
497  bool operator> (unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix>(int)u;} \
498  bool operator> (unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix>(int)us;} \
499  bool operator> (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix>(int)ul;} \
500  bool operator> (unsigned long long ul) const {assert(isValidExtended() && isValid(ul)); return ix>(int)ul;} \
501  bool operator<=(int i) const {return !operator>(i);} \
502  bool operator<=(short s) const {return !operator>(s);} \
503  bool operator<=(long l) const {return !operator>(l);} \
504  bool operator<=(long long l) const {return !operator>(l);} \
505  bool operator<=(unsigned int u) const {return !operator>(u);} \
506  bool operator<=(unsigned short us)const {return !operator>(us);} \
507  bool operator<=(unsigned long ul) const {return !operator>(ul);} \
508  bool operator<=(unsigned long long ul) const {return !operator>(ul);} \
509  \
510  const NAME& operator++() {assert(isValid()); ++ix; return *this;} /*prefix */ \
511  NAME operator++(int) {assert(isValid()); ++ix; return NAME(ix-1);} /*postfix*/ \
512  const NAME& operator--() {assert(isValid()); --ix; return *this;} /*prefix */ \
513  NAME operator--(int) {assert(isValid()); --ix; return NAME(ix+1);} /*postfix*/ \
514  NAME next() const {assert(isValid()); return NAME(ix+1);} \
515  NAME prev() const {assert(isValid()); return NAME(ix-1);} /*might return -1*/ \
516  \
517  NAME& operator+=(int i) {assert(isValid() && isValidExtended(ix+i)); ix+=i; return *this;} \
518  NAME& operator-=(int i) {assert(isValid() && isValidExtended(ix-i)); ix-=i; return *this;} \
519  NAME& operator+=(short s){assert(isValid() && SimTK::canStoreInInt(s) && isValidExtended(ix+(int)s)); ix+=(int)s; return *this;} \
520  NAME& operator-=(short s){assert(isValid() && SimTK::canStoreInInt(s) && isValidExtended(ix-(int)s)); ix-=(int)s; 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 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-=(long long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix-(int)l)); ix-=(int)l; return *this;} \
525  NAME& operator+=(unsigned int u) {assert(isValid()&& SimTK::canStoreInInt(u) && isValid(ix+(int)u)); ix+=(int)u; return *this;} \
526  NAME& operator-=(unsigned int u) {assert(isValid()&& SimTK::canStoreInInt(u) && isValidExtended(ix-(int)u)); ix-=(int)u; return *this;} \
527  NAME& operator+=(unsigned short us){assert(isValid()&& SimTK::canStoreInInt(us) && isValid(ix+(int)us)); ix+=(int)us; return *this;} \
528  NAME& operator-=(unsigned short us){assert(isValid()&& SimTK::canStoreInInt(us) && isValidExtended(ix-(int)us)); ix-=(int)us; return *this;} \
529  NAME& operator+=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValid(ix+(int)ul)); ix+=(int)ul; return *this;} \
530  NAME& operator-=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValidExtended(ix-(int)ul)); ix-=(int)ul; return *this;} \
531  NAME& operator+=(unsigned long long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValid(ix+(int)ul)); ix+=(int)ul; return *this;} \
532  NAME& operator-=(unsigned long long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValidExtended(ix-(int)ul)); ix-=(int)ul; return *this;} \
533  \
534  static const NAME& Invalid() {static const NAME invalid; return invalid;} \
535  static bool isValid(int i) {return i>=0;} \
536  static bool isValid(short s){return s>=0;} \
537  static bool isValid(long l) {return SimTK::canStoreInNonnegativeInt(l);} \
538  static bool isValid(long long l) {return SimTK::canStoreInNonnegativeInt(l);} \
539  static bool isValid(unsigned int u) {return SimTK::canStoreInInt(u);} \
540  static bool isValid(unsigned short) {return true;} \
541  static bool isValid(unsigned long ul) {return SimTK::canStoreInInt(ul);} \
542  static bool isValid(unsigned long long ul) {return SimTK::canStoreInInt(ul);} \
543  static bool isValidExtended(int i) {return i>=-1;} \
544  static bool isValidExtended(short s){return s>=-1;} \
545  static bool isValidExtended(long l) {return SimTK::canStoreInInt(l) && l>=-1;} \
546  static bool isValidExtended(long long l) {return SimTK::canStoreInInt(l) && l>=-1;} \
547  /* IndexTraits for use in Array_<T,X> with this as X; same as int */ \
548  typedef int size_type; \
549  typedef int difference_type; \
550  static size_type max_size() {return std::numeric_limits<int>::max();} \
551 };
552 
559 #ifndef NDEBUG
560  #define SimTK_DYNAMIC_CAST_DEBUG dynamic_cast // safe but slow
561 #else
562  #define SimTK_DYNAMIC_CAST_DEBUG static_cast // unsafe but fast
563 #endif
564 
568 #define SimTK_DOWNCAST(Derived,Parent) \
569  static bool isA(const Parent& p) \
570  { return dynamic_cast<const Derived*>(&p) != 0; } \
571  static const Derived& downcast(const Parent& p) \
572  { return SimTK_DYNAMIC_CAST_DEBUG<const Derived&>(p); } \
573  static Derived& updDowncast(Parent& p) \
574  { return SimTK_DYNAMIC_CAST_DEBUG<Derived&>(p); } \
575  static Derived& downcast(Parent& p) \
576  { return SimTK_DYNAMIC_CAST_DEBUG<Derived&>(p); }
577 
580 #define SimTK_DOWNCAST2(Derived,Helper,Parent) \
581  static bool isA(const Parent& p) \
582  { return Helper::isA(p); } \
583  static const Derived& downcast(const Parent& p) \
584  { return static_cast<const Derived&>(Helper::downcast(p)); } \
585  static Derived& updDowncast(Parent& p) \
586  { return static_cast<Derived&>(Helper::downcast(p)); } \
587  static Derived& downcast(Parent& p) \
588  { return static_cast<Derived&>(Helper::downcast(p)); }
589 
590 
594 #define SimTK_PIMPL_DOWNCAST(Derived, Parent) \
595  static bool isInstanceOf(const Parent&); \
596  static const Derived& downcast(const Parent&); \
597  static Derived& updDowncast(Parent&)
598 
599 namespace SimTK {
600 
603 namespace Exception { }
604 
607 typedef SimTK_Real Real;
610 typedef std::complex<Real> Complex;
612 typedef std::complex<float> fComplex;
614 typedef std::complex<double> dComplex;
615 
616 
617 // Forward declaration giving template defaults must come before any
618 // other declarations.
619 template <int M, class ELT=Real, int STRIDE=1> class Vec;
620 template <int N, class ELT=Real, int STRIDE=1> class Row;
621 template <int M, int N, class ELT=Real, int CS=M, int RS=1> class Mat;
622 template <int M, class ELT=Real, int RS=1> class SymMat;
623 
626 struct Segment {
627  Segment() : length(0), offset(0) { }
628  explicit Segment(int l, int ofs=0) : length(l), offset(ofs) {
629  assert(l>=0 && ofs>=0);
630  }
631  // default copy, assignment, destructor
632  int length;
633  int offset;
634 };
635 
636 // With compiler support for <=> operator these four methods below don't
637 // need to be manually defined. (from gcc 10, clang 10 & msvc 19.22)
638 // also exclude if SWIG_PYTHON is defined to build python bindings in OpenSim
639 #if !defined(__cpp_lib_three_way_comparison) && !defined SWIG_PYTHON
640 // These next four methods supply the missing relational operators for any
641 // types L and R where L==R and L<R have been defined. This is like the
642 // operators in the std::rel_ops namespace, except that those require both
643 // types to be the same.
644 template<class L, class R> inline
645 bool operator!=(const L& left, const R& right)
646 { // test for inequality, in terms of equality
647  return !(left == right);
648 }
649 
650 template<class L, class R> inline
651 bool operator>(const L& left, const R& right)
652 { // test if left > right, in terms of operator<
653  return right < left;
654 }
655 
656 template<class L, class R> inline
657 bool operator<=(const L& left, const R& right)
658 { // test if left <= right, in terms of operator<
659  return !(right < left);
660 }
661 
662 template<class L, class R> inline
663 bool operator>=(const L& left, const R& right)
664 { // test if left >= right, in terms of operator<
665  return !(left < right);
666 }
667 #endif
668 
674 struct DontCopy {};
678 struct TrustMe {};
679 
682 struct FalseType {};
685 struct TrueType {};
686 
688 template <class L, class R> struct AndOpType {};
689 template<> struct AndOpType<FalseType,FalseType> {typedef FalseType Result;};
690 template<> struct AndOpType<FalseType,TrueType> {typedef FalseType Result;};
691 template<> struct AndOpType<TrueType, FalseType> {typedef FalseType Result;};
692 template<> struct AndOpType<TrueType, TrueType> {typedef TrueType Result;};
693 
695 template <class L, class R> struct OrOpType {};
696 template<> struct OrOpType<FalseType,FalseType> {typedef FalseType Result;};
697 template<> struct OrOpType<FalseType,TrueType> {typedef TrueType Result;};
698 template<> struct OrOpType<TrueType, FalseType> {typedef TrueType Result;};
699 template<> struct OrOpType<TrueType, TrueType> {typedef TrueType Result;};
700 
702 template <class L, class R> struct XorOpType {};
703 template<> struct XorOpType<FalseType,FalseType> {typedef FalseType Result;};
704 template<> struct XorOpType<FalseType,TrueType> {typedef TrueType Result;};
705 template<> struct XorOpType<TrueType, FalseType> {typedef TrueType Result;};
706 template<> struct XorOpType<TrueType, TrueType> {typedef FalseType Result;};
707 
709 template <class T> struct IsIntegralType {
712  typedef FalseType Result;
715  static const bool result = false;
716 };
719 #define SimTK_SPECIALIZE_INTEGRAL_TYPE(T) \
720  template<> struct IsIntegralType<T> \
721  {typedef TrueType Result; static const bool result = true;}
722 
725 // This causes problems when used with Qt which for some crazy
726 // reason likes to make its own wchar_t rather than using the built in.
727 // SimTK_SPECIALIZE_INTEGRAL_TYPE(wchar_t);
733 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned int); // a.k.a. "unsigned"
737 SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned long long);
738 
740 template <class T> struct IsFloatingType {
743  typedef FalseType Result;
746  static const bool result = false;
747 };
750 #define SimTK_SPECIALIZE_FLOATING_TYPE(T) \
751  template<> struct IsFloatingType<T> \
752  {typedef TrueType Result; static const bool result = true;}
753 
756 
758 template <class T> struct IsVoidType {
761  typedef FalseType Result;
764  static const bool result = false;
765 };
766 template<> struct IsVoidType<void>
767 {typedef TrueType Result; static const bool result = true;};
768 
771 template <class T> struct IsArithmeticType {
778  static const bool result = IsIntegralType<T>::result
780 };
781 
782 // This struct's sole use is to allow us to define the typedef
783 // Is64BitPlatformType as equivalent to either TrueType or FalseType.
784 template <bool is64Bit> struct Is64BitHelper {};
785 template<> struct Is64BitHelper<true>
786 {typedef TrueType Result; static const bool result = true;};
787 template<> struct Is64BitHelper<false>
788 {typedef FalseType Result; static const bool result = false;};
789 
794 // We use a constexpr function to avoid a bug in SWIG.
795 constexpr bool detect64BitPlatform() { return (sizeof(size_t) > sizeof(int)); }
796 static const bool Is64BitPlatform = detect64BitPlatform();
798 
799 
805 std::string demangle(const char* name);
806 
815 std::string canonicalizeTypeName(std::string&& demangledTypeName);
816 
819 inline std::string canonicalizeTypeName(const std::string& demangledTypeName)
820 { return canonicalizeTypeName(std::string(demangledTypeName)); }
821 
828 std::string encodeTypeNameForXML(std::string&& canonicalizedTypeName);
829 
832 inline std::string encodeTypeNameForXML(const std::string& niceTypeName)
833 { return encodeTypeNameForXML(std::string(niceTypeName)); }
834 
840 std::string decodeXMLTypeName(std::string&& xmlTypeName);
841 
844 inline std::string decodeXMLTypeName(const std::string& xmlTypeName)
845 { return decodeXMLTypeName(std::string(xmlTypeName)); }
846 
862 template <class T> struct NiceTypeName {
866  static const char* name() {return typeid(T).name();}
871  static const std::string& namestr() {
872  static const std::string canonical =
874  return canonical;
875  }
878  static const std::string& xmlstr() {
879  static const std::string xml = encodeTypeNameForXML(namestr());
880  return xml;
881  }
882 };
883 
884 } // namespace SimTK
885 
892 #define SimTK_NICETYPENAME_LITERAL(T) \
893 namespace SimTK { \
894 template <> struct NiceTypeName< T > { \
895  static const char* name() { return #T; } \
896  static const std::string& namestr() { \
897  static const std::string str(#T); \
898  return str; \
899  } \
900  static const std::string& xmlstr() { \
901  static const std::string xml = encodeTypeNameForXML(namestr()); \
902  return xml; \
903  } \
904 }; \
905 }
906 
907 // Some types for which we'd like to see nice type names.
910 // This causes problems when used with Qt which for some crazy
911 // reason likes to make its own wchar_t rather than using the built in.
912 // SimTK_NICETYPENAME_LITERAL(wchar_t);
916 SimTK_NICETYPENAME_LITERAL(unsigned short);
918 SimTK_NICETYPENAME_LITERAL(unsigned); // preferred to "unsigned int"
922 SimTK_NICETYPENAME_LITERAL(unsigned long long);
927 SimTK_NICETYPENAME_LITERAL(std::complex<float>);
928 SimTK_NICETYPENAME_LITERAL(std::complex<double>);
929 SimTK_NICETYPENAME_LITERAL(std::complex<long double>);
932 
933 
934 #endif /* C++ stuff */
935 
936 #endif /* SimTK_SimTKCOMMON_COMMON_H_ */
#define SimTK_SimTKCOMMON_EXPORT
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:224
#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:892
double SimTK_Real
This type is for use in C; in C++ use SimTK::Real instead.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:113
void SimTK_version_SimTKcommon(int *major, int *minor, int *build)
Obtain version information for the currently-loaded SimTKcommon library.
void SimTK_about_SimTKcommon(const char *key, int maxlen, char *value)
Obtain "about" information for the currently-loaded SimTKcommon library.
This class represents a small matrix whose size is known at compile time, containing elements of any ...
Definition: Mat.h:97
This is a fixed-length row vector designed for no-overhead inline computation.
Definition: Row.h:132
This is a small, fixed-size symmetric or Hermitian matrix designed for no-overhead inline computation...
Definition: SymMat.h:87
This is a fixed-length column vector designed for no-overhead inline computation.
Definition: Vec.h:184
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37
bool isIndexInRange(char ix, char sz)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:357
std::complex< double > dComplex
An abbreviation for std::complex<double> for consistency with others.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:614
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:610
bool canStoreInNonnegativeInt(bool)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:320
bool isSizeInRange(char sz, char mx)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:338
SimTK_SPECIALIZE_FLOATING_TYPE(float)
std::complex< float > fComplex
An abbreviation for std::complex<float> for consistency with others.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:612
SimTK_SPECIALIZE_INTEGRAL_TYPE(bool)
bool operator>(const L &left, const R &right)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:651
bool operator>=(const L &left, const R &right)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:663
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:795
bool operator<=(const L &left, const R &right)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:657
bool isNonnegative(bool)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:373
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:607
Is64BitHelper< Is64BitPlatform >::Result Is64BitPlatformType
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:797
bool operator!=(const L &left, const R &right)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:645
bool canStoreInInt(bool)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:305
static const bool Is64BitPlatform
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:796
static const int InvalidIndex
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:390
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:689
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:690
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:691
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:692
This is an operator for and-ing compile-time truth types.
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:674
This is a compile-time equivalent of "false", used in compile-time condition checking in templatized ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:682
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:788
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:786
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:784
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:771
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:778
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:775
Compile-time type test: is this one of the built-in floating point types?.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:740
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:746
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:743
Compile-time type test: is this one of the built-in integral types?.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:709
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:712
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:715
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:767
Compile-time type test: is this the void type?.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:758
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:764
FalseType Result
This typedef is TrueType if the template type T is "void"; otherwise it is FalseType.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:761
Obtain human-readable and XML-usable names for arbitrarily-complicated C++ types.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:862
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:871
static const char * name()
The default implementation of name() here returns the raw result from typeid(T).
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:866
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:819
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...
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:844
std::string canonicalizeTypeName(std::string &&demangledTypeName)
Given a compiler-dependent demangled type name string as returned by SimTK::demangle(),...
std::string demangle(const char *name)
Attempt to demangle a type name as returned by typeid.name(), with the result hopefully suitable for ...
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:832
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:878
std::string decodeXMLTypeName(std::string &&xmlTypeName)
Given a type name that was encoded for XML by SimTK::encodeTypeNameForXML(), restore it to its canoni...
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:696
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:697
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:698
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:699
This is an operator for or-ing compile-time truth types.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:695
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:626
int length
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:632
int offset
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:633
Segment(int l, int ofs=0)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:628
Segment()
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:627
This is a compile-time equivalent of "true", used in compile-time condition checking in templatized i...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:685
This is a special type used for forcing invocation of a particularly dangerous constructor or method ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:678
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:703
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:704
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:705
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:706
This is an operator for exclusive or-ing compile-time truth types.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:702