Q about ctype.narrow

Jerry Quinn jlquinn@optonline.net
Tue Nov 25 04:44:00 GMT 2003


Paolo Carlini writes:
 > Jerry Quinn wrote:
 > 
 > >... But it seems the standard won't let me.
 > >
 > Yes, unfortunately. Did you follow this thread
 > 
 >     http://gcc.gnu.org/ml/libstdc++/2003-10/msg00000.html
 >     http://gcc.gnu.org/ml/libstdc++/2003-10/msg00004.html
 >     http://gcc.gnu.org/ml/libstdc++/2003-10/msg00006.html
 > 
 > ??
 > 
 > That's why a fast ctype::narrow it's on my to to list... Perhaps
 > I have already mentioned that in passing some days ago...

I took a quick look at this and got discouraged.  The problem I found
is that filling a narrow() lookup table for ctype<char> and
ctype<wchar_t> depends on what default is.  It's not an issue for the
library-supplied ctype facets, but it is when the user overrides
do_narrow().

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);
}

And then the user's do_narrow:

char derived::do_narrow(char c, char default)
{
  if (!source_char_set(c)) return default;
  return c;
}

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.

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.

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.

BTW, do you have a nice benchmark for this?

Jerry




More information about the Libstdc++ mailing list