Boost logo

Boost :

From: Terje Slettebø (tslettebo_at_[hidden])
Date: 2002-08-22 05:44:33


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

> a discussion on an STLport forum triggered a little discussion on
> lexical_cast. I believe that current implementation has a couple of flaws:
>
> 1) it requires that both the Target and Source type have a operator>> and
> operator<<, respectively.

That's the point. It's supposed to convert between the lexical
representation of types. This is, as I understand, given by their stream
operators.

However, you may provide specialisations, as you point out below here.

> There are situation in which it is desirable not
> to define those operators (for example, SGI rope does not have the
> operator>>). It's true that you can always provide something that you
don't
> have...
>
> 2) sometimes, operator<< or operator>> may perform a task different than
the
> one suitable by lexical_cast.
>
> Notice that in both cases, the "problematic" type is the Target. In fact
you
> could solve the problem via overload if it was the Source type, but you
> can't overload according to the return type. In order to solve both issues
> and also gain a bit or flexibility the simplest solution would to use two
> helper functions, like this:
>
> template<typename Source>
> inline bool lexical_cast_inserter(std::ostream& interpreter, const Source&
> s)
> {
> return (interpreter << s).good();
> }
>
> template<typename Target>
> inline bool lexical_cast_extractor(std::stringstream& interpreter, Target&
> t)
> {
> return (interpreter >> t).good() && (interpreter >> std::ws).eof();
> }
>
> Target operator()(Source arg) const
> {
> std::stringstream interpreter;
>
> Target result;
> if(!lexical_cast_inserter(interpreter, s) ||
> !lexical_cast_extractor(interpreter, result))
> throw bad_lexical_cast();
> return result;
> }
>
> The reason why the first argument in lexical_cast_extractor is
> std::stringstream and not std::istream is just to allow possible
> optimizations (see below). Then we could write (or let the user write)
> specializations for string and rope like this:
>
> template<>
> inline bool lexical_cast_extractor(std::stringstream& interpreter,
> std::string& t)
> {
> t = interpreter.str();
> return true;
> }
>
> template<>
> inline bool lexical_cast_extractor(std::stringstream& interpreter,
> std::crope& t)
> {
> t = interpreter.str().c_str();
> return true;
> }
>
> Does this make sense to anyone?

Sure. As mentioned earlier, in cooperation with Kevlin Henney, and with
feedback from people here, I've made a new version of lexical_cast, which is
here (http://groups.yahoo.com/group/boost/files/lexical_cast_proposition/).
This was finished about a month ago. However, Kevlin hasn't yet reviewed it,
and due to the upcoming new Boost release, I've mailed him about this. He
said he'd check the new version out.

The above may be done with the new version, by specialising the
lexical_cast_impl template. However, also to accomodate the speedup
suggested by Gennadiy
(http://groups.yahoo.com/group/boost/files/lexical_cast_propositions/), it
may be useful to instead use two such insertion/extraction function/struct
templates. A struct template may be better, as you can't partially
specialise a function template.

> template<>
> inline bool lexical_cast_extractor(std::stringstream& interpreter,
> std::string& t)
> {
> t = interpreter.str();
> return true;
> }

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

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

Also, as mentioned above, Gennadiy has proposed that when the source is
std::string/char *, then the interpreter could be initialised with it,
directly (rather than default-constructing, and using the stream insertion
operator). This could improve the efficiency, which he's also found by
timing.

Since Kevlin hadn't got around to reviewing the original proposal, I waited
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 into
the proposal in this posting.

> template<>
> inline bool lexical_cast_extractor(std::stringstream& interpreter,
> std::crope& t)
> {
> t = interpreter.str().c_str();
> return true;
> }

Regards,

Terje


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk