All pastes #741879 Raw Edit

Unnamed

public text v1 · immutable
·published 2007-10-19 01:23 UTC
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;
}