Tom
Tom

Reputation: 7992

GCC, std::ctype specialisation & streams

I've written my own specialisation of each virtual member function of std::ctype<char16_t>, so that this now works:

#include <string>
#include <locale>
#include "char16_facets.h"  // Header containing my ctype specialisation
#include <sstream>
#include <iostream>

// Implemented elsewhere using iconv
std::string Convert(std::basic_string<char16_t>);

int main() {
    std::basic_string<char16_t> s("Hello, world.");
    std::basic_stringstream<char16_t> ss(s);
    ss.imbue(std::locale(ss.getloc(), new std::ctype<char16_t>()));
    std::basic_string<char16_t> t;
    ss >> t;
    std::cout << Convert(t) << " ";
    ss >> t;
    std::cout << Convert(t) << std::endl;
}

Is there a way to make streams use the new ctype specialisation by default, so I don't have to imbue each stream with a new locale?

I haven't written a new class, just provided

template<>
inline bool std::ctype<char16_t>::do_is (std::ctype_base::mask m, char16_t c) const {

etc. I'd sort of hoped it would be picked up automatically, so long as it was declared before I #include <sstream> but it isn't.

Most of the work for the above was done using G++ and libstdc++ 4.8, but I get the same result with them built from SVN trunk.

Edit - Update This question originally asked about how to get number extraction working. However, given a stream imbued with correct ctype and numpunct implementations, then no specialisation of num_get is necessary; simply

ss.imbue(std::locale(ss.getloc(), new std::num_get<char16_t>()));

and it will work, with either gcc version.

Again, is there some way to get the streams to pick this up automatically, rather than having to imbue every stream with it?

Upvotes: 1

Views: 538

Answers (1)

David G
David G

Reputation: 96845

Use std::locale::global():

std::locale::global(std::locale(std::locale(), new std::ctype<char16_t>()));

Upvotes: 4

Related Questions