/usr/include/simbody/SimTKcommon/internal/common.h is in libsimbody-dev 3.5.4+dfsg-1ubuntu2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 | #ifndef SimTK_SimTKCOMMON_COMMON_H_
#define SimTK_SimTKCOMMON_COMMON_H_
/* -------------------------------------------------------------------------- *
* Simbody(tm): SimTKcommon *
* -------------------------------------------------------------------------- *
* This is part of the SimTK biosimulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
* *
* Portions copyright (c) 2005-14 Stanford University and the Authors. *
* Authors: Michael Sherman *
* Contributors: Chris Dembia *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may *
* not use this file except in compliance with the License. You may obtain a *
* copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* -------------------------------------------------------------------------- */
/**@file
Mandatory first inclusion for any Simbody source or header file.
Every source and most header files using %SimTK must include this
header as its \e first inclusion. Declarations and definitions that
must be available and compiler-and machine-specific issues are dealt
with here.
This file must be includable from either C++ or ANSI C. It uses
the ANSI-C++ macro "__cplusplus" for any code that will compile
only under C++. **/
// Provide doxygen documentation for the SimTK namespace.
/**@namespace SimTK
This is the top-level %SimTK namespace into which all %SimTK names are
placed to avoid collision with other symbols. If you get tired of prefacing
every symbol with "SimTK::", include the statement "using namespace SimTK;"
at the beginning of your %SimTK-using compilation units. Any names which
cannot be put in the namespace (macro names, for example) begin with the
prefix "SimTK_" instead. **/
// Define shared doxygen "modules" and sub-modules here. We'll put things
// in them at various places when appropriate.
/**@defgroup GlobalFunctions Global Functions in the SimTK namespace
These are functions at the top level of the SimTK namespace, meaning
that a function named funcName() is invoked as SimTK::funcName(), or
just funcName() if there is a "using namespace SimTK;" statement in effect. **/
/**@defgroup ScalarFunctions Scalar Functions
@ingroup GlobalFunctions
These functions are overloaded to act on %SimTK scalar types and C++
built-in types, including integral types when appropriate. **/
/**@defgroup BitFunctions Bit-twiddling Functions
@ingroup GlobalFunctions
These functions perform highly optimized bit-twiddling operations on
the built-in integral types, and sometimes on the representations of
floating point types as well. **/
/**@defgroup Serialization Utilities for De/serializing
@ingroup GlobalFunctions
These namespace-scope templatized utilities provide uniform serialization
and deserialization behavior for built-in and SimTK-defined types. See
SimTK::Xml for support of serialization to/from Xml files. **/
/**@defgroup UniqueIndexTypes Type-Safe Integer Indices
It is common to store objects or information about them in randomly-indexable
arrays, and then to support maximum-performance selection by allowing the
index to be used. We want these arrays indexable by simple ints for speed, but
this quickly leads to APIs in which there are multiple int arguments in a
function call, each intended to select a different kind of object. A common
error when there is a series of identical argument types is to put them in
the wrong order. To avoid that, we define unique index types here for
accessing each category to help stay out of trouble.
A unique index type is just a type-safe non-negative int, augmented with a
"NaN" value called InvalidBLAH where BLAH is the type name. For most uses it
will behave like an int, and it has an implicit conversion *to* int. Importantly
though, it has no implicit conversion *from* int so you can't pass a plain int
or any other Index type to an argument expecting a certain Index type. **/
/*****************************/
/* ANSI-C COMPATIBLE SECTION */
/*****************************/
/* Set up a few compile-time options that affect all SimTK Core headers. */
/**
* This compile-time constant determines the default precision used everywhere
* in %SimTK Core code. Wherever a SimTK::Real, SimTK::Vector, SimTK::Matrix,
* etc. appears with no precision specified, it will have this underlying precision.
* We use 1==float, 2==double, 4==long double. Any other value will cause
* a compile time error. The default is 2, i.e., double precision.
*/
#ifndef SimTK_DEFAULT_PRECISION
# define SimTK_DEFAULT_PRECISION 2
#endif
#if (SimTK_DEFAULT_PRECISION == 1)
/** This type is for use in C; in C++ use SimTK::Real instead. */
typedef float SimTK_Real;
#elif (SimTK_DEFAULT_PRECISION == 2)
/** This type is for use in C; in C++ use SimTK::Real instead. */
typedef double SimTK_Real;
#elif (SimTK_DEFAULT_PRECISION == 4)
/** This type is for use in C; in C++ use SimTK::Real instead. */
typedef long double SimTK_Real;
#else
#error ILLEGAL VALUE FOR DEFAULT PRECISION
#endif
#ifndef NDEBUG
#if defined(__cplusplus)
#include <cstdio>
#define SimTK_DEBUG(s) std::printf("DBG: " s)
#define SimTK_DEBUG1(s,a1) std::printf("DBG: " s,a1)
#define SimTK_DEBUG2(s,a1,a2) std::printf("DBG: " s,a1,a2)
#define SimTK_DEBUG3(s,a1,a2,a3) std::printf("DBG: " s,a1,a2,a3)
#define SimTK_DEBUG4(s,a1,a2,a3,a4) std::printf("DBG: " s,a1,a2,a3,a4)
#else
#include <stdio.h>
#define SimTK_DEBUG(s) printf("DBG: " s)
#define SimTK_DEBUG1(s,a1) printf("DBG: " s,a1)
#define SimTK_DEBUG2(s,a1,a2) printf("DBG: " s,a1,a2)
#define SimTK_DEBUG3(s,a1,a2,a3) printf("DBG: " s,a1,a2,a3)
#define SimTK_DEBUG4(s,a1,a2,a3,a4) printf("DBG: " s,a1,a2,a3,a4)
#endif
#else
#define SimTK_DEBUG(s)
#define SimTK_DEBUG1(s,a1)
#define SimTK_DEBUG2(s,a1,a2)
#define SimTK_DEBUG3(s,a1,a2,a3)
#define SimTK_DEBUG4(s,a1,a2,a3,a4)
#endif
/*
* Shared libraries are messy in Visual Studio. We have to distinguish three
* cases:
* (1) this header is being used to build the SimTKcommon shared library (dllexport)
* (2) this header is being used by a *client* of the SimTKcommon shared
* library (dllimport)
* (3) we are building the SimTKcommon static library, or the client is
* being compiled with the expectation of linking with the
* SimTKcommon static library (nothing special needed)
* In the CMake script for building this library, we define one of the symbols
* SimTK_SimTKCOMMON_BUILDING_{SHARED|STATIC}_LIBRARY
* Client code normally has no special symbol defined, in which case we'll
* assume it wants to use the shared library. However, if the client defines
* the symbol SimTK_USE_STATIC_LIBRARIES we'll suppress the dllimport so
* that the client code can be linked with static libraries. Note that
* the client symbol is not library dependent, while the library symbols
* affect only the SimTKcommon library, meaning that other libraries can
* be clients of this one. However, we are assuming all-static or all-shared.
*/
#ifdef _WIN32
#ifdef _MSC_VER
#pragma warning(disable:4231) /*need to use 'extern' template explicit instantiation*/
#pragma warning(disable:4251) /*no DLL interface for type of member of exported class*/
#pragma warning(disable:4275) /*no DLL interface for base class of exported class*/
#pragma warning(disable:4345) /*warning about PODs being default-initialized*/
/* Until VS2015 struct timespec was missing from <ctime> so is faked here
if needed. However, note that it is also defined in the pthread.h header on
Windows, so the guard symbol must match here to avoid a duplicate declaration.
TODO: there is a potential problem here since VS2015's struct timespec
doesn't appear to match pthread's definition. */
#ifndef HAVE_STRUCT_TIMESPEC
#define HAVE_STRUCT_TIMESPEC 1
#if _MSC_VER < 1900
struct timespec {
long tv_sec; // TODO: this should be time_t but must fix in pthreads too
long tv_nsec;
};
#endif
#endif /* HAVE_STRUCT_TIMESPEC */
#endif
#if defined(SimTK_SimTKCOMMON_BUILDING_SHARED_LIBRARY)
#define SimTK_SimTKCOMMON_EXPORT __declspec(dllexport)
/* Keep MS VC++ quiet when it tries to instantiate incomplete template classes in a DLL. */
#ifdef _MSC_VER
#pragma warning(disable:4661)
#endif
#elif defined(SimTK_SimTKCOMMON_BUILDING_STATIC_LIBRARY) || defined(SimTK_USE_STATIC_LIBRARIES)
#define SimTK_SimTKCOMMON_EXPORT
#else
#define SimTK_SimTKCOMMON_EXPORT __declspec(dllimport) /*i.e., a client of a shared library*/
#endif
/* VC++ tries to be secure by leaving bounds checking on for STL containers
* even in Release mode. This macro exists to disable that feature and can
* result in a considerable speedup.
* CAUTION: every linked-together compilation unit must have this set the same
* way. Everyone who properly includes this file first is fine; but as of this
* writing Simmath's IpOpt doesn't do so.
* NOTE: Microsoft corrected this problem with VC10 -- the feature is
* disabled by default in that compiler and later.
*/
/* (sherm 081204 disabling for now: doesn't work on VC++ 8 and is
* tricky on VC++ 9 because all libraries, including 3rd party, must
* be built the same way). Better to use the SimTK::Array_<T> class in
* place of the std::vector<T> class to get better performance.
#ifdef NDEBUG
#undef _SECURE_SCL
#define _SECURE_SCL 0
#endif
*/
#else
#define SimTK_SimTKCOMMON_EXPORT // Linux, Mac
#endif
/* Every SimTK Core library must provide these two routines, with the library
* name appearing after the "version_" and "about_".
*/
#if defined(__cplusplus)
extern "C" {
#endif
/** Obtain version information for the currently-loaded SimTKcommon library. */
SimTK_SimTKCOMMON_EXPORT void SimTK_version_SimTKcommon(int* major, int* minor, int* build);
/**
* Obtain "about" information for the currently-loaded SimTKcommon library.
* Available keywords are "version" (major.minor.build), "library",
* "type" (shared or static), "copyright", "svn_revision", "authors",
* "debug" (debug or release).
*/
SimTK_SimTKCOMMON_EXPORT void SimTK_about_SimTKcommon(const char* key, int maxlen, char* value);
#if defined(__cplusplus)
}
#endif
/************************************/
/* END OF ANSI-C COMPATIBLE SECTION */
/************************************/
#if defined(__cplusplus)
#include <cstddef>
#include <cassert>
#include <cstring>
#include <cmath>
#include <cfloat>
#include <complex>
#include <limits>
#include <typeinfo>
#include <algorithm>
/* Transition macros for C++11 support. VC10 and VC11 have partial support for
C++11, early VC's do not. If using gcc or Clang, we check for C++11 support. */
#ifndef SWIG
#if _MSC_VER>=1700 || (defined(__GNUG__) && __cplusplus>=201103L)
/* VC11 or higher, OR using gcc or Clang and using C++11 */
#define OVERRIDE_11 override
#define FINAL_11 final
#elif _MSC_VER==1600 /* VC10 */
#define OVERRIDE_11 override
#define FINAL_11 sealed
#else /* gcc or Clang without C++11, or earlier VC */
#define OVERRIDE_11
#define FINAL_11
#endif
#else /* Swigging */
#define OVERRIDE_11
#define FINAL_11
#endif
/* Be very careful with this macro -- don't use it unless you have measured
a performance improvement. You can end up with serious code bloat if you
override the compiler's judgement about when to inline, and that can cause
cache misses which ultimately reduce performance. */
#ifdef _MSC_VER
#define SimTK_FORCE_INLINE __forceinline
#else
#define SimTK_FORCE_INLINE __attribute__((always_inline))
#endif
/* In Microsoft VC++ 11 (2012) and earlier these C99-compatible floating
point functions are missing. We'll create them here and install them into
namespace std. They were added in VC++ 12 (2013). */
#if defined(_MSC_VER) && (_MSC_VER <= 1700) // VC++ 12 (2013, _MSC_VER=1800) added these
namespace std {
inline bool isfinite(float f) {return _finite(f) != 0;}
inline bool isfinite(double d) {return _finite(d) != 0;}
inline bool isfinite(long double l) {return _finite(l) != 0;}
inline bool isnan(float f) {return _isnan(f) != 0;}
inline bool isnan(double d) {return _isnan(d) != 0;}
inline bool isnan(long double l) {return _isnan(l) != 0;}
inline bool isinf(float f) {return std::abs(f)==std::numeric_limits<float>::infinity();}
inline bool isinf(double d) {return std::abs(d)==std::numeric_limits<double>::infinity();}
inline bool isinf(long double l) {return std::abs(l)==std::numeric_limits<double>::infinity();}
inline bool signbit(float f) {return (*reinterpret_cast<unsigned*>(&f) & 0x80000000U) != 0;}
inline bool signbit(double d) {return (*reinterpret_cast<unsigned long long*>(&d)
& 0x8000000000000000ULL) != 0;}
inline bool signbit(long double l) {return (*reinterpret_cast<unsigned long long*>(&l)
& 0x8000000000000000ULL) != 0;}
}
#endif
namespace SimTK {
// This utility answers the question "if I put this integral value in an int and then
// get it back, will its value be the same?".
inline bool canStoreInInt(bool) {return true;}
inline bool canStoreInInt(char) {return true;}
inline bool canStoreInInt(unsigned char) {return true;}
inline bool canStoreInInt(signed char) {return true;}
inline bool canStoreInInt(short) {return true;}
inline bool canStoreInInt(unsigned short) {return true;}
inline bool canStoreInInt(int) {return true;}
inline bool canStoreInInt(unsigned int u) {return (unsigned int)(int(u)) == u;}
inline bool canStoreInInt(long i) {return long(int(i)) == i;}
inline bool canStoreInInt(unsigned long u) {return (unsigned long)(int(u)) == u;}
inline bool canStoreInInt(long long i) {return (long long)(int(i)) == i;}
inline bool canStoreInInt(unsigned long long u) {return (unsigned long long)(int(u)) == u;}
// This utility answers the question "is this integral value a nonnegative number
// that can be stored in an int?".
inline bool canStoreInNonnegativeInt(bool) {return true;}
inline bool canStoreInNonnegativeInt(char c) {return c >= 0;}
inline bool canStoreInNonnegativeInt(unsigned char) {return true;}
inline bool canStoreInNonnegativeInt(signed char c) {return c >= 0;}
inline bool canStoreInNonnegativeInt(short s) {return s >= 0;}
inline bool canStoreInNonnegativeInt(unsigned short) {return true;}
inline bool canStoreInNonnegativeInt(int i) {return i >= 0;}
inline bool canStoreInNonnegativeInt(long l) {return canStoreInInt(l) && l >= 0;}
inline bool canStoreInNonnegativeInt(long long l) {return canStoreInInt(l) && l >= 0;}
inline bool canStoreInNonnegativeInt(unsigned int u) {return canStoreInInt(u);}
inline bool canStoreInNonnegativeInt(unsigned long u) {return canStoreInInt(u);}
inline bool canStoreInNonnegativeInt(unsigned long long u) {return canStoreInInt(u);}
// This utility answers the question of whether an integer is suitable as a size
// limited by the given maximum size. Signed types must be checked for being
// nonegative; doing that with unsigned types leads to compiler warnings.
// char can be signed or unsigned depending on the compiler; assume signed.
inline bool isSizeInRange(char sz, char mx){return 0<=sz&&sz<=mx;}
inline bool isSizeInRange(signed char sz, signed char mx){return 0<=sz&&sz<=mx;}
inline bool isSizeInRange(short sz, short mx){return 0<=sz&&sz<=mx;}
inline bool isSizeInRange(int sz, int mx){return 0<=sz&&sz<=mx;}
inline bool isSizeInRange(long sz, long mx){return 0<=sz&&sz<=mx;}
inline bool isSizeInRange(long long sz, long long mx){return 0<=sz&&sz<=mx;}
inline bool isSizeInRange(unsigned char sz, unsigned char mx){return sz<=mx;}
inline bool isSizeInRange(unsigned short sz, unsigned short mx){return sz<=mx;}
inline bool isSizeInRange(unsigned int sz, unsigned int mx){return sz<=mx;}
inline bool isSizeInRange(unsigned long sz, unsigned long mx){return sz<=mx;}
inline bool isSizeInRange(unsigned long long sz, unsigned long long mx){return sz<=mx;}
// This utility answers the question of whether an integer is suitable as an index
// for an array limited by the given maximum size. Signed types must be checked for being
// nonegative; doing that with unsigned types leads to compiler warnings. This is just
// like the "size in range" check above except the maximum value allowed for an index
// is one less that the size.
// char can be signed or unsigned depending on the compiler; assume signed.
inline bool isIndexInRange(char ix, char sz){return 0<=ix&&ix<sz;}
inline bool isIndexInRange(signed char ix, signed char sz){return 0<=ix&&ix<sz;}
inline bool isIndexInRange(short ix, short sz){return 0<=ix&&ix<sz;}
inline bool isIndexInRange(int ix, int sz){return 0<=ix&&ix<sz;}
inline bool isIndexInRange(long ix, long sz){return 0<=ix&&ix<sz;}
inline bool isIndexInRange(long long ix, long long sz){return 0<=ix&&ix<sz;}
inline bool isIndexInRange(unsigned char ix, unsigned char sz){return ix<sz;}
inline bool isIndexInRange(unsigned short ix, unsigned short sz){return ix<sz;}
inline bool isIndexInRange(unsigned int ix, unsigned int sz){return ix<sz;}
inline bool isIndexInRange(unsigned long ix, unsigned long sz){return ix<sz;}
inline bool isIndexInRange(unsigned long long ix, unsigned long long sz){return ix<sz;}
// This utility answers the question: is this integral value nonnegative? The answer
// is always true for unsigned types and you'll get a warning from some compilers if
// you check.
inline bool isNonnegative(bool) {return true;}
// char can be signed or unsigned depending on the compiler; assume signed.
inline bool isNonnegative(char n) {return n>=0;}
inline bool isNonnegative(signed char n) {return n>=0;}
inline bool isNonnegative(short n) {return n>=0;}
inline bool isNonnegative(int n) {return n>=0;}
inline bool isNonnegative(long n) {return n>=0;}
inline bool isNonnegative(long long n) {return n>=0;}
inline bool isNonnegative(unsigned char) {return true;}
inline bool isNonnegative(unsigned short) {return true;}
inline bool isNonnegative(unsigned int) {return true;}
inline bool isNonnegative(unsigned long) {return true;}
inline bool isNonnegative(unsigned long long){return true;}
// A NaN-like value for unique index types created using the macro
// SimTK_DEFINE_UNIQUE_INDEX_TYPE(). A unique, typed constant with
// this numerical value is created for each index type.
static const int InvalidIndex = -1111111111;
}
/**
* Use this macro to define a unique "Index" type which is just a type-safe
* non-negative int, augmented with a "NaN" value given by the predefined
* int constant SimTK::InvalidIndex. We also allow the Index to take on
* the value -1 if that is produced by a subtraction operation acting on a
* previously-valid Index, since that can occur during loops which are
* processed from the end towards the beginning. -1 is then allowed in
* comparision operators but not in any other operations, including further
* decrementing.
*
* No namespace is assumed for the newly-defined type; if you want the
* symbol in a namespace be sure to invoke the macro within that namespace.
* Make sure that the statement "#include <cassert>" appears somewhere before
* the point of invocation of this macro, because the defined Index type uses
* the assert() macro when in Debug mode.
*
* For most uses it will behave like an int, and it has an implicit
* conversion \e to int. Importantly though, it has no implicit conversion
* \e from int so you can't pass some other kind of number where a particular
* kind of Index was expected. This is used to create Index types
* which can be used as array indices but which prevent accidental mixing
* of types. Examples: SubsystemIndex, ConstraintIndex.
*
* If you create a type "ThingIndex" you will also get a constant of
* type ThingIndex named "InvalidThingIndex" which will be the initial
* value of any objects of type ThingIndex, and will have the same numerical
* value as SimTK::InvalidIndex.
*/
/** Define a global (that is, SimTK namespace level) Index class that is not
exported in MS VC++ DLLs. **/
#define SimTK_DEFINE_UNIQUE_INDEX_TYPE(NAME) \
SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,,,NAME) \
static const NAME Invalid ## NAME;
/** Define a global (that is, SimTK namespace level) Index class with a MS VC++
"export" specification for DLLs. **/
#define SimTK_DEFINE_AND_EXPORT_UNIQUE_INDEX_TYPE(EXPORT,NAME) \
SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,,,NAME) \
static const NAME Invalid ## NAME;
/** Define a local Index class within a Parent class. **/
#define SimTK_DEFINE_UNIQUE_LOCAL_INDEX_TYPE(PARENT,NAME) \
SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,PARENT,::,NAME)
/** The most general form allows a MS VC++ "export" specification for DLLs,
and a Parent class (with SEP=::) for local Index names. **/
#define SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,PARENT,SEP,NAME) \
class EXPORT NAME { \
int ix; \
public: \
NAME() : ix(SimTK::InvalidIndex) { } \
explicit NAME(int i) : ix(i) {assert(i>=0 || i==SimTK::InvalidIndex);} \
explicit NAME(long l): ix((int)l) {assert(SimTK::canStoreInNonnegativeInt(l));} \
explicit NAME(unsigned int u) : ix((int)u) {assert(SimTK::canStoreInInt(u));} \
explicit NAME(unsigned long ul) : ix((int)ul) {assert(SimTK::canStoreInInt(ul));} \
operator int() const {return ix;} \
bool isValid() const {return ix>=0;} \
bool isValidExtended() const {return ix>=-1;} \
void invalidate(){ix=SimTK::InvalidIndex;} \
\
bool operator==(int i) const {assert(isValidExtended() && isValidExtended(i)); return ix==i;} \
bool operator==(short s) const{assert(isValidExtended() && isValidExtended(s)); return ix==(int)s;} \
bool operator==(long l) const {assert(isValidExtended() && isValidExtended(l)); return ix==(int)l;} \
bool operator==(unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix==(int)u;} \
bool operator==(unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix==(int)us;} \
bool operator==(unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix==(int)ul;} \
bool operator!=(int i) const {return !operator==(i);} \
bool operator!=(short s) const {return !operator==(s);} \
bool operator!=(long l) const {return !operator==(l);} \
bool operator!=(unsigned int u) const {return !operator==(u);} \
bool operator!=(unsigned long ul) const {return !operator==(ul);} \
\
bool operator< (int i) const {assert(isValidExtended() && isValidExtended(i)); return ix<i;} \
bool operator< (short s) const{assert(isValidExtended() && isValidExtended(s)); return ix<(int)s;} \
bool operator< (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix<(int)l;} \
bool operator< (unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix<(int)u;} \
bool operator< (unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix<(int)us;} \
bool operator< (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix<(int)ul;} \
bool operator>=(int i) const {return !operator<(i);} \
bool operator>=(short s) const {return !operator<(s);} \
bool operator>=(long l) const {return !operator<(l);} \
bool operator>=(unsigned int u) const {return !operator<(u);} \
bool operator>=(unsigned short us)const {return !operator<(us);} \
bool operator>=(unsigned long ul) const {return !operator<(ul);} \
\
bool operator> (int i) const {assert(isValidExtended() && isValidExtended(i)); return ix>i;} \
bool operator> (short s) const{assert(isValidExtended() && isValidExtended(s)); return ix>(int)s;} \
bool operator> (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix>(int)l;} \
bool operator> (unsigned int u) const {assert(isValidExtended() && isValid(u)); return ix>(int)u;} \
bool operator> (unsigned short us)const {assert(isValidExtended() && isValid(us)); return ix>(int)us;} \
bool operator> (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix>(int)ul;} \
bool operator<=(int i) const {return !operator>(i);} \
bool operator<=(short s) const {return !operator>(s);} \
bool operator<=(long l) const {return !operator>(l);} \
bool operator<=(unsigned int u) const {return !operator>(u);} \
bool operator<=(unsigned short us)const {return !operator>(us);} \
bool operator<=(unsigned long ul) const {return !operator>(ul);} \
\
const NAME& operator++() {assert(isValid()); ++ix; return *this;} /*prefix */ \
NAME operator++(int) {assert(isValid()); ++ix; return NAME(ix-1);} /*postfix*/ \
const NAME& operator--() {assert(isValid()); --ix; return *this;} /*prefix */ \
NAME operator--(int) {assert(isValid()); --ix; return NAME(ix+1);} /*postfix*/ \
NAME next() const {assert(isValid()); return NAME(ix+1);} \
NAME prev() const {assert(isValid()); return NAME(ix-1);} /*might return -1*/ \
\
NAME& operator+=(int i) {assert(isValid() && isValidExtended(ix+i)); ix+=i; return *this;} \
NAME& operator-=(int i) {assert(isValid() && isValidExtended(ix-i)); ix-=i; return *this;} \
NAME& operator+=(short s){assert(isValid() && SimTK::canStoreInInt(s) && isValidExtended(ix+(int)s)); ix+=(int)s; return *this;} \
NAME& operator-=(short s){assert(isValid() && SimTK::canStoreInInt(s) && isValidExtended(ix-(int)s)); ix-=(int)s; return *this;} \
NAME& operator+=(long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix+(int)l)); ix+=(int)l; return *this;} \
NAME& operator-=(long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix-(int)l)); ix-=(int)l; return *this;} \
NAME& operator+=(unsigned int u) {assert(isValid()&& SimTK::canStoreInInt(u) && isValid(ix+(int)u)); ix+=(int)u; return *this;} \
NAME& operator-=(unsigned int u) {assert(isValid()&& SimTK::canStoreInInt(u) && isValidExtended(ix-(int)u)); ix-=(int)u; return *this;} \
NAME& operator+=(unsigned short us){assert(isValid()&& SimTK::canStoreInInt(us) && isValid(ix+(int)us)); ix+=(int)us; return *this;} \
NAME& operator-=(unsigned short us){assert(isValid()&& SimTK::canStoreInInt(us) && isValidExtended(ix-(int)us)); ix-=(int)us; return *this;} \
NAME& operator+=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValid(ix+(int)ul)); ix+=(int)ul; return *this;} \
NAME& operator-=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValidExtended(ix-(int)ul)); ix-=(int)ul; return *this;} \
\
static const NAME& Invalid() {static const NAME invalid; return invalid;} \
static bool isValid(int i) {return i>=0;} \
static bool isValid(short s){return s>=0;} \
static bool isValid(long l) {return SimTK::canStoreInNonnegativeInt(l);} \
static bool isValid(unsigned int u) {return SimTK::canStoreInInt(u);} \
static bool isValid(unsigned short) {return true;} \
static bool isValid(unsigned long ul) {return SimTK::canStoreInInt(ul);} \
static bool isValidExtended(int i) {return i>=-1;} \
static bool isValidExtended(short s){return s>=-1;} \
static bool isValidExtended(long l) {return SimTK::canStoreInInt(l) && l>=-1;} \
/* IndexTraits for use in Array_<T,X> with this as X; same as int */ \
typedef int size_type; \
typedef int difference_type; \
static size_type max_size() {return std::numeric_limits<int>::max();} \
};
/** Use this macro to generate a cast that is dynamic_cast in Debug builds
but static_cast in Release builds, for uses where you don't want to
pay for the extra safety. Caution: these are not necessarily equivalent for
dynamic types that use multiple inheritance; don't use this macro in that
case, and don't use it where you are using dynamic_cast on a pointer to
check what type of derived object you're looking at. **/
#ifndef NDEBUG
#define SimTK_DYNAMIC_CAST_DEBUG dynamic_cast // safe but slow
#else
#define SimTK_DYNAMIC_CAST_DEBUG static_cast // unsafe but fast
#endif
/** Add public static method declaration in class derived from an abstract
parent to assist in downcasting objects of the parent type to the derived
type. **/
#define SimTK_DOWNCAST(Derived,Parent) \
static bool isA(const Parent& p) \
{ return dynamic_cast<const Derived*>(&p) != 0; } \
static const Derived& downcast(const Parent& p) \
{ return SimTK_DYNAMIC_CAST_DEBUG<const Derived&>(p); } \
static Derived& updDowncast(Parent& p) \
{ return SimTK_DYNAMIC_CAST_DEBUG<Derived&>(p); } \
static Derived& downcast(Parent& p) \
{ return SimTK_DYNAMIC_CAST_DEBUG<Derived&>(p); }
/** This is like SimTK_DOWNCAST except it allows for an intermediate "helper"
class between Derived and Parent. **/
#define SimTK_DOWNCAST2(Derived,Helper,Parent) \
static bool isA(const Parent& p) \
{ return Helper::isA(p); } \
static const Derived& downcast(const Parent& p) \
{ return static_cast<const Derived&>(Helper::downcast(p)); } \
static Derived& updDowncast(Parent& p) \
{ return static_cast<Derived&>(Helper::downcast(p)); } \
static Derived& downcast(Parent& p) \
{ return static_cast<Derived&>(Helper::downcast(p)); }
/** Similar to the above but for private implementation abstract classes, that
is, abstract class hierarchies where the virtual function table is hidden on
the library side. **/
#define SimTK_PIMPL_DOWNCAST(Derived, Parent) \
static bool isInstanceOf(const Parent&); \
static const Derived& downcast(const Parent&); \
static Derived& updDowncast(Parent&)
namespace SimTK {
/** This sub-namespace of SimTK is used for the exception types that are
thrown by our error handing code. **/
namespace Exception { }
/** This is the default compiled-in floating point type for SimTK, either
float or double. @see SimTK_DEFAULT_PRECISION **/
typedef SimTK_Real Real;
/** This is the default complex type for SimTK, with precision for the real
and imaginary parts set to the compiled-in Real type. @see Real **/
typedef std::complex<Real> Complex;
/** An abbreviation for std::complex<float> for consistency with others. **/
typedef std::complex<float> fComplex;
/** An abbreviation for std::complex<double> for consistency with others. **/
typedef std::complex<double> dComplex;
// Forward declaration giving template defaults must come before any
// other declarations.
template <int M, class ELT=Real, int STRIDE=1> class Vec;
template <int N, class ELT=Real, int STRIDE=1> class Row;
template <int M, int N, class ELT=Real, int CS=M, int RS=1> class Mat;
template <int M, class ELT=Real, int RS=1> class SymMat;
/** A convenient struct for anything requiring an offset and length to specify
a segment of some larger sequence. **/
struct Segment {
Segment() : length(0), offset(0) { }
explicit Segment(int l, int ofs=0) : length(l), offset(ofs) {
assert(l>=0 && ofs>=0);
}
// default copy, assignment, destructor
int length;
int offset;
};
/** This is a special type used for causing invocation of a particular
constructor or method overload that will avoid making a copy of the source
(that is, perform a "shallow" copy rather than a "deep" copy). Typically these
methods will have some dangerous side effects so make sure you know what you're
doing. **/
struct DontCopy {};
/** This is a special type used for forcing invocation of a particularly
dangerous constructor or method overload; don't use this unless you are an
advanced user and know exactly what you're getting into. **/
struct TrustMe {};
/** This is a compile-time equivalent of "false", used in compile-time
condition checking in templatized implementations. **/
struct FalseType {};
/** This is a compile-time equivalent of "true", used in compile-time
condition checking in templatized implementations. **/
struct TrueType {};
/** This is an operator for and-ing compile-time truth types. */
template <class L, class R> struct AndOpType {};
template<> struct AndOpType<FalseType,FalseType> {typedef FalseType Result;};
template<> struct AndOpType<FalseType,TrueType> {typedef FalseType Result;};
template<> struct AndOpType<TrueType, FalseType> {typedef FalseType Result;};
template<> struct AndOpType<TrueType, TrueType> {typedef TrueType Result;};
/** This is an operator for or-ing compile-time truth types. */
template <class L, class R> struct OrOpType {};
template<> struct OrOpType<FalseType,FalseType> {typedef FalseType Result;};
template<> struct OrOpType<FalseType,TrueType> {typedef TrueType Result;};
template<> struct OrOpType<TrueType, FalseType> {typedef TrueType Result;};
template<> struct OrOpType<TrueType, TrueType> {typedef TrueType Result;};
/** This is an operator for exclusive or-ing compile-time truth types. */
template <class L, class R> struct XorOpType {};
template<> struct XorOpType<FalseType,FalseType> {typedef FalseType Result;};
template<> struct XorOpType<FalseType,TrueType> {typedef TrueType Result;};
template<> struct XorOpType<TrueType, FalseType> {typedef TrueType Result;};
template<> struct XorOpType<TrueType, TrueType> {typedef FalseType Result;};
/** Compile-time type test: is this one of the built-in integral types?. **/
template <class T> struct IsIntegralType {
/** This typedef is TrueType if the template type T is an integral type;
otherwise it is FalseType. **/
typedef FalseType Result;
/** This compile-time constant bool is true if the template type T is an
integral type otherwise it is false. **/
static const bool result = false;
};
/** This macro must be invoked once for each of the built-in integral types to
specialize the IsIntegralType struct template for those types. **/
#define SimTK_SPECIALIZE_INTEGRAL_TYPE(T) \
template<> struct IsIntegralType<T> \
{typedef TrueType Result; static const bool result = true;}
SimTK_SPECIALIZE_INTEGRAL_TYPE(bool);
SimTK_SPECIALIZE_INTEGRAL_TYPE(char);
// This causes problems when used with Qt which for some crazy
// reason likes to make its own wchar_t rather than using the built in.
// SimTK_SPECIALIZE_INTEGRAL_TYPE(wchar_t);
SimTK_SPECIALIZE_INTEGRAL_TYPE(signed char);
SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned char);
SimTK_SPECIALIZE_INTEGRAL_TYPE(short);
SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned short);
SimTK_SPECIALIZE_INTEGRAL_TYPE(int);
SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned int); // a.k.a. "unsigned"
SimTK_SPECIALIZE_INTEGRAL_TYPE(long);
SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned long);
SimTK_SPECIALIZE_INTEGRAL_TYPE(long long);
SimTK_SPECIALIZE_INTEGRAL_TYPE(unsigned long long);
/** Compile-time type test: is this one of the built-in floating point types?. **/
template <class T> struct IsFloatingType {
/** This typedef is TrueType if the template type T is a floating point type;
otherwise it is FalseType. **/
typedef FalseType Result;
/** This compile-time constant bool is true if the template type T is a
floating point type otherwise it is false. **/
static const bool result = false;
};
/** This macro must be invoked once for each of the built-in floating point
types to specialize the IsFloatingType struct template for those types. **/
#define SimTK_SPECIALIZE_FLOATING_TYPE(T) \
template<> struct IsFloatingType<T> \
{typedef TrueType Result; static const bool result = true;}
SimTK_SPECIALIZE_FLOATING_TYPE(float);
SimTK_SPECIALIZE_FLOATING_TYPE(double);
SimTK_SPECIALIZE_FLOATING_TYPE(long double);
/** Compile-time type test: is this the void type?. **/
template <class T> struct IsVoidType {
/** This typedef is TrueType if the template type T is "void";
otherwise it is FalseType. **/
typedef FalseType Result;
/** This compile-time constant bool is true if the template type T is
"void" otherwise it is false. **/
static const bool result = false;
};
template<> struct IsVoidType<void>
{typedef TrueType Result; static const bool result = true;};
/** Compile-time test: is this one of the built-in "arithmetic" types, meaning
an integral or floating type? **/
template <class T> struct IsArithmeticType {
/** This typedef is TrueType if the template type T is one of the integral;
or floating point types, otherwise it is FalseType. **/
typedef OrOpType<typename IsIntegralType<T>::Result,
typename IsFloatingType<T>::Result> Result;
/** This compile-time constant bool is true if the template type T is
one of the integral or floating point types, otherwise it is false. **/
static const bool result = IsIntegralType<T>::result
|| IsFloatingType<T>::result;
};
// This struct's sole use is to allow us to define the typedef
// Is64BitPlatformType as equivalent to either TrueType or FalseType.
template <bool is64Bit> struct Is64BitHelper {};
template<> struct Is64BitHelper<true>
{typedef TrueType Result; static const bool result = true;};
template<> struct Is64BitHelper<false>
{typedef FalseType Result; static const bool result = false;};
/** Compile-time test: this typedef will be TrueType if this is a 64-bit
platform, meaning that the size of a pointer is the same as the size of a
long long; otherwise it will be FalseType and we have a 32-bit platform meaning
that the size of a pointer is the same as an int. **/
static const bool Is64BitPlatform = sizeof(size_t) > sizeof(int);
typedef Is64BitHelper<Is64BitPlatform>::Result Is64BitPlatformType;
/** Attempt to demangle a type name as returned by typeid.name(), with the
result hopefully suitable for meaningful display to a human. Behavior is
compiler-dependent. **/
SimTK_SimTKCOMMON_EXPORT std::string demangle(const char* name);
/** In case you don't like the name you get from typeid(), you can specialize
this class to provide a nicer name. This class is typically used for error
messages and testing. **/
template <class T> struct NiceTypeName {
/** The default implementation of name() here returns the raw result from
typeid(T).name() which will be fast but may be a mangled name in some
compilers (gcc and clang included). **/
static const char* name() {return typeid(T).name();}
/** The default implementation of namestr() attempts to return a nicely
demangled type name on all platforms, using the SimTK::demangle() method
defined above. Don't expect this to be fast. **/
static std::string namestr() {return demangle(name());}
};
} // namespace SimTK
/** This specializes the name of a type to be exactly the text you use to
specify it, rather than whatever ugly thing might result on different platforms
from resolution of typedefs, default template arguments, etc. Note that this
macro generates a template specialization that must be done in the SimTK
namespace; consequently it opens and closes namespace SimTK and must not
be invoked if you already have that namespace open. **/
#define SimTK_NICETYPENAME_LITERAL(T) \
namespace SimTK { \
template <> struct NiceTypeName< T > { \
static std::string namestr() { return #T; } \
static const char* name() { return #T; } \
}; \
}
// Some types for which we'd like to see nice type names.
SimTK_NICETYPENAME_LITERAL(bool);
SimTK_NICETYPENAME_LITERAL(char);
// This causes problems when used with Qt which for some crazy
// reason likes to make its own wchar_t rather than using the built in.
// SimTK_NICETYPENAME_LITERAL(wchar_t);
SimTK_NICETYPENAME_LITERAL(signed char);
SimTK_NICETYPENAME_LITERAL(unsigned char);
SimTK_NICETYPENAME_LITERAL(short);
SimTK_NICETYPENAME_LITERAL(unsigned short);
SimTK_NICETYPENAME_LITERAL(int);
SimTK_NICETYPENAME_LITERAL(unsigned); // preferred to "unsigned int"
SimTK_NICETYPENAME_LITERAL(long);
SimTK_NICETYPENAME_LITERAL(unsigned long);
SimTK_NICETYPENAME_LITERAL(long long);
SimTK_NICETYPENAME_LITERAL(unsigned long long);
SimTK_NICETYPENAME_LITERAL(float);
SimTK_NICETYPENAME_LITERAL(double);
SimTK_NICETYPENAME_LITERAL(long double);
SimTK_NICETYPENAME_LITERAL(std::string);
SimTK_NICETYPENAME_LITERAL(std::complex<float>);
SimTK_NICETYPENAME_LITERAL(std::complex<double>);
SimTK_NICETYPENAME_LITERAL(std::complex<long double>);
SimTK_NICETYPENAME_LITERAL(SimTK::FalseType);
SimTK_NICETYPENAME_LITERAL(SimTK::TrueType);
#endif /* C++ stuff */
#endif /* SimTK_SimTKCOMMON_COMMON_H_ */
|