Boost logo

Boost :

From: Terje Slettebø (tslettebo_at_[hidden])
Date: 2002-08-22 16:52:43

>From: "Alberto Barbati" <abarbati_at_[hidden]>

>Terje Slettebø wrote:

>> Would it really be an advantage to use "t=interpreter.str()" instead of
>> << interpreter"? Performance, perhaps. Have you done any measurements, or
>> something like that, to show that this specialisation is worthwile?

>It's not just a matter of performances here. "t=interpreter.str()" and
>"interpreter >> t" do two completely different things. In particular,
>the latter stops at the first whitespace while the former does not. In
>fact, one thing that striked me at first when studying lexical_cast is
>that with the current implementation, the expression:

>boost::lexical_cast<std::string>(std::string("hello, world"))

>not only does not return the string "hello, world" but throws an
>exception because of the space. It's very counter-intuitive, IMHO.

Yes. That's one of the reasons for the new proposition.

The above is just the tip of the iceberg. There are 20+ specialisations in
the proposition, to handle special cases to remove such problems with
whitespace (both for strings and characters), being able to handle other
character types, and for efficiency.

However, you're right - This case is not covered - reading out of the
stringstream, into a string, when the source is something else than char *,
std::string, etc. In the latter case, it handles this by avoiding the
stringstream althogether.

This is definitely a good reason for making a special case for when the
target is string, etc. also in the case of any source type.

Good catch, all of you who have contributed, here. :)

I'll soon upload the updated version, and post all the info about it, here.
It also includes your specialisation-suggestion, and support for std::rope
(it could be done by the user, but is included for convenience).

>> In addition, this would only work for "char" character types. It would
>> to be generalised to deal with other character types. Nevertheless,
>> possible, too.

>I'm now aware of the char/wchar_t/whatever problem (I wasn't before
>posting). Hot stuff, indeed.

Oh, yeah. :) The real "fun" starts when you try to make it work on the
compilers. Then you'll find that the support for wide characters is rather
poor on several compilers. However, the situation is improving.

>I had a look at your proposal. The main interesting difference between
>the two approaches (correct if I'm wrong, please) is that your proposal
>always consider Target/Source as a pair or template arguments, therefore
>in order to provide a specialization for one type you probably need
>partial specialization, which could be unavaible. My approach de-couples
>Targets from Source, thus avoiding the inconvenience.

Yes, I've considered that, too (also when I saw Gennadiy's proposal in the
"Files" section), and with your proposal earlier, here. However, there's a
couple of things to consider:

- Many of the specialisations, more or less all, requires _both_ types to be
considered, to determine the right implementation. There's a simple example
with the specialisation that checks if source and target is the same type,
and in that case performs a simple, implicit copy, avoiding stringstream
completely. There are _many_ such cases. This can't be handled by only
treating them separately, as in your suggestion.

I'll include the complete conversion table, when posting about it soon.

- Even if you only consider one parameter, you may _still_ need partial
specialisation, in order to deal with different character types. Consider
this (from lexical_cast.hpp):

// From std::basic_string to CharType

template<class CharType, class CharTraits, class Allocator>
struct lexical_cast_impl<CharType, std::basic_string<CharType, CharTraits,
Allocator> > :
  string_to_char_base<CharType, const std::basic_string<CharType,
CharTraits, Allocator> &> {};

In many cases, you don't need partial specialisation, caused by using both
source and target as parameters. In any case, there's a section that
simulates all the specialisations, for compilers without PTS, so it works on
MSVC and BCC, too. :) (I know BCC has PTS, but let's be honest with
ourselves... It's buggy.)

In the case where the PTS is simulated, it only handles char/wchar_t, not
arbitrary character types. However, come to think of it, since basic_string
exports the character type, traits type and allocator type (as typedefs), it
would be possible to make the simulated PTS work also for arbitrary
character types. Hm... :) I'll look into that.

>> Since Kevlin hadn't got around to reviewing the original proposal, I
>> with any changes. However, as it now seems he may do it, and due to the
>> release date extension, I'll look into adding this, as well, and look
>> the proposal in this posting.

>In fact the two approaches could be merged to have both de-coupling and
>solve the char/wchar_t: we could use a machinery like the one in your
>proposal to choose the "right" interpreter (think about Target and
>Source "negotiating" the best one), then use the two inserter/extractor
>helper functions. What do you think?

That might be possible, but I don't know how much it buys you, as the use of
base classes to factor out the special cases, means that there isn't that
much code there. However, it seems you also realise here that you may need
to consider both types, when selecting an implementation.

What we could do, is that when I upload, and post about, the new update, you
can look into it, and see if separating the two functions could make it

I appreciate a lot the feedback I've got from you, Gennaro, Victor, Rob, and
the others regarding this one, and you'll be credited.

As Aleksey said it in the MPL review, you Boosters rock. :)

By the way, I realise that some of this may be confusing, as it refers to a
version that hasn't yet been uploaded. It should be much clearer when it's
uploaded, and things like the conversion table is provided.



Boost list run by bdawes at, gregod at, cpdaniel at, john at