This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]