Still improving! (Was: Re: [PATCH] Avoid strtok for thread safety)
Paolo Carlini
pcarlini@unitus.it
Wed Nov 27 07:43:00 GMT 2002
Nathan Myers wrote:
>Paolo set me straight about the format of the locale string.
>
> {
> char const* __save = __s;
> size_t __i = 0;
> for (; __i < _S_categories_size + _S_extra_categories_size; ++__i)
> {
> __save = std::find(__save, __s + __len, "=");
> char const* __next = std::find(__save, s + __len, ";");
> char* __new = new char[__next - __save];
> char* __eos = std::copy(__save + 1, __next, __new);
> *__eos = '\0';
> _M_names[__i] = __new;
> if (*__next == '\0')
> break;
> __save = __next + 1;
> }
> }
>
Thanks Nathan!
>Note that the C++ algorithms have much nicer termination semantics than
>most of the C string functions (strcspn excepted).
>
Nice, I didn't consider that... However, in the meanwhile, I tried to post
(without success, due to a problem with my smtp server :( a different
version
(tested x86-linux), which basically avoid half the finds thanks to the a
priori knowldege of the names of the various categories. Something like
this:
{
char* __new;
const char* __end;
const char* __beg = __s + strlen(_S_categories[0]) + 1;
for (size_t __i = 0;
__i < _S_categories_size + _S_extra_categories_size - 1; ++__i)
{
__end = strpbrk(__beg, ";");
__new = new char[__end - __beg + 1];
memcpy(__new, __beg, __end - __beg);
__new[__end - __beg] = '\0';
_M_names[__i] = __new;
__beg = __end + strlen(_S_categories[__i + 1]) + 2;
}
__new = new char[__s + __len - __beg];
memcpy(__new, __beg, __s + __len - __beg);
_M_names[_S_categories_size + _S_extra_categories_size - 1] = __new;
}
Still, your solution is shorter (but has an additional 'if' in the loop ;-)
Also, it seems to me that in the existing practice of locale implementation
in v3 C++ algorithms like std::copy and std::find are not used, dunno
exactly
why, however...
Ciao, Paolo.
More information about the Libstdc++
mailing list