1 /** @addtogroup cometa
2 * @{
3 */
4 #pragma once
5
6 #include "../cometa.hpp"
7
8 namespace cometa
9 {
10
11 /// @brief Short names for common types
12 using b8 = bool;
13 using f32 = float;
14 using f64 = double;
15 using i8 = int8_t;
16 using i16 = int16_t;
17 using i32 = int32_t;
18 using i64 = int64_t;
19 using u8 = uint8_t;
20 using u16 = uint16_t;
21 using u32 = uint32_t;
22 using u64 = uint64_t;
23 using umax = uint64_t;
24 using imax = int64_t;
25 using fmax = double;
26 using f80 = long double;
27
28 #if defined(CMT_BASETYPE_F32) || defined(CMT_NO_NATIVE_F64)
29 using fbase = float;
30 #else
31 using fbase = double;
32 #endif
33
34 namespace details
35 {
36 template <typename T>
37 struct fix_type_impl
38 {
39 using type = T;
40 };
41
42 template <>
43 struct fix_type_impl<char>
44 {
45 using type = i8;
46 };
47
48 template <>
49 struct fix_type_impl<unsigned long>
50 {
51 #if ULONG_MAX == ULLONG_MAX
52 using type = u64;
53 #else
54 using type = u32;
55 #endif
56 };
57
58 template <>
59 struct fix_type_impl<signed long>
60 {
61 #if LONG_MAX == LLONG_MAX
62 using type = i64;
63 #else
64 using type = i32;
65 #endif
66 };
67
68 template <>
69 struct fix_type_impl<unsigned long long>
70 {
71 using type = u64;
72 };
73
74 template <>
75 struct fix_type_impl<signed long long>
76 {
77 using type = i64;
78 };
79
80 } // namespace details
81
82 template <typename T>
83 using fix_type = typename details::fix_type_impl<T>::type;
84
85 /// @brief An enumeration representing data type
86 enum class datatype : int
87 {
88 typebits_mask = 0xFF,
89 f = 0x100, // floating point
90 i = 0x200, // signed integer
91 u = 0x300, // unsigned integer
92 c = 0x400, // complex floating point
93 b = 0x500, // boolean
94 typeclass_mask = 0xF00,
95 f16 = static_cast<int>(f) | 16,
96 f32 = static_cast<int>(f) | 32,
97 f64 = static_cast<int>(f) | 64,
98 f80 = static_cast<int>(f) | 80,
99 i8 = static_cast<int>(i) | 8,
100 i16 = static_cast<int>(i) | 16,
101 i24 = static_cast<int>(i) | 24,
102 i32 = static_cast<int>(i) | 32,
103 i64 = static_cast<int>(i) | 64,
104 u8 = static_cast<int>(u) | 8,
105 u16 = static_cast<int>(u) | 16,
106 u24 = static_cast<int>(u) | 24,
107 u32 = static_cast<int>(u) | 32,
108 u64 = static_cast<int>(u) | 64,
109 c32 = static_cast<int>(c) | 32,
110 c64 = static_cast<int>(c) | 64,
111 b8 = static_cast<int>(b) | 8
112 };
113
operator |(datatype x,datatype y)114 constexpr inline datatype operator|(datatype x, datatype y)
115 {
116 using type = underlying_type<datatype>;
117 return static_cast<datatype>(static_cast<type>(x) | static_cast<type>(y));
118 }
119
operator &(datatype x,datatype y)120 constexpr inline datatype operator&(datatype x, datatype y)
121 {
122 using type = underlying_type<datatype>;
123 return static_cast<datatype>(static_cast<type>(x) & static_cast<type>(y));
124 }
125
126 template <typename T>
127 constexpr inline datatype typeclass = is_floating_point<typename compound_type_traits<T>::subtype>
128 ? datatype::f
129 : is_integral<typename compound_type_traits<T>::subtype>
130 ? (is_unsigned<typename compound_type_traits<T>::subtype>
131 ? datatype::u
132 : datatype::i)
133 : datatype();
134
135 template <typename T>
136 constexpr inline bool is_f_class = typeclass<T> == datatype::f;
137 template <typename T>
138 constexpr inline bool is_u_class = typeclass<T> == datatype::u;
139 template <typename T>
140 constexpr inline bool is_i_class = typeclass<T> == datatype::i;
141
142 template <typename T>
143 struct typebits
144 {
145 constexpr static size_t bits = sizeof(typename compound_type_traits<T>::subtype) * 8;
146 constexpr static size_t width = compound_type_traits<T>::is_scalar ? 0 : compound_type_traits<T>::width;
147 using subtype = typename compound_type_traits<T>::subtype;
148 };
149
150 template <typename T>
151 using ftype =
152 typename compound_type_traits<T>::template deep_rebind<float_type<typebits<deep_subtype<T>>::bits>>;
153 template <typename T>
154 using itype =
155 typename compound_type_traits<T>::template deep_rebind<int_type<typebits<deep_subtype<T>>::bits>>;
156 template <typename T>
157 using utype =
158 typename compound_type_traits<T>::template deep_rebind<unsigned_type<typebits<deep_subtype<T>>::bits>>;
159
160 template <typename T>
161 using uitype = conditional<is_i_class<deep_subtype<T>>, T, utype<T>>;
162
163 template <typename T>
164 using fsubtype = ftype<subtype<T>>;
165 template <typename T>
166 using isubtype = itype<subtype<T>>;
167 template <typename T>
168 using usubtype = utype<subtype<T>>;
169 namespace details
170 {
171 template <typename T>
172 struct flt_type_impl
173 {
174 using type = conditional<sizeof(T) <= 2, float, fbase>;
175 };
176
177 template <>
178 struct flt_type_impl<float>
179 {
180 using type = float;
181 };
182 template <>
183 struct flt_type_impl<double>
184 {
185 using type = double;
186 };
187 } // namespace details
188
189 template <typename T>
190 using flt_type = typename cometa::compound_type_traits<T>::template deep_rebind<
191 typename details::flt_type_impl<deep_subtype<T>>::type>;
192
193 } // namespace cometa
194