/*=========================================================================

  Program:   Visualization Toolkit
  Module:    ADIOSUtilities.h

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#ifndef __ADIOSUtilities_h
#define __ADIOSUtilities_h

#include <stdint.h>

#include <cstddef>

#include <complex>
#include <stdexcept>
#include <string>

#include <adios_types.h>

namespace ADIOS
{

// Description:
// Retrieve and parse error messages generated by the ADIOS write system
class WriteError : public std::runtime_error
{
public:
  WriteError(const std::string& msg = "");
  virtual ~WriteError() throw() { }

  // Description:
  // Test error codes for expected values.  An exception is thrown with the
  // appropriate error message if detected
  template<typename T>
  static void TestEq(const T& expected, const T& actual,
    const std::string& msg = "")
  {
    if(actual != expected)
    {
      throw WriteError(msg);
    }
  }

  // Description:
  // Test error codes for unexpected values.  An exception is thrown with
  // The appropriate error message if detected.
  template<typename T>
  static void TestNe(const T& notExpected, const T& actual,
    const std::string& msg = "")
  {
    if(actual == notExpected)
    {
      throw WriteError(msg);
    }
  }
};

// Description:
// Retrieve and parse error messages generated by the ADIOS read system
class ReadError : public std::runtime_error
{
public:
  ReadError(const std::string& msg = "");
  virtual ~ReadError() throw() { }

  // Description:
  // Test error codes for expected values.  An exception is thrown with the
  // appropriate error message if detected
  template<typename T>
  static void TestEq(const T& expected, const T& actual,
    const std::string& msg = "")
  {
    if(actual != expected)
    {
      throw ReadError(msg);
    }
  }

  // Description:
  // Test error codes for unexpected values.  An exception is thrown with
  // The appropriate error message if detected.
  template<typename T>
  static void TestNe(const T& notExpected, const T& actual,
    const std::string& msg = "")
  {
    if(actual == notExpected)
    {
      throw ReadError(msg);
    }
  }
};

namespace Type
{

// Description:
// Given a size in bytes, return the ADIOS signed integral type
template<size_t S> ADIOS_DATATYPES SizeToInt();
template<> ADIOS_DATATYPES SizeToInt<1>();
template<> ADIOS_DATATYPES SizeToInt<2>();
template<> ADIOS_DATATYPES SizeToInt<4>();
template<> ADIOS_DATATYPES SizeToInt<8>();

// Description:
// Given a size in bytes, return the ADIOS unsigned integral type
template<size_t S> ADIOS_DATATYPES SizeToUInt();
template<> ADIOS_DATATYPES SizeToUInt<1>();
template<> ADIOS_DATATYPES SizeToUInt<2>();
template<> ADIOS_DATATYPES SizeToUInt<4>();
template<> ADIOS_DATATYPES SizeToUInt<8>();

// Description:
// Map C and C++ primitive datatypes into ADIOS datatypes
template<typename TN>
ADIOS_DATATYPES NativeToADIOS();
template<> ADIOS_DATATYPES NativeToADIOS<int8_t>();
template<> ADIOS_DATATYPES NativeToADIOS<int16_t>();
template<> ADIOS_DATATYPES NativeToADIOS<int32_t>();
template<> ADIOS_DATATYPES NativeToADIOS<int64_t>();
template<> ADIOS_DATATYPES NativeToADIOS<uint8_t>();
template<> ADIOS_DATATYPES NativeToADIOS<uint16_t>();
template<> ADIOS_DATATYPES NativeToADIOS<uint32_t>();
template<> ADIOS_DATATYPES NativeToADIOS<uint64_t>();
template<> ADIOS_DATATYPES NativeToADIOS<float>();
template<> ADIOS_DATATYPES NativeToADIOS<double>();
template<> ADIOS_DATATYPES NativeToADIOS<std::complex<float> >();
template<> ADIOS_DATATYPES NativeToADIOS<std::complex<double> >();
template<> ADIOS_DATATYPES NativeToADIOS<std::string>();

// Description:
// Map type sizes
size_t SizeOf(ADIOS_DATATYPES ta);

// Description:
// Is the specified type an integer
bool IsInt(ADIOS_DATATYPES ta);

} // End namespace Type
} // End namespace ADIOS
#endif
// VTK-HeaderTest-Exclude: ADIOSUtilities.h
