rendered paste body#include <iostream>
#include <sstream>
#include <locale>
using namespace std;
typedef unsigned short UC;
class uctype : public locale::facet, public ctype_base
{
public:
static locale::id id;
typedef UC char_type;
uctype(size_t refs = 0): locale::facet(refs) {}
public:
bool is(mask m, UC c) const;
const UC *is(const UC *low, const UC *high, mask *vec) const;
const UC *scan_is(mask m, const UC *low, const UC *high) const;
const UC *scan_not(mask m, const UC *low, const UC *high) const;
UC toupper(UC c) const;
const UC *toupper(UC *low, const UC *high) const;
UC tolower(UC c) const;
const UC *tolower(UC *low, const UC *high) const;
UC widen(char) const;
const char *widen(const char *low, const char *high, UC *dest) const;
char narrow(UC, char defchar) const;
const UC *narrow(const UC *low, const UC *high, char defchar, char *dest) const;
};
locale::id uctype::id;
static const UC char_limit(0x100);
class ClassicCtype
{
public:
typedef ctype<char>::mask mask_t;
ClassicCtype()
{
const ctype<char>& classic =
use_facet<ctype<char> >(locale::classic());
char buf[char_limit];
for (int i = 0; i < char_limit; ++i) buf[i] = i;
classic.is(buf, buf + char_limit, masks_);
memcpy(uppercases_, buf, char_limit);
classic.toupper(uppercases_, uppercases_ + char_limit);
memcpy(lowercases_, buf, char_limit);
classic.tolower(lowercases_, lowercases_ + char_limit);
}
mask_t mask(UC c) const { return (c >= char_limit ? mask_t() : masks_[c]); }
UC toupper(UC c) const { return (c >= char_limit ? c : uppercases_[c]); }
UC tolower(UC c) const { return (c >= char_limit ? c : lowercases_[c]); }
protected:
mask_t masks_[char_limit];
char uppercases_[char_limit], lowercases_[char_limit];
};
static ClassicCtype classic_ctype;
bool uctype::is(mask m, UC c) const {
return static_cast<bool>(classic_ctype.mask(c) & m);
}
const UC *uctype::is(const UC *low, const UC *high, mask *vec) const {
while (low != high) *vec++ = classic_ctype.mask(*low++);
return high;
}
const UC *uctype::scan_is(mask m, const UC *low, const UC *high) const {
while (low != high) { if (classic_ctype.mask(*low) & m) break; ++low; }
return low;
}
const UC *uctype::scan_not(mask m, const UC *low, const UC *high) const {
while (low != high) { if (!(classic_ctype.mask(*low) & m)) break; ++low; }
return low;
}
UC uctype::toupper(UC c) const { return classic_ctype.toupper(c); }
const UC *uctype::toupper(UC *low, const UC *high) const {
while (low != high) { *low = classic_ctype.toupper(*low); ++low; }
return low;
}
UC uctype::tolower(UC c) const { return classic_ctype.tolower(c); }
const UC *uctype::tolower(UC *low, const UC *high) const {
while (low != high) { *low = classic_ctype.tolower(*low); ++low; }
return low;
}
UC uctype::widen(char c) const { return static_cast<UC>(static_cast<unsigned char>(c)); }
const char *uctype::widen(const char *low, const char *high, UC *dest) const {
while (low != high) *dest++ = static_cast<UC>(static_cast<unsigned char>(*low++));
return low;
}
char uctype::narrow(UC c, char defchar) const {
if (c >= char_limit) return defchar;
return static_cast<char>(c);
}
const UC *uctype::narrow(const UC *low, const UC *high, char defchar, char *dest) const {
while (low != high) {
*dest = (*low >= char_limit ? defchar : static_cast<char>(*low));
++low; ++dest;
}
return low;
}
namespace std {
template <>
class ctype<UC> : public uctype
{
public:
ctype(size_t refs=0): uctype(refs) {}
};
}
int main() {
basic_ostringstream<UC> oss;
oss.imbue(locale(locale(locale(), new ctype<UC>), new num_put<UC>));
oss << 42;
basic_string<UC> s = oss.str();
cout << s.length();
return 0;
}