In C++, to simplify string conversion between std::string
and std::wstring
, I created the following utility template functions:
#pragma once
#include <vector>
#include <string>
#include <cstring>
#include <cwchar>
#include <cassert>
template<typename Td>
Td string_cast( const char* pSource, unsigned int codePage = CP_ACP );
template<typename Td>
Td string_cast( const wchar_t* pSource, unsigned int codePage = 1200 );
template<typename Td>
Td string_cast( const std::string& source, unsigned int codePage = CP_ACP );
template<typename Td>
Td string_cast( const std::wstring& source, unsigned int codePage = 1200 );
template<>
std::string string_cast( const char* pSource, unsigned int codePage )
{
assert( pSource != 0 );
return std::string( pSource );
}
template<>
std::wstring string_cast( const char* pSource, unsigned int codePage )
{
assert( pSource != 0 );
std::size_t sourceLength = std::strlen( pSource );
if( sourceLength == 0 )
{
return std::wstring();
}
int length = ::MultiByteToWideChar( codePage, 0, pSource, sourceLength, NULL, 0 );
if( length == 0 )
{
return std::wstring();
}
std::vector<wchar_t> buffer( length );
::MultiByteToWideChar( codePage, 0, pSource, sourceLength, &buffer[ 0 ], length );
return std::wstring( buffer.begin(), buffer.end() );
}
template<>
std::string string_cast( const wchar_t* pSource, unsigned int codePage )
{
assert( pSource != 0 );
size_t sourceLength = std::wcslen( pSource );
if( sourceLength == 0 )
{
return std::string();
}
int length = ::WideCharToMultiByte( codePage, 0, pSource, sourceLength, NULL, 0, NULL, NULL );
if( length == 0 )
{
return std::string();
}
std::vector<char> buffer( length );
::WideCharToMultiByte( codePage, 0, pSource, sourceLength, &buffer[ 0 ], length, NULL, NULL );
return std::string( buffer.begin(), buffer.end() );
}
template<>
std::wstring string_cast( const wchar_t* pSource, unsigned int codePage )
{
assert( pSource != 0 );
return std::wstring( pSource );
}
template<>
std::string string_cast( const std::string& source, unsigned int codePage )
{
return source;
}
template<>
std::wstring string_cast( const std::string& source, unsigned int codePage )
{
if( source.empty() )
{
return std::wstring();
}
int length = ::MultiByteToWideChar( codePage, 0, source.data(), source.length(), NULL, 0 );
if( length == 0 )
{
return std::wstring();
}
std::vector<wchar_t> buffer( length );
::MultiByteToWideChar( codePage, 0, source.data(), source.length(), &buffer[ 0 ], length );
return std::wstring( buffer.begin(), buffer.end() );
}
template<>
std::string string_cast( const std::wstring& source, unsigned int codePage )
{
if( source.empty() )
{
return std::string();
}
int length = ::WideCharToMultiByte( codePage, 0, source.data(), source.length(), NULL, 0, NULL, NULL );
if( length == 0 )
{
return std::string();
}
std::vector<char> buffer( length );
::WideCharToMultiByte( codePage, 0, source.data(), source.length(), &buffer[ 0 ], length, NULL, NULL );
return std::string( buffer.begin(), buffer.end() );
}
template<>
std::wstring string_cast( const std::wstring& source, unsigned int codePage )
{
return source;
}
Are there any bugs or further optimizations?
int
is hardly discoverable... \$\endgroup\$ – Ion Todirel Nov 20 '11 at 2:59#include <Windows.h>
. On the other hand, are<cstring>
,<cwchar>
and<cassert>
really necessary? \$\endgroup\$ – Marc.2377 Sep 12 '19 at 2:43