This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
RE: Q about ctype.narrow
- From: Jerry Quinn <jlquinn at optonline dot net>
- To: Pétur Runólfsson <peturr02 at ru dot is>
- Cc: Paolo Carlini <pcarlini at unitus dot it>, libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Tue, 25 Nov 2003 23:56:13 -0500
- Subject: RE: Q about ctype.narrow
- References: <07D05A69A3D0C14FAEA60C3ACE8E5564028F5601@mail.ru.is>
Pétur Runólfsson writes:
> 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.)
I hope that's not required by the standard. If so, it clobbers ANY
optimization that caches values from virtual function calls. You
wouldn't be able to to cache widen results for numpunct fields, for
example, since the spec says that the results have to be as if all the
various do_widen's happened on a particular call.
That would kiss goodbye a lot of performance improvements and make the
library much slower than C code for I/O.
> 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:
It lets library users of ctype<char>.narrow get the optimization as
well as uses within the library.
[...]
> 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:
This can also be done within the ctype<wchar_t> facet instead.
What is the benefit in this case of keeping the cache table elsewhere?
It's not like there are many copies of ctype running around, right?
When you use_facet, you get back a reference, so you don't have
expensive copying of the table.
Jerry