字符串转换数字,数字转换字符串,虽然有标准的C++stream可用,虽说类型安全,但是它太慢了。
fast_cast函数封装了C的转换方式,速度快,较适合要求速度的场合,还可以转换Ansi字符串和Unicode
字符串。
/*
fast_cast.h
sdragon 2006-11-23 20:33:31
使用示例:
int a = fast_cast<int>("123"); //十进制
int b = fast_cast<int>("FF8", 16); //十六进制
string str = fast_cast<string>(123); //十进制
string str = fast_cast<string>(123, 16); //十六进制
string str = fast_cast<string>(123.456); //默认格式
string str = fast_cast<string>(123.456, 4, 6); //至少4位整数,6位小数,不够补0
*/
#ifndef FAST_CAST_H_20061123203331
#define FAST_CAST_H_20061123203331
#include "char_buf.h"
template<typename T>
class fast_stream
{
public:
T operator()(const char* str) { return atoi(str); }
T operator()(const wchar_t* str) { return _wtoi(str); }
T operator()(const string& str) { return operator()(str.c_str()); }
T operator()(const wstring& str) { return operator()(str.c_str()); }
T operator()(const char* str, int radix){ return strtoul(str, NULL, radix); }
T operator()(const wchar_t* str, int radix){ return wcstoul(str, NULL, radix); }
T operator()(const string& str, int radix){ return operator()(str.c_str(), radix); }
T operator()(const wstring& str, int radix){ return operator()(str.c_str(), radix); }
};
template<>long fast_stream<long>::operator() (const char* str){
return atol(str); }
template<>long fast_stream<long>::operator() (const wchar_t* str){
return _wtol(str); }
template<>unsigned long fast_stream<unsigned long>::operator() (const char* str){
return atol(str); }
template<>unsigned long fast_stream<unsigned long>::operator() (const wchar_t* str){
return _wtol(str); }
template<>__int64 fast_stream<__int64>::operator() (const char* str){
return _atoi64(str); }
template<>__int64 fast_stream<__int64>::operator() (const wchar_t* str){
return _wtoi64(str); }
template<>unsigned __int64 fast_stream<unsigned __int64>::operator()(const char* str){
return _atoi64(str); }
template<>unsigned __int64 fast_stream<unsigned __int64>::operator()(const wchar_t* str){
return _wtoi64(str); }
template<>
class fast_stream<float>
{
public:
float operator()(const char* str){ return atof(str); }
float operator()(const wchar_t* str){ return _wtof(str); }
float operator()(const string& str){ return operator()(str.c_str()); }
float operator()(const wstring& str){ return operator()(str.c_str()); }
};
template<>
class fast_stream<double>
{
public:
double operator()(const char* str){ return atof(str); }
double operator()(const wchar_t* str){ return _wtof(str); }
double operator()(const string& str){ return operator()(str.c_str()); }
double operator()(const wstring& str){ return operator()(str.c_str()); }
};
template<>
class fast_stream<long double>
{
public:
long double operator()(const char* str){ return _atold(str); }
long double operator()(const wchar_t* str){ return _wtold(str); }
long double operator()(const string& str){ return operator()(str.c_str()); }
long double operator()(const wstring& str){ return operator()(str.c_str()); }
};
template<>
class fast_stream<string>
{
public:
string operator()(int n, int radix = 10){ return string(itoa(n,
char_buf<char, 32>(), radix), 32); }
string operator()(unsigned int n, int radix = 10){ return string(ultoa(n,
char_buf<char, 32>(), radix), 32); }
string operator()(long n, int radix = 10){ return string(ltoa(n,
char_buf<char, 32>(), radix), 32); }
string operator()(unsigned long n, int radix = 10){ return string(ultoa(n,
char_buf<char, 32>(), radix), 32); }
string operator()(__int64 n, int radix = 10){ return string(_i64toa(n,
char_buf<char, 32>(), radix), 32); }
string operator()(unsigned __int64 n, int radix = 10){ return string(_ui64toa(n,
char_buf<char, 32>(), radix), 32); }
string operator()(float n){ return from_float(n); }
string operator()(double n){ return from_float(n); }
string operator()(long double n){ return from_float(n); }
string operator()(float n, int int_length, int dec_length){ return from_float(n,
int_length, dec_length); }
string operator()(double n, int int_length, int dec_length){ return from_float(n,
int_length, dec_length); }
string operator()(long double n, int int_length, int dec_length){ return from_float(n,
int_length, dec_length); }
string operator()(const wchar_t* str) { return from_string(str);
}
string operator()(const wchar_t* str, int length){ return from_string(str, length);
}
string operator()(const wstring& str) { return from_string(str.c_str());
}
string operator()(const wstring& str, int length){ return from_string(str.c_str(),
length); }
private:
string from_string(const wchar_t* str)
{
#ifdef _WIN32
return from_string(str, -1);
#else
vector<char> buf;
size_t length = wcstombs(NULL, str, 0);
buf.reserve(length);
wcstombs(&buf[0], str, length);
return string(&buf[0], length);
#endif
}
string from_string(const wchar_t* str, int length)
{
#ifdef _WIN32
vector<char> buf;
size_t n = WideCharToMultiByte(CP_ACP, 0, str, length, 0, 0, NULL, NULL);
buf.reserve(n);
WideCharToMultiByte(CP_ACP, 0, str, length, &buf[0], n, NULL, NULL);
return string(&buf.front(), n);
#else
return from_string(wstring(str, length));
#endif
}
string from_float(double n)
{
char_buf<char, 32> buf;
snprintf(buf, buf.size, "%.16G", n);
return string(buf, buf.size);
}
string from_float(double n, int int_length, int dec_length)
{
int_length += dec_length +
static_cast<bool>(dec_length) + //小数点占位
static_cast<bool>(n<0); //负号占位
vector<char> buf(int_length);
int length = snprintf(&buf[0], int_length, "%0*.*f", int_length, dec_length, n);
return string(buf.begin(), buf.end());
}
};
template<>
class fast_stream<wstring>
{
public:
wstring operator()(int n, int radix = 10){ return wstring(_itow(n,
char_buf<wchar_t, 32>(), radix), 32); }
wstring operator()(unsigned int n, int radix = 10){ return wstring(_ultow(n,
char_buf<wchar_t, 32>(), radix), 32); }
wstring operator()(long n, int radix = 10){ return wstring(_ltow(n,
char_buf<wchar_t, 32>(), radix), 32); }
wstring operator()(unsigned long n, int radix = 10){ return wstring(_ultow(n,
char_buf<wchar_t, 32>(), radix), 32); }
wstring operator()(__int64 n, int radix = 10){ return wstring(_i64tow(n,
char_buf<wchar_t, 32>(), radix), 32); }
wstring operator()(unsigned __int64 n, int radix = 10){ return wstring(_ui64tow(n,
char_buf<wchar_t, 32>(), radix), 32); }
wstring operator()(float n){ return from_float(n); }
wstring operator()(double n){ return from_float(n); }
wstring operator()(long double n){ return from_float(n); }
wstring operator()(float n, int int_length, int dec_length){ return from_float(n,
int_length, dec_length); }
wstring operator()(double n, int int_length, int dec_length){ return from_float(n,
int_length, dec_length); }
wstring operator()(long double n, int int_length, int dec_length){ return from_float(n,
int_length, dec_length); }
wstring operator()(const char* str) { return from_string(str);
}
wstring operator()(const char* str, int length){ return from_string(str, length);
}
wstring operator()(const string& str) { return from_string(str.c_str());
}
wstring operator()(const string& str, int length){ return from_string(str.c_str(),
length); }
private:
wstring from_string(const char* str)
{
#ifdef _WIN32
return from_string(str, -1);
#else
vector<wchar_t> buf;
print("c1");
size_t length = mbstowcs(NULL, str, 0);
buf.reserve(length);
mbstowcs(&buf[0], str, length);
return wstring(&buf[0], length);
#endif
}
wstring from_string(const char* str, int length)
{
#ifdef _WIN32
vector<wchar_t> buf;
size_t n = MultiByteToWideChar(CP_ACP, 0, str, length, NULL, 0);
buf.reserve(n);
MultiByteToWideChar(CP_ACP, 0, str, length, &buf[0], n);
return wstring(&buf[0], n);
#else
return from_string(string(str, length));
#endif
}
wstring from_float(double n)
{
char_buf<wchar_t, 32> buf;
snwprintf(buf, buf.size, L"%.16G", n);
return wstring(buf, buf.size);
}
wstring from_float(double n, int int_length, int dec_length)
{
int_length += dec_length +
static_cast<bool>(dec_length) + //小数点占位
static_cast<bool>(n<0); //负号占位
vector<wchar_t> buf(int_length);
int length = snwprintf(&buf[0], int_length, L"%0*.*f", int_length, dec_length, n);
return wstring(buf.begin(), buf.end());
}
};
template<typename result_t, typename arg_t>
result_t fast_cast(arg_t a)
{
fast_stream<result_t> fs;
return fs(a);
}
template<typename result_t, typename arg_t>
result_t fast_cast(arg_t a, int b)
{
fast_stream<result_t> fs;
return fs(a, b);
}
template<typename result_t, typename arg_t>
result_t fast_cast(arg_t a, int b, int c)
{
fast_stream<result_t> fs;
return fs(a, b, c);
}
#endif //FAST_CAST_H_20061123203331