9 #ifndef LLU_UTILITIES_HPP
10 #define LLU_UTILITIES_HPP
14 #include <type_traits>
34 template<
typename A,
typename B>
35 using disable_if_same_or_derived =
typename std::enable_if_t<!std::is_same<A, B>::value && !std::is_base_of<A, remove_cv_ref<B>>::value>;
42 template<
typename A,
typename B>
43 using enable_if_same_or_derived =
typename std::enable_if_t<std::is_same<A, B>::value || std::is_base_of<A, remove_cv_ref<B>>::value>;
49 template<
typename Iterator>
56 template<
typename Container>
57 using enable_if_integral_elements =
typename std::enable_if_t<std::is_integral<typename std::remove_reference_t<Container>::value_type>::value>;
59 template<
typename Container,
typename = std::
void_t<>>
60 struct has_value_type : std::false_type {};
62 template<
typename Container>
63 struct has_value_type<Container, std::void_t<typename Container::value_type>> : std::true_type {};
65 template<
typename Container,
typename T>
66 struct has_matching_type : std::is_same<typename Container::value_type, T> {};
68 template<
typename Container,
typename = std::
void_t<>>
69 struct has_size : std::false_type {};
71 template<
typename Container>
72 struct has_size<Container, std::void_t<decltype(std::declval<Container>().size())>> : std::true_type {};
75 template<
typename Container>
76 inline constexpr
bool has_size_v = has_size<Container>::value;
78 template<
typename Container,
typename = std::
void_t<>>
79 struct is_iterable : std::false_type {};
81 template<
typename Container>
82 struct is_iterable<Container, std::void_t<decltype(*std::begin(std::declval<Container>())), decltype(std::end(std::declval<Container>()))>>
86 template<
typename Container,
typename T>
88 std::conjunction<std::is_class<Container>, has_value_type<Container>, is_iterable<Container>, has_matching_type<Container, T>>::value;
98 template<
typename VariantType,
typename T, std::
size_t index = 0>
101 if constexpr (index >= std::variant_size_v<VariantType>) {
103 }
else if (std::is_same_v<std::variant_alternative_t<index, VariantType>, T>) {
106 return variant_index<VariantType, T, index + 1>();
114 template<
typename... Ts>
132 template<numericarray_data_t>
138 using type = std::int8_t;
139 static constexpr
const char* typeName =
"Integer8";
143 using type = std::uint8_t;
144 static constexpr
const char* typeName =
"UnsignedInteger8";
147 struct NumericArrayFromEnum<MNumericArray_Type_Bit16> {
148 using type = std::int16_t;
149 static constexpr
const char* typeName =
"Integer16";
152 struct NumericArrayFromEnum<MNumericArray_Type_UBit16> {
153 using type = std::uint16_t;
154 static constexpr
const char* typeName =
"UnsignedInteger16";
157 struct NumericArrayFromEnum<MNumericArray_Type_Bit32> {
158 using type = std::int32_t;
159 static constexpr
const char* typeName =
"Integer32";
162 struct NumericArrayFromEnum<MNumericArray_Type_UBit32> {
163 using type = std::uint32_t;
164 static constexpr
const char* typeName =
"UnsignedInteger32";
167 struct NumericArrayFromEnum<MNumericArray_Type_Bit64> {
168 using type = std::int64_t;
169 static constexpr
const char* typeName =
"Integer64";
172 struct NumericArrayFromEnum<MNumericArray_Type_UBit64> {
173 using type = std::uint64_t;
174 static constexpr
const char* typeName =
"UnsignedInteger64";
177 struct NumericArrayFromEnum<MNumericArray_Type_Real32> {
179 static constexpr
const char* typeName =
"Real32";
182 struct NumericArrayFromEnum<MNumericArray_Type_Real64> {
184 static constexpr
const char* typeName =
"Real64";
187 struct NumericArrayFromEnum<MNumericArray_Type_Complex_Real32> {
188 using type = std::complex<float>;
189 static constexpr
const char* typeName =
"ComplexReal32";
192 struct NumericArrayFromEnum<MNumericArray_Type_Complex_Real64> {
193 using type = std::complex<double>;
194 static constexpr
const char* typeName =
"ComplexReal64";
199 template<numericarray_data_t rat>
208 Check = MNumericArray_Convert_Check,
209 ClipCheck = MNumericArray_Convert_Clip_Check,
210 Coerce = MNumericArray_Convert_Coerce,
211 ClipCoerce = MNumericArray_Convert_Clip_Coerce,
212 Round = MNumericArray_Convert_Round,
213 ClipRound = MNumericArray_Convert_Clip_Round,
214 Scale = MNumericArray_Convert_Scale,
215 ClipScale = MNumericArray_Convert_Clip_Scale,
225 case MNumericArray_Type_Undef:
return "Undefined";
249 inline constexpr imagedata_t
ImageType = MImage_Type_Undef;
252 inline constexpr imagedata_t ImageType<int8_t> = MImage_Type_Bit;
254 inline constexpr imagedata_t ImageType<uint8_t> = MImage_Type_Bit8;
256 inline constexpr imagedata_t ImageType<uint16_t> = MImage_Type_Bit16;
258 inline constexpr imagedata_t ImageType<float> = MImage_Type_Real32;
260 inline constexpr imagedata_t ImageType<double> = MImage_Type_Real;
268 inline constexpr numericarray_data_t NumericArrayType<int8_t> = MNumericArray_Type_Bit8;
270 inline constexpr numericarray_data_t NumericArrayType<uint8_t> = MNumericArray_Type_UBit8;
272 inline constexpr numericarray_data_t NumericArrayType<int16_t> = MNumericArray_Type_Bit16;
274 inline constexpr numericarray_data_t NumericArrayType<uint16_t> = MNumericArray_Type_UBit16;
276 inline constexpr numericarray_data_t NumericArrayType<int32_t> = MNumericArray_Type_Bit32;
278 inline constexpr numericarray_data_t NumericArrayType<uint32_t> = MNumericArray_Type_UBit32;
280 inline constexpr numericarray_data_t NumericArrayType<int64_t> = MNumericArray_Type_Bit64;
282 inline constexpr numericarray_data_t NumericArrayType<uint64_t> = MNumericArray_Type_UBit64;
284 inline constexpr numericarray_data_t NumericArrayType<float> = MNumericArray_Type_Real32;
286 inline constexpr numericarray_data_t NumericArrayType<double> = MNumericArray_Type_Real64;
288 inline constexpr numericarray_data_t NumericArrayType<std::complex<float>> = MNumericArray_Type_Complex_Real32;
290 inline constexpr numericarray_data_t NumericArrayType<std::complex<double>> = MNumericArray_Type_Complex_Real64;
298 inline constexpr mint TensorType<mint> = MType_Integer;
300 inline constexpr mint TensorType<double> = MType_Real;
302 inline constexpr mint TensorType<std::complex<double>> = MType_Complex;
307 #endif // LLU_UTILITIES_HPP