2

Is there any way to do it nicely. When I try to use Boost's to_upper(), I get a std::bad_cast, so I ended with something like this:

while(str[i]!=u'\0')
{
    str[i]=(char16_t)to_upper((wchar_t)str[i]);
    i++;
}

I'm not even sure that this is correct because I don't know if it is guaranteed that to_upper of char16_t has the same size as the original character. And I'm not sure if that would cause overwriting of the next character or reading again the second half of the last one precessed. Sorry for my stupid questions, but I have problems when it comes to random access and char types that have variable-length encodings.

Marc Mutz - mmutz
  • 24,485
  • 12
  • 80
  • 90
NoSenseEtAl
  • 28,205
  • 28
  • 128
  • 277
  • We don't know if char16_t and wchar_t have the same size **or** the same encoding, unless you check your specific system. – Bo Persson May 19 '11 at 16:58
  • Oh, this is hell :) Is there a clean way to do it? Maybe first filling tmp array with uppercased, then copying the uppercased from tmp to the str. – NoSenseEtAl May 20 '11 at 08:48
  • The problem is of course that we don't know (portably) what wchar_t is. That's why we got the new char16_t and char32_t. However, they got core language support and work with std::string, but are not supported much in the rest of the library. – Bo Persson May 20 '11 at 09:24
  • So IF I understand you correctly there is no "std way" of doing uppercasing of the that kind of array(char16_t[N])? Luckily for me I think that all the char that my functions will be eating are UCS-2 and they are all 16bit in size(also i use GCC so wchar_t should be big enough, although I'm scared about the uppercasing not producing the expected result), but still this makes me very very uncomfortable. :) – NoSenseEtAl May 20 '11 at 11:57
  • The uppercasing is kind of locale dependent, so the "obvious" way would be to user `toupper(ch, loc)` from ``. However, that would use `ctype` which isn't mandatory for the locales. So it might work, or it might not. :-( – Bo Persson May 20 '11 at 12:17

1 Answers1

2

The best way to do it is probably something like this:

char16_t upper = std::use_facet<std::ctype<char16_t>>(std::locale()).toupper(ch);
Sven
  • 21,903
  • 4
  • 56
  • 63
  • 1
    oh my, can you explain what does that line mean. I dont wanna be boring, but I feel uncomfortable c/p code without understanding it. – NoSenseEtAl Jun 05 '11 at 21:36
  • 2
    `ctype` is a facet (element of a locale) that classifies characters of a certain type. `use_facet` uses the specified facet type from the specified locale. The only issue is that the current draft of C++0x doesn't require `ctype` and `ctype` specializations, so it may not always work. It's still the best way of doing it that I can think of. – Sven Jun 06 '11 at 04:06
  • Error - `Implicit instantiation of undefined template 'std::__1::ctype'` – x4444 Dec 30 '20 at 02:03