Boost logo

Boost Users :

From: Terje Slettebų (terje.s_at_[hidden])
Date: 2002-05-23 07:21:40


>From: ravioli_at_[hidden]

>Would it be possible to use an existing conversion operator ?
>Example :
>class Output {
>...
>}

>class Input {
> operator Output(void) [ return ... ; }
>}

>Then :
>lexical_cast<Output>( Input )
>... would use this conversion operator.

It would be possible, yes.

That would mean that it uses the fastest and most accurate conversion
available, and only resorts to using stringstream when it has to. That seems
like a good idea.

I've incorporated this change, and updated the version in the Boost files
section
(http://groups.yahoo.com/group/boost/files/lexical_cast_proposition/). It
uses boost::is_convertible for it. Even if that may not work on all
compilers, if it doesn't work, it will just resort to using stringstream.
Thanks for the suggestion. :)

Actually, come to think of it, this also makes some of the special case
handling in the previous version obsolete, and that's a good thing. This
includes things like converting from char to char, or wchar_t to wchar_t.
Therefore, I've removed those special cases, where they are handled by
implicit conversion. There's still conversion between char and string, that
needs special handling.

However, this does mean that the semantics is changed slightly. In the cases
where an implicit conversion exists, it may give a different result than if
not, in the case of char/wchar_t. Without implict conversion, you get 1 ->
'1'. With implicit conversion, you get 1 -> 1 (ASCII 1). As far as I can
tell, this only affects conversions between char/wchar_t and other types,
though. If this is a problem, please let me know, and I can change it to
make an exception for char/wchar_t.

Another thing I've been thinking of, is some way to configure the
interpreter stream, to be able to change the formatting, such as number
base, precision and field width.

In fact, I've just now made a version where that is possible, _without_
changing the interface of lexical_cast. I've updated the version in the
Boost files version with this. I'll post the details for how to use the
stream configuration, in another posting.

>This article
>http://www.cuj.com/experts/1810/alexandr.htm?topic=experts
>
>... describes how it is possible at compile-time to detect whether a class
A is convertible to class B,
>ie if an operator already exists. If so, we would not need in
lexical_cast<> to use the serialization operation.

Exactly. In fact, I'm both using the conversion (using
boost::is_convertible), and the Int2Type technique descibed in the article
(and in "Modern C++ Design"), in order to make it work, to select between
implicit conversion, or using stringstream. Without the Int2Type technique,
it won't compile. I'm using a different name in the source, though, but the
technique is the same:

template<bool flag>
struct int_to_type
{
};

>What also would be great, is to specialise lexical_cast<> for conversion
where is very fast builtin function or operator already exists.

That's also an idea. Again, this means it would use the most efficient way
possible. However, it may not work that well with things like locale, and if
configuration of the interpreter is possible. Maybe have the specialisations
as an option.

Do you know about any such fast functions or operators (besides the
conversion operators mentioned earlier here) for some types?

Thanks for the feedback. :)

Regards,

Terje

  ----- Original Message -----
  From: Terje Slettebų
  To: Boost-Users_at_[hidden]
  Sent: Wednesday, May 22, 2002 10:46 PM
  Subject: RE: [Boost-Users] boost::lexical_cast string to string problem -
New proposition available

>--- In Boost-Users_at_y..., Tom Matelich <tmatelich_at_z...> wrote:
> I and many others have requested fixes for this for a very long time.
> Basically, it involves creating class templates to do the actual
  conversion.
> It's not the most complicated system, just nobody has done it yet. If
you
> search the boost list archives, you'll see a lot of mail about this.
  There
> is no quick solution to your problem though.

  I've searched the archive, now, and see that there's been quite a few
  propositions for changes, but apparently none of them have ended up in the
  lexical_cast implementation.

  There's also a couple of propositions, here
  (http://groups.yahoo.com/group/boost/files/lexical_cast_propositions/).

  Some of the proposed changes are:

  - wlexical_cast - A version that can use wide characters
  - basic_lexical_cast - A version that takes the interpreter (stringstream)
  as a parameter, to support things like changing locale
  - Being able to set number base (dec, oct or hex). This would be
implicitly
  possible using basic_lexical_cast
  - Being able to set precision for numerical conversions. This may also be
  done with basic_lexical_cast
  - Checking for change of sign, when using unsigned numbers. This is
  addressed using an integer adapter, in the above lexical_cast_propositions

  One problem with doing these changes, after having talked with Kevlin
Henney
  a while ago (without knowing it had been already proposed, I proposed an
  extra parameter, for setting the number base). is that he prefers to not
  have extra parameters in the interface, as it then will no longer look
like
  a cast, and it may be less generic, depending on the way it's done. For
  example, a base-setting argument wouldn't make much sense if you converted
  from floating point to string.

  In any case, I have actually just now made a version of lexical_cast, that
  fixes the problem pointed out by OP, here, and I've made it available in
the
  Boost files section
  (http://groups.yahoo.com/group/boost/files/lexical_cast_proposition/).
I've
  also put a unit test for it, there. Feedback is welcome.

  It doesn't change the interface in any way, so it should be ok.

  The new version supports conversion between string and char, including
char
  containing whitespace, and when the string is empty, or containing only
  whitespace.

  If the source or destination (or both) is basic_string or char/wchar_t, it
  will set the interpreter to use the char type used, so it implicitely
  supports wide characters. Wide character support requires partial
  specialisation if one of the operands is not either basic_string or
  char/wchar_t.

  In the case where the source is basic_string, it also uses pass by const
  reference, for efficiency.

  It's tested on Intel C++ 6.0, MSVC 6.0 and BCC 5.6.

  Regards,

  Terje


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net