Q about ctype.narrow
Pétur Runólfsson
peturr02@ru.is
Tue Nov 25 17:38:00 GMT 2003
Jerry Quinn wrote:
> Here's the issue. Assume we have ctype<char> that has been subclassed
> by a library client. Now:
>
> char ctype<char>::narrow(char c, char default)
> {
> if (table[c]) return table[c];
> return table[c] = do_narrow(c, default);
> }
I don't think this is allowed under the as-if rule. (Calling a virtual
function is an observable effect.)
[...]
> Fixing this starts to get uglier. I think you need to detect that
> default may get returned and not cache the result in that case:
>
> char ctype<char>::narrow(char c, char default)
> {
> if (table[c]) return table[c];
> char x = do_narrow(c, default);
> if (x != default) table[c] = x;
> return x;
> }
Is there any reason why the cache needs to be in ctype, rather than
in a separate class (like numpunct_cache)? Since the default is
usually known at compile time, something like this seems possible:
template<typename charT, char dfault>
class narrow_cache
{
ctype<charT>* ct;
public:
void init(ctype<charT>* f) { ct = f; }
char narrow(charT c) const { return ct->narrow(c, dfault); }
};
template<char dfault>
class narrow_cache<char, dfault>
{
ctype<charT>* ct;
char narrow_table[256];
public:
void init(ctype<charT>* f)
{
ct = f;
for (int i = 0; i < 256; ++i)
narrow_table[i] = ct->narrow(i, dfault);
}
char narrow(char c) const { return narrow_table[(unsigned char)c]; }
};
Then change
ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
if (__ctype.narrow(*__beg, 0) != '%')
to
narrow_cache<_CharT, '0'> const& __narrow_cache = ...;
if (__narrow_cache.narrow(*__beg) != '%')
This scheme also allows narrow to be cached for wchar_t. Since most
format strings passed to time_put::put only contain format
characters (such as %X %x %c %H etc.) it should be sufficient to
cache characters 0 to 128, and fall back to the virtual for higher
values:
char narrow(wchar_t c) const
{
if (c < 128)
return narrow_table[c];
return ct->narrow(c, dfault);
}
(This obviously can't be done for the generic version, since character
types are not required to be convertible to integers.)
Regards,
Petur
More information about the Libstdc++
mailing list