//******************************************************************************************
//* Taken from http://codereview.stackexchange.com/questions/18746/mingw-wcout-and-locales *
//******************************************************************************************
#ifndef CUSTOM_LOCALE_H
#define CUSTOM_LOCALE_H
#include "BaseDecl.h"
#ifdef WINDOWS
#if (__cplusplus >= 201103L)
#define CUSTOM_LOCALE_OVERRIDE override
#else
#define CUSTOM_LOCALE_OVERRIDE
#endif
#include <locale>
#include <iostream>
#include <windows.h>
namespace custom_locale
{
class CustomLocale : public std::codecvt <wchar_t, char, std::mbstate_t> {
public:
explicit CustomLocale ( size_t r = 0 ) : std::codecvt <wchar_t, char, std::mbstate_t> (r) {}
protected:
result do_in (state_type&, const char* from, const char* from_end,
const char*& from_next, wchar_t* to, wchar_t* to_end, wchar_t*& to_next ) const CUSTOM_LOCALE_OVERRIDE
{
std::size_t size = from_end - from;
std::size_t buffer_size = to_end - to;
std::size_t written = MultiByteToWideChar(CP_OEMCP, 0, from, size, to, buffer_size);
to_next = to + written;
if (written == 0) {
return error;
}
else if (written != buffer_size) {
return partial;
}
else {
return ok;
}
}
result do_out (state_type&, const wchar_t* from, const wchar_t* from_end,
const wchar_t*& from_next, char* to, char* to_end, char*& to_next ) const CUSTOM_LOCALE_OVERRIDE
{
std::size_t size = from_end - from;
std::size_t buffer_size = to_end - to;
std::size_t written = WideCharToMultiByte(CP_OEMCP, 0, from, size, to, buffer_size, 0, 0);
to_next = to + written;
if (written == 0) {
return error;
}
else if (written != buffer_size) {
return partial;
}
else {
return ok;
}
}
result do_unshift ( state_type&, char*, char*, char*& ) const CUSTOM_LOCALE_OVERRIDE { return ok; }
int do_encoding () const throw () CUSTOM_LOCALE_OVERRIDE { return 1; }
bool do_always_noconv () const throw () CUSTOM_LOCALE_OVERRIDE { return false; }
int do_length ( state_type& state, const char* from, const char* from_end, size_t max ) const CUSTOM_LOCALE_OVERRIDE
{
return std::codecvt <wchar_t, char, std::mbstate_t>::do_length ( state, from, from_end, max );
}
int do_max_length () const throw () CUSTOM_LOCALE_OVERRIDE
{
return std::codecvt <wchar_t, char, std::mbstate_t>::do_max_length ();
}
};
inline void init()
{
std::locale loc ( std::locale(), new CustomLocale() );
std::ios_base::sync_with_stdio (false);
std::wcout.imbue(loc);
std::wcin.imbue(loc);
}
}
#endif
#endif