/*
 * string.cpp
 *
 * Created on: Apr 1, 2013
 * Author: Jan Travnicek
 */

#include "string.hpp"
#include <sstream>

namespace ext {

std::string to_string ( const std::string & value ) {
	return value;
}

std::string to_string ( int value ) {
	return std::to_string ( value );
}

std::string to_string ( bool value ) {
	return std::to_string ( static_cast < int > ( value ) );
}

std::string to_string ( long value ) {
	return std::to_string ( value );
}

std::string to_string ( long long value ) {
	return std::to_string ( value );
}

std::string to_string ( unsigned value ) {
	return std::to_string ( value );
}

std::string to_string ( unsigned long value ) {
	return std::to_string ( value );
}

std::string to_string ( unsigned long long value ) {
	return std::to_string ( value );
}

std::string to_string ( double value ) {
	return std::to_string ( value );
}

std::string to_string ( char value ) {
	return std::string ( 1, value );
}

std::string to_string ( char * param ) {
	std::string res ( param );

	free ( param );
	return res;
}

template < >
std::string from_string ( const std::string & value ) {
	return value;
}

template < >
int from_string ( const std::string & value ) {
	return std::stoi ( value );
}

template < >
bool from_string ( const std::string & value ) {
	return value == "true" || value == "1";
}

template < >
long from_string ( const std::string & value ) {
	return std::stol ( value );
}

template < >
long long from_string ( const std::string & value ) {
	return std::stoll ( value );
}

template < >
unsigned from_string ( const std::string & value ) {
	return std::stoul ( value );
}

template < >
unsigned long from_string ( const std::string & value ) {
	return std::stoul ( value );
}

template < >
unsigned long long from_string ( const std::string & value ) {
	return std::stoull ( value );
}

template < >
double from_string ( const std::string & value ) {
	return std::stod ( value );
}

ext::vector < std::string > explode ( const std::string & source, const std::string & delimiter ) {
	ext::vector < std::string > res;
	size_t start_pos = 0;
	size_t end_pos;

	while ( ( end_pos = source.find ( delimiter, start_pos ) ) != std::string::npos ) {
		res.push_back ( source.substr ( start_pos, end_pos - start_pos ) );
		start_pos = end_pos + delimiter.size ( );
	}

	res.push_back ( source.substr ( start_pos, source.size ( ) ) );

	return res;
}

std::string implode ( const std::vector < std::string > & source, const std::string & delimiter ) {
	std::stringstream ss;
	bool first = true;
	for ( const std::string & str : source ) {
		if ( first )
			first = false;
		else
			ss << delimiter;

		ss << str;
	}

	return ss.str ( );
}

} /* namespace ext */
