23 #include "openPMD/auxiliary/TypeTraits.hpp"
24 #include "openPMD/auxiliary/UniquePtr.hpp"
28 #include "openPMD/DatatypeMacros.hpp"
40 #include <type_traits>
109 template <
typename Arg,
typename... Args>
110 using variant_tail_t = std::variant<Args...>;
113 #define OPENPMD_ENUMERATE_TYPES(type) , type
115 using dataset_types =
116 detail::variant_tail_t<
detail::bottom OPENPMD_FOREACH_DATASET_DATATYPE(
117 OPENPMD_ENUMERATE_TYPES)>;
119 using non_vector_types =
120 detail::variant_tail_t<
detail::bottom OPENPMD_FOREACH_NONVECTOR_DATATYPE(
121 OPENPMD_ENUMERATE_TYPES)>;
123 using attribute_types =
125 OPENPMD_ENUMERATE_TYPES)>;
127 #undef OPENPMD_ENUMERATE_TYPES
138 template <
typename T,
typename U>
141 typename std::remove_pointer<typename std::remove_cv<
142 typename std::decay<typename std::remove_all_extents<T>::type>::
144 typename std::remove_pointer<typename std::remove_cv<
145 typename std::decay<typename std::remove_all_extents<U>::type>::
146 type>::type>::type>::type
149 template <
typename T,
typename U>
152 template <
typename T>
153 inline constexpr
Datatype determineDatatype()
160 else if (decay_equiv<T, unsigned char>::value)
164 else if (decay_equiv<T, signed char>::value)
168 else if (decay_equiv<T, short>::value)
172 else if (decay_equiv<T, int>::value)
176 else if (decay_equiv<T, long>::value)
180 else if (decay_equiv<T, long long>::value)
184 else if (decay_equiv<T, unsigned short>::value)
188 else if (decay_equiv<T, unsigned int>::value)
192 else if (decay_equiv<T, unsigned long>::value)
196 else if (decay_equiv<T, unsigned long long>::value)
198 return DT::ULONGLONG;
200 else if (decay_equiv<T, float>::value)
204 else if (decay_equiv<T, double>::value)
208 else if (decay_equiv<T, long double>::value)
210 return DT::LONG_DOUBLE;
212 else if (decay_equiv<T, std::complex<float>>::value)
216 else if (decay_equiv<T, std::complex<double>>::value)
220 else if (decay_equiv<T, std::complex<long double>>::value)
222 return DT::CLONG_DOUBLE;
224 else if (decay_equiv<T, std::string>::value)
228 else if (decay_equiv<T, std::vector<char>>::value)
232 else if (decay_equiv<T, std::vector<short>>::value)
234 return DT::VEC_SHORT;
236 else if (decay_equiv<T, std::vector<int>>::value)
240 else if (decay_equiv<T, std::vector<long>>::value)
244 else if (decay_equiv<T, std::vector<long long>>::value)
246 return DT::VEC_LONGLONG;
248 else if (decay_equiv<T, std::vector<unsigned char>>::value)
250 return DT::VEC_UCHAR;
252 else if (decay_equiv<T, std::vector<signed char>>::value)
254 return DT::VEC_SCHAR;
256 else if (decay_equiv<T, std::vector<unsigned short>>::value)
258 return DT::VEC_USHORT;
260 else if (decay_equiv<T, std::vector<unsigned int>>::value)
264 else if (decay_equiv<T, std::vector<unsigned long>>::value)
266 return DT::VEC_ULONG;
268 else if (decay_equiv<T, std::vector<unsigned long long>>::value)
270 return DT::VEC_ULONGLONG;
272 else if (decay_equiv<T, std::vector<float>>::value)
274 return DT::VEC_FLOAT;
276 else if (decay_equiv<T, std::vector<double>>::value)
278 return DT::VEC_DOUBLE;
280 else if (decay_equiv<T, std::vector<long double>>::value)
282 return DT::VEC_LONG_DOUBLE;
284 else if (decay_equiv<T, std::vector<std::complex<float>>>::value)
286 return DT::VEC_CFLOAT;
288 else if (decay_equiv<T, std::vector<std::complex<double>>>::value)
290 return DT::VEC_CDOUBLE;
292 else if (decay_equiv<T, std::vector<std::complex<long double>>>::value)
294 return DT::VEC_CLONG_DOUBLE;
296 else if (decay_equiv<T, std::vector<std::string>>::value)
298 return DT::VEC_STRING;
300 else if (decay_equiv<T, std::array<double, 7>>::value)
302 return DT::ARR_DBL_7;
304 else if (decay_equiv<T, bool>::value)
309 return Datatype::UNDEFINED;
320 template <
typename T>
321 inline constexpr
Datatype determineDatatype(T &&val)
324 using T_stripped = std::remove_cv_t<std::remove_reference_t<T>>;
325 if constexpr (auxiliary::IsPointer_v<T_stripped>)
327 return determineDatatype<auxiliary::IsPointer_t<T_stripped>>();
329 else if constexpr (auxiliary::IsContiguousContainer_v<T_stripped>)
331 static_assert(auxiliary::dependent_false_v<T_stripped>, R
"(
332 Error: Passed a contiguous container type to determineDatatype<>().
333 These types are not directly supported due to colliding semantics.
334 Assuming a vector object `std::vector<float> vec;`,
335 use one of the following alternatives:
337 1) If what you want is a direct openPMD::Datatype equivalent
338 of the container type, use:
339 `determineDatatype<decltype(vec)>()`
341 `determineDatatype<std::vector<float>>()`.
342 The result will be `Datatype::VECTOR_FLOAT`.
343 2) If what you want is the openPMD::Datatype equivalent of the *contained type*,
344 use the raw pointer overload by:
345 `determineDatatype(vec.data())`
346 The result will be `Datatype::FLOAT`.
347 This is the variant that you likely wish to use if intending to write data
348 from the vector via `storeChunk()`, e.g. `storeChunk(vec, {0}, {10})`.
353 static_assert(auxiliary::dependent_false_v<T_stripped>, R
"(
354 Error: Unknown datatype passed to determineDatatype<>().
355 For a direct translation from C++ type to the openPMD::Datatype enum, use:
356 `auto determineDatatype<T>() -> Datatype`.
358 For detecting the contained datatpye of a pointer type (shared or raw pointer),
359 use this following template (i.e. `auto determineDatatype<T>(T &&) -> Datatype`)
360 which accepts pointer-type parameters (raw, shared or unique).
364 return Datatype::UNDEFINED;
384 return sizeof(
unsigned char);
387 return sizeof(
signed char);
390 return sizeof(short);
398 case DT::VEC_LONGLONG:
399 return sizeof(
long long);
402 return sizeof(
unsigned short);
405 return sizeof(
unsigned int);
408 return sizeof(
unsigned long);
410 case DT::VEC_ULONGLONG:
411 return sizeof(
unsigned long long);
414 return sizeof(float);
418 return sizeof(double);
419 case DT::LONG_DOUBLE:
420 case DT::VEC_LONG_DOUBLE:
421 return sizeof(
long double);
424 return sizeof(float) * 2;
426 case DT::VEC_CDOUBLE:
427 return sizeof(double) * 2;
428 case DT::CLONG_DOUBLE:
429 case DT::VEC_CLONG_DOUBLE:
430 return sizeof(
long double) * 2;
435 throw std::runtime_error(
"toBytes: Invalid datatype!");
464 case DT::VEC_LONGLONG:
469 case DT::VEC_ULONGLONG:
472 case DT::VEC_LONG_DOUBLE:
474 case DT::VEC_CDOUBLE:
475 case DT::VEC_CLONG_DOUBLE:
500 case DT::LONG_DOUBLE:
501 case DT::VEC_LONG_DOUBLE:
525 case DT::VEC_CDOUBLE:
526 case DT::CLONG_DOUBLE:
527 case DT::VEC_CLONG_DOUBLE:
541 template <
typename T>
544 Datatype dtype = determineDatatype<T>();
556 template <
typename T>
559 Datatype dtype = determineDatatype<T>();
585 case DT::VEC_LONGLONG:
586 return std::make_tuple(
true,
true);
594 case DT::VEC_ULONGLONG:
595 return std::make_tuple(
true,
false);
597 return std::make_tuple(
false,
false);
609 template <
typename T>
612 Datatype dtype = determineDatatype<T>();
623 template <
typename T_FP>
627 bool tt_is_fp = isFloatingPoint<T_FP>();
632 if (tt_is_fp && dt_is_fp &&
toBits(d) ==
toBits(determineDatatype<T_FP>()))
645 template <
typename T_CFP>
649 bool tt_is_cfp = isComplexFloatingPoint<T_CFP>();
654 if (tt_is_cfp && dt_is_cfp &&
668 template <
typename T_Int>
672 bool tt_is_int, tt_is_sig;
673 std::tie(tt_is_int, tt_is_sig) = isInteger<T_Int>();
676 bool dt_is_int, dt_is_sig;
677 std::tie(dt_is_int, dt_is_sig) =
isInteger(d);
679 if (tt_is_int && dt_is_int && tt_is_sig == dt_is_sig &&
698 case Datatype::SCHAR:
699 case Datatype::UCHAR:
718 template <
typename T_Char>
730 if (
static_cast<int>(d) ==
static_cast<int>(e))
737 bool d_is_int, d_is_sig;
738 std::tie(d_is_int, d_is_sig) =
isInteger(d);
739 bool e_is_int, e_is_sig;
740 std::tie(e_is_int, e_is_sig) =
isInteger(e);
741 if (d_is_int && e_is_int && d_is_vec == e_is_vec && d_is_sig == e_is_sig &&
749 if (d_is_fp && e_is_fp && d_is_vec == e_is_vec &&
toBits(d) ==
toBits(e))
756 if (d_is_cfp && e_is_cfp && d_is_vec == e_is_vec &&
toBits(d) ==
toBits(e))
772 std::string datatypeToString(
Datatype dt);
774 Datatype stringToDatatype(
const std::string &s);
776 void warnWrongDtype(std::string
const &key,
Datatype store,
Datatype request);
794 template <
typename Action,
typename... Args>
796 -> decltype(Action::template call<char>(std::forward<Args>(args)...));
813 template <
typename Action,
typename... Args>
815 -> decltype(Action::template call<char>(std::forward<Args>(args)...));
832 template <
typename Action,
typename... Args>
834 -> decltype(Action::template call<char>(std::forward<Args>(args)...));
838 #if !defined(_MSC_VER)
864 #include "openPMD/Datatype.tpp"
865 #include "openPMD/UndefDatatypeMacros.hpp"
Public definitions of openPMD-api.
Definition: Date.cpp:29
bool isVector(Datatype d)
Compare if a Datatype is a vector type.
Definition: Datatype.hpp:454
constexpr bool isSameChar(Datatype d)
Determines if d and T_Char are char types of same representation.
bool isSameFloatingPoint(Datatype d)
Compare if a Datatype is equivalent to a floating point type.
Definition: Datatype.hpp:624
bool isSameComplexFloatingPoint(Datatype d)
Compare if a Datatype is equivalent to a complex floating point type.
Definition: Datatype.hpp:646
size_t toBits(Datatype d)
Return number of bits representing a Datatype.
Definition: Datatype.hpp:444
bool isComplexFloatingPoint(Datatype d)
Compare if a Datatype is a complex floating point type.
Definition: Datatype.hpp:516
constexpr bool isChar(Datatype d)
Determines if d represents a char type.
Definition: Datatype.hpp:693
std::vector< Datatype > openPMD_Datatypes()
All openPMD datatypes defined in Datatype, listed in order in a vector.
Definition: Datatype.cpp:227
bool isFloatingPoint(Datatype d)
Compare if a Datatype is a floating point type.
Definition: Datatype.hpp:490
std::tuple< bool, bool > isInteger(Datatype d)
Compare if a Datatype is an integer type.
Definition: Datatype.hpp:572
bool isSame(openPMD::Datatype const d, openPMD::Datatype const e)
Comparison for two Datatypes.
Definition: Datatype.hpp:727
size_t toBytes(Datatype d)
Return number of bytes representing a Datatype.
Definition: Datatype.hpp:372
bool isSameInteger(Datatype d)
Compare if a Datatype is equivalent to an integer type.
Definition: Datatype.hpp:669
Datatype
Concrete datatype of an object available at runtime.
Definition: Datatype.hpp:51
constexpr auto switchType(Datatype dt, Args &&...args) -> decltype(Action::template call< char >(std::forward< Args >(args)...))
Generalizes switching over an openPMD datatype.
constexpr auto switchNonVectorType(Datatype dt, Args &&...args) -> decltype(Action::template call< char >(std::forward< Args >(args)...))
Generalizes switching over an openPMD datatype.
Datatype basicDatatype(Datatype dt)
basicDatatype Strip openPMD Datatype of std::vector, std::array et.
Definition: Datatype.cpp:289
constexpr auto switchDatasetType(Datatype dt, Args &&...args) -> decltype(Action::template call< char >(std::forward< Args >(args)...))
Generalizes switching over an openPMD datatype.
Fundamental equivalence check for two given types T and U.
Definition: Datatype.hpp:147
Definition: Datatype.hpp:105