ML 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 
50 template <typename T>
51 struct TypeTraits
52 {
53  typedef void ComponentType;
54  typedef void IntermediateType;
55 
56  enum {
57  dataType = ML_INVALID_DATA_TYPE,
58  isBuiltInFloatType = false,
60  isBuiltInSignedType = false,
61  isScalarType = 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 
365 template<typename T>
366 inline typename ML_NAMESPACE::TypeTraits<typename ML_NAMESPACE::TypeTraits<T>::IntermediateType>::ComponentType
368 {
369  return ml_component_cast<typename ML_NAMESPACE::TypeTraits<T>::IntermediateType>(v);
370 }
371 
373 template<typename T>
374 inline typename ML_NAMESPACE::TypeTraits<typename ML_NAMESPACE::TypeTraits<T>::IntermediateType>::ComponentType
375 ml_scalar_factor_cast(double v, const T& /*dummy*/)
376 {
377  return ml_component_cast<typename ML_NAMESPACE::TypeTraits<T>::IntermediateType>(v);
378 }
379 
381 template<typename T>
382 inline T ml_cast_from_scalar(double v)
383 {
384  return static_cast<T>(ml_component_cast<T>(v));
385 }
386 
389 template<typename T>
390 inline typename ML_NAMESPACE::TypeTraits<T>::IntermediateType ml_cast_to_intermediate_type(const T& v)
391 {
392  return static_cast<typename ML_NAMESPACE::TypeTraits<T>::IntermediateType>(v);
393 }
394 
396 template<typename T, typename S>
397 inline typename ML_NAMESPACE::TypeTraits<T>::IntermediateType
399 {
400  return static_cast<typename ML_NAMESPACE::TypeTraits<T>::IntermediateType>(v) *
401  ml_component_cast<typename ML_NAMESPACE::TypeTraits<T>::IntermediateType>(s);
402 }
403 
404 // GCC 7 is a little bit too eager with its warnings...
405 #if defined(__GNUC__) && (__GNUC__ >= 7)
406 #pragma GCC diagnostic push
407 #pragma GCC diagnostic warning "-Wfloat-conversion"
408 #endif
409 
410 // Version for built-in integer types, performs clamping and rounding.
411 template<typename T>
412 inline T _ml_cast_from_intermediate_type(const typename ML_NAMESPACE::TypeTraits<T>::IntermediateType& v, OverloadSelector::OnTrue)
413 {
414  // clamping to allowed value range:
415  if (v < static_cast<const typename ML_NAMESPACE::TypeTraits<T>::IntermediateType>(_ml_numeric_limits<T>::MinValue)) {
416  return static_cast<T>(_ml_numeric_limits<T>::MinValue);
417  } else if (v > static_cast<const typename ML_NAMESPACE::TypeTraits<T>::IntermediateType>(_ml_numeric_limits<T>::MaxValue)) {
418  return static_cast<T>(_ml_numeric_limits<T>::MaxValue);
419  } else {
420  // rounding to next integer:
421  return static_cast<T>(floor(v+0.5));
422  }
423 }
424 
425 #if defined(__GNUC__) && (__GNUC__ >= 7)
426 #pragma GCC diagnostic pop
427 #endif
428 
429 // Version for all other types, does nothing.
430 template<typename T>
431 inline T _ml_cast_from_intermediate_type(const typename ML_NAMESPACE::TypeTraits<T>::IntermediateType& v, OverloadSelector::OnFalse)
432 {
433  return static_cast<T>(v);
434 }
435 
438 template<typename T>
439 inline T ml_cast_from_intermediate_type(const typename ML_NAMESPACE::TypeTraits<T>::IntermediateType& v)
440 {
441  return _ml_cast_from_intermediate_type<T>(v, OverloadSelector::isBuiltInIntegerType<T>());
442 }
443 
444 // Version for built-in integer types, performs rounding.
445 template<typename T>
446 inline T _ml_cast_from_intermediate_type_without_clamping(const typename ML_NAMESPACE::TypeTraits<T>::IntermediateType& v, OverloadSelector::OnTrue)
447 {
448  return static_cast<T>(floor(v+0.5));
449 }
450 
451 // Version for all other types, does nothing.
452 template<typename T>
453 inline T _ml_cast_from_intermediate_type_without_clamping(const typename ML_NAMESPACE::TypeTraits<T>::IntermediateType& v, OverloadSelector::OnFalse)
454 {
455  return static_cast<T>(v);
456 }
457 
461 template<typename T>
462 inline T ml_cast_from_intermediate_type_without_clamping(const typename ML_NAMESPACE::TypeTraits<T>::IntermediateType& v)
463 {
464  return _ml_cast_from_intermediate_type_without_clamping<T>(v, OverloadSelector::isBuiltInIntegerType<T>());
465 }
466 
467 
468 #endif // of __mlTypeTraits_H
469 
#define ML_INVALID_DATA_TYPE
Defines an invalid MLDataType.
Definition: mlTypeDefs.h:613
MLint32 MLDataType
MLDataType.
Definition: mlTypeDefs.h:596
@ MLVector8i16Type
Definition: mlTypeDefs.h:661
@ MLVector7fType
Definition: mlTypeDefs.h:641
@ MLVector2fType
Definition: mlTypeDefs.h:636
@ MLMatrix2dType
Definition: mlTypeDefs.h:649
@ MLVector8i32Type
Definition: mlTypeDefs.h:661
@ MLComplexdType
Definition: mlTypeDefs.h:632
@ MLVector64i16Type
Definition: mlTypeDefs.h:666
@ MLVector6fType
Definition: mlTypeDefs.h:640
@ MLVector6i32Type
Definition: mlTypeDefs.h:659
@ MLVector2i8Type
Definition: mlTypeDefs.h:655
@ MLVector5i64Type
Definition: mlTypeDefs.h:658
@ MLMatrix6dType
Definition: mlTypeDefs.h:653
@ MLVector2i16Type
Definition: mlTypeDefs.h:655
@ MLVector10i32Type
Definition: mlTypeDefs.h:663
@ MLVector3fType
Definition: mlTypeDefs.h:637
@ MLVector3i16Type
Definition: mlTypeDefs.h:656
@ MLVector7i64Type
Definition: mlTypeDefs.h:660
@ MLQuaternionfType
Definition: mlTypeDefs.h:634
@ MLVector5fType
Definition: mlTypeDefs.h:639
@ MLVector10fType
Definition: mlTypeDefs.h:644
@ MLVector32i8Type
Definition: mlTypeDefs.h:665
@ MLComplexfType
Definition: mlTypeDefs.h:632
@ MLMatrix5fType
Definition: mlTypeDefs.h:652
@ MLVector9fType
Definition: mlTypeDefs.h:643
@ MLVector7i16Type
Definition: mlTypeDefs.h:660
@ MLVector16fType
Definition: mlTypeDefs.h:645
@ MLVector16i32Type
Definition: mlTypeDefs.h:664
@ MLMatrix3dType
Definition: mlTypeDefs.h:650
@ MLVector64dType
Definition: mlTypeDefs.h:647
@ MLVector4i32Type
Definition: mlTypeDefs.h:657
@ MLVector64i64Type
Definition: mlTypeDefs.h:666
@ MLVector32i64Type
Definition: mlTypeDefs.h:665
@ MLVector3i32Type
Definition: mlTypeDefs.h:656
@ MLVector4i64Type
Definition: mlTypeDefs.h:657
@ MLVector16dType
Definition: mlTypeDefs.h:645
@ MLVector3i64Type
Definition: mlTypeDefs.h:656
@ MLVector7i32Type
Definition: mlTypeDefs.h:660
@ MLVector32dType
Definition: mlTypeDefs.h:646
@ MLVector3dType
Definition: mlTypeDefs.h:637
@ MLVector2i64Type
Definition: mlTypeDefs.h:655
@ MLVector32i32Type
Definition: mlTypeDefs.h:665
@ MLMatrix4dType
Definition: mlTypeDefs.h:651
@ MLVector64i8Type
Definition: mlTypeDefs.h:666
@ MLVector5i32Type
Definition: mlTypeDefs.h:658
@ MLVector8fType
Definition: mlTypeDefs.h:642
@ MLMatrix5dType
Definition: mlTypeDefs.h:652
@ MLVector64fType
Definition: mlTypeDefs.h:647
@ MLVector6i8Type
Definition: mlTypeDefs.h:659
@ MLVector2dType
Definition: mlTypeDefs.h:636
@ MLVector5i16Type
Definition: mlTypeDefs.h:658
@ MLVector7dType
Definition: mlTypeDefs.h:641
@ MLVector9dType
Definition: mlTypeDefs.h:643
@ MLVector4i16Type
Definition: mlTypeDefs.h:657
@ MLVector4fType
Definition: mlTypeDefs.h:638
@ MLVector16i16Type
Definition: mlTypeDefs.h:664
@ MLVector3i8Type
Definition: mlTypeDefs.h:656
@ MLVector4dType
Definition: mlTypeDefs.h:638
@ MLMatrix3fType
Definition: mlTypeDefs.h:650
@ MLVector6dType
Definition: mlTypeDefs.h:640
@ MLMatrix6fType
Definition: mlTypeDefs.h:653
@ MLVector5i8Type
Definition: mlTypeDefs.h:658
@ MLVector10i8Type
Definition: mlTypeDefs.h:663
@ MLVector6i16Type
Definition: mlTypeDefs.h:659
@ MLVector9i32Type
Definition: mlTypeDefs.h:662
@ MLVector10i16Type
Definition: mlTypeDefs.h:663
@ MLVector2i32Type
Definition: mlTypeDefs.h:655
@ MLVector32i16Type
Definition: mlTypeDefs.h:665
@ MLVector32fType
Definition: mlTypeDefs.h:646
@ MLVector6i64Type
Definition: mlTypeDefs.h:659
@ MLVector64i32Type
Definition: mlTypeDefs.h:666
@ MLQuaterniondType
Definition: mlTypeDefs.h:634
@ MLVector9i8Type
Definition: mlTypeDefs.h:662
@ MLVector16i8Type
Definition: mlTypeDefs.h:664
@ MLMatrix4fType
Definition: mlTypeDefs.h:651
@ MLMatrix2fType
Definition: mlTypeDefs.h:649
@ MLVector4i8Type
Definition: mlTypeDefs.h:657
@ MLVector7i8Type
Definition: mlTypeDefs.h:660
@ MLVector8i64Type
Definition: mlTypeDefs.h:661
@ MLVector9i16Type
Definition: mlTypeDefs.h:662
@ MLVector10dType
Definition: mlTypeDefs.h:644
@ MLVector8i8Type
Definition: mlTypeDefs.h:661
@ MLVector10i64Type
Definition: mlTypeDefs.h:663
@ MLVector9i64Type
Definition: mlTypeDefs.h:662
@ MLVector8dType
Definition: mlTypeDefs.h:642
@ MLVector5dType
Definition: mlTypeDefs.h:639
@ MLVector16i64Type
Definition: mlTypeDefs.h:664
UINT64 MLuint64
Introduce platform-independent 64-bit unsigned integer type.
Definition: mlTypeDefs.h:425
unsigned int MLuint32
Definition: mlTypeDefs.h:185
unsigned char MLuint8
Definition: mlTypeDefs.h:109
double MLdouble
Definition: mlTypeDefs.h:217
unsigned short MLuint16
Definition: mlTypeDefs.h:142
signed short MLint16
Definition: mlTypeDefs.h:125
char MLint8
Definition: mlTypeDefs.h:97
INT64 MLint64
Include 64-bit integer support for Windows or Unix.
Definition: mlTypeDefs.h:412
signed int MLint32
Definition: mlTypeDefs.h:161
float MLfloat
Definition: mlTypeDefs.h:201
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:398
#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)
Casts from an intermediate type to the desired type; performs clamping and rounding for the built-in ...
Definition: mlTypeTraits.h:439
T _ml_cast_from_intermediate_type_without_clamping(const typename ml::TypeTraits< T >::IntermediateType &v, OverloadSelector::OnTrue)
Definition: mlTypeTraits.h:446
#define ML_DECLARE_SCALAR_TYPETRAIT(TYPE, FLAGS)
Macro to declare custom 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)
Casts from an intermediate type to the desired type; performs rounding but no clamping for the built-...
Definition: mlTypeTraits.h:462
ml::TypeTraits< T >::IntermediateType ml_cast_to_intermediate_type(const T &v)
Casts type to an intermediate type suitable for consecutive arithmetic operations; integer types will...
Definition: mlTypeTraits.h:390
#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:412
T ml_cast_from_scalar(double v)
Casts the (scalar) argument to the type of the template argument.
Definition: mlTypeTraits.h:382
ml::TypeTraits< T >::ComponentType ml_component_cast(double v)
Casts 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)
Casts the double argument to a type suitable for multiplying with the template type.
Definition: mlTypeTraits.h:367
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 is only to return different result types depending on whether T is a sca...
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
Defines a template to get the minimum and maximum 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:52
void IntermediateType
Definition: mlTypeTraits.h:54
static MLDataType getDataType()
Returns the data type.
Definition: mlTypeTraits.h:75
static bool matches(MLDataType)
Returns whether the template argument matches the given data type id.
Definition: mlTypeTraits.h:73