#ifndef HTIO2_CAST_H
#define HTIO2_CAST_H

#include <sstream>

#include "htio2/Enum.h"

namespace htio2
{

template <typename T>
bool from_string(const std::string& input, T& output);

template <>
inline bool from_string<std::string>(const std::string& input, std::string& output)
{
    output = input;
    return true;
}

template <>
bool from_string<bool>(const std::string& input, bool& output);

// cast to signed integers
template <>
bool from_string<short>(const std::string& input, short& output);

template <>
bool from_string<int>(const std::string& input, int& output);

template <>
bool from_string<long>(const std::string& input, long& output);

template <>
bool from_string<long long>(const std::string& input, long long& output);

// cast to unsigned integers
template <>
bool from_string<unsigned short>(const std::string& input, unsigned short& output);

template <>
bool from_string<unsigned int>(const std::string& input, unsigned int& output);

template <>
bool from_string<unsigned long>(const std::string& input, unsigned long& output);

template <>
bool from_string<unsigned long long>(const std::string& input, unsigned long long& output);

// cast to floating points
template <>
bool from_string<float>(const std::string& input, float& output);

template <>
bool from_string<double>(const std::string& input, double& output);

template <>
bool from_string<long double>(const std::string& input, long double& output);

// cast to HTIO enum types
template<>
bool from_string<Strand>(const std::string& input, Strand& output);

template<>
bool from_string<SeqFormat>(const std::string& input, SeqFormat& output);

template<>
bool from_string<HeaderFormat>(const std::string& input, HeaderFormat& output);

template<>
bool from_string<QualityEncode>(const std::string& input, QualityEncode& output);

template<>
bool from_string<CompressFormat>(const std::string& input, CompressFormat& output);

// stringify primitive types
template <typename T>
std::string to_string(T input)
{
    std::ostringstream result;
    result << input;
    return result.str();
}

// stringify HTIO enum types
template<>
std::string to_string<Strand>(Strand input);

template<>
std::string to_string<SeqFormat>(SeqFormat input);

template<>
std::string to_string<HeaderFormat>(HeaderFormat input);

template<>
std::string to_string<QualityEncode>(QualityEncode input);

template<>
std::string to_string<CompressFormat>(CompressFormat input);

} // namespace htio2

#endif // HTIO2_CAST_H
