// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.

#ifndef tools_tos
#define tools_tos

// Used in BatchLab/MemoryTuple and Rio_Tuple.
// We need something different than the to<T>
// to handle std::vector<> and bool.

#include "sprintf"
#include "charmanip"
#include "typedefs"

#include <vector>

namespace tools {

inline std::string tos(unsigned char a_value){
  std::string _s;
  if(is_printable(a_value))
    sprintf(_s,32,"%c",a_value);
  else
    sprintf(_s,32,"%d",a_value);
  return _s;
}

inline std::string tos(char a_value){
  std::string _s;
  if(is_printable(a_value))
    sprintf(_s,32,"%c",a_value);
  else
    sprintf(_s,32,"%d",a_value);
  return _s;
}

inline std::string tos(unsigned short a_value) {
  std::string _s;
  sprintf(_s,32,"%d",a_value);
  return _s;
}

inline std::string tos(short a_value){
  std::string _s;
  sprintf(_s,32,"%d",a_value);
  return _s;
}

inline std::string tos(unsigned int a_value) {
  std::string _s;
  sprintf(_s,32,"%u",a_value);
  return _s;
}

inline std::string tosx(unsigned int a_value) {
  std::string _s;
  sprintf(_s,32,"%x",a_value);
  return _s;
}

inline std::string tos(int a_value){
  std::string _s;
  sprintf(_s,32,"%d",a_value);
  return _s;
}

inline std::string tos(uint64 a_value) {
  std::string _s;
  sprintf(_s,32,uint64_format(),a_value);
  return _s;
}

inline std::string tos(int64 a_value){
  std::string _s;
  sprintf(_s,32,int64_format(),a_value);
  return _s;
}

inline std::string tos(float a_value){
  std::string _s;
  sprintf(_s,32,"%g",a_value);
  return _s;
}

inline std::string tos(double a_value){
  std::string _s;
  sprintf(_s,32,"%g",a_value);
  return _s;
}

inline std::string tos(bool a_value){
  return std::string(a_value?"true":"false");
}

inline std::string tos(const std::string& a_value){return a_value;}

template <class T>
inline std::string tos(const std::vector<T>& a_vals,
                       const std::string& a_sep = "\n",
                       bool a_sep_at_end = false) {
  size_t number = a_vals.size();
  if(number<=0) return "";
  std::string result;
  number--;
  for(size_t index=0;index<number;index++) {
    result += tos(a_vals[index]);
    result += a_sep;
  }
  result += tos(a_vals[number]);
  if(a_sep_at_end) result += a_sep;
  return result;
}

inline std::string tos(unsigned int a_linen,const char* a_lines[]) {
  std::string _s;
  for(unsigned int index=0;index<a_linen;index++) {
    _s += std::string(a_lines[index]);
    _s += "\n";
  }
  return _s;
}

}

#endif
