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)
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)
231extern "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
263a performance improvement. You can end up with serious code bloat if you
264override the compiler's judgement about when to inline, and that can cause
265cache 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
280that 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.
296Don't use them. Sorry, can't use the DEPRECATED_14 macro here! */
297#define OVERRIDE_11 override
298#define FINAL_11 final
299
300namespace 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?".
305inline bool canStoreInInt(bool) {return true;}
306inline bool canStoreInInt(char) {return true;}
307inline bool canStoreInInt(unsigned char) {return true;}
308inline bool canStoreInInt(signed char) {return true;}
309inline bool canStoreInInt(short) {return true;}
310inline bool canStoreInInt(unsigned short) {return true;}
311inline bool canStoreInInt(int) {return true;}
312inline bool canStoreInInt(unsigned int u) {return (unsigned int)(int(u)) == u;}
313inline bool canStoreInInt(long i) {return long(int(i)) == i;}
314inline bool canStoreInInt(unsigned long u) {return (unsigned long)(int(u)) == u;}
315inline bool canStoreInInt(long long i) {return (long long)(int(i)) == i;}
316inline 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?".
320inline bool canStoreInNonnegativeInt(bool) {return true;}
321inline bool canStoreInNonnegativeInt(char c) {return c >= 0;}
322inline bool canStoreInNonnegativeInt(unsigned char) {return true;}
323inline bool canStoreInNonnegativeInt(signed char c) {return c >= 0;}
324inline bool canStoreInNonnegativeInt(short s) {return s >= 0;}
325inline bool canStoreInNonnegativeInt(unsigned short) {return true;}
326inline bool canStoreInNonnegativeInt(int i) {return i >= 0;}
327inline bool canStoreInNonnegativeInt(long l) {return canStoreInInt(l) && l >= 0;}
328inline bool canStoreInNonnegativeInt(long long l) {return canStoreInInt(l) && l >= 0;}
329inline bool canStoreInNonnegativeInt(unsigned int u) {return canStoreInInt(u);}
330inline bool canStoreInNonnegativeInt(unsigned long u) {return canStoreInInt(u);}
331inline 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.
338inline bool isSizeInRange(char sz, char mx){return 0<=sz&&sz<=mx;}
339inline bool isSizeInRange(signed char sz, signed char mx){return 0<=sz&&sz<=mx;}
340inline bool isSizeInRange(short sz, short mx){return 0<=sz&&sz<=mx;}
341inline bool isSizeInRange(int sz, int mx){return 0<=sz&&sz<=mx;}
342inline bool isSizeInRange(long sz, long mx){return 0<=sz&&sz<=mx;}
343inline bool isSizeInRange(long long sz, long long mx){return 0<=sz&&sz<=mx;}
344inline bool isSizeInRange(unsigned char sz, unsigned char mx){return sz<=mx;}
345inline bool isSizeInRange(unsigned short sz, unsigned short mx){return sz<=mx;}
346inline bool isSizeInRange(unsigned int sz, unsigned int mx){return sz<=mx;}
347inline bool isSizeInRange(unsigned long sz, unsigned long mx){return sz<=mx;}
348inline 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.
357inline bool isIndexInRange(char ix, char sz){return 0<=ix&&ix<sz;}
358inline bool isIndexInRange(signed char ix, signed char sz){return 0<=ix&&ix<sz;}
359inline bool isIndexInRange(short ix, short sz){return 0<=ix&&ix<sz;}
360inline bool isIndexInRange(int ix, int sz){return 0<=ix&&ix<sz;}
361inline bool isIndexInRange(long ix, long sz){return 0<=ix&&ix<sz;}
362inline bool isIndexInRange(long long ix, long long sz){return 0<=ix&&ix<sz;}
363inline bool isIndexInRange(unsigned char ix, unsigned char sz){return ix<sz;}
364inline bool isIndexInRange(unsigned short ix, unsigned short sz){return ix<sz;}
365inline bool isIndexInRange(unsigned int ix, unsigned int sz){return ix<sz;}
366inline bool isIndexInRange(unsigned long ix, unsigned long sz){return ix<sz;}
367inline 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
373inline bool isNonnegative(bool) {return true;}
374// char can be signed or unsigned depending on the compiler; assume signed.
375inline bool isNonnegative(char n) {return n>=0;}
376inline bool isNonnegative(signed char n) {return n>=0;}
377inline bool isNonnegative(short n) {return n>=0;}
378inline bool isNonnegative(int n) {return n>=0;}
379inline bool isNonnegative(long n) {return n>=0;}
380inline bool isNonnegative(long long n) {return n>=0;}
381inline bool isNonnegative(unsigned char) {return true;}
382inline bool isNonnegative(unsigned short) {return true;}
383inline bool isNonnegative(unsigned int) {return true;}
384inline bool isNonnegative(unsigned long) {return true;}
385inline 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.
390static 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) \
443class EXPORT NAME { \
444 int ix; \
445public: \
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
598namespace SimTK {
599
602namespace Exception { }
603
609typedef std::complex<Real> Complex;
611typedef std::complex<float> fComplex;
613typedef std::complex<double> dComplex;
614
615
616// Forward declaration giving template defaults must come before any
617// other declarations.
618template <int M, class ELT=Real, int STRIDE=1> class Vec;
619template <int N, class ELT=Real, int STRIDE=1> class Row;
620template <int M, int N, class ELT=Real, int CS=M, int RS=1> class Mat;
621template <int M, class ELT=Real, int RS=1> class SymMat;
622
625struct 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
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
640template<class L, class R> inline
641bool operator!=(const L& left, const R& right)
642{ // test for inequality, in terms of equality
643 return !(left == right);
644}
645
646template<class L, class R> inline
647bool operator>(const L& left, const R& right)
648{ // test if left > right, in terms of operator<
649 return right < left;
650}
651
652template<class L, class R> inline
653bool operator<=(const L& left, const R& right)
654{ // test if left <= right, in terms of operator<
655 return !(right < left);
656}
657
658template<class L, class R> inline
659bool operator>=(const L& left, const R& right)
660{ // test if left >= right, in terms of operator<
661 return !(left < right);
662}
663
664
670struct DontCopy {};
674struct TrustMe {};
675
678struct FalseType {};
681struct TrueType {};
682
684template <class L, class R> struct AndOpType {};
685template<> struct AndOpType<FalseType,FalseType> {typedef FalseType Result;};
686template<> struct AndOpType<FalseType,TrueType> {typedef FalseType Result;};
687template<> struct AndOpType<TrueType, FalseType> {typedef FalseType Result;};
688template<> struct AndOpType<TrueType, TrueType> {typedef TrueType Result;};
689
691template <class L, class R> struct OrOpType {};
692template<> struct OrOpType<FalseType,FalseType> {typedef FalseType Result;};
693template<> struct OrOpType<FalseType,TrueType> {typedef TrueType Result;};
694template<> struct OrOpType<TrueType, FalseType> {typedef TrueType Result;};
695template<> struct OrOpType<TrueType, TrueType> {typedef TrueType Result;};
696
698template <class L, class R> struct XorOpType {};
699template<> struct XorOpType<FalseType,FalseType> {typedef FalseType Result;};
700template<> struct XorOpType<FalseType,TrueType> {typedef TrueType Result;};
701template<> struct XorOpType<TrueType, FalseType> {typedef TrueType Result;};
702template<> struct XorOpType<TrueType, TrueType> {typedef FalseType Result;};
703
705template <class T> struct IsIntegralType {
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);
729SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned int); // a.k.a. "unsigned"
734
736template <class T> struct IsFloatingType {
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
754template <class T> struct IsVoidType {
760 static const bool result = false;
761};
762template<> struct IsVoidType<void>
763{typedef TrueType Result; static const bool result = true;};
764
767template <class T> struct IsArithmeticType {
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.
780template <bool is64Bit> struct Is64BitHelper {};
781template<> struct Is64BitHelper<true>
782{typedef TrueType Result; static const bool result = true;};
783template<> 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.
791constexpr bool detect64BitPlatform() { return (sizeof(size_t) > sizeof(int)); }
794
795
801std::string demangle(const char* name);
802
811std::string canonicalizeTypeName(std::string&& demangledTypeName);
812
815inline std::string canonicalizeTypeName(const std::string& demangledTypeName)
816{ return canonicalizeTypeName(std::string(demangledTypeName)); }
817
824std::string encodeTypeNameForXML(std::string&& canonicalizedTypeName);
825
828inline std::string encodeTypeNameForXML(const std::string& niceTypeName)
829{ return encodeTypeNameForXML(std::string(niceTypeName)); }
830
836std::string decodeXMLTypeName(std::string&& xmlTypeName);
837
840inline std::string decodeXMLTypeName(const std::string& xmlTypeName)
841{ return decodeXMLTypeName(std::string(xmlTypeName)); }
842
858template <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) \
889namespace SimTK { \
890template <> 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);
914SimTK_NICETYPENAME_LITERAL(unsigned); // preferred to "unsigned int"
918SimTK_NICETYPENAME_LITERAL(unsigned long long);
923SimTK_NICETYPENAME_LITERAL(std::complex<float>);
924SimTK_NICETYPENAME_LITERAL(std::complex<double>);
925SimTK_NICETYPENAME_LITERAL(std::complex<long double>);
928
929
930#endif /* C++ stuff */
931
932#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:888
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:613
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
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:611
SimTK_SPECIALIZE_INTEGRAL_TYPE(bool)
bool operator>(const L &left, const R &right)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:647
bool operator>=(const L &left, const R &right)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:659
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
bool operator<=(const L &left, const R &right)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:653
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:606
Is64BitHelper< Is64BitPlatform >::Result Is64BitPlatformType
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:793
bool operator!=(const L &left, const R &right)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:641
bool canStoreInInt(bool)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:305
static const bool Is64BitPlatform
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:792
static const int InvalidIndex
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:390
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:685
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:686
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:687
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:688
This is an operator for and-ing compile-time truth types.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:684
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
This is a compile-time equivalent of "false", used in compile-time condition checking in templatized ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:678
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:784
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:782
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:780
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
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
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
Compile-time type test: is this one of the built-in floating point types?.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:736
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
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
Compile-time type test: is this one of the built-in integral types?.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:705
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
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
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:763
Compile-time type test: is this the void type?.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:754
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
This typedef is TrueType if the template type T is "void"; otherwise it is FalseType.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:757
Obtain human-readable and XML-usable names for arbitrarily-complicated C++ types.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:858
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
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
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
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:840
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:828
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
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:692
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:693
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:694
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
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
int length
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:631
int offset
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:632
Segment(int l, int ofs=0)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:627
Segment()
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:626
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
This is a special type used for forcing invocation of a particularly dangerous constructor or method ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:674
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:699
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:700
TrueType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:701
FalseType Result
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:702
This is an operator for exclusive or-ing compile-time truth types.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:698