/*
 * SPDX-FileCopyrightText: 2026 Oak Ridge National Laboratory and Contributors
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef ADIOS2_BINDINGS_CXX_CXX_IO_TCC_
#define ADIOS2_BINDINGS_CXX_CXX_IO_TCC_

#include "IO.h"

#include "adios2/core/IO.h"

namespace adios2
{

template <class T>
Variable<T> IO::DefineVariable(const std::string &name, const Dims &shape, const Dims &start,
                               const Dims &count, const bool constantDims)
{
    helper::CheckForNullptr(m_IO, "for variable name " + name + ", in call to IO::DefineVariable");
    return Variable<T>(&m_IO->DefineVariable<typename TypeInfo<T>::IOType>(name, shape, start,
                                                                           count, constantDims));
}

template <class T>
Variable<T> IO::InquireVariable(const std::string &name)
{
    helper::CheckForNullptr(m_IO, "for variable name " + name + ", in call to IO::InquireVariable");
    return Variable<T>(m_IO->InquireVariable<typename TypeInfo<T>::IOType>(name));
}

template <class T>
Attribute<T> IO::DefineAttribute(const std::string &name, const T *data, const size_t size,
                                 const std::string &variableName, const std::string separator,
                                 const bool allowModification)
{
    using IOType = typename TypeInfo<T>::IOType;
    helper::CheckForNullptr(m_IO, "for attribute name " + name + " and variable name " +
                                      variableName + ", in call to IO::DefineAttribute");
    return Attribute<T>(&m_IO->DefineAttribute(name, reinterpret_cast<const IOType *>(data), size,
                                               variableName, separator, allowModification));
}

template <class T>
Attribute<T> IO::DefineAttribute(const std::string &name, const T &value,
                                 const std::string &variableName, const std::string separator,
                                 const bool allowModification)
{
    using IOType = typename TypeInfo<T>::IOType;
    helper::CheckForNullptr(m_IO,
                            "for attribute name " + name + ", in call to IO::DefineAttribute");
    return Attribute<T>(&m_IO->DefineAttribute(name, reinterpret_cast<const IOType &>(value),
                                               variableName, separator, allowModification));
}

template <class T>
Attribute<T> IO::InquireAttribute(const std::string &name, const std::string &variableName,
                                  const std::string separator)
{
    using IOType = typename TypeInfo<T>::IOType;
    helper::CheckForNullptr(m_IO,
                            "for attribute name " + name + ", in call to IO::InquireAttribute");
    return Attribute<T>(m_IO->InquireAttribute<IOType>(name, variableName, separator));
}

} // end namespace adios2

#endif // ADIOS2_BINDINGS_CXX_CXX_IO_TCC_
