23 #include "openPMD/auxiliary/TypeTraits.hpp" 24 #include "openPMD/auxiliary/UniquePtr.hpp" 36 #include <type_traits> 106 template <
typename T,
typename U>
109 typename std::remove_pointer<typename std::remove_cv<
110 typename std::decay<typename std::remove_all_extents<T>::type>::
112 typename std::remove_pointer<typename std::remove_cv<
113 typename std::decay<typename std::remove_all_extents<U>::type>::
114 type>::type>::type>::type
117 template <
typename T,
typename U>
120 template <
typename T>
121 inline constexpr
Datatype determineDatatype()
166 return DT::ULONGLONG;
178 return DT::LONG_DOUBLE;
188 else if (
decay_equiv<
T, std::complex<long double>>::value)
190 return DT::CLONG_DOUBLE;
202 return DT::VEC_SHORT;
214 return DT::VEC_LONGLONG;
216 else if (
decay_equiv<
T, std::vector<unsigned char>>::value)
218 return DT::VEC_UCHAR;
220 else if (
decay_equiv<
T, std::vector<signed char>>::value)
222 return DT::VEC_SCHAR;
224 else if (
decay_equiv<
T, std::vector<unsigned short>>::value)
226 return DT::VEC_USHORT;
228 else if (
decay_equiv<
T, std::vector<unsigned int>>::value)
232 else if (
decay_equiv<
T, std::vector<unsigned long>>::value)
234 return DT::VEC_ULONG;
236 else if (
decay_equiv<
T, std::vector<unsigned long long>>::value)
238 return DT::VEC_ULONGLONG;
242 return DT::VEC_FLOAT;
246 return DT::VEC_DOUBLE;
248 else if (
decay_equiv<
T, std::vector<long double>>::value)
250 return DT::VEC_LONG_DOUBLE;
252 else if (
decay_equiv<
T, std::vector<std::complex<float>>>::value)
254 return DT::VEC_CFLOAT;
256 else if (
decay_equiv<
T, std::vector<std::complex<double>>>::value)
258 return DT::VEC_CDOUBLE;
260 else if (
decay_equiv<
T, std::vector<std::complex<long double>>>::value)
262 return DT::VEC_CLONG_DOUBLE;
264 else if (
decay_equiv<
T, std::vector<std::string>>::value)
266 return DT::VEC_STRING;
270 return DT::ARR_DBL_7;
277 return Datatype::UNDEFINED;
288 template <
typename T>
292 using T_stripped = std::remove_cv_t<std::remove_reference_t<T>>;
293 if constexpr (auxiliary::IsPointer_v<T_stripped>)
295 return determineDatatype<auxiliary::IsPointer_t<T_stripped>>();
297 else if constexpr (auxiliary::IsContiguousContainer_v<T_stripped>)
299 static_assert(auxiliary::dependent_false_v<T_stripped>, R
"( 300 Error: Passed a contiguous container type to determineDatatype<>(). 301 These types are not directly supported due to colliding semantics. 302 Assuming a vector object `std::vector<float> vec;`, 303 use one of the following alternatives: 305 1) If what you want is a direct openPMD::Datatype equivalent 306 of the container type, use: 307 `determineDatatype<decltype(vec)>()` 309 `determineDatatype<std::vector<float>>()`. 310 The result will be `Datatype::VECTOR_FLOAT`. 311 2) If what you want is the openPMD::Datatype equivalent of the *contained type*, 312 use the raw pointer overload by: 313 `determineDatatype(vec.data())` 314 The result will be `Datatype::FLOAT`. 315 This is the variant that you likely wish to use if intending to write data 316 from the vector via `storeChunk()`, e.g. `storeChunk(vec, {0}, {10})`. 321 static_assert(auxiliary::dependent_false_v<T_stripped>, R
"( 322 Error: Unknown datatype passed to determineDatatype<>(). 323 For a direct translation from C++ type to the openPMD::Datatype enum, use: 324 `auto determineDatatype<T>() -> Datatype`. 326 For detecting the contained datatpye of a pointer type (shared or raw pointer), 327 use this following template (i.e. `auto determineDatatype<T>(T &&) -> Datatype`) 328 which accepts pointer-type parameters (raw, shared or unique). 332 return Datatype::UNDEFINED;
352 return sizeof(
unsigned char);
355 return sizeof(
signed char);
358 return sizeof(short);
366 case DT::VEC_LONGLONG:
367 return sizeof(
long long);
370 return sizeof(
unsigned short);
373 return sizeof(
unsigned int);
376 return sizeof(
unsigned long);
378 case DT::VEC_ULONGLONG:
379 return sizeof(
unsigned long long);
382 return sizeof(float);
386 return sizeof(double);
387 case DT::LONG_DOUBLE:
388 case DT::VEC_LONG_DOUBLE:
389 return sizeof(
long double);
392 return sizeof(float) * 2;
394 case DT::VEC_CDOUBLE:
395 return sizeof(double) * 2;
396 case DT::CLONG_DOUBLE:
397 case DT::VEC_CLONG_DOUBLE:
398 return sizeof(
long double) * 2;
403 throw std::runtime_error(
"toBytes: Invalid datatype!");
432 case DT::VEC_LONGLONG:
437 case DT::VEC_ULONGLONG:
440 case DT::VEC_LONG_DOUBLE:
442 case DT::VEC_CDOUBLE:
443 case DT::VEC_CLONG_DOUBLE:
468 case DT::LONG_DOUBLE:
469 case DT::VEC_LONG_DOUBLE:
493 case DT::VEC_CDOUBLE:
494 case DT::CLONG_DOUBLE:
495 case DT::VEC_CLONG_DOUBLE:
509 template <
typename T>
512 Datatype dtype = determineDatatype<T>();
524 template <
typename T>
527 Datatype dtype = determineDatatype<T>();
553 case DT::VEC_LONGLONG:
554 return std::make_tuple(
true,
true);
562 case DT::VEC_ULONGLONG:
563 return std::make_tuple(
true,
false);
565 return std::make_tuple(
false,
false);
577 template <
typename T>
580 Datatype dtype = determineDatatype<T>();
591 template <
typename T_FP>
595 bool tt_is_fp = isFloatingPoint<T_FP>();
600 if (tt_is_fp && dt_is_fp &&
toBits(d) ==
toBits(determineDatatype<T_FP>()))
613 template <
typename T_CFP>
617 bool tt_is_cfp = isComplexFloatingPoint<T_CFP>();
622 if (tt_is_cfp && dt_is_cfp &&
636 template <
typename T_Int>
640 bool tt_is_int, tt_is_sig;
641 std::tie(tt_is_int, tt_is_sig) = isInteger<T_Int>();
644 bool dt_is_int, dt_is_sig;
645 std::tie(dt_is_int, dt_is_sig) =
isInteger(d);
647 if (tt_is_int && dt_is_int && tt_is_sig == dt_is_sig &&
663 if (static_cast<int>(d) == static_cast<int>(e))
670 bool d_is_int, d_is_sig;
671 std::tie(d_is_int, d_is_sig) =
isInteger(d);
672 bool e_is_int, e_is_sig;
673 std::tie(e_is_int, e_is_sig) =
isInteger(e);
674 if (d_is_int && e_is_int && d_is_vec == e_is_vec && d_is_sig == e_is_sig &&
682 if (d_is_fp && e_is_fp && d_is_vec == e_is_vec &&
toBits(d) ==
toBits(e))
689 if (d_is_cfp && e_is_cfp && d_is_vec == e_is_vec &&
toBits(d) ==
toBits(e))
705 std::string datatypeToString(
Datatype dt);
707 Datatype stringToDatatype(std::string s);
709 void warnWrongDtype(std::string
const &key,
Datatype store,
Datatype request);
715 #if !defined(_MSC_VER) bool isVector(Datatype d)
Compare if a Datatype is a vector type.
Definition: Datatype.hpp:422
std::vector< Datatype > openPMD_Datatypes
All openPMD datatypes defined in Datatype, listed in order in a vector.
Definition: Datatype.cpp:227
bool isSameFloatingPoint(Datatype d)
Compare if a Datatype is equivalent to a floating point type.
Definition: Datatype.hpp:592
bool isSameComplexFloatingPoint(Datatype d)
Compare if a Datatype is equivalent to a complex floating point type.
Definition: Datatype.hpp:614
bool isSameInteger(Datatype d)
Compare if a Datatype is equivalent to an integer type.
Definition: Datatype.hpp:637
Fundamental equivalence check for two given types T and U.
Definition: Datatype.hpp:107
bool isComplexFloatingPoint(Datatype d)
Compare if a Datatype is a complex floating point type.
Definition: Datatype.hpp:484
Datatype
Concrete datatype of an object available at runtime.
Definition: Datatype.hpp:45
size_t toBits(Datatype d)
Return number of bits representing a Datatype.
Definition: Datatype.hpp:412
Public definitions of openPMD-api.
Datatype basicDatatype(Datatype dt)
basicDatatype Strip openPMD Datatype of std::vector, std::array et.
Definition: Datatype.cpp:286
size_t toBytes(Datatype d)
Return number of bytes representing a Datatype.
Definition: Datatype.hpp:340
bool isFloatingPoint(Datatype d)
Compare if a Datatype is a floating point type.
Definition: Datatype.hpp:458
std::tuple< bool, bool > isInteger(Datatype d)
Compare if a Datatype is an integer type.
Definition: Datatype.hpp:540
bool isSame(openPMD::Datatype const d, openPMD::Datatype const e)
Comparison for two Datatypes.
Definition: Datatype.hpp:660