The category ctype has various specializations to help localization.
The class ctype<char> has four protected data members:
Each of the pointers refers to an array of length ctype<char>::table_size. The destructor ~ctype<char>() will delete __table_ if __owns_ is true, but it will not delete __lower_map_ and __upper_map_. The derived class destructor must take care of deleting these pointers if they are allocated on the heap ( ctype<char> will not allocate these pointers). A derived class can set these pointers however it sees fit, and have ctype<char> implement all of the rest of the functionality.
The class ctype<wchar_t> has three protected data members:
Metrowerks::range_map<charT, ctype_base::mask> __table_;
Metrowerks::range_map<charT, charT> __lower_map_;
Metrowerks::range_map<charT, charT> __upper_map_;
The class range_map works much like the tables in ctype<char> except that they are sparse tables. This avoids having tables of length 0xFFFF. These tables map the first template parameter into the second.
template <class T, class U> class range_map { public: U operator[](const T& x) const; void insert(const T& x1, const T& x2, const U& y1, const U& y2); void insert(const T& x1, const T& x2, const U& y1); void insert(const T& x1, const U& y1); void clear(); };
When constructed, the range_map implicitly holds a map of all T that map to U(). Use of the insert methods allows exceptions to that default mapping. For example, the first insert method maps the rang e [x1 - x2] into [y1 - y2]. The second insert method maps the x-range into a constant: y1. And the third insert method maps the single T(x1) into U(y1). The method clear() brings the range_map back to the default setting: all T map into U().
A class derived from ctype<wchar_t> can fill __table_,__lower_map_ and __upper_map_ as it sees fit, and allow the base class to query these tables. For an example see ctype_byname<wchar_t>.