Boost logo

Boost :

From: Terje Slettebø (tslettebo_at_[hidden])
Date: 2002-05-24 23:04:07


>From: "Neal D. Becker" <nbecker_at_[hidden]>

> I was surprised to find that lexical_cast<bool> only accepts ascii
> numbers. I think it should also accept "true/false". iostream can be
> set to output bool as "true/false".

Good point. The reason it doesn't accept "true/false", is that it uses a
default-constructed stringstream, and with such a stream the
ios_base::boolalpha flag is not set, so reading/writing bool uses 0 and 1,
rather than true/false (or some other locale-dependent names).

To get around this, you need to be able to set the state of the stringstream
used to perform the conversion. That's possible in the lexical_cast version
I've uploaded in the Boost files section (lexical_cast_proposition).

Note, however, that due to implicit conversion from char * to bool, this
doesn't work in that version. In fact, I've found now that much of the
conversions doesn't work, now, because of the implicit conversions. The
reason this wasn't detected in the unit test, was that the test used to
convert back and forth, and compare if you got the same result. In other
words, it didn't check the result of the conversion, directly. I've now
changed the unit test, to test the result of the conversion. I'll upload new
versions of lexical_cast and the test, soon, and I'll post a note about it
when I do.

Currently, to avoid changing the interface of lexical_cast, configuring the
stringstream object is done using a static stringstream object in the
lexical_cast implementation. However, this is not thread-safe, so I'm
working on a new version where you can supply the stringstream object as an
optional argument to lexical_cast. Either way will be possible, to get
feedback.

So, in order to configure the stream used for the conversion, in the
proposed version, this may either be perfomed without changing the
interface, using a static object, which is not thread-safe, or allow change
in the interface, to add a parameter, and get a thread safe-stream
configuration.

To solve what you say, here, one may use either of the following ways:

Using static stringstream object (not thread-safe):

--- Start ---

#define BOOST_LEXICAL_CAST_STREAM // To enable stream configuration, using
static stringstream

#include <iostream>
#include <iomanip>
#include "lexical_cast.hpp"

int main()
{
std::cout << boost::lexical_cast<bool>("1") << '\n'; // Prints "1"
std::cout << boost::lexical_cast<bool>("0") << '\n'; // Prints "0"

boost::lexical_cast_stream<bool,char *>::stream() << std::boolalpha;
boost::lexical_cast_stream<bool,char *>::stream() >> std::boolalpha;

std::cout << boost::lexical_cast<bool>("true") << '\n'; // Prints
"1"
std::cout << boost::lexical_cast<bool>("false") << '\n'; // Prints "0"
std::cout << boost::lexical_cast<std::string>(true) << '\n'; // Prints
"true"
std::cout << boost::lexical_cast<std::string>(false) << '\n'; // Prints
"false"
}

The names used for true/false also depends on the locale, which may be
changed, as well.

--- End ---

Alternative way, using optional stream parameter (thread-safe):

--- Start ---

#include <iostream>
#include <iomanip>
#include "lexical_cast.hpp"

int main()
{
std::cout << boost::lexical_cast<bool>("1") << '\n'; // Prints "1"
std::cout << boost::lexical_cast<bool>("0") << '\n'; // Prints "0"

boost::lexical_cast_stream<bool,char *>::stream_type stream;

stream << std::boolalpha;
stream >> std::boolalpha;

std::cout << boost::lexical_cast<bool>("true",stream) << '\n'; //
Prints "1"
std::cout << boost::lexical_cast<bool>("false",stream) << '\n'; //
Prints "0"
std::cout << boost::lexical_cast<std::string>(true,stream) << '\n'; //
Prints "true"
std::cout << boost::lexical_cast<std::string>(false,stream) << '\n'; //
Prints "false"
}

--- End ---

The names uses the locale here, as well.

Using such stream configuration, you can configure the stream in any way,
such as setting precision, number base (dec, hex, oct), field width, locale,
etc.

What is people's opinion on such configuration, and how it's done, here? Any
suggestion for alternative ways?

It appears to in order to get a thread-safe version, the stream parameter
has to be supplied. However, this changes the interface, if that
functionality is to be used.

Note: The second version isn't made, yet. A version with both possibilities
will be made available, soon.

As usual, any comments are welcome.

Regards,

Terje


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