From 44d007559c0f4b3427fc07e6e002865b55e9afd9 Mon Sep 17 00:00:00 2001
From: Chuck Atkins <chuck.atkins@kitware.com>
Date: Thu, 13 Apr 2017 11:07:10 -0400
Subject: [PATCH] Add type traits to map C type info to fixed width types.

The type traits will be useful for maping ambiguous C types to fixed
width integer types used for the actual I/O operations, for instance:

  adios::TypeInfo<char>::IOType resolves to int8_t
  adios::TypeInfo<signed char>::IOType resolves to int8_t
  adios::TypeInfo<unsigned signed char>::IOType resolves to uint8_t
  adios::TypeInfo<long int>::IOType resolves to int64_t
  adios::TypeInfo<long long int>::IOType resolves to int64_t

So in this case, even though char and signed char are "the same", they
are distinctly separate types to the compiler.  Using
adios::TyperInfo<T>::IOType you can use the same fundamental type for all
of them.  Similarly for long int and long long int.
---
 include/ADIOSTypes.h | 71 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)

diff --git a/include/ADIOSTypes.h b/include/ADIOSTypes.h
index 878d4b76b..fa0efcb73 100644
--- a/include/ADIOSTypes.h
+++ b/include/ADIOSTypes.h
@@ -14,6 +14,7 @@
 #include <complex>
 #include <cstddef>
 #include <cstdint>
+#include <type_traits>
 
 namespace adios
 {
@@ -61,6 +62,76 @@ using real64_t = double;
 using complex32_t = std::complex<real32_t>;
 using complex64_t = std::complex<real64_t>;
 
+// Get a fixed width integer type from a size specification
+template <size_t Bytes, bool Signed>
+struct FixedWidthInt;
+
+template <>
+struct FixedWidthInt<1, true>
+{
+    using Type = std::int8_t;
+};
+template <>
+struct FixedWidthInt<2, true>
+{
+    using Type = std::int16_t;
+};
+template <>
+struct FixedWidthInt<4, true>
+{
+    using Type = std::int32_t;
+};
+template <>
+struct FixedWidthInt<8, true>
+{
+    using Type = std::int64_t;
+};
+template <>
+struct FixedWidthInt<1, false>
+{
+    using Type = std::uint8_t;
+};
+template <>
+struct FixedWidthInt<2, false>
+{
+    using Type = std::uint16_t;
+};
+template <>
+struct FixedWidthInt<4, false>
+{
+    using Type = std::uint32_t;
+};
+template <>
+struct FixedWidthInt<8, false>
+{
+    using Type = std::uint64_t;
+};
+
+// Some core type information that may be useful at compile time
+template <typename T, typename Enable = void>
+struct TypeInfo;
+
+template <typename T>
+struct TypeInfo<T, typename std::enable_if<std::is_integral<T>::value>::type>
+{
+    using IOType =
+        typename FixedWidthInt<sizeof(T), std::is_signed<T>::value>::Type;
+};
+
+template <typename T>
+struct TypeInfo<T,
+                typename std::enable_if<std::is_floating_point<T>::value>::type>
+{
+    using IOType = T;
+};
+
+template <typename T>
+struct TypeInfo<T, typename std::enable_if<std::is_same<
+                       T, std::complex<typename T::value_type>>::value>::type>
+{
+    using IOType = T;
+};
+
 } // end namespace adios
 
 #endif /* ADIOS_TYPES_H_ */
-- 
GitLab