This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: Q about ctype.narrow
Jerry Quinn wrote:
...
Now, call narrow(125, 5) followed by narrow(125,10). Assuming the
table was inited with 0's, table[125] will get 5, the first time
through, and the second time, we'll return 5 instead of 10.
Good point. I hadn't thought of that.
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;
}
Maybe this still speeds things up over always doing do_narrow, but the
complexity seems unpleasant.
Is it really that bad? The only thing that needs to be optimized
is successful table lookups, everything else can be outlined:
inline char ctype<char>::narrow(char c, char dfault)
{
if (table[c]) return table[c];
return __narrow (c, dfault);
}
/* out-of-line */ char ctype<char>::__narrow(char c, char dfault)
{
char x = do_narrow(c, dfault);
if (x != dfault) table[c] = x;
return x;
}
I actually first tried filling in the complete table when narrow is
first called, but that also breaks due to the default issue. And is
probably harder to fix.
This too I think should be possible if you just don't fill the cache
in those cases:
inline char ctype<char>::narrow(char c, char dfault)
{
if (table[c]) return table[c];
return __narrow (c, dfault);
}
/* out-of-line */ char ctype<char>::__narrow(char c, char dfault)
{
if (cache_empty) {
const char s[] = { \000, \001, ..., \0377 };
do_narrow (s, s + sizeof s, table, 0); // fill cache
cache_empty = false;
}
// and still call corresponding do_narrow() to make users happy
char x = do_narrow(c, dfault);
assert (x == dfault || x == table [c]);
return x;
}
Martin