Line data Source code
1 : /** 2 : * \file TypeTraits.h 3 : */ 4 : 5 : #ifndef ATK_CORE_TYPETRAITS_H 6 : #define ATK_CORE_TYPETRAITS_H 7 : 8 : #include <ATK/config.h> 9 : 10 : #include <algorithm> 11 : #include <complex> 12 : #include <cstdint> 13 : #include <limits> 14 : #include <type_traits> 15 : 16 : namespace ATK 17 : { 18 : /// Traits to handle conversion integer full scale from/to double 19 : template<typename DataType> 20 : class IntegralTypeTraits 21 : { 22 : public: 23 : using Scalar = DataType; 24 : 25 : /// Converts an integer to a double 26 36700183 : static double to_double(DataType el) 27 : { 28 36700183 : return -static_cast<double>(el) / std::numeric_limits<DataType>::min(); 29 : } 30 : 31 : /// Converts a double to an integer 32 34603033 : static DataType from_double(double el) 33 : { 34 34603033 : return static_cast<DataType>(-el * std::numeric_limits<DataType>::min()); 35 : } 36 : 37 3 : static DataType conj(DataType el) 38 : { 39 3 : return el; 40 : } 41 : 42 150 : static DataType Zero() 43 : { 44 150 : return 0; 45 : } 46 : 47 3 : static DataType One() 48 : { 49 3 : return 1; 50 : } 51 : 52 3 : static DataType max(DataType a, DataType b) 53 : { 54 3 : return std::max(a, b); 55 : } 56 : }; 57 : 58 : /// Special case for 24bits 59 : template<> 60 : class IntegralTypeTraits<char[3]> 61 : { 62 : public: 63 : using Scalar = int64_t; 64 : 65 : /// Converts an integer 24bits to a double 66 1 : static double to_double(const char el[3]) 67 : { 68 1 : int32_t data = 0; 69 1 : char* temp = reinterpret_cast<char*>(&data); 70 4 : for(int i = 0; i < 3; ++i) 71 : { 72 3 : temp[1+i] = el[i]; 73 : } 74 1 : data = data >> 8; 75 1 : return -static_cast<double>(data) / (static_cast<double>(1 << 8) * std::numeric_limits<std::int16_t>::min()); 76 : } 77 : 78 : /// Converts a double to an integer 64bits 79 1 : static int32_t from_double(double el) 80 : { 81 1 : return static_cast<int32_t>(-el * (static_cast<double>(1 << 8) * std::numeric_limits<std::int16_t>::min())); 82 : } 83 : 84 1 : static int32_t Zero() 85 : { 86 1 : return 0; 87 : } 88 : 89 1 : static int32_t One() 90 : { 91 1 : return 1; 92 : } 93 : }; 94 : 95 : /// Traits to handle conversion floating point numbers from/to double 96 : template<typename DataType> 97 : class RealTypeTraits 98 : { 99 : public: 100 : using Scalar = DataType; 101 : 102 : /// Converts to a double 103 20335000 : static double to_double(DataType el) 104 : { 105 20335000 : return static_cast<double>(el); 106 : } 107 : 108 : /// Converts from a double 109 21383510 : static DataType from_double(double el) 110 : { 111 21383510 : return static_cast<DataType>(el); 112 : } 113 : 114 67738 : static DataType conj(DataType el) 115 : { 116 67738 : return el; 117 : } 118 : 119 237333 : static DataType Zero() 120 : { 121 237333 : return 0; 122 : } 123 : 124 1029 : static DataType One() 125 : { 126 1029 : return 1; 127 : } 128 : 129 25 : static DataType max(DataType a, DataType b) 130 : { 131 25 : return std::max(a, b); 132 : } 133 : }; 134 : 135 : /// Traits to handle conversion complex floating point numbers from/to double 136 : template<typename DataType> 137 : class ComplexRealTypeTraits 138 : { 139 : }; 140 : 141 : /// Traits to handle conversion complex floating point numbers from/to double 142 : template<typename DataType> 143 : class ComplexRealTypeTraits<std::complex<DataType> > 144 : { 145 : public: 146 : using Scalar = typename std::complex<DataType>::value_type; 147 : 148 : /// Converts to a double 149 6291460 : static std::complex<double> to_double(std::complex<DataType> el) 150 : { 151 6291460 : return static_cast<std::complex<double> >(el); 152 : } 153 : 154 : /// Converts from a double 155 7340030 : static std::complex<DataType> from_double(std::complex<double> el) 156 : { 157 7340030 : return static_cast<std::complex<DataType> >(el); 158 : } 159 : 160 2 : static std::complex<DataType> conj(std::complex<DataType> el) 161 : { 162 2 : return std::conj(el); 163 : } 164 : 165 25 : static DataType Zero() 166 : { 167 25 : return 0; 168 : } 169 : 170 2 : static DataType One() 171 : { 172 2 : return 1; 173 : } 174 : }; 175 : 176 : /// Common base class for conversion type traits 177 : template<typename DataType> 178 : class TypeTraits : public std::conditional<std::is_class<DataType>::value, ComplexRealTypeTraits<DataType>, 179 : typename std::conditional<std::is_floating_point<DataType>::value, RealTypeTraits<DataType>, IntegralTypeTraits<DataType>>::type>::type 180 : { 181 : }; 182 : } 183 : 184 : #endif