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
28ML_START_NAMESPACE
29
32
50template <typename T>
52{
53 typedef void ComponentType;
54 typedef void IntermediateType;
55
56 enum {
58 isBuiltInFloatType = false,
59 isBuiltInIntegerType= 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
81template <int dataTypeId> struct DataTypeSelector {};
82
83// Flags for TypeTraits (anonymous, shall only be used for TypeTrait setup).
84enum {
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
150ML_DECLARE_SCALAR_TYPETRAIT(MLuint8 , ML_INTEGER_TYPE)
151ML_DECLARE_SCALAR_TYPETRAIT(MLint8 , ML_INTEGER_TYPE | ML_SIGNED_TYPE)
153ML_DECLARE_SCALAR_TYPETRAIT(MLint16 , ML_INTEGER_TYPE | ML_SIGNED_TYPE)
155ML_DECLARE_SCALAR_TYPETRAIT(MLint32 , ML_INTEGER_TYPE | ML_SIGNED_TYPE)
157ML_DECLARE_SCALAR_TYPETRAIT(MLint64 , ML_INTEGER_TYPE | ML_SIGNED_TYPE)
158
159
160ML_DECLARE_SCALAR_TYPETRAIT(MLfloat , ML_FLOAT_TYPE | ML_SIGNED_TYPE)
161ML_DECLARE_SCALAR_TYPETRAIT(MLdouble , ML_FLOAT_TYPE | ML_SIGNED_TYPE)
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
171template <typename DT> class TQuaternion;
174
175
176
177template <class DT> class Tvec2;
180
181template <class DT> class Tvec3;
184
185template <class DT> class Tvec4;
188
189template <class DT> class Tvec5;
192
193template <class DT> class Tvec6;
196
197template <class DT> class Tvec7;
200
201template <class DT> class Tvec8;
204
205template <class DT> class Tvec9;
208
209template <class DT> class Tvec10;
212
213template <class DT> class Tvec16;
216
217template <class DT> class Tvec32;
220
221template <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
232template <class DT> class Tmat2;
235
236template <class DT> class Tmat3;
239
240template <class DT> class Tmat4;
243
244template <class DT> class Tmat5;
247
248template <class DT> class Tmat6;
251
252#undef ML_DECLARE_MATRIX_TYPETRAIT
253
254
256template <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
326ML_END_NAMESPACE
327
328
351
353template<typename T>
354inline 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
365template<typename T>
366inline 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
373template<typename T>
374inline typename ML_NAMESPACE::TypeTraits<typename ML_NAMESPACE::TypeTraits<T>::IntermediateType>::ComponentType
375ml_scalar_factor_cast(double v, const T& /*dummy*/)
376{
377 return ml_component_cast<typename ML_NAMESPACE::TypeTraits<T>::IntermediateType>(v);
378}
379
381template<typename T>
382inline T ml_cast_from_scalar(double v)
383{
384 return static_cast<T>(ml_component_cast<T>(v));
385}
386
389template<typename T>
390inline 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
396template<typename T, typename S>
397inline 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.
411template<typename T>
412inline 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.
430template<typename T>
431inline 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
438template<typename T>
439inline 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.
445template<typename T>
446inline 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.
452template<typename T>
453inline 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
461template<typename T>
462inline 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
@ T
@ S
#define ML_INVALID_DATA_TYPE
Defines an invalid MLDataType.
Definition mlTypeDefs.h:612
MLint32 MLDataType
MLDataType.
Definition mlTypeDefs.h:595
@ MLVector8i16Type
Definition mlTypeDefs.h:660
@ MLVector7fType
Definition mlTypeDefs.h:640
@ MLVector2fType
Definition mlTypeDefs.h:635
@ MLMatrix2dType
Definition mlTypeDefs.h:648
@ MLVector8i32Type
Definition mlTypeDefs.h:660
@ MLComplexdType
Definition mlTypeDefs.h:631
@ MLVector64i16Type
Definition mlTypeDefs.h:665
@ MLVector6fType
Definition mlTypeDefs.h:639
@ MLVector6i32Type
Definition mlTypeDefs.h:658
@ MLVector2i8Type
Definition mlTypeDefs.h:654
@ MLVector5i64Type
Definition mlTypeDefs.h:657
@ MLMatrix6dType
Definition mlTypeDefs.h:652
@ MLVector2i16Type
Definition mlTypeDefs.h:654
@ MLVector10i32Type
Definition mlTypeDefs.h:662
@ MLVector3fType
Definition mlTypeDefs.h:636
@ MLVector3i16Type
Definition mlTypeDefs.h:655
@ MLVector7i64Type
Definition mlTypeDefs.h:659
@ MLQuaternionfType
Definition mlTypeDefs.h:633
@ MLVector5fType
Definition mlTypeDefs.h:638
@ MLVector10fType
Definition mlTypeDefs.h:643
@ MLVector32i8Type
Definition mlTypeDefs.h:664
@ MLComplexfType
Definition mlTypeDefs.h:631
@ MLMatrix5fType
Definition mlTypeDefs.h:651
@ MLVector9fType
Definition mlTypeDefs.h:642
@ MLVector7i16Type
Definition mlTypeDefs.h:659
@ MLVector16fType
Definition mlTypeDefs.h:644
@ MLVector16i32Type
Definition mlTypeDefs.h:663
@ MLMatrix3dType
Definition mlTypeDefs.h:649
@ MLVector64dType
Definition mlTypeDefs.h:646
@ MLVector4i32Type
Definition mlTypeDefs.h:656
@ MLVector64i64Type
Definition mlTypeDefs.h:665
@ MLVector32i64Type
Definition mlTypeDefs.h:664
@ MLVector3i32Type
Definition mlTypeDefs.h:655
@ MLVector4i64Type
Definition mlTypeDefs.h:656
@ MLVector16dType
Definition mlTypeDefs.h:644
@ MLVector3i64Type
Definition mlTypeDefs.h:655
@ MLVector7i32Type
Definition mlTypeDefs.h:659
@ MLVector32dType
Definition mlTypeDefs.h:645
@ MLVector3dType
Definition mlTypeDefs.h:636
@ MLVector2i64Type
Definition mlTypeDefs.h:654
@ MLVector32i32Type
Definition mlTypeDefs.h:664
@ MLMatrix4dType
Definition mlTypeDefs.h:650
@ MLVector64i8Type
Definition mlTypeDefs.h:665
@ MLVector5i32Type
Definition mlTypeDefs.h:657
@ MLVector8fType
Definition mlTypeDefs.h:641
@ MLMatrix5dType
Definition mlTypeDefs.h:651
@ MLVector64fType
Definition mlTypeDefs.h:646
@ MLVector6i8Type
Definition mlTypeDefs.h:658
@ MLVector2dType
Definition mlTypeDefs.h:635
@ MLVector5i16Type
Definition mlTypeDefs.h:657
@ MLVector7dType
Definition mlTypeDefs.h:640
@ MLVector9dType
Definition mlTypeDefs.h:642
@ MLVector4i16Type
Definition mlTypeDefs.h:656
@ MLVector4fType
Definition mlTypeDefs.h:637
@ MLVector16i16Type
Definition mlTypeDefs.h:663
@ MLVector3i8Type
Definition mlTypeDefs.h:655
@ MLVector4dType
Definition mlTypeDefs.h:637
@ MLMatrix3fType
Definition mlTypeDefs.h:649
@ MLVector6dType
Definition mlTypeDefs.h:639
@ MLMatrix6fType
Definition mlTypeDefs.h:652
@ MLVector5i8Type
Definition mlTypeDefs.h:657
@ MLVector10i8Type
Definition mlTypeDefs.h:662
@ MLVector6i16Type
Definition mlTypeDefs.h:658
@ MLVector9i32Type
Definition mlTypeDefs.h:661
@ MLVector10i16Type
Definition mlTypeDefs.h:662
@ MLVector2i32Type
Definition mlTypeDefs.h:654
@ MLVector32i16Type
Definition mlTypeDefs.h:664
@ MLVector32fType
Definition mlTypeDefs.h:645
@ MLVector6i64Type
Definition mlTypeDefs.h:658
@ MLVector64i32Type
Definition mlTypeDefs.h:665
@ MLQuaterniondType
Definition mlTypeDefs.h:633
@ MLVector9i8Type
Definition mlTypeDefs.h:661
@ MLVector16i8Type
Definition mlTypeDefs.h:663
@ MLMatrix4fType
Definition mlTypeDefs.h:650
@ MLMatrix2fType
Definition mlTypeDefs.h:648
@ MLVector4i8Type
Definition mlTypeDefs.h:656
@ MLVector7i8Type
Definition mlTypeDefs.h:659
@ MLVector8i64Type
Definition mlTypeDefs.h:660
@ MLVector9i16Type
Definition mlTypeDefs.h:661
@ MLVector10dType
Definition mlTypeDefs.h:643
@ MLVector8i8Type
Definition mlTypeDefs.h:660
@ MLVector10i64Type
Definition mlTypeDefs.h:662
@ MLVector9i64Type
Definition mlTypeDefs.h:661
@ MLVector8dType
Definition mlTypeDefs.h:641
@ MLVector5dType
Definition mlTypeDefs.h:638
@ MLVector16i64Type
Definition mlTypeDefs.h:663
UINT64 MLuint64
Introduce platform-independent 64-bit unsigned integer type.
Definition mlTypeDefs.h:424
unsigned int MLuint32
Definition mlTypeDefs.h:184
unsigned char MLuint8
Definition mlTypeDefs.h:108
double MLdouble
Definition mlTypeDefs.h:216
unsigned short MLuint16
Definition mlTypeDefs.h:141
signed short MLint16
Definition mlTypeDefs.h:124
char MLint8
Definition mlTypeDefs.h:96
INT64 MLint64
Include 64-bit integer support for Windows or Unix.
Definition mlTypeDefs.h:411
signed int MLint32
Definition mlTypeDefs.h:160
float MLfloat
Definition mlTypeDefs.h:200
#define ML_DECLARE_INT_VECTOR_TYPETRAIT(BASE_TYPE, DIM_NUM, TYPE_ID)
ml::TypeTraits< T >::ComponentType ml_component_cast(double v)
Casts the argument to the component type of the template argument.
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 ...
T _ml_cast_from_intermediate_type_without_clamping(const typename ml::TypeTraits< T >::IntermediateType &v, OverloadSelector::OnTrue)
#define ML_DECLARE_SCALAR_TYPETRAIT(TYPE, FLAGS)
Macro to declare custom type traits.
ml::TypeTraits< typenameml::TypeTraits< T >::IntermediateType >::ComponentType ml_scalar_factor_cast(double v)
Casts the double argument to a type suitable for multiplying with the template type.
#define ML_DECLARE_FLOAT_VECTOR_TYPETRAIT(TEMPLATE_TYPE, BASE_TYPE, TYPE_ID)
Declaration of standard integer type traits.
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-...
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...
#define ML_DECLARE_MATRIX_TYPETRAIT(TEMPLATE_TYPE, BASE_TYPE, TYPE_ID)
T _ml_cast_from_intermediate_type(const typename ml::TypeTraits< T >::IntermediateType &v, OverloadSelector::OnTrue)
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.
T ml_cast_from_scalar(double v)
Casts the (scalar) argument to the type of the template argument.
double floor(T value)
SwitchType< true > OnTrue
SwitchType< ml::TypeTraits< T >::isBuiltInIntegerType > isBuiltInIntegerType()
SwitchType< false > OnFalse
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...
@ ML_FLOAT_TYPE
@ ML_SIGNED_TYPE
@ ML_INTEGER_TYPE
Helper types to switch between implementations of functions by overloading.
Defines a template to get the minimum and maximum values for each basic integer type.
Helper template so select a data type from its type ID.
TypeTraits for scalar ML datatypes.
static MLDataType getDataType()
Returns the data type.
static bool matches(MLDataType)
Returns whether the template argument matches the given data type id.