SimTKcommon/internal/common.h

Go to the documentation of this file.
00001 #ifndef SimTK_SimTKCOMMON_COMMON_H_
00002 #define SimTK_SimTKCOMMON_COMMON_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                      SimTK Core: SimTKcommon                               *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK Core biosimulation toolkit originating from      *
00008  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00009  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00010  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
00011  *                                                                            *
00012  * Portions copyright (c) 2005-9 Stanford University and the Authors.         *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Permission is hereby granted, free of charge, to any person obtaining a    *
00017  * copy of this software and associated documentation files (the "Software"), *
00018  * to deal in the Software without restriction, including without limitation  *
00019  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
00020  * and/or sell copies of the Software, and to permit persons to whom the      *
00021  * Software is furnished to do so, subject to the following conditions:       *
00022  *                                                                            *
00023  * The above copyright notice and this permission notice shall be included in *
00024  * all copies or substantial portions of the Software.                        *
00025  *                                                                            *
00026  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
00027  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
00028  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
00029  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
00030  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
00031  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
00032  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
00033  * -------------------------------------------------------------------------- */
00034 
00048 // Provide doxygen documentation for the SimTK namespace.
00049 
00060 // Define shared doxygen "modules" and sub-modules here. We'll put things 
00061 // in them at various places when appropriate.
00062 
00085 /*****************************/
00086 /* ANSI-C COMPATIBLE SECTION */
00087 /*****************************/
00088 
00089 /* Set up a few compile-time options that affect all SimTK Core headers. */
00090 
00098 #ifndef SimTK_DEFAULT_PRECISION
00099 #   define SimTK_DEFAULT_PRECISION 2
00100 #endif
00101 
00102 #if   (SimTK_DEFAULT_PRECISION == 1)
00103 
00104     typedef float SimTK_Real;
00105 #elif (SimTK_DEFAULT_PRECISION == 2)
00106 
00107     typedef double SimTK_Real;
00108 #elif (SimTK_DEFAULT_PRECISION == 4)
00109 
00110     typedef long double SimTK_Real;
00111 #else
00112     #error ILLEGAL VALUE FOR DEFAULT PRECISION
00113 #endif
00114 
00115 #ifndef NDEBUG
00116     #if defined(__cplusplus)
00117         #include <cstdio>
00118         #define SimTK_DEBUG(s) std::printf("DBG: " s)
00119         #define SimTK_DEBUG1(s,a1) std::printf("DBG: " s,a1)    
00120         #define SimTK_DEBUG2(s,a1,a2) std::printf("DBG: " s,a1,a2)  
00121         #define SimTK_DEBUG3(s,a1,a2,a3) std::printf("DBG: " s,a1,a2,a3)    
00122         #define SimTK_DEBUG4(s,a1,a2,a3,a4) std::printf("DBG: " s,a1,a2,a3,a4)
00123     #else
00124         #include <stdio.h>
00125         #define SimTK_DEBUG(s) printf("DBG: " s)
00126         #define SimTK_DEBUG1(s,a1) printf("DBG: " s,a1) 
00127         #define SimTK_DEBUG2(s,a1,a2) printf("DBG: " s,a1,a2)   
00128         #define SimTK_DEBUG3(s,a1,a2,a3) printf("DBG: " s,a1,a2,a3) 
00129         #define SimTK_DEBUG4(s,a1,a2,a3,a4) printf("DBG: " s,a1,a2,a3,a4)
00130     #endif
00131 #else
00132     #define SimTK_DEBUG(s)
00133     #define SimTK_DEBUG1(s,a1)
00134     #define SimTK_DEBUG2(s,a1,a2)
00135     #define SimTK_DEBUG3(s,a1,a2,a3)    
00136     #define SimTK_DEBUG4(s,a1,a2,a3,a4)
00137 #endif
00138 
00139 /*
00140  * Shared libraries are messy in Visual Studio. We have to distinguish three
00141  * cases:
00142  *   (1) this header is being used to build the SimTKcommon shared library (dllexport)
00143  *   (2) this header is being used by a *client* of the SimTKcommon shared
00144  *       library (dllimport)
00145  *   (3) we are building the SimTKcommon static library, or the client is
00146  *       being compiled with the expectation of linking with the
00147  *       SimTKcommon static library (nothing special needed)
00148  * In the CMake script for building this library, we define one of the symbols
00149  *     SimTK_SimTKCOMMON_BUILDING_{SHARED|STATIC}_LIBRARY
00150  * Client code normally has no special symbol defined, in which case we'll
00151  * assume it wants to use the shared library. However, if the client defines
00152  * the symbol SimTK_USE_STATIC_LIBRARIES we'll suppress the dllimport so
00153  * that the client code can be linked with static libraries. Note that
00154  * the client symbol is not library dependent, while the library symbols
00155  * affect only the SimTKcommon library, meaning that other libraries can
00156  * be clients of this one. However, we are assuming all-static or all-shared.
00157  */
00158 
00159 #ifdef _WIN32
00160     #ifdef _MSC_VER
00161     #pragma warning(disable:4231) // need to use 'extern' template explicit instantiation
00162     #pragma warning(disable:4251) // no DLL interface for type of member of exported class
00163     #endif
00164     #if defined(SimTK_SimTKCOMMON_BUILDING_SHARED_LIBRARY)
00165         #define SimTK_SimTKCOMMON_EXPORT __declspec(dllexport)
00166         /* Keep MS VC++ quiet when it tries to instantiate incomplete template classes in a DLL. */
00167         #ifdef _MSC_VER
00168         #pragma warning(disable:4661)
00169         #endif
00170     #elif defined(SimTK_SimTKCOMMON_BUILDING_STATIC_LIBRARY) || defined(SimTK_USE_STATIC_LIBRARIES)
00171         #define SimTK_SimTKCOMMON_EXPORT
00172     #else
00173         #define SimTK_SimTKCOMMON_EXPORT __declspec(dllimport)   // i.e., a client of a shared library
00174     #endif
00175     /* VC++ tries to be secure by leaving bounds checking on for STL containers
00176      * even in Release mode. This macro exists to disable that feature and can
00177      * result in a considerable speedup.
00178      * CAUTION: every linked-together compilation unit must have this set the same
00179      * way. Everyone who properly includes this file first is fine; but as of this
00180      * writing Simmath's IpOpt doesn't do so.
00181      */
00182     /* (sherm 081204 disabling for now: doesn't work on VC++ 8 and is 
00183      * tricky on VC++ 9 because all libraries, including 3rd party, must
00184      * be built the same way)
00185      #ifdef NDEBUG
00186         #undef _SECURE_SCL
00187         #define _SECURE_SCL 0
00188      #endif
00189      */
00190 #else
00191     #define SimTK_SimTKCOMMON_EXPORT // Linux, Mac
00192 #endif
00193 
00194 /* Every SimTK Core library must provide these two routines, with the library
00195  * name appearing after the "version_" and "about_".
00196  */
00197 #if defined(__cplusplus)
00198 extern "C" {
00199 #endif
00200 
00201     SimTK_SimTKCOMMON_EXPORT void SimTK_version_SimTKcommon(int* major, int* minor, int* build);
00208     SimTK_SimTKCOMMON_EXPORT void SimTK_about_SimTKcommon(const char* key, int maxlen, char* value);
00209 #if defined(__cplusplus)
00210 }
00211 #endif
00212 
00213 /************************************/
00214 /* END OF ANSI-C COMPATIBLE SECTION */
00215 /************************************/
00216 
00217 #if defined(__cplusplus)
00218 
00219 #include <cstddef>
00220 #include <cassert>
00221 #include <cmath>
00222 #include <cfloat>
00223 #include <complex>
00224 #include <limits>
00225 #include <typeinfo>
00226 
00227 
00228 /* Currently (Microsoft VC++ 9) these C99-compatible floating point functions are
00229  * missing. We'll create them here and install them into namespace std.
00230  * TODO: This should be removed when these are available.
00231  */
00232 #ifdef _MSC_VER
00233 namespace std {
00234 inline bool isfinite(float f) {return _finite(f) != 0;}
00235 inline bool isfinite(double d) {return _finite(d) != 0;}
00236 inline bool isfinite(long double l) {return _finite(l) != 0;}
00237 inline bool isnan(float f) {return _isnan(f) != 0;}
00238 inline bool isnan(double d) {return _isnan(d) != 0;}
00239 inline bool isnan(long double l) {return _isnan(l) != 0;}
00240 inline bool isinf(float f) {return std::abs(f)==std::numeric_limits<float>::infinity();}
00241 inline bool isinf(double d) {return std::abs(d)==std::numeric_limits<double>::infinity();}
00242 inline bool isinf(long double l) {return std::abs(l)==std::numeric_limits<double>::infinity();}
00243 inline bool signbit(float f) {return (*reinterpret_cast<unsigned*>(&f) & 0x80000000U) != 0;}
00244 inline bool signbit(double d) {return (*reinterpret_cast<unsigned long long*>(&d)
00245                                & 0x8000000000000000ULL) != 0;}
00246 inline bool signbit(long double l) {return (*reinterpret_cast<unsigned long long*>(&l)
00247                                     & 0x8000000000000000ULL) != 0;}
00248 }
00249 #endif
00250 
00251 
00252 namespace SimTK {
00253 // This utility answers the question "if I put this integral value in an int and then
00254 // get it back, will its value be the same?".
00255 inline bool canStoreInInt(char)            {return true;}
00256 inline bool canStoreInInt(unsigned char)   {return true;}
00257 inline bool canStoreInInt(signed char)     {return true;}
00258 inline bool canStoreInInt(short)           {return true;}
00259 inline bool canStoreInInt(unsigned short)  {return true;}
00260 inline bool canStoreInInt(int)             {return true;}
00261 inline bool canStoreInInt(unsigned int  u) {return (unsigned int)(int(u)) == u;}
00262 inline bool canStoreInInt(long i)          {return long(int(i)) == i;}
00263 inline bool canStoreInInt(unsigned long u) {return (unsigned long)(int(u)) == u;}
00264 
00265 // This utility answers the question "is this integral value a nonnegative number
00266 // that can be stored in an int?".
00267 inline bool canStoreInNonnegativeInt(char c)           {return c >= 0;}
00268 inline bool canStoreInNonnegativeInt(unsigned char c)  {return true;}
00269 inline bool canStoreInNonnegativeInt(signed char c)    {return c >= 0;}
00270 inline bool canStoreInNonnegativeInt(short s)          {return s >= 0;}
00271 inline bool canStoreInNonnegativeInt(unsigned short s) {return true;}
00272 inline bool canStoreInNonnegativeInt(int  i)           {return i >= 0;}
00273 inline bool canStoreInNonnegativeInt(long l)           {return canStoreInInt(l) && l >= 0;}
00274 inline bool canStoreInNonnegativeInt(unsigned int  u)  {return canStoreInInt(u);}
00275 inline bool canStoreInNonnegativeInt(unsigned long u)  {return canStoreInInt(u);}
00276 
00277 // A NaN-like value for unique index types created using the macro
00278 // SimTK_DEFINE_UNIQUE_INDEX_TYPE(). A unique, typed constant with
00279 // this numerical value is created for each index type.
00280 static const int InvalidIndex = -1111111111;
00281 }
00282 
00312 
00313 
00314 #define SimTK_DEFINE_UNIQUE_INDEX_TYPE(NAME)                   \
00315     SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,,,NAME)   \
00316     static const NAME Invalid ## NAME;
00317 
00320 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_INDEX_TYPE(EXPORT,NAME)     \
00321     SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,,,NAME) \
00322     static const NAME Invalid ## NAME;
00323 
00325 #define SimTK_DEFINE_UNIQUE_LOCAL_INDEX_TYPE(PARENT,NAME) \
00326     SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(,PARENT,::,NAME)
00327 
00330 #define SimTK_DEFINE_AND_EXPORT_UNIQUE_LOCAL_INDEX_TYPE(EXPORT,PARENT,SEP,NAME)   \
00331 class EXPORT NAME {                         \
00332     int ix;                                 \
00333 public:                                     \
00334     NAME() : ix(SimTK::InvalidIndex) { }       \
00335     explicit NAME(int i) : ix(i)      {assert(i>=0 || i==SimTK::InvalidIndex);} \
00336     explicit NAME(long l): ix((int)l) {assert(SimTK::canStoreInNonnegativeInt(l));}    \
00337     explicit NAME(unsigned int  u)  : ix((int)u)  {assert(SimTK::canStoreInInt(u));}   \
00338     explicit NAME(unsigned long ul) : ix((int)ul) {assert(SimTK::canStoreInInt(ul));}  \
00339     operator int() const {return ix;}               \
00340     bool isValid() const {return ix>=0;}            \
00341     bool isValidExtended() const {return ix>=-1;}   \
00342     void invalidate(){ix=SimTK::InvalidIndex;}      \
00343     \
00344     bool operator==(int  i) const {assert(isValidExtended() && isValidExtended(i)); return ix==i;}    \
00345     bool operator==(long l) const {assert(isValidExtended() && isValidExtended(l)); return ix==(int)l;}  \
00346     bool operator==(unsigned int  u)  const {assert(isValidExtended() && isValid(u)); return ix==(int)u;}   \
00347     bool operator==(unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix==(int)ul;} \
00348     bool operator!=(int  i)           const {return !operator==(i);}    \
00349     bool operator!=(long l)           const {return !operator==(l);}    \
00350     bool operator!=(unsigned int  u)  const {return !operator==(u);}    \
00351     bool operator!=(unsigned long ul) const {return !operator==(ul);}   \
00352     \
00353     bool operator< (int  i) const {assert(isValidExtended() && isValidExtended(i)); return ix<i;}        \
00354     bool operator< (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix<(int)l;}   \
00355     bool operator< (unsigned int  u)  const {assert(isValidExtended() && isValid(u));  return ix<(int)u;}    \
00356     bool operator< (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix<(int)ul;}   \
00357     bool operator>=(int  i)           const {return !operator<(i);}    \
00358     bool operator>=(long l)           const {return !operator<(l);}    \
00359     bool operator>=(unsigned int  u)  const {return !operator<(u);}    \
00360     bool operator>=(unsigned long ul) const {return !operator<(ul);}   \
00361     \
00362     bool operator> (int  i) const {assert(isValidExtended() && isValidExtended(i)); return ix>i;}        \
00363     bool operator> (long l) const {assert(isValidExtended() && isValidExtended(l)); return ix>(int)l;}   \
00364     bool operator> (unsigned int  u)  const {assert(isValidExtended() && isValid(u));  return ix>(int)u;}    \
00365     bool operator> (unsigned long ul) const {assert(isValidExtended() && isValid(ul)); return ix>(int)ul;}   \
00366     bool operator<=(int  i)           const {return !operator>(i);}    \
00367     bool operator<=(long l)           const {return !operator>(l);}    \
00368     bool operator<=(unsigned int  u)  const {return !operator>(u);}    \
00369     bool operator<=(unsigned long ul) const {return !operator>(ul);}   \
00370     \
00371     const NAME& operator++() {assert(isValid()); ++ix; return *this;}       /*prefix */   \
00372     NAME operator++(int)     {assert(isValid()); ++ix; return NAME(ix-1);}  /*postfix*/   \
00373     const NAME& operator--() {assert(isValid()); --ix; return *this;}       /*prefix */   \
00374     NAME operator--(int)     {assert(isValid()); --ix; return NAME(ix+1);}  /*postfix*/   \
00375     \
00376     NAME& operator+=(int i)  {assert(isValid() && isValidExtended(ix+i)); ix+=i; return *this;}     \
00377     NAME& operator-=(int i)  {assert(isValid() && isValidExtended(ix-i)); ix-=i; return *this;}     \
00378     NAME& operator+=(long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix+(int)l)); ix+=(int)l; return *this;}     \
00379     NAME& operator-=(long l) {assert(isValid() && SimTK::canStoreInInt(l) && isValidExtended(ix-(int)l)); ix-=(int)l; return *this;}     \
00380     NAME& operator+=(unsigned int  u)  {assert(isValid()&& SimTK::canStoreInInt(u)  && isValid(ix+(int)u));  ix+=(int)u;  return *this;}  \
00381     NAME& operator-=(unsigned int  u)  {assert(isValid()&& SimTK::canStoreInInt(u)  && isValidExtended(ix-(int)u));  ix-=(int)u;  return *this;}  \
00382     NAME& operator+=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValid(ix+(int)ul)); ix+=(int)ul; return *this;}  \
00383     NAME& operator-=(unsigned long ul) {assert(isValid()&& SimTK::canStoreInInt(ul) && isValidExtended(ix-(int)ul)); ix-=(int)ul; return *this;}  \
00384     \
00385     static const NAME& Invalid() {static const NAME invalid; return invalid;}       \
00386     static bool isValid(int  i) {return i>=0;}                                      \
00387     static bool isValid(long l) {return SimTK::canStoreInNonnegativeInt(l);}        \
00388     static bool isValid(unsigned int  u)  {return SimTK::canStoreInInt(u);}         \
00389     static bool isValid(unsigned long ul) {return SimTK::canStoreInInt(ul);}        \
00390     static bool isValidExtended(int  i) {return i>=-1;}                             \
00391     static bool isValidExtended(long l) {return SimTK::canStoreInInt(l) && l>=-1;}  \
00392 };
00393 
00399 #define SimTK_DOWNCAST(Derived,Parent) \
00400     static bool isA(const Parent& p)                        \
00401         { return dynamic_cast<const Derived*>(&p) != 0; }   \
00402     static const Derived& downcast(const Parent& p)         \
00403         { return dynamic_cast<const Derived&>(p); }         \
00404     static Derived& updDowncast(Parent& p)                  \
00405         { return dynamic_cast<Derived&>(p); }               \
00406     static Derived& downcast(Parent& p)                     \
00407         { return dynamic_cast<Derived&>(p); }
00408 
00413 #define SimTK_DOWNCAST2(Derived,Helper,Parent) \
00414     static bool isA(const Parent& p)                                        \
00415         { return Helper::isA(p); }                                          \
00416     static const Derived& downcast(const Parent& p)                         \
00417         { return reinterpret_cast<const Derived&>(Helper::downcast(p)); }   \
00418     static Derived& updDowncast(Parent& p)                                  \
00419         { return reinterpret_cast<Derived&>(Helper::downcast(p)); }         \
00420     static Derived& downcast(Parent& p)                                     \
00421         { return reinterpret_cast<Derived&>(Helper::downcast(p)); }
00422 
00423 
00424 // Similar to the above but for private implementation abstract classes, that
00425 // is, abstract class hierarchies where the virtual function table is 
00426 // hidden on the library side.
00427 #define SimTK_PIMPL_DOWNCAST(Derived, Parent)           \
00428     static bool           isInstanceOf(const Parent&);  \
00429     static const Derived& downcast(const Parent&);      \
00430     static Derived&       updDowncast(Parent&)
00431 
00432 namespace SimTK {
00433     
00434 namespace Options { }
00435 namespace Exception { }
00436 
00440 typedef SimTK_Real              Real;
00444 typedef std::complex<Real>      Complex;
00445 
00448 struct Segment {
00449     Segment() : length(0), offset(0) { }
00450     explicit Segment(int l, int ofs=0) : length(l), offset(ofs) { 
00451         assert(l>=0 && ofs>=0);
00452     }
00453     // default copy, assignment, destructor
00454     int length;
00455     int offset;
00456 };  
00457 
00458 template <class T> class TypeInfo {
00459 public:
00460     static const char* name() {return typeid(T).name();}
00461 };
00462 
00463 #define SimTK_TYPEINFO_SPECIALIZE(T)            \
00464 template <> class TypeInfo< T > {               \
00465 public:                                         \
00466     static const char* name() { return #T; }    \
00467 };
00468 // Built-in types
00469 SimTK_TYPEINFO_SPECIALIZE(bool);            SimTK_TYPEINFO_SPECIALIZE(signed char); 
00470 SimTK_TYPEINFO_SPECIALIZE(char);            SimTK_TYPEINFO_SPECIALIZE(unsigned char);
00471 SimTK_TYPEINFO_SPECIALIZE(short);           SimTK_TYPEINFO_SPECIALIZE(int); 
00472 SimTK_TYPEINFO_SPECIALIZE(long);
00473 SimTK_TYPEINFO_SPECIALIZE(unsigned short);  SimTK_TYPEINFO_SPECIALIZE(unsigned int); 
00474 SimTK_TYPEINFO_SPECIALIZE(unsigned long);
00475 SimTK_TYPEINFO_SPECIALIZE(float);           SimTK_TYPEINFO_SPECIALIZE(double); 
00476 SimTK_TYPEINFO_SPECIALIZE(long double);
00477 SimTK_TYPEINFO_SPECIALIZE(std::complex<float>);
00478 SimTK_TYPEINFO_SPECIALIZE(std::complex<double>); 
00479 SimTK_TYPEINFO_SPECIALIZE(std::complex<long double>); 
00480 
00481 
00482 } // namespace SimTK
00483 
00484 namespace SimTKimpl {
00485 
00488 typedef void*       (*IndexT)(void* tp, int n);
00489 typedef const void* (*IndexConstT)(const void* tp, int n);
00490 typedef void*       (*CreateOneT)(const void* iptr);
00491 typedef void        (*DestructOneT)(void*& tvptr);  
00492 typedef void        (*AssignArrayOfT)(void* dest, const void* src, int n);
00493 typedef void        (*SetT)(void* dest, const void* valuep, int n);
00494 typedef void*       (*CreateArrayOfT)(int n, const void* iptr);
00495 typedef void        (*DestructArrayOfT)(void*& tvptr);
00497 
00498 struct TypeManipulatorT {
00499     TypeManipulatorT(int z, IndexT it, IndexConstT ict,
00500                      CreateOneT c1t, DestructOneT d1t, AssignArrayOfT aat, SetT st,
00501                      CreateArrayOfT cat, DestructArrayOfT dat)
00502         : sizeOfT(z), indexT(it), indexConstT(ict), 
00503           createOneT(c1t), destructOneT(d1t), assignArrayOfT(aat), setT(st),
00504           createArrayOfT(cat), destructArrayOfT(dat)
00505     { }
00506     
00507     bool operator==(const TypeManipulatorT& t) const
00508       { return sizeOfT==t.sizeOfT && indexT==t.indexT; }
00509 
00510     // THESE MUST NEVER CHANGE ORDER! This is effectively a compiler-independent
00511     // virtual function table. The first entry is a size in bytes and the rest have
00512     // type "pointer to function" so all the data should have a very predictable
00513     // and stable layout in memory.
00514     //
00515     // This is the one place in the SimTK API where the client
00516     // side and library side must agree on the physical layout of the class. 
00517     // It is safe to add new entries to the end of this list, but inserting earlier,
00518     // deleting or reordering anything already here will break binary compatibility.
00519     const int               sizeOfT;
00520     const IndexT            indexT;
00521     const IndexConstT       indexConstT;
00522     const CreateOneT        createOneT;
00523     const DestructOneT      destructOneT;
00524     const AssignArrayOfT    assignArrayOfT;
00525     const SetT              setT;
00526     const CreateArrayOfT    createArrayOfT;
00527     const DestructArrayOfT  destructArrayOfT;
00528 };
00529 
00544 template <class T> class MakeTypeManipulator {
00545 public:
00546     MakeTypeManipulator() { }
00547     // default copy, assignment, destructor
00548     
00549     static const TypeManipulatorT& getTypeManipulatorT() { return manipT; }
00550     static T& updAs(void* v) 
00551       { assert(v); return *reinterpret_cast<T*>(v); }
00552     static const T& getAs(const void* v) 
00553       { assert(v); return *reinterpret_cast<const T*>(v); }
00554 
00555 private:    
00561     static int sizeT() { return (int)sizeof(T); }
00562     
00567     static void* indexT(void* tp, int n)
00568         { return (void*)(reinterpret_cast<T*>(tp) + n); }
00569     static const void* indexConstT(const void* tp, int n)
00570         { return (const void*)(reinterpret_cast<const T*>(tp) + n); }
00572 
00576     static void* createOneT(const void* iptr=0)
00577     {
00578         T* tptr = new T;
00579         if (iptr) *tptr = *reinterpret_cast<const T*>(iptr);
00580         return tptr;
00581     }
00582     
00585     static void destructOneT(void*& tvptr)
00586     {
00587         T* tptr = reinterpret_cast<T*>(tvptr);
00588         delete tptr;
00589         tvptr = 0;
00590     }
00591 
00597     static void assignArrayOfT(void* dest, const void* src, int n)
00598     {   assert(n>=0);
00599         if (n==0) return;
00600         assert(dest && src);
00601         assert(indexT(dest,n) < src || indexConstT(src,n) < dest);      
00602         T*       d = reinterpret_cast<T*>(dest);
00603         const T* s = reinterpret_cast<const T*>(src);
00604         for (int i=0; i < n; ++i) *d++ = *s++;
00605     }
00606         
00611     static void setT(void* dest, const void* valuep, int n=1)
00612     {   assert(n>=0);
00613         if (n==0) return;
00614         assert(dest && valuep);
00615         T*       d = reinterpret_cast<T*>(dest);
00616         const T& v = *reinterpret_cast<const T*>(valuep);
00617         for (int i=0; i < n; ++i) *d++ = v; 
00618     }
00619     
00622     static void* createArrayOfT(int n, const void* iptr=0)
00623     {   assert(n>=0);
00624         if (n == 0) return 0;
00625         T* tptr = new T[n];
00626         if (iptr) {
00627             const T& init = *reinterpret_cast<const T*>(iptr);
00628             for (int i=0; i < n; ++i) tptr[i] = init;
00629         }       
00630         return tptr;
00631     }
00632     
00637     static void destructArrayOfT(void*& tvptr)
00638     {
00639         T* tptr = reinterpret_cast<T*>(tvptr);
00640         delete[] tptr;
00641         tvptr = 0;
00642     }
00643     
00644 private:    
00645     static const TypeManipulatorT manipT;
00646 };
00647 
00648 /*static*/ template <class T> const TypeManipulatorT
00649 MakeTypeManipulator<T>::manipT = TypeManipulatorT(
00650                                     (int)sizeof(T),indexT,indexConstT,
00651                                     createOneT, destructOneT, assignArrayOfT, setT, 
00652                                     createArrayOfT, destructArrayOfT);
00653 } // namespace SimTKimpl
00654 
00655 
00656 #endif /* C++ stuff */
00657 
00658 #endif /* SimTK_SimTKCOMMON_COMMON_H_ */

Generated by  doxygen 1.6.2