MeVisLab Toolbox Reference
mlTypeTraits.h
Go to the documentation of this file.
1 /*************************************************************************************
2 **
3 ** Copyright 2009, MeVis Medical Solutions AG
4 **
5 ** The user may use this file in accordance with the license agreement provided with
6 ** the Software or, alternatively, in accordance with the terms contained in a
7 ** written agreement between the user and MeVis Medical Solutions AG.
8 **
9 ** For further information use the contact form at https://www.mevislab.de/contact
10 **
11 **************************************************************************************/
12 
13 #ifndef ML_TYPE_TRAITS_H
14 #define ML_TYPE_TRAITS_H
15 
16 #include "mlInitSystemML.h"
17 
18 #ifndef __mlRangeCasts_H
19 // we need the _ml_numeric_limits templates from this file
20 #include "mlRangeCasts.h"
21 #endif
22 
23 // needed to define type traits for complex types:
24 #include <ThirdPartyWarningsDisable.h>
25 #include <complex>
26 #include <ThirdPartyWarningsRestore.h>
27 
28 ML_START_NAMESPACE
29 
32 
49 template <typename T>
50 struct TypeTraits
51 {
52  typedef void ComponentType;
53  typedef void IntermediateType;
54 
55  enum {
56  dataType = ML_INVALID_DATA_TYPE,
57  isBuiltInFloatType = false,
59  isBuiltInSignedType = false,
60  isScalarType = false,
61  isStandardType = false,
62  is8BitInteger = false,
63  is16BitInteger = false,
64  is32BitInteger = false,
65  is64BitInteger = false,
66  is8_16_32BitInteger = false,
67  isUnknown = true
68  };
69 
73  static inline bool matches(MLDataType) { return true; }
75  static inline MLDataType getDataType() { return dataType; }
76 };
77 
81 template <int dataTypeId> struct DataTypeSelector {};
82 
83 // Flags for TypeTraits (anonymous, shall only be used for TypeTrait setup.
84 enum {
85  ML_INTEGER_TYPE = 0x01, // Flag that is used internally for TypeTraits
86  ML_FLOAT_TYPE = 0x02, // Flag that is used internally for TypeTraits
87  ML_SIGNED_TYPE = 0x04 // Flag that is used internally for TypeTraits
88 };
89 
90 #define _ML_DECLARE_SCALAR_TYPETRAIT_BODY(TYPE, FLAGS) \
91  template <> struct DataTypeSelector<TYPE##Type> { typedef TYPE Type; }; \
92  template <> struct TypeTraits<TYPE > { \
93  typedef TYPE ComponentType; \
94  typedef double IntermediateType; \
95  enum { \
96  dataType = TYPE##Type, \
97  isBuiltInFloatType = (((FLAGS) & ML_FLOAT_TYPE) != 0), \
98  isBuiltInIntegerType = (((FLAGS) & ML_INTEGER_TYPE) != 0), \
99  isScalarType = (((FLAGS) & (ML_INTEGER_TYPE | ML_FLOAT_TYPE)) != 0), \
100  isStandardType = isScalarType, \
101  isBuiltInSignedType = (((FLAGS) & ML_SIGNED_TYPE) != 0), \
102  is8BitInteger = ((((FLAGS) & ML_INTEGER_TYPE) != 0) && (sizeof(TYPE)==sizeof(MLuint8)) ), \
103  is16BitInteger = ((((FLAGS) & ML_INTEGER_TYPE) != 0) && (sizeof(TYPE)==sizeof(MLuint16)) ), \
104  is32BitInteger = ((((FLAGS) & ML_INTEGER_TYPE) != 0) && (sizeof(TYPE)==sizeof(MLuint32)) ), \
105  is64BitInteger = ((((FLAGS) & ML_INTEGER_TYPE) != 0) && (sizeof(TYPE)==sizeof(MLuint64)) ), \
106  is8_16_32BitInteger = ((((FLAGS) & ML_INTEGER_TYPE) != 0) && \
107  ((sizeof(TYPE)==sizeof(MLuint8)) || \
108  (sizeof(TYPE)==sizeof(MLuint16)) || \
109  (sizeof(TYPE)==sizeof(MLuint32)))), \
110  isUnknown = false \
111  }; \
112  \
113  static inline bool matches(MLDataType dt) { return dt == dataType; } \
114  static inline MLDataType getDataType() { return dataType; } \
115  };
116 
118 #define ML_DECLARE_SCALAR_TYPETRAIT(TYPE, FLAGS) \
119  _ML_DECLARE_SCALAR_TYPETRAIT_BODY(TYPE, FLAGS)
120 
121 #define _ML_DECLARE_EXTENDED_TYPETRAIT_BODY(TYPE, TYPE_ID, COMPONENT_TYPE) \
122  template <> struct DataTypeSelector<TYPE_ID> { typedef TYPE Type; }; \
123  template <> struct TypeTraits<TYPE > { \
124  typedef COMPONENT_TYPE ComponentType; \
125  typedef TYPE IntermediateType; \
126  enum { \
127  dataType = TYPE_ID, \
128  isBuiltInFloatType = false, \
129  isBuiltInIntegerType = false, \
130  isScalarType = false, \
131  isStandardType = false, \
132  isBuiltInSignedType = false, \
133  is8BitInteger = false, \
134  is16BitInteger = false, \
135  is32BitInteger = false, \
136  is64BitInteger = false, \
137  is8_16_32BitInteger = false, \
138  isUnknown = false \
139  }; \
140  \
141  static inline bool matches(MLDataType dt) { return dt == dataType; } \
142  static inline MLDataType getDataType() { return dataType; } \
143  };
144 
146 #define ML_DECLARE_EXTENDED_TYPETRAIT(TYPE, TYPE_ID, COMPONENT_TYPE) \
147  _ML_DECLARE_EXTENDED_TYPETRAIT_BODY(TYPE, TYPE_ID, COMPONENT_TYPE)
148 
158 
162 
163 #define ML_DECLARE_FLOAT_VECTOR_TYPETRAIT(TEMPLATE_TYPE, BASE_TYPE, TYPE_ID) \
164  ML_DECLARE_EXTENDED_TYPETRAIT(TEMPLATE_TYPE<BASE_TYPE>, TYPE_ID, BASE_TYPE)
165 
169 
170 template <typename DT> class TQuaternion;
174 
175 
176 template <class DT> class Tvec2;
180 
181 template <class DT> class Tvec3;
184 
185 template <class DT> class Tvec4;
188 
189 template <class DT> class Tvec5;
192 
193 template <class DT> class Tvec6;
196 
197 template <class DT> class Tvec7;
200 
201 template <class DT> class Tvec8;
204 
205 template <class DT> class Tvec9;
208 
209 template <class DT> class Tvec10;
212 
213 template <class DT> class Tvec16;
216 
217 template <class DT> class Tvec32;
220 
221 template <class DT> class Tvec64;
224 
225 #undef ML_DECLARE_FLOAT_VECTOR_TYPETRAIT
226 
227 
228 #define ML_DECLARE_MATRIX_TYPETRAIT(TEMPLATE_TYPE, BASE_TYPE, TYPE_ID) \
229  ML_DECLARE_EXTENDED_TYPETRAIT(TEMPLATE_TYPE<BASE_TYPE>, TYPE_ID, BASE_TYPE)
230 
232 template <class DT> class Tmat2;
235 
236 template <class DT> class Tmat3;
239 
240 template <class DT> class Tmat4;
243 
244 template <class DT> class Tmat5;
247 
248 template <class DT> class Tmat6;
251 
252 #undef ML_DECLARE_MATRIX_TYPETRAIT
253 
254 
256 template <typename CompIntType, int NumDim> class TVectorNDBase;
257 
258 #define INT_VECTOR_EXPANDER(BASE_TYPE, DIM_NUM) TVectorNDBase<BASE_TYPE, DIM_NUM>
259 
260 #define ML_DECLARE_INT_VECTOR_TYPETRAIT(BASE_TYPE, DIM_NUM, TYPE_ID) \
261  _ML_DECLARE_EXTENDED_TYPETRAIT_BODY(INT_VECTOR_EXPANDER(BASE_TYPE, DIM_NUM), TYPE_ID, BASE_TYPE)
262 
267 
272 
277 
282 
287 
292 
297 
302 
307 
312 
317 
322 
323 #undef ML_DECLARE_INT_VECTOR_TYPETRAIT
324 #undef INT_VECTOR_EXPANDER
325 
326 ML_END_NAMESPACE
327 
328 
329 namespace OverloadSelector {
330 
332 template<bool b> struct SwitchType {};
335 
340 template<typename T>
343 }
344 
345 template<typename T>
348 }
349 
350 }
351 
353 template<typename T>
354 inline typename ML_NAMESPACE::TypeTraits<T>::ComponentType ml_component_cast(double v)
355 {
356  return static_cast<typename ML_NAMESPACE::TypeTraits<T>::ComponentType>(v);
357 }
358 
363 template<typename T>
364 inline typename ML_NAMESPACE::TypeTraits<typename ML_NAMESPACE::TypeTraits<T>::IntermediateType>::ComponentType
366 {
367  return ml_component_cast<typename ML_NAMESPACE::TypeTraits<T>::IntermediateType>(v);
368 }
369 
371 template<typename T>
372 inline typename ML_NAMESPACE::TypeTraits<typename ML_NAMESPACE::TypeTraits<T>::IntermediateType>::ComponentType
373 ml_scalar_factor_cast(double v, const T& /*dummy*/)
374 {
375  return ml_component_cast<typename ML_NAMESPACE::TypeTraits<T>::IntermediateType>(v);
376 }
377 
379 template<typename T>
380 inline T ml_cast_from_scalar(double v)
381 {
382  return static_cast<T>(ml_component_cast<T>(v));
383 }
384 
387 template<typename T>
388 inline typename ML_NAMESPACE::TypeTraits<T>::IntermediateType ml_cast_to_intermediate_type(const T& v)
389 {
390  return static_cast<typename ML_NAMESPACE::TypeTraits<T>::IntermediateType>(v);
391 }
392 
394 template<typename T, typename S>
395 inline typename ML_NAMESPACE::TypeTraits<T>::IntermediateType
397 {
398  return static_cast<typename ML_NAMESPACE::TypeTraits<T>::IntermediateType>(v) *
399  ml_component_cast<typename ML_NAMESPACE::TypeTraits<T>::IntermediateType>(s);
400 }
401 
402 // GCC 7 is a little bit to eager with its warnings...
403 #if defined(__GNUC__) && (__GNUC__ >= 7)
404 #pragma GCC diagnostic push
405 #pragma GCC diagnostic warning "-Wfloat-conversion"
406 #endif
407 
408 // version for built-in integer types, does clamping and rounding
409 template<typename T>
410 inline T _ml_cast_from_intermediate_type(const typename ML_NAMESPACE::TypeTraits<T>::IntermediateType& v, OverloadSelector::OnTrue)
411 {
412  // clamping to allowed value range:
413  if (v < static_cast<const typename ML_NAMESPACE::TypeTraits<T>::IntermediateType>(_ml_numeric_limits<T>::MinValue)) {
414  return static_cast<T>(_ml_numeric_limits<T>::MinValue);
415  } else if (v > static_cast<const typename ML_NAMESPACE::TypeTraits<T>::IntermediateType>(_ml_numeric_limits<T>::MaxValue)) {
416  return static_cast<T>(_ml_numeric_limits<T>::MaxValue);
417  } else {
418  // rounding to next integer:
419  return static_cast<T>(floor(v+0.5));
420  }
421 }
422 
423 #if defined(__GNUC__) && (__GNUC__ >= 7)
424 #pragma GCC diagnostic pop
425 #endif
426 
427 // version for all other types, does nothing
428 template<typename T>
429 inline T _ml_cast_from_intermediate_type(const typename ML_NAMESPACE::TypeTraits<T>::IntermediateType& v, OverloadSelector::OnFalse)
430 {
431  return static_cast<T>(v);
432 }
433 
436 template<typename T>
437 inline T ml_cast_from_intermediate_type(const typename ML_NAMESPACE::TypeTraits<T>::IntermediateType& v)
438 {
439  return _ml_cast_from_intermediate_type<T>(v, OverloadSelector::isBuiltInIntegerType<T>());
440 }
441 
442 // version for built-in integer types, does rounding
443 template<typename T>
444 inline T _ml_cast_from_intermediate_type_without_clamping(const typename ML_NAMESPACE::TypeTraits<T>::IntermediateType& v, OverloadSelector::OnTrue)
445 {
446  return static_cast<T>(floor(v+0.5));
447 }
448 
449 // version for all other types, does nothing
450 template<typename T>
451 inline T _ml_cast_from_intermediate_type_without_clamping(const typename ML_NAMESPACE::TypeTraits<T>::IntermediateType& v, OverloadSelector::OnFalse)
452 {
453  return static_cast<T>(v);
454 }
455 
459 template<typename T>
460 inline T ml_cast_from_intermediate_type_without_clamping(const typename ML_NAMESPACE::TypeTraits<T>::IntermediateType& v)
461 {
462  return _ml_cast_from_intermediate_type_without_clamping<T>(v, OverloadSelector::isBuiltInIntegerType<T>());
463 }
464 
465 
466 #endif // of __mlTypeTraits_H
467 
@ T
Definition: SoKeyGrabber.h:71
@ S
Definition: SoKeyGrabber.h:70
#define ML_INVALID_DATA_TYPE
Defines an invalid MLDataType.
Definition: mlTypeDefs.h:715
MLint32 MLDataType
MLDataType.
Definition: mlTypeDefs.h:684
@ MLVector8i16Type
Definition: mlTypeDefs.h:763
@ MLVector7fType
Definition: mlTypeDefs.h:743
@ MLVector2fType
Definition: mlTypeDefs.h:738
@ MLMatrix2dType
Definition: mlTypeDefs.h:751
@ MLVector8i32Type
Definition: mlTypeDefs.h:763
@ MLComplexdType
Definition: mlTypeDefs.h:734
@ MLVector64i16Type
Definition: mlTypeDefs.h:768
@ MLVector6fType
Definition: mlTypeDefs.h:742
@ MLVector6i32Type
Definition: mlTypeDefs.h:761
@ MLVector2i8Type
Definition: mlTypeDefs.h:757
@ MLVector5i64Type
Definition: mlTypeDefs.h:760
@ MLMatrix6dType
Definition: mlTypeDefs.h:755
@ MLVector2i16Type
Definition: mlTypeDefs.h:757
@ MLVector10i32Type
Definition: mlTypeDefs.h:765
@ MLVector3fType
Definition: mlTypeDefs.h:739
@ MLVector3i16Type
Definition: mlTypeDefs.h:758
@ MLVector7i64Type
Definition: mlTypeDefs.h:762
@ MLQuaternionfType
Definition: mlTypeDefs.h:736
@ MLVector5fType
Definition: mlTypeDefs.h:741
@ MLVector10fType
Definition: mlTypeDefs.h:746
@ MLVector32i8Type
Definition: mlTypeDefs.h:767
@ MLComplexfType
Definition: mlTypeDefs.h:734
@ MLMatrix5fType
Definition: mlTypeDefs.h:754
@ MLVector9fType
Definition: mlTypeDefs.h:745
@ MLVector7i16Type
Definition: mlTypeDefs.h:762
@ MLVector16fType
Definition: mlTypeDefs.h:747
@ MLVector16i32Type
Definition: mlTypeDefs.h:766
@ MLMatrix3dType
Definition: mlTypeDefs.h:752
@ MLVector64dType
Definition: mlTypeDefs.h:749
@ MLVector4i32Type
Definition: mlTypeDefs.h:759
@ MLVector64i64Type
Definition: mlTypeDefs.h:768
@ MLVector32i64Type
Definition: mlTypeDefs.h:767
@ MLVector3i32Type
Definition: mlTypeDefs.h:758
@ MLVector4i64Type
Definition: mlTypeDefs.h:759
@ MLVector16dType
Definition: mlTypeDefs.h:747
@ MLVector3i64Type
Definition: mlTypeDefs.h:758
@ MLVector7i32Type
Definition: mlTypeDefs.h:762
@ MLVector32dType
Definition: mlTypeDefs.h:748
@ MLVector3dType
Definition: mlTypeDefs.h:739
@ MLVector2i64Type
Definition: mlTypeDefs.h:757
@ MLVector32i32Type
Definition: mlTypeDefs.h:767
@ MLMatrix4dType
Definition: mlTypeDefs.h:753
@ MLVector64i8Type
Definition: mlTypeDefs.h:768
@ MLVector5i32Type
Definition: mlTypeDefs.h:760
@ MLVector8fType
Definition: mlTypeDefs.h:744
@ MLMatrix5dType
Definition: mlTypeDefs.h:754
@ MLVector64fType
Definition: mlTypeDefs.h:749
@ MLVector6i8Type
Definition: mlTypeDefs.h:761
@ MLVector2dType
Definition: mlTypeDefs.h:738
@ MLVector5i16Type
Definition: mlTypeDefs.h:760
@ MLVector7dType
Definition: mlTypeDefs.h:743
@ MLVector9dType
Definition: mlTypeDefs.h:745
@ MLVector4i16Type
Definition: mlTypeDefs.h:759
@ MLVector4fType
Definition: mlTypeDefs.h:740
@ MLVector16i16Type
Definition: mlTypeDefs.h:766
@ MLVector3i8Type
Definition: mlTypeDefs.h:758
@ MLVector4dType
Definition: mlTypeDefs.h:740
@ MLMatrix3fType
Definition: mlTypeDefs.h:752
@ MLVector6dType
Definition: mlTypeDefs.h:742
@ MLMatrix6fType
Definition: mlTypeDefs.h:755
@ MLVector5i8Type
Definition: mlTypeDefs.h:760
@ MLVector10i8Type
Definition: mlTypeDefs.h:765
@ MLVector6i16Type
Definition: mlTypeDefs.h:761
@ MLVector9i32Type
Definition: mlTypeDefs.h:764
@ MLVector10i16Type
Definition: mlTypeDefs.h:765
@ MLVector2i32Type
Definition: mlTypeDefs.h:757
@ MLVector32i16Type
Definition: mlTypeDefs.h:767
@ MLVector32fType
Definition: mlTypeDefs.h:748
@ MLVector6i64Type
Definition: mlTypeDefs.h:761
@ MLVector64i32Type
Definition: mlTypeDefs.h:768
@ MLQuaterniondType
Definition: mlTypeDefs.h:736
@ MLVector9i8Type
Definition: mlTypeDefs.h:764
@ MLVector16i8Type
Definition: mlTypeDefs.h:766
@ MLMatrix4fType
Definition: mlTypeDefs.h:753
@ MLMatrix2fType
Definition: mlTypeDefs.h:751
@ MLVector4i8Type
Definition: mlTypeDefs.h:759
@ MLVector7i8Type
Definition: mlTypeDefs.h:762
@ MLVector8i64Type
Definition: mlTypeDefs.h:763
@ MLVector9i16Type
Definition: mlTypeDefs.h:764
@ MLVector10dType
Definition: mlTypeDefs.h:746
@ MLVector8i8Type
Definition: mlTypeDefs.h:763
@ MLVector10i64Type
Definition: mlTypeDefs.h:765
@ MLVector9i64Type
Definition: mlTypeDefs.h:764
@ MLVector8dType
Definition: mlTypeDefs.h:744
@ MLVector5dType
Definition: mlTypeDefs.h:741
@ MLVector16i64Type
Definition: mlTypeDefs.h:766
UINT64 MLuint64
Introduce platform independent 64 bit unsigned integer type.
Definition: mlTypeDefs.h:513
unsigned int MLuint32
Definition: mlTypeDefs.h:191
unsigned char MLuint8
Definition: mlTypeDefs.h:115
double MLdouble
Definition: mlTypeDefs.h:223
unsigned short MLuint16
Definition: mlTypeDefs.h:148
signed short MLint16
Definition: mlTypeDefs.h:131
char MLint8
Definition: mlTypeDefs.h:103
INT64 MLint64
Include 64 bit integer support for Windows or Unix.
Definition: mlTypeDefs.h:500
signed int MLint32
Definition: mlTypeDefs.h:167
float MLfloat
Definition: mlTypeDefs.h:207
ml::TypeTraits< T >::IntermediateType ml_cast_to_intermediate_type_and_multiply(const T &v, S s)
same as above, but will also multiply with the second argument
Definition: mlTypeTraits.h:396
#define ML_DECLARE_INT_VECTOR_TYPETRAIT(BASE_TYPE, DIM_NUM, TYPE_ID)
Definition: mlTypeTraits.h:260
T ml_cast_from_intermediate_type(const typename ml::TypeTraits< T >::IntermediateType &v)
cast from an intermediate type to the desired type; does clamping and rounding for the built-in integ...
Definition: mlTypeTraits.h:437
T _ml_cast_from_intermediate_type_without_clamping(const typename ml::TypeTraits< T >::IntermediateType &v, OverloadSelector::OnTrue)
Definition: mlTypeTraits.h:444
#define ML_DECLARE_SCALAR_TYPETRAIT(TYPE, FLAGS)
Macro to declare own type traits.
Definition: mlTypeTraits.h:118
#define ML_DECLARE_FLOAT_VECTOR_TYPETRAIT(TEMPLATE_TYPE, BASE_TYPE, TYPE_ID)
Declaration of standard integer type traits.
Definition: mlTypeTraits.h:163
T ml_cast_from_intermediate_type_without_clamping(const typename ml::TypeTraits< T >::IntermediateType &v)
cast from an intermediate type to the desired type; does rounding but no clamping for the built-in in...
Definition: mlTypeTraits.h:460
ml::TypeTraits< T >::IntermediateType ml_cast_to_intermediate_type(const T &v)
cast type to an intermediate type suitable for consecutive arithmetic operations; integer types will ...
Definition: mlTypeTraits.h:388
#define ML_DECLARE_MATRIX_TYPETRAIT(TEMPLATE_TYPE, BASE_TYPE, TYPE_ID)
Definition: mlTypeTraits.h:228
T _ml_cast_from_intermediate_type(const typename ml::TypeTraits< T >::IntermediateType &v, OverloadSelector::OnTrue)
Definition: mlTypeTraits.h:410
T ml_cast_from_scalar(double v)
cast the (scalar) argument to the type of the template argument
Definition: mlTypeTraits.h:380
ml::TypeTraits< T >::ComponentType ml_component_cast(double v)
cast the argument to the component type of the template argument
Definition: mlTypeTraits.h:354
ml::TypeTraits< typename ml::TypeTraits< T >::IntermediateType >::ComponentType ml_scalar_factor_cast(double v)
cast the double argument to a type suitable for multiplying with the template type (this is double fo...
Definition: mlTypeTraits.h:365
SwitchType< true > OnTrue
Definition: mlTypeTraits.h:333
SwitchType< ml::TypeTraits< T >::isBuiltInIntegerType > isBuiltInIntegerType()
Definition: mlTypeTraits.h:346
SwitchType< ml::TypeTraits< T >::isStandardType > isScalarType()
The purpose of this function only is to return different result types depending on if T is a scalar t...
Definition: mlTypeTraits.h:341
SwitchType< false > OnFalse
Definition: mlTypeTraits.h:334
@ ML_FLOAT_TYPE
Definition: mlTypeTraits.h:86
@ ML_SIGNED_TYPE
Definition: mlTypeTraits.h:87
@ ML_INTEGER_TYPE
Definition: mlTypeTraits.h:85
helper types to switch between implementations of functions by overloading
Definition: mlTypeTraits.h:332
Define a template to get the min and max values for each basic integer type.
Definition: mlRangeCasts.h:47
Helper template so select a data type from its type id.
Definition: mlTypeTraits.h:81
TypeTraits for scalar ML Datatypes.
Definition: mlTypeTraits.h:51
void IntermediateType
Definition: mlTypeTraits.h:53
static MLDataType getDataType()
Return the data type.
Definition: mlTypeTraits.h:75
static bool matches(MLDataType)
Return whether the template argument matches the given data type id.
Definition: mlTypeTraits.h:73