diff --git a/include/utilities/format/bp1/BP1Writer.h b/include/utilities/format/bp1/BP1Writer.h
index a551114ad7a117257c64656a331703d722c19311..e293077713319b5d182aec28afd3a0a18c9933a7 100644
--- a/include/utilities/format/bp1/BP1Writer.h
+++ b/include/utilities/format/bp1/BP1Writer.h
@@ -18,6 +18,7 @@
 /// \endcond
 
 #include "ADIOSMacros.h"
+#include "ADIOSTypes.h"
 #include "utilities/format/bp1/BP1Base.h"
 #include "utilities/format/bp1/BP1Structs.h"
 
@@ -83,7 +84,7 @@ public:
         noexcept;
 
     /**
-     * Version for primitive types (except std::complex<T>)
+     * Write metadata for a given variable
      * @param variable
      * @param heap
      * @param metadataSet
@@ -93,17 +94,6 @@ public:
                                capsule::STLVector &heap,
                                BP1MetadataSet &metadataSet) const noexcept;
 
-    /**
-     * Overloaded version for std::complex<T> variables
-     * @param variable
-     * @param heap
-     * @param metadataSet
-     */
-    template <class T>
-    void WriteVariableMetadata(const Variable<std::complex<T>> &variable,
-                               capsule::STLVector &heap,
-                               BP1MetadataSet &metadataSet) const noexcept;
-
     /**
      * Expensive part this is only for heap buffers need to adapt to vector of
      * capsules
@@ -150,36 +140,23 @@ public:
         noexcept;
 
 private:
-    /**
-     * Common function called from WriterVariableMetadata for primitive and
-     * complex types
-     * @param variable
-     * @param stats
-     * @param heap
-     * @param metadataSet
-     */
-    template <class T, class U>
-    void WriteVariableMetadataCommon(const Variable<T> &variable,
-                                     Stats<U> &stats, capsule::STLVector &heap,
-                                     BP1MetadataSet &metadataSet) const
-        noexcept;
-
-    template <class T, class U>
-    void WriteVariableMetadataInData(const Variable<T> &variable,
-                                     const Stats<U> &stats,
-                                     capsule::STLVector &heap) const noexcept;
+    template <class T>
+    void WriteVariableMetadataInData(
+        const Variable<T> &variable,
+        const Stats<typename TypeInfo<T>::ValueType> &stats,
+        capsule::STLVector &heap) const noexcept;
 
-    template <class T, class U>
-    void WriteVariableMetadataInIndex(const Variable<T> &variable,
-                                      const Stats<U> &stats, const bool isNew,
-                                      BP1Index &index) const noexcept;
+    template <class T>
+    void WriteVariableMetadataInIndex(
+        const Variable<T> &variable,
+        const Stats<typename TypeInfo<T>::ValueType> &stats, const bool isNew,
+        BP1Index &index) const noexcept;
 
-    template <class T, class U>
-    void WriteVariableCharacteristics(const Variable<T> &variable,
-                                      const Stats<U> &stats,
-                                      std::vector<char> &buffer,
-                                      const bool addLength = false) const
-        noexcept;
+    template <class T>
+    void WriteVariableCharacteristics(
+        const Variable<T> &variable,
+        const Stats<typename TypeInfo<T>::ValueType> &stats,
+        std::vector<char> &buffer, const bool addLength = false) const noexcept;
 
     /**
      * Writes from &buffer[position]:  [2
@@ -212,20 +189,13 @@ private:
                                const bool addType = false) const noexcept;
 
     /**
-     * GetStats for primitive types except std::complex<T> types
-     * @param variable
-     * @return stats
-     */
-    template <class T>
-    Stats<T> GetStats(const Variable<T> &variable) const noexcept;
-
-    /**
-     * GetStats for std::complex<T> types
+     * Get variable statistics
      * @param variable
      * @return stats
      */
     template <class T>
-    Stats<T> GetStats(const Variable<std::complex<T>> &variable) const noexcept;
+    Stats<typename TypeInfo<T>::ValueType>
+    GetStats(const Variable<T> &variable) const noexcept;
 
     template <class T>
     void WriteBoundsRecord(const bool isScalar, const Stats<T> &stats,
@@ -282,28 +252,13 @@ private:
 #define declare_template_instantiation(T)                                      \
     extern template void BP1Writer::WriteVariablePayload(                      \
         const Variable<T> &variable, capsule::STLVector &heap,                 \
-        const unsigned int nthreads) const noexcept;
-
-ADIOS_FOREACH_TYPE_1ARG(declare_template_instantiation)
-#undef declare_template_instantiation
-
-// SEPARATE PRIMITIVE FROM COMPLEX OVERLOADS
-// PRIMITIVE
-#define declare_template_instantiation(T)                                      \
+        const unsigned int nthreads) const noexcept;                           \
+                                                                               \
     extern template void BP1Writer::WriteVariableMetadata(                     \
         const Variable<T> &variable, capsule::STLVector &heap,                 \
         BP1MetadataSet &metadataSet) const noexcept;
 
-ADIOS_FOREACH_PRIMITIVE_TYPE_1ARG(declare_template_instantiation)
-#undef declare_template_instantiation
-
-// COMPLEX
-#define declare_template_instantiation(T)                                      \
-    extern template void BP1Writer::WriteVariableMetadata(                     \
-        const Variable<std::complex<T>> &variable, capsule::STLVector &heap,   \
-        BP1MetadataSet &metadataSet) const noexcept;
-
-ADIOS_FOREACH_COMPLEX_TYPE_1ARG(declare_template_instantiation)
+ADIOS_FOREACH_TYPE_1ARG(declare_template_instantiation)
 #undef declare_template_instantiation
 
 } // end namespace format
diff --git a/source/utilities/format/bp1/BP1Writer.cpp b/source/utilities/format/bp1/BP1Writer.cpp
index 1233cf2752c686a8686ab035ac92684264388f02..69145b946d6476e7d71917f08c574d9c0e21f013 100644
--- a/source/utilities/format/bp1/BP1Writer.cpp
+++ b/source/utilities/format/bp1/BP1Writer.cpp
@@ -424,28 +424,13 @@ void BP1Writer::FlattenMetadata(BP1MetadataSet &metadataSet,
 #define declare_template_instantiation(T)                                      \
     template void BP1Writer::WriteVariablePayload(                             \
         const Variable<T> &variable, capsule::STLVector &heap,                 \
-        const unsigned int nthreads) const noexcept;
-
-ADIOS_FOREACH_TYPE_1ARG(declare_template_instantiation)
-#undef declare_template_instantiation
-
-// SEPARATE PRIMITIVE FROM COMPLEX OVERLOADS
-// PRIMITIVE
-#define declare_template_instantiation(T)                                      \
+        const unsigned int nthreads) const noexcept;                           \
+                                                                               \
     template void BP1Writer::WriteVariableMetadata(                            \
         const Variable<T> &variable, capsule::STLVector &heap,                 \
         BP1MetadataSet &metadataSet) const noexcept;
 
-ADIOS_FOREACH_PRIMITIVE_TYPE_1ARG(declare_template_instantiation)
-#undef declare_template_instantiation
-
-// COMPLEX
-#define declare_template_instantiation(T)                                      \
-    template void BP1Writer::WriteVariableMetadata(                            \
-        const Variable<std::complex<T>> &variable, capsule::STLVector &heap,   \
-        BP1MetadataSet &metadataSet) const noexcept;
-
-ADIOS_FOREACH_COMPLEX_TYPE_1ARG(declare_template_instantiation)
+ADIOS_FOREACH_TYPE_1ARG(declare_template_instantiation)
 #undef declare_template_instantiation
 
 //------------------------------------------------------------------------------
diff --git a/source/utilities/format/bp1/BP1Writer.tcc b/source/utilities/format/bp1/BP1Writer.tcc
index a554b0314590bfa29d3b8006ded75e7f5fc4956a..d516af9dcf52abaf3229d9cfce9a06c9201cf8c5 100644
--- a/source/utilities/format/bp1/BP1Writer.tcc
+++ b/source/utilities/format/bp1/BP1Writer.tcc
@@ -62,18 +62,24 @@ void BP1Writer::WriteVariableMetadata(const Variable<T> &variable,
                                       BP1MetadataSet &metadataSet) const
     noexcept
 {
-    Stats<T> stats = GetStats(variable);
-    WriteVariableMetadataCommon(variable, stats, heap, metadataSet);
-}
+    Stats<typename TypeInfo<T>::ValueType> stats = GetStats(variable);
 
-template <class T>
-void BP1Writer::WriteVariableMetadata(const Variable<std::complex<T>> &variable,
-                                      capsule::STLVector &heap,
-                                      BP1MetadataSet &metadataSet) const
-    noexcept
-{
-    Stats<T> stats = GetStats(variable);
-    WriteVariableMetadataCommon(variable, stats, heap, metadataSet);
+    stats.TimeIndex = metadataSet.TimeStep;
+    // Get new Index or point to existing index
+    bool isNew = true; // flag to check if variable is new
+    BP1Index &varIndex =
+        GetBP1Index(variable.m_Name, metadataSet.VarsIndices, isNew);
+    stats.MemberID = varIndex.MemberID;
+
+    // write metadata header in data and extract offsets
+    stats.Offset = heap.m_DataAbsolutePosition;
+    WriteVariableMetadataInData(variable, stats, heap);
+    stats.PayloadOffset = heap.m_DataAbsolutePosition;
+
+    // write to metadata  index
+    WriteVariableMetadataInIndex(variable, stats, isNew, varIndex);
+
+    ++metadataSet.DataPGVarsCount;
 }
 
 template <class T>
@@ -88,10 +94,10 @@ void BP1Writer::WriteVariablePayload(const Variable<T> &variable,
 
 // PRIVATE
 template <class T>
-BP1Writer::Stats<T> BP1Writer::GetStats(const Variable<T> &variable) const
-    noexcept
+BP1Writer::Stats<typename TypeInfo<T>::ValueType>
+BP1Writer::GetStats(const Variable<T> &variable) const noexcept
 {
-    Stats<T> stats;
+    Stats<typename TypeInfo<T>::ValueType> stats;
     const std::size_t valuesSize = variable.TotalSize();
 
     if (m_Verbosity == 0)
@@ -107,30 +113,6 @@ BP1Writer::Stats<T> BP1Writer::GetStats(const Variable<T> &variable) const
     return stats;
 }
 
-template <class T>
-BP1Writer::Stats<T>
-BP1Writer::GetStats(const Variable<std::complex<T>> &variable) const noexcept
-{
-    Stats<T> stats;
-    const std::size_t valuesSize = variable.TotalSize();
-
-    if (m_Verbosity == 0)
-    {
-        // ten million? this needs actual results
-        // to make decisions for threads usage
-        if (valuesSize >= 10000000)
-        {
-            GetMinMax(variable.m_AppValues, valuesSize, stats.Min, stats.Max,
-                      m_Threads);
-        }
-        else
-        {
-            GetMinMax(variable.m_AppValues, valuesSize, stats.Min, stats.Max);
-        }
-    }
-    return stats;
-}
-
 template <class T>
 void BP1Writer::WriteBoundsRecord(const bool isScalar, const Stats<T> &stats,
                                   std::vector<char> &buffer,
@@ -174,36 +156,11 @@ void BP1Writer::WriteCharacteristicRecord(const std::uint8_t characteristicID,
     ++characteristicsCounter;
 }
 
-template <class T, class U>
-void BP1Writer::WriteVariableMetadataCommon(const Variable<T> &variable,
-                                            Stats<U> &stats,
-                                            capsule::STLVector &heap,
-                                            BP1MetadataSet &metadataSet) const
-    noexcept
-{
-    stats.TimeIndex = metadataSet.TimeStep;
-    // Get new Index or point to existing index
-    bool isNew = true; // flag to check if variable is new
-    BP1Index &varIndex =
-        GetBP1Index(variable.m_Name, metadataSet.VarsIndices, isNew);
-    stats.MemberID = varIndex.MemberID;
-
-    // write metadata header in data and extract offsets
-    stats.Offset = heap.m_DataAbsolutePosition;
-    WriteVariableMetadataInData(variable, stats, heap);
-    stats.PayloadOffset = heap.m_DataAbsolutePosition;
-
-    // write to metadata  index
-    WriteVariableMetadataInIndex(variable, stats, isNew, varIndex);
-
-    ++metadataSet.DataPGVarsCount;
-}
-
-template <class T, class U>
-void BP1Writer::WriteVariableMetadataInData(const Variable<T> &variable,
-                                            const Stats<U> &stats,
-                                            capsule::STLVector &heap) const
-    noexcept
+template <class T>
+void BP1Writer::WriteVariableMetadataInData(
+    const Variable<T> &variable,
+    const Stats<typename TypeInfo<T>::ValueType> &stats,
+    capsule::STLVector &heap) const noexcept
 {
     auto &buffer = heap.m_Data;
 
@@ -246,11 +203,11 @@ void BP1Writer::WriteVariableMetadataInData(const Variable<T> &variable,
                                            // used as payload position
 }
 
-template <class T, class U>
-void BP1Writer::WriteVariableMetadataInIndex(const Variable<T> &variable,
-                                             const Stats<U> &stats,
-                                             const bool isNew,
-                                             BP1Index &index) const noexcept
+template <class T>
+void BP1Writer::WriteVariableMetadataInIndex(
+    const Variable<T> &variable,
+    const Stats<typename TypeInfo<T>::ValueType> &stats, const bool isNew,
+    BP1Index &index) const noexcept
 {
     auto &buffer = index.Buffer;
 
@@ -282,12 +239,11 @@ void BP1Writer::WriteVariableMetadataInIndex(const Variable<T> &variable,
     WriteVariableCharacteristics(variable, stats, buffer);
 }
 
-template <class T, class U>
-void BP1Writer::WriteVariableCharacteristics(const Variable<T> &variable,
-                                             const Stats<U> &stats,
-                                             std::vector<char> &buffer,
-                                             const bool addLength) const
-    noexcept
+template <class T>
+void BP1Writer::WriteVariableCharacteristics(
+    const Variable<T> &variable,
+    const Stats<typename TypeInfo<T>::ValueType> &stats,
+    std::vector<char> &buffer, const bool addLength) const noexcept
 {
     const std::size_t characteristicsCountPosition =
         buffer.size(); // very important to track as writer is going back to