From 07cb73a96c116086dd6a90ccfc42a092fbcae7c2 Mon Sep 17 00:00:00 2001 From: nobody Date: Sat, 1 Mar 2003 19:43:06 +0000 Subject: [PATCH 01/12] This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'. [SVN r17693] From 027afb3a8745c00f92e456ba643bebbe0b9da9c1 Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Wed, 12 Mar 2003 21:33:16 +0000 Subject: [PATCH 02/12] update from Kevlin and Terje [SVN r17861] --- include/boost/lexical_cast.hpp | 189 +++++++++++--- lexical_cast.htm | 356 +++++++++++--------------- lexical_cast_test.cpp | 454 ++++++++++++++++++++++----------- 3 files changed, 607 insertions(+), 392 deletions(-) diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index bd37e9a..924d6ac 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -1,31 +1,29 @@ -// boost lexical_cast.hpp header -------------------------------------------// - -// See http://www.boost.org/libs/conversion for documentation. - #ifndef BOOST_LEXICAL_CAST_INCLUDED #define BOOST_LEXICAL_CAST_INCLUDED +// boost lexical_cast.hpp header --------------------------------------------// + +// See http://www.boost.org/libs/conversion for documentation. +// See end of this header for rights and permissions. +// // what: lexical_cast custom keyword cast -// who: contributed by Kevlin Henney, with alternative naming, behaviors -// and fixes contributed by Dave Abrahams, Daryle Walker and other -// Boosters on the list -// when: November 2000 -// where: tested with MSVC 6.0, BCC 5.5, and g++ 2.91 - -#include - -// Some sstream implementations are broken for the purposes of lexical cast. -# if defined(BOOST_NO_STRINGSTREAM) -# define BOOST_LEXICAL_CAST_USE_STRSTREAM -# endif - -#ifdef BOOST_LEXICAL_CAST_USE_STRSTREAM -# include -#else -# include -#endif +// who: contributed by Kevlin Henney, +// enhanced with contributions from Terje Slettebų, +// with additional fixes and suggestions from Gennaro Prota, +// Dave Abrahams, Daryle Walker, and other Boosters on the list +// when: November 2000, March 2003 +#include #include +#include +#include +#include + +#ifdef BOOST_NO_STRINGSTREAM +#include +#else +#include +#endif namespace boost { @@ -33,35 +31,146 @@ namespace boost class bad_lexical_cast : public std::bad_cast { public: - // constructors, destructors, and assignment operator defaulted - - // function inlined for brevity and consistency with rest of library - virtual const char * what() const throw() + virtual ~bad_lexical_cast() throw() { - return "bad lexical cast: " - "source type value could not be interpreted as target"; } }; + namespace detail // actual underlying concrete exception type + { + template + class no_lexical_conversion : public bad_lexical_cast + { + public: + no_lexical_conversion() + : description( + std::string() + "bad lexical cast: " + + "source type value could not be interpreted as target, Target=" + + typeid(Target).name() + ", Source=" + typeid(Source).name()) + { + } + virtual ~no_lexical_conversion() throw() + { + } + virtual const char *what() const throw() + { + return description.c_str(); + } + private: + const std::string description; // static initialization fails on MSVC6 + }; + } + + namespace detail // selectors for choosing stream character type + { + template + struct stream_char + { + typedef char type; + }; + + #ifndef BOOST_NO_STRINGSTREAM + template<> + struct stream_char + { + typedef wchar_t type; + }; + + template<> + struct stream_char + { + typedef wchar_t type; + }; + + template<> + struct stream_char + { + typedef wchar_t type; + }; + + template<> + struct stream_char + { + typedef wchar_t type; + }; + #endif + + template + struct widest_char + { + typedef TargetChar type; + }; + + template<> + struct widest_char + { + typedef wchar_t type; + }; + } + + namespace detail // stream wrapper for handling lexical conversions + { + template + class lexical_stream + { + public: + lexical_stream() + { + stream.unsetf(std::ios::skipws); + + if(std::numeric_limits::is_specialized) + stream.precision(std::numeric_limits::digits10 + 1); + else if(std::numeric_limits::is_specialized) + stream.precision(std::numeric_limits::digits10 + 1); + } + ~lexical_stream() + { + #if defined(BOOST_NO_STRINGSTREAM) + stream.freeze(false); + #endif + } + bool operator<<(const Source &input) + { + return stream << input; + } + template + bool operator>>(InputStreamable &output) + { + return !is_pointer::value && + stream >> output && + (stream >> std::ws).eof(); + } + template + bool operator>>(std::basic_string &output) + { + return std::getline(stream, output, char_type()).eof(); + } + private: + typedef typename widest_char< + typename stream_char::type, + typename stream_char::type>::type char_type; + + #if defined(BOOST_NO_STRINGSTREAM) + std::strstream stream; + #else + std::basic_stringstream stream; + #endif + }; + } + template Target lexical_cast(Source arg) { -# ifdef BOOST_LEXICAL_CAST_USE_STRSTREAM - std::strstream interpreter; // for out-of-the-box g++ 2.95.2 -# else - std::stringstream interpreter; -# endif + detail::lexical_stream interpreter; Target result; - if(!(interpreter << arg) || !(interpreter >> result) || - !(interpreter >> std::ws).eof()) - throw bad_lexical_cast(); - + if(!(interpreter << arg && interpreter >> result)) + throw detail::no_lexical_conversion(); return result; } } -// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. +// Copyright Kevlin Henney, 2000-2003. All rights reserved. // // Permission to use, copy, modify, and distribute this software for any // purpose is hereby granted without fee, provided that this copyright and @@ -69,8 +178,4 @@ namespace boost // // This software is provided "as is" without express or implied warranty. -#ifdef BOOST_LEXICAL_CAST_USE_STRSTREAM -# undef BOOST_LEXICAL_CAST_USE_STRSTREAM -#endif - #endif diff --git a/lexical_cast.htm b/lexical_cast.htm index 870068d..6b52fb5 100644 --- a/lexical_cast.htm +++ b/lexical_cast.htm @@ -1,99 +1,94 @@ - - lexical_cast - - - - - - -

c++boost.gif (8819 bytes)Header -boost/lexical_cast.hpp

- - - -
-

Motivation

- -Sometimes a value must be converted to a literal text form, such as an -int represented as a string, or vice-versa, when -a string is interpreted as an int. Such examples -are common when converting between data types internal to a program and -representation external to a program, such as windows and configuration files. -

-The standard C and C++ libraries offer a number of facilities for performing -such conversions. However, they vary with their ease of use, extensibility, -and safety. -

-For instance, there are a number of limitations with the family of standard C -functions typified by atoi: -

    -
  • - Conversion is supported in one direction only: from text to - internal data type. Converting the other way using the C library - requires either the inconvenience and compromised safety of the - sprintf function, or the loss of portability associated - with non-standard functions such as itoa. -
  • -
  • - The range of types supported is only a subset of the built-in numeric - types, namely int, long, - and double. -
  • -
  • - The range of types cannot be extended in a uniform manner. For - instance, conversion from string representation to - complex or rational. -
  • -
-The standard C functions typified by strtol have the same basic -limitations, but offer finer control over the conversion process. However, for -the common case such control is often either not required or not used. The -scanf family of functions offer even greater control, but also -lack safety and ease of use. -

-The standard C++ library offers stringstream for the kind of -in-core formatting being discussed. It offers a great deal of control over the -formatting and conversion of I/O to and from arbitrary types through text. -However, for simple conversions direct use of stringstream can be -either clumsy (with the introduction of extra local variables and the loss of -infix-expression convenience) or obscure (where stringstream -objects are created as temporary objects in an expression). Facets provide a -comprehensive concept and facility for controlling textual representation, but -their relatively high entry level requires an extreme degree of involvement -for simple conversions. -

-The lexical_cast template function offers a convenient and consistent -form for supporting common conversions to and from arbitrary types when they are -represented as text. The simplification it offers is in expression-level -convenience for such conversions. For more involved conversions, such as where -precision or formatting need tighter control than is offered by the default -behavior of lexical_cast, the conventional -stringstream approach is recommended. Where the conversions are -numeric to numeric, numeric_cast -may offer more reasonable behavior than lexical_cast. -

-For a good discussion of the options and issues involved in string-based formatting, -including comparison of stringstream, lexical_cast, and -others, see Herb Sutter's article, -The String Formatters of Manor Farm. -

- -


-

Examples

- -The following example treats command line arguments as a sequence of numeric data: -
-
+	
+		lexical_cast
+		
+		
+	
+	
+		

c++boost.gif (8819 bytes)Header + boost/lexical_cast.hpp

+ +
+

Motivation

+ Sometimes a value must be converted to a literal text form, such as an int + represented as a string, or vice-versa, when a string + is interpreted as an int. Such examples are common when converting + between data types internal to a program and representation external to a + program, such as windows and configuration files. +

+ The standard C and C++ libraries offer a number of facilities for performing + such conversions. However, they vary with their ease of use, extensibility, and + safety. +

+ For instance, there are a number of limitations with the family of standard C + functions typified by atoi: +

    +
  • + Conversion is supported in one direction only: from text to internal data type. + Converting the other way using the C library requires either the inconvenience + and compromised safety of the sprintf function, or the loss of + portability associated with non-standard functions such as itoa. +
  • +
  • + The range of types supported is only a subset of the built-in numeric types, + namely int, long, and double. +
  • +
  • + The range of types cannot be extended in a uniform manner. For instance, + conversion from string representation to complex or rational. +
  • +
+ The standard C functions typified by strtol have the same basic + limitations, but offer finer control over the conversion process. However, for + the common case such control is often either not required or not used. The scanf + family of functions offer even greater control, but also lack safety and ease + of use. +

+ The standard C++ library offers stringstream for the kind of + in-core formatting being discussed. It offers a great deal of control over the + formatting and conversion of I/O to and from arbitrary types through text. + However, for simple conversions direct use of stringstream can be + either clumsy (with the introduction of extra local variables and the loss of + infix-expression convenience) or obscure (where stringstream + objects are created as temporary objects in an expression). Facets provide a + comprehensive concept and facility for controlling textual representation, but + their perceived complexity and high entry level requires an extreme degree of + involvement for simple conversions, and excludes all but a few programmers. +

+ The lexical_cast function template offers a convenient and + consistent form for supporting common conversions to and from arbitrary types + when they are represented as text. The simplification it offers is in + expression-level convenience for such conversions. For more involved + conversions, such as where precision or formatting need tighter control than is + offered by the default behavior of lexical_cast, the conventional + stringstream approach is recommended. Where the conversions are + numeric to numeric, numeric_cast + may offer more reasonable behavior than lexical_cast + . +

+ For a good discussion of the options and issues involved in string-based + formatting, including comparison of stringstream, lexical_cast, + and others, see Herb Sutter's article, + The String Formatters of Manor Farm + . +

+


+

Examples

+ The following example treats command line arguments as a sequence of numeric + data:
+
 int main(int argc, char * argv[])
 {
     using boost::lexical_cast;
@@ -115,11 +110,8 @@ int main(int argc, char * argv[])
     ...
 }
 
-
- -The following example uses numeric data in a string expression: -
-
+			
The following example uses numeric data in a string expression:
+
 void log_message(const std::string &);
 
 void log_errno(int yoko)
@@ -127,15 +119,12 @@ void log_errno(int yoko)
     log_message("Error " + boost::lexical_cast<std::string>(yoko) + ": " + strerror(yoko));
 }
 
-
- -
-

Synopsis

- -Library features defined in "boost/lexical_cast.hpp": - -
-
+			
+
+

Synopsis

+ Library features defined in "boost/lexical_cast.hpp": +
+
 namespace boost
 {
     class bad_lexical_cast;
@@ -143,110 +132,65 @@ namespace boost
       Target lexical_cast(Source arg);
 }
 
-
- -Test harness defined in "lexical_cast_test.cpp". -

- -


-

lexical_cast

- -
-
+			
Unit test defined in "lexical_cast_test.cpp". +

+


+

lexical_cast

+
+
 template<typename Target, typename Source>
   Target lexical_cast(Source arg);
 
-
- -Returns the result of streaming arg into a std::stringstream and then -out as a Target object. If the conversion is unsuccessful, a -bad_lexical_cast exception is thrown. -

-The requirements on the argument and result types are: -

    -
  • - Source is OutputStreamable, meaning that an - operator<< is defined that takes a - std::ostream object on the left hand side and an instance - of the argument type on the right. -
  • -
  • - Both Source and Target are CopyConstructible [20.1.3]. -
  • -
  • - Target is InputStreamable, meaning that an - operator>> is defined that takes a - std::istream object on the left hand side and an instance - of the result type on the right. -
  • -
  • - Target is DefaultConstructible, meaning that it is - possible to default-initialize an object of that type [8.5, 20.1.3]. -
  • -
  • - Target is Assignable [23.1]. -
  • -
-

- -


-

bad_lexical_cast

- -
-
+			
Returns the result of streaming arg into a std::stringstream + and then out as a Target object. Note that spaces are significant + in any conversion and are not skipped. If the conversion is unsuccessful, a + bad_lexical_cast + exception is thrown. +

+ The requirements on the argument and result types are: +

    +
  • + Source is OutputStreamable, meaning that an operator<< + is defined that takes a std::ostream or std::wostream object on the + left hand side and an instance of the argument type on the right. +
  • +
  • + Both Source and Target are CopyConstructible [20.1.3]. +
  • +
  • + Target is InputStreamable, meaning that an operator>> + is defined that takes a std::istream or std::wistream object on the left hand side + and an instance of the result type on the right. +
  • +
  • + Target is DefaultConstructible, meaning that it is possible + to default-initialize an object of that type [8.5, 20.1.4]. +
  • +
+ The character type of the underlying stream is assumed to be char unless + the either the Source or the Target type is wchar_t + or a wide-character string type — either wchar_t * or std::wstring — + in which case wchar_t is used. +

+ Where a higher degree of control is required over conversions, std::stringstream + and std::wstringstream offer a more appropriate path. Where non-stream-based conversions are + required, lexical_cast + is the wrong tool for the job, and is not special-cased for such scenarios. +

+


+

bad_lexical_cast

+
+
 class bad_lexical_cast : public std::bad_cast
 {
 public:
-    virtual const char * what() const throw();
+    ... // same member function interface as std::exception
 };
 
-
- -Exception used to indicate runtime lexical_cast failure. -

- -


-

Portability

- -To date the code and test harness have been compiled successfully using -Microsoft Visual C++ 6.0, Borland C++ 5.5, and GNU g++ 2.91. Tests have run successfully for -Microsoft Visual C++ 6.0 and Borland C++ 5.5. For g++ streams interpret any integer, rather than -just 0 and 1, as valid for bool; the other tests pass -without problem. The deprecated standard header <strstream> is used in -preference to the standard <sstream> header for out-of-the-box g++ support. -

- -


-

Future directions

- -
    -
  • - Improved string handling, correctly accommodating wide character strings, incompatible - basic_string types, and empty strings. -
  • -
  • - Optimize the use of a stream away for identity conversions. -
  • -
  • - An interpret_cast that performs a do-something-reasonable conversion between - types. It would, for instance, select between numeric_cast and lexical_cast - based on std::numeric_limits<>::is_specialized. This would be an interesting - project, but there are no concrete plans to pursue this at the moment. -
  • -
  • - It is also worth mentioning future non-directions: anything that involves adding extra - arguments for a conversion operation is not being considered. A custom keyword cast, such as - lexical_cast, is intended to look like a built-in cast operator: built-in cast operators - take only a single operand. Where a higher degree of control is required over conversions, the - standard stringstream offers a more appropriate path. Where non-stream-based conversions - are required, lexical_cast is the wrong tool for the job, and so it won't be special-cased - for such scenarios. -
  • -
- -
- -
© Copyright Kevlin Henney, 2000, 2002
- - +
Exception used to indicate runtime lexical_cast + failure. +

+


+
© Copyright Kevlin Henney, 2000–2003
+ diff --git a/lexical_cast_test.cpp b/lexical_cast_test.cpp index c19cf08..1d3c631 100644 --- a/lexical_cast_test.cpp +++ b/lexical_cast_test.cpp @@ -1,149 +1,315 @@ -// boost lexical_cast_test.cpp program -------------------------------------// - -// See http://www.boost.org for most recent version including documentation. - -// what: lexical_cast custom keyword cast tests -// who: contributed by Kevlin Henney -// when: October 2000 -// where: tested with MSVC 6.0 and BCC 5.5 - -#include -#include "test.hpp" -#include -#include -#include - -using namespace boost; -using namespace std; - -typedef test::test test_case; -typedef const test_case * test_case_iterator; - -extern const test_case_iterator begin, end; - -int main() -{ - test::tester test_suite(begin, end); - return test_suite() ? EXIT_SUCCESS : EXIT_FAILURE; -} - -void test_to_string() -{ - test::check_equal( - lexical_cast(2001), "2001", - "2001 -> \"2001\""); - test::check_equal( - lexical_cast(2001.0), "2001", - "2001.0 ->\"2001\""); - test::check_equal( - lexical_cast(complex(2000,1)), "(2000,1)", - "complex(2000,1) -> \"(2000,1)\""); -} - -void test_to_int() -{ - test::check_equal( - lexical_cast("2001"), 2001, - "\"2001\" -> 2001"); - test::check_equal( - lexical_cast(" 2001"), 2001, - "\" 2001\" -> 2001"); - test::check_equal( - lexical_cast("2001 "), 2001, - "\"2001 \" -> 2001"); - TEST_CHECK_THROW( - lexical_cast("Two thousand and one"), - bad_lexical_cast, - "\"Two thousand and one\""); - TEST_CHECK_THROW( - lexical_cast("2001: A Space Odyssey"), - bad_lexical_cast, - "\"2001: A Space Odyssey\""); - TEST_CHECK_THROW( - lexical_cast(200.1), - bad_lexical_cast, - "200.1"); - TEST_CHECK_THROW( - lexical_cast("200e1"), - bad_lexical_cast, - "\"200e1\""); -} - -void test_to_char() -{ - test::check_equal( - lexical_cast("2"), '2', - "\"2\" -> '2'"); - test::check_equal( - lexical_cast(" 2"), '2', - "\" 2\" -> '2'"); - test::check_equal( - lexical_cast("2 "), '2', - "\"2 \" -> '2'"); - test::check_equal( - lexical_cast(2), '2', - "2 -> '2'"); - TEST_CHECK_THROW( - lexical_cast("2001"), - bad_lexical_cast, - "\"2001\""); - TEST_CHECK_THROW( - lexical_cast(2001), - bad_lexical_cast, - "2001"); -} - -void test_to_double() -{ - test::check_equal( - lexical_cast("1e6"), 1e6, - "\"1e6\" -> 1e6"); - test::check_equal( - lexical_cast("1e-2"), 1e-2, - "\"1e-2\" -> 1e-2"); -} - -void test_to_bool() -{ - test::check_equal( - lexical_cast(1), true, - "1 -> true"); - test::check_equal( - lexical_cast('0'), false, - "'0' -> false"); - TEST_CHECK_THROW( - lexical_cast(2001), - bad_lexical_cast, - "2001"); - TEST_CHECK_THROW( - lexical_cast(2), - bad_lexical_cast, - "2"); - TEST_CHECK_THROW( - lexical_cast("true thousand and one"), - bad_lexical_cast, - "\"true thousand and one\""); -} - -const test_case test_cases[] = -{ - { "lexical_cast", test_to_string }, - { "lexical_cast", test_to_int }, - { "lexical_cast", test_to_char }, - { "lexical_cast", test_to_double }, - { "lexical_cast", test_to_bool } -}; - -const test_case_iterator begin = test_cases; -const test_case_iterator end = - test_cases + (sizeof test_cases / sizeof *test_cases); - -// Copyright Kevlin Henney, 2000. All rights reserved. +// Unit test for boost::lexical_cast. +// +// See http://www.boost.org for most recent version, including documentation. +// +// Copyright Terje Slettebų and Kevlin Henney, 2003. // // Permission to use, copy, modify, and distribute this software for any // purpose is hereby granted without fee, provided that this copyright and -// permissions notice appear in all copies and derivatives, and that no -// charge may be made for the software and its documentation except to cover -// cost of distribution. +// permissions notice appear in all copies and derivatives. // // This software is provided "as is" without express or implied warranty. + +#include + +#if defined(__INTEL_COMPILER) +#pragma warning(disable: 383 488 981 1418 1419) +#elif defined(BOOST_MSVC) +#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800) +#endif + +#include +#include +#include + +// If BOOST_NO_STRINGSTREAM is defined wide character support is unavailable, +// and all wide character tests are disabled. + +#ifdef BOOST_NO_STRINGSTREAM +#define NO_WIDE_CHAR_SUPPORT +#endif + +using namespace boost; + +void test_conversion_to_char(); +void test_conversion_to_int(); +void test_conversion_to_double(); +void test_conversion_to_bool(); +void test_conversion_to_string(); +void test_conversion_to_pointer(); +void test_conversion_from_wchar_t(); +void test_conversion_to_wchar_t(); +void test_conversion_from_wstring(); +void test_conversion_to_wstring(); + +unit_test_framework::test_suite *init_unit_test_suite(int, char **) +{ + unit_test_framework::test_suite *suite = + BOOST_TEST_SUITE("lexical_cast unit test"); + suite->add(BOOST_TEST_CASE(test_conversion_to_char)); + suite->add(BOOST_TEST_CASE(test_conversion_to_int)); + suite->add(BOOST_TEST_CASE(test_conversion_to_double)); + suite->add(BOOST_TEST_CASE(test_conversion_to_bool)); + suite->add(BOOST_TEST_CASE(test_conversion_to_pointer)); + suite->add(BOOST_TEST_CASE(test_conversion_to_string)); + #ifndef NO_WIDE_CHAR_SUPPORT + suite->add(BOOST_TEST_CASE(test_conversion_from_wchar_t)); + suite->add(BOOST_TEST_CASE(test_conversion_to_wchar_t)); + suite->add(BOOST_TEST_CASE(test_conversion_from_wstring)); + suite->add(BOOST_TEST_CASE(test_conversion_to_wstring)); + #endif + return suite; +} + +void test_conversion_to_char() +{ + BOOST_CHECK_EQUAL('A', lexical_cast('A')); + BOOST_CHECK_EQUAL(' ', lexical_cast(' ')); + BOOST_CHECK_EQUAL('1', lexical_cast(1)); + BOOST_CHECK_EQUAL('0', lexical_cast(0)); + BOOST_CHECK_THROW(lexical_cast(123), boost::bad_lexical_cast); + BOOST_CHECK_EQUAL('1', lexical_cast(1.0)); + BOOST_CHECK_EQUAL('1', lexical_cast(true)); + BOOST_CHECK_EQUAL('0', lexical_cast(false)); + BOOST_CHECK_EQUAL('A', lexical_cast("A")); + BOOST_CHECK_EQUAL(' ', lexical_cast(" ")); + BOOST_CHECK_THROW(lexical_cast(""), boost::bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast); + BOOST_CHECK_EQUAL('A', lexical_cast("A")); + BOOST_CHECK_EQUAL(' ', lexical_cast(" ")); + BOOST_CHECK_THROW(lexical_cast(""), boost::bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast); + BOOST_CHECK_EQUAL('A', lexical_cast(std::string("A"))); + BOOST_CHECK_EQUAL(' ', lexical_cast(std::string(" "))); + BOOST_CHECK_THROW( + lexical_cast(std::string("")), boost::bad_lexical_cast); + BOOST_CHECK_THROW( + lexical_cast(std::string("Test")), boost::bad_lexical_cast); +} + +void test_conversion_to_int() +{ + BOOST_CHECK_EQUAL(1,lexical_cast('1')); + BOOST_CHECK_EQUAL(0,lexical_cast('0')); + BOOST_CHECK_THROW(lexical_cast('A'),boost::bad_lexical_cast); + BOOST_CHECK_EQUAL(1,lexical_cast(1)); + BOOST_CHECK_EQUAL( + std::numeric_limits::max(), + lexical_cast(std::numeric_limits::max())); + BOOST_CHECK_EQUAL(1,lexical_cast(1.0)); + + BOOST_CHECK_THROW(lexical_cast(1.23), boost::bad_lexical_cast); + + BOOST_CHECK_THROW(lexical_cast(1e20), boost::bad_lexical_cast); + BOOST_CHECK_EQUAL(1, lexical_cast(true)); + BOOST_CHECK_EQUAL(0, lexical_cast(false)); + BOOST_CHECK_EQUAL(123, lexical_cast("123")); + BOOST_CHECK_THROW( + lexical_cast(" 123"), boost::bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(""), boost::bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast); + BOOST_CHECK_EQUAL(123, lexical_cast("123")); + BOOST_CHECK_THROW(lexical_cast(""), boost::bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast); + BOOST_CHECK_EQUAL(123,lexical_cast(std::string("123"))); + BOOST_CHECK_THROW( + lexical_cast(std::string(" 123")), boost::bad_lexical_cast); + BOOST_CHECK_THROW( + lexical_cast(std::string("")), boost::bad_lexical_cast); + BOOST_CHECK_THROW( + lexical_cast(std::string("Test")), boost::bad_lexical_cast); +} + +void test_conversion_to_double() +{ + BOOST_CHECK_EQUAL(1.0, lexical_cast('1')); + BOOST_CHECK_THROW(lexical_cast('A'), boost::bad_lexical_cast); + BOOST_CHECK_EQUAL(1.0, lexical_cast(1)); + BOOST_CHECK_EQUAL(1.23, lexical_cast(1.23)); + BOOST_CHECK_CLOSE( + std::numeric_limits::max() / 2, + lexical_cast(std::numeric_limits::max() / 2), + std::numeric_limits::epsilon()); + BOOST_CHECK_EQUAL(1.0, lexical_cast(true)); + BOOST_CHECK_EQUAL(0.0, lexical_cast(false)); + BOOST_CHECK_EQUAL(1.23, lexical_cast("1.23")); + BOOST_CHECK_THROW(lexical_cast(""), boost::bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast); + BOOST_CHECK_EQUAL(1.23, lexical_cast("1.23")); + BOOST_CHECK_THROW(lexical_cast(""), boost::bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast); + BOOST_CHECK_EQUAL(1.23, lexical_cast(std::string("1.23"))); + BOOST_CHECK_THROW( + lexical_cast(std::string("")), boost::bad_lexical_cast); + BOOST_CHECK_THROW( + lexical_cast(std::string("Test")), boost::bad_lexical_cast); +} + +void test_conversion_to_bool() +{ + BOOST_CHECK_EQUAL(true, lexical_cast('1')); + BOOST_CHECK_EQUAL(false, lexical_cast('0')); + BOOST_CHECK_THROW(lexical_cast('A'), boost::bad_lexical_cast); + BOOST_CHECK_EQUAL(true, lexical_cast(1)); + BOOST_CHECK_EQUAL(false, lexical_cast(0)); + BOOST_CHECK_THROW(lexical_cast(123), boost::bad_lexical_cast); + BOOST_CHECK_EQUAL(true, lexical_cast(1.0)); + BOOST_CHECK_EQUAL(false, lexical_cast(0.0)); + BOOST_CHECK_EQUAL(true, lexical_cast(true)); + BOOST_CHECK_EQUAL(false, lexical_cast(false)); + BOOST_CHECK_EQUAL(true, lexical_cast("1")); + BOOST_CHECK_EQUAL(false, lexical_cast("0")); + BOOST_CHECK_THROW(lexical_cast(""), boost::bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast); + BOOST_CHECK_EQUAL(true, lexical_cast("1")); + BOOST_CHECK_EQUAL(false, lexical_cast("0")); + BOOST_CHECK_THROW(lexical_cast(""), boost::bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast); + BOOST_CHECK_EQUAL(true, lexical_cast(std::string("1"))); + BOOST_CHECK_EQUAL(false, lexical_cast(std::string("0"))); + BOOST_CHECK_THROW( + lexical_cast(std::string("")), boost::bad_lexical_cast); + BOOST_CHECK_THROW( + lexical_cast(std::string("Test")), boost::bad_lexical_cast); +} + +void test_conversion_to_string() +{ + // *** All the following gives compilation error (ambiguity) on MSVC 6 + BOOST_CHECK_EQUAL("A", lexical_cast('A')); + BOOST_CHECK_EQUAL(" ", lexical_cast(' ')); + BOOST_CHECK_EQUAL("123", lexical_cast(123)); + BOOST_CHECK_EQUAL("1.23", lexical_cast(1.23)); + BOOST_CHECK_EQUAL("1.111111111", lexical_cast(1.111111111)); + BOOST_CHECK_EQUAL("1",lexical_cast(true)); + BOOST_CHECK_EQUAL("0",lexical_cast(false)); + BOOST_CHECK_EQUAL("Test", lexical_cast("Test")); + BOOST_CHECK_EQUAL(" ", lexical_cast(" ")); + BOOST_CHECK_EQUAL("", lexical_cast("")); + BOOST_CHECK_EQUAL("Test", lexical_cast("Test")); + BOOST_CHECK_EQUAL(" ", lexical_cast(" ")); + BOOST_CHECK_EQUAL("", lexical_cast("")); + BOOST_CHECK_EQUAL("Test", lexical_cast(std::string("Test"))); + BOOST_CHECK_EQUAL(" ", lexical_cast(std::string(" "))); + BOOST_CHECK_EQUAL("", lexical_cast(std::string(""))); +} + +void test_conversion_to_pointer() +{ + BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast); + #ifndef NO_WIDE_CHAR_SUPPORT + BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast); + #endif +} + +void test_conversion_from_wchar_t() +{ + #ifndef NO_WIDE_CHAR_SUPPORT + BOOST_CHECK_EQUAL(1, lexical_cast(L'1')); + BOOST_CHECK_THROW(lexical_cast(L'A'), boost::bad_lexical_cast); + + BOOST_CHECK_EQUAL(123, lexical_cast(L"123")); + BOOST_CHECK_THROW(lexical_cast(L""), boost::bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(L"Test"), boost::bad_lexical_cast); + BOOST_CHECK_EQUAL(123, lexical_cast(L"123")); + BOOST_CHECK_THROW(lexical_cast(L""), boost::bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(L"Test"), boost::bad_lexical_cast); + + BOOST_CHECK_EQUAL(1.0, lexical_cast(L'1')); + BOOST_CHECK_THROW(lexical_cast(L'A'), boost::bad_lexical_cast); + + BOOST_CHECK_EQUAL(1.23, lexical_cast(L"1.23")); + BOOST_CHECK_THROW(lexical_cast(L""), boost::bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(L"Test"), boost::bad_lexical_cast); + BOOST_CHECK_EQUAL(1.23, lexical_cast(L"1.23")); + BOOST_CHECK_THROW(lexical_cast(L""), boost::bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(L"Test"), boost::bad_lexical_cast); + + BOOST_CHECK_EQUAL(true, lexical_cast(L'1')); + BOOST_CHECK_EQUAL(false, lexical_cast(L'0')); + BOOST_CHECK_THROW(lexical_cast(L'A'), boost::bad_lexical_cast); + BOOST_CHECK_EQUAL(true, lexical_cast(L"1")); + BOOST_CHECK_EQUAL(false, lexical_cast(L"0")); + BOOST_CHECK_THROW(lexical_cast(L""), boost::bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(L"Test"), boost::bad_lexical_cast); + BOOST_CHECK_EQUAL(true, lexical_cast(L"1")); + BOOST_CHECK_EQUAL(false, lexical_cast(L"0")); + BOOST_CHECK_THROW(lexical_cast(L""), boost::bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(L"Test"), boost::bad_lexical_cast); + #endif +} + +void test_conversion_to_wchar_t() +{ + #ifndef NO_WIDE_CHAR_SUPPORT + BOOST_CHECK_EQUAL(L'1', lexical_cast(1)); + BOOST_CHECK_EQUAL(L'0', lexical_cast(0)); + BOOST_CHECK_THROW(lexical_cast(123), boost::bad_lexical_cast); + BOOST_CHECK_EQUAL(L'1', lexical_cast(1.0)); + BOOST_CHECK_EQUAL(L'0', lexical_cast(0.0)); + BOOST_CHECK_EQUAL(L'1', lexical_cast(true)); + BOOST_CHECK_EQUAL(L'0', lexical_cast(false)); + BOOST_CHECK_EQUAL(L'A', lexical_cast(L'A')); + BOOST_CHECK_EQUAL(L' ', lexical_cast(L' ')); + BOOST_CHECK_EQUAL(L'A', lexical_cast(L"A")); + BOOST_CHECK_EQUAL(L' ', lexical_cast(L" ")); + BOOST_CHECK_THROW(lexical_cast(L""), boost::bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(L"Test"), boost::bad_lexical_cast); + BOOST_CHECK_EQUAL(L'A', lexical_cast(L"A")); + BOOST_CHECK_EQUAL(L' ', lexical_cast(L" ")); + BOOST_CHECK_THROW(lexical_cast(L""), boost::bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(L"Test"), boost::bad_lexical_cast); + BOOST_CHECK_EQUAL(L'A', lexical_cast(std::wstring(L"A"))); + BOOST_CHECK_EQUAL(L' ', lexical_cast(std::wstring(L" "))); + BOOST_CHECK_THROW( + lexical_cast(std::wstring(L"")), boost::bad_lexical_cast); + BOOST_CHECK_THROW( + lexical_cast(std::wstring(L"Test")), boost::bad_lexical_cast); + #endif +} + +void test_conversion_from_wstring() +{ + #ifndef NO_WIDE_CHAR_SUPPORT + BOOST_CHECK_EQUAL(123, lexical_cast(std::wstring(L"123"))); + BOOST_CHECK_THROW( + lexical_cast(std::wstring(L"")), boost::bad_lexical_cast); + BOOST_CHECK_THROW( + lexical_cast(std::wstring(L"Test")), boost::bad_lexical_cast); + + BOOST_CHECK_EQUAL(1.23, lexical_cast(std::wstring(L"1.23"))); + BOOST_CHECK_THROW( + lexical_cast(std::wstring(L"")), boost::bad_lexical_cast); + BOOST_CHECK_THROW( + lexical_cast(std::wstring(L"Test")), boost::bad_lexical_cast); + + BOOST_CHECK_EQUAL(true, lexical_cast(std::wstring(L"1"))); + BOOST_CHECK_EQUAL(false, lexical_cast(std::wstring(L"0"))); + BOOST_CHECK_THROW( + lexical_cast(std::wstring(L"")), boost::bad_lexical_cast); + BOOST_CHECK_THROW( + lexical_cast(std::wstring(L"Test")), boost::bad_lexical_cast); + #endif +} + +void test_conversion_to_wstring() +{ + #ifndef NO_WIDE_CHAR_SUPPORT + BOOST_CHECK(L"123" == lexical_cast(123)); + BOOST_CHECK(L"1.23" == lexical_cast(1.23)); + BOOST_CHECK(L"1.111111111" == lexical_cast(1.111111111)); + BOOST_CHECK(L"1" == lexical_cast(true)); + BOOST_CHECK(L"0" == lexical_cast(false)); + BOOST_CHECK(L"A" == lexical_cast(L'A')); + BOOST_CHECK(L" " == lexical_cast(L' ')); + BOOST_CHECK(L"Test" == lexical_cast(L"Test")); + BOOST_CHECK(L" " == lexical_cast(L" ")); + BOOST_CHECK(L"" == lexical_cast(L"")); + BOOST_CHECK(L"Test" == lexical_cast(L"Test")); + BOOST_CHECK(L" " == lexical_cast(L" ")); + BOOST_CHECK(L"" == lexical_cast(L"")); + BOOST_CHECK(L"Test" == lexical_cast(std::wstring(L"Test"))); + BOOST_CHECK(L" " == lexical_cast(std::wstring(L" "))); + BOOST_CHECK(L"" == lexical_cast(std::wstring(L""))); + #endif +} From 1b796221b4d6a2eec7deb9856e79b59c1cd78b56 Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Thu, 13 Mar 2003 00:36:13 +0000 Subject: [PATCH 03/12] BOOST_NO_STD_WSTRING [SVN r17872] --- include/boost/lexical_cast.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index 924d6ac..820e4d1 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -88,6 +88,7 @@ namespace boost typedef wchar_t type; }; + #ifndef BOOST_NO_STD_WSTRING template<> struct stream_char { @@ -95,6 +96,8 @@ namespace boost }; #endif + #endif + template struct widest_char { From b06d9f56396d8d472a8be6e267bfed0db66aa2ca Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Thu, 13 Mar 2003 17:27:06 +0000 Subject: [PATCH 04/12] overloading fix + less permissive wide character support [SVN r17893] --- include/boost/lexical_cast.hpp | 29 +++++++++++++++++++---------- lexical_cast_test.cpp | 22 ++++++++++------------ 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index 820e4d1..3a248f1 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -1,16 +1,16 @@ #ifndef BOOST_LEXICAL_CAST_INCLUDED #define BOOST_LEXICAL_CAST_INCLUDED -// boost lexical_cast.hpp header --------------------------------------------// - -// See http://www.boost.org/libs/conversion for documentation. +// Boost lexical_cast.hpp header -------------------------------------------// +// +// See http://www.boost.org for most recent version including documentation. // See end of this header for rights and permissions. // // what: lexical_cast custom keyword cast // who: contributed by Kevlin Henney, // enhanced with contributions from Terje Slettebų, // with additional fixes and suggestions from Gennaro Prota, -// Dave Abrahams, Daryle Walker, and other Boosters on the list +// Beman Dawes, Dave Abrahams, Daryle Walker, and other Boosters // when: November 2000, March 2003 #include @@ -25,6 +25,12 @@ #include #endif +#if defined(BOOST_NO_STRINGSTREAM) || \ + defined(BOOST_NO_STD_WSTRING) || \ + defined(BOOST_NO_INTRINSIC_WCHAR_T) +#define DISABLE_WIDE_CHAR_SUPPORT +#endif + namespace boost { // exception used to indicate runtime lexical_cast failure @@ -69,7 +75,7 @@ namespace boost typedef char type; }; - #ifndef BOOST_NO_STRINGSTREAM + #ifndef DISABLE_WIDE_CHAR_SUPPORT template<> struct stream_char { @@ -88,7 +94,6 @@ namespace boost typedef wchar_t type; }; - #ifndef BOOST_NO_STD_WSTRING template<> struct stream_char { @@ -96,8 +101,6 @@ namespace boost }; #endif - #endif - template struct widest_char { @@ -143,11 +146,16 @@ namespace boost stream >> output && (stream >> std::ws).eof(); } - template - bool operator>>(std::basic_string &output) + bool operator>>(std::string &output) { return std::getline(stream, output, char_type()).eof(); } + #ifndef DISABLE_WIDE_CHAR_SUPPORT + bool operator>>(std::wstring &output) + { + return std::getline(stream, output, char_type()).eof(); + } + #endif private: typedef typename widest_char< typename stream_char::type, @@ -181,4 +189,5 @@ namespace boost // // This software is provided "as is" without express or implied warranty. +#undef DISABLE_WIDE_CHAR_SUPPORT #endif diff --git a/lexical_cast_test.cpp b/lexical_cast_test.cpp index 1d3c631..8fe79bb 100644 --- a/lexical_cast_test.cpp +++ b/lexical_cast_test.cpp @@ -22,11 +22,10 @@ #include #include -// If BOOST_NO_STRINGSTREAM is defined wide character support is unavailable, -// and all wide character tests are disabled. - -#ifdef BOOST_NO_STRINGSTREAM -#define NO_WIDE_CHAR_SUPPORT +#if defined(BOOST_NO_STRINGSTREAM) || \ + defined(BOOST_NO_STD_WSTRING) || \ + defined(BOOST_NO_INTRINSIC_WCHAR_T) +#define DISABLE_WIDE_CHAR_SUPPORT #endif using namespace boost; @@ -52,7 +51,7 @@ unit_test_framework::test_suite *init_unit_test_suite(int, char **) suite->add(BOOST_TEST_CASE(test_conversion_to_bool)); suite->add(BOOST_TEST_CASE(test_conversion_to_pointer)); suite->add(BOOST_TEST_CASE(test_conversion_to_string)); - #ifndef NO_WIDE_CHAR_SUPPORT + #ifndef DISABLE_WIDE_CHAR_SUPPORT suite->add(BOOST_TEST_CASE(test_conversion_from_wchar_t)); suite->add(BOOST_TEST_CASE(test_conversion_to_wchar_t)); suite->add(BOOST_TEST_CASE(test_conversion_from_wstring)); @@ -175,7 +174,6 @@ void test_conversion_to_bool() void test_conversion_to_string() { - // *** All the following gives compilation error (ambiguity) on MSVC 6 BOOST_CHECK_EQUAL("A", lexical_cast('A')); BOOST_CHECK_EQUAL(" ", lexical_cast(' ')); BOOST_CHECK_EQUAL("123", lexical_cast(123)); @@ -197,14 +195,14 @@ void test_conversion_to_string() void test_conversion_to_pointer() { BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast); - #ifndef NO_WIDE_CHAR_SUPPORT + #ifndef DISABLE_WIDE_CHAR_SUPPORT BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast); #endif } void test_conversion_from_wchar_t() { - #ifndef NO_WIDE_CHAR_SUPPORT + #ifndef DISABLE_WIDE_CHAR_SUPPORT BOOST_CHECK_EQUAL(1, lexical_cast(L'1')); BOOST_CHECK_THROW(lexical_cast(L'A'), boost::bad_lexical_cast); @@ -241,7 +239,7 @@ void test_conversion_from_wchar_t() void test_conversion_to_wchar_t() { - #ifndef NO_WIDE_CHAR_SUPPORT + #ifndef DISABLE_WIDE_CHAR_SUPPORT BOOST_CHECK_EQUAL(L'1', lexical_cast(1)); BOOST_CHECK_EQUAL(L'0', lexical_cast(0)); BOOST_CHECK_THROW(lexical_cast(123), boost::bad_lexical_cast); @@ -270,7 +268,7 @@ void test_conversion_to_wchar_t() void test_conversion_from_wstring() { - #ifndef NO_WIDE_CHAR_SUPPORT + #ifndef DISABLE_WIDE_CHAR_SUPPORT BOOST_CHECK_EQUAL(123, lexical_cast(std::wstring(L"123"))); BOOST_CHECK_THROW( lexical_cast(std::wstring(L"")), boost::bad_lexical_cast); @@ -294,7 +292,7 @@ void test_conversion_from_wstring() void test_conversion_to_wstring() { - #ifndef NO_WIDE_CHAR_SUPPORT + #ifndef DISABLE_WIDE_CHAR_SUPPORT BOOST_CHECK(L"123" == lexical_cast(123)); BOOST_CHECK(L"1.23" == lexical_cast(1.23)); BOOST_CHECK(L"1.111111111" == lexical_cast(1.111111111)); From 3f452717cf0e8dcecf9ddc6311fa2d2a06cf9444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Terje=20Sletteb=C3=B8?= Date: Fri, 14 Mar 2003 20:17:47 +0000 Subject: [PATCH 05/12] no message [SVN r17921] --- include/boost/lexical_cast.hpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index 3a248f1..ff295be 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -10,7 +10,8 @@ // who: contributed by Kevlin Henney, // enhanced with contributions from Terje Slettebų, // with additional fixes and suggestions from Gennaro Prota, -// Beman Dawes, Dave Abrahams, Daryle Walker, and other Boosters +// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov, +// and other Boosters // when: November 2000, March 2003 #include @@ -148,12 +149,17 @@ namespace boost } bool operator>>(std::string &output) { - return std::getline(stream, output, char_type()).eof(); + #if defined(BOOST_NO_STRINGSTREAM) + stream << '\0'; + #endif + output = stream.str(); + return true; } #ifndef DISABLE_WIDE_CHAR_SUPPORT bool operator>>(std::wstring &output) { - return std::getline(stream, output, char_type()).eof(); + output = stream.str(); + return true; } #endif private: From aad1bfda73a0bfe294bd8697f4137e1c56b3de9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Terje=20Sletteb=C3=B8?= Date: Fri, 14 Mar 2003 20:32:51 +0000 Subject: [PATCH 06/12] Updated Changes section [SVN r17922] --- lexical_cast.htm | 67 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 20 deletions(-) diff --git a/lexical_cast.htm b/lexical_cast.htm index 6b52fb5..1215a52 100644 --- a/lexical_cast.htm +++ b/lexical_cast.htm @@ -1,3 +1,4 @@ + @@ -8,7 +9,7 @@

c++boost.gif (8819 bytes)Header boost/lexical_cast.hpp

-
    +

    Motivation

    @@ -34,7 +37,7 @@

    For instance, there are a number of limitations with the family of standard C functions typified by atoi: -

      +
      • Conversion is supported in one direction only: from text to internal data type. Converting the other way using the C library requires either the inconvenience @@ -75,14 +78,12 @@ offered by the default behavior of lexical_cast, the conventional stringstream approach is recommended. Where the conversions are numeric to numeric, numeric_cast - may offer more reasonable behavior than lexical_cast - . + may offer more reasonable behavior than lexical_cast.

        For a good discussion of the options and issues involved in string-based formatting, including comparison of stringstream, lexical_cast, and others, see Herb Sutter's article, - The String Formatters of Manor Farm - . + The String Formatters of Manor Farm.


        Examples

        @@ -141,41 +142,46 @@ namespace boost template<typename Target, typename Source> Target lexical_cast(Source arg); - Returns the result of streaming arg into a std::stringstream - and then out as a Target object. Note that spaces are significant - in any conversion and are not skipped. If the conversion is unsuccessful, a - bad_lexical_cast - exception is thrown. + Returns the result of streaming arg into a + standard library string-based stream and then out as a Target object. + Where Target is either std::string + or std::wstring, stream extraction takes the whole content + of the string, including spaces, rather than relying on the default + operator>> behavior. + If the conversion is unsuccessful, a + bad_lexical_cast exception is thrown.

        The requirements on the argument and result types are: -

          +
          • Source is OutputStreamable, meaning that an operator<< is defined that takes a std::ostream or std::wostream object on the left hand side and an instance of the argument type on the right.
          • -
          • - Both Source and Target are CopyConstructible [20.1.3]. -
          • Target is InputStreamable, meaning that an operator>> is defined that takes a std::istream or std::wistream object on the left hand side and an instance of the result type on the right.
          • +
          • + Both Source and Target are CopyConstructible [20.1.3]. +
          • Target is DefaultConstructible, meaning that it is possible to default-initialize an object of that type [8.5, 20.1.4].
          The character type of the underlying stream is assumed to be char unless - the either the Source or the Target type is wchar_t - or a wide-character string type — either wchar_t * or std::wstring — - in which case wchar_t is used. + either the Source or the Target requires wide-character + streaming, in which case the underlying stream uses wchar_t. + Source types that require wide-character streaming are wchar_t, + wchar_t *, and std::wstring. Target types that + require wide-character streaming are wchar_t and std::wstring.

          Where a higher degree of control is required over conversions, std::stringstream and std::wstringstream offer a more appropriate path. Where non-stream-based conversions are required, lexical_cast - is the wrong tool for the job, and is not special-cased for such scenarios. + is the wrong tool for the job and is not special-cased for such scenarios.


          bad_lexical_cast

          @@ -189,7 +195,28 @@ public: Exception used to indicate runtime lexical_cast failure. -

          +


          +

          Changes

          +
            +
          • The previous version of lexical_cast used the default stream precision for reading + and writing floating-point numbers. For numerics that have a corresponding specialization of + std::numeric_limits, the current version now chooses a precision to match. +
          • The previous version of lexical_cast did not support conversion to or from any + wide-character-based types. For compilers with full language and library support for wide characters, + lexical_cast now supports conversions from wchar_t, wchar_t *, + and std::wstring and to wchar_t and std::wstring. +
          • The previous version of lexical_cast assumed that the conventional stream extractor + operators were sufficient for reading values. However, string I/O is asymmetric, with the result + that spaces play the role of I/O separators rather than string content. The current version fixes + this error for std::string and, where supported, std::wstring: + lexical_cast<std::string>("Hello, World") succeeds instead of failing with + a bad_lexical_cast exception. +
          • The previous version of lexical_cast allowed unsafe and meaningless conversions to + pointers. The current version now throws a bad_lexical_cast for conversions to pointers: + lexical_cast<char *>("Goodbye, World") now throws an exception instead of + causing undefined behavior. +
          +


          © Copyright Kevlin Henney, 2000–2003
          From 62014cf4b6d7269ae5c395b309aba1e4fc11209d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 18 Mar 2003 23:55:14 +0000 Subject: [PATCH 07/12] Commit Terje's changes [SVN r17982] --- include/boost/lexical_cast.hpp | 11 ++++++-- lexical_cast_test.cpp | 49 +++++++--------------------------- 2 files changed, 19 insertions(+), 41 deletions(-) diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index ff295be..b7d6a63 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include #ifdef BOOST_NO_STRINGSTREAM #include @@ -28,10 +28,15 @@ #if defined(BOOST_NO_STRINGSTREAM) || \ defined(BOOST_NO_STD_WSTRING) || \ - defined(BOOST_NO_INTRINSIC_WCHAR_T) + defined(BOOST_NO_STD_LOCALE) || \ + defined(BOOST_NO_CWCHAR) #define DISABLE_WIDE_CHAR_SUPPORT #endif +#ifdef BOOST_NO_INTRINSIC_WCHAR_T +#include +#endif + namespace boost { // exception used to indicate runtime lexical_cast failure @@ -169,6 +174,8 @@ namespace boost #if defined(BOOST_NO_STRINGSTREAM) std::strstream stream; + #elif defined(BOOST_NO_STD_LOCALE) + std::stringstream stream; #else std::basic_stringstream stream; #endif diff --git a/lexical_cast_test.cpp b/lexical_cast_test.cpp index 8fe79bb..7444199 100644 --- a/lexical_cast_test.cpp +++ b/lexical_cast_test.cpp @@ -13,7 +13,7 @@ #include #if defined(__INTEL_COMPILER) -#pragma warning(disable: 383 488 981 1418 1419) +#pragma warning(disable: 193 383 488 981 1418 1419) #elif defined(BOOST_MSVC) #pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800) #endif @@ -21,10 +21,12 @@ #include #include #include +#include #if defined(BOOST_NO_STRINGSTREAM) || \ defined(BOOST_NO_STD_WSTRING) || \ - defined(BOOST_NO_INTRINSIC_WCHAR_T) + defined(BOOST_NO_STD_LOCALE) || \ + defined(BOOST_NO_CWCHAR) #define DISABLE_WIDE_CHAR_SUPPORT #endif @@ -74,10 +76,6 @@ void test_conversion_to_char() BOOST_CHECK_EQUAL(' ', lexical_cast(" ")); BOOST_CHECK_THROW(lexical_cast(""), boost::bad_lexical_cast); BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast); - BOOST_CHECK_EQUAL('A', lexical_cast("A")); - BOOST_CHECK_EQUAL(' ', lexical_cast(" ")); - BOOST_CHECK_THROW(lexical_cast(""), boost::bad_lexical_cast); - BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast); BOOST_CHECK_EQUAL('A', lexical_cast(std::string("A"))); BOOST_CHECK_EQUAL(' ', lexical_cast(std::string(" "))); BOOST_CHECK_THROW( @@ -108,8 +106,6 @@ void test_conversion_to_int() BOOST_CHECK_THROW(lexical_cast(""), boost::bad_lexical_cast); BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast); BOOST_CHECK_EQUAL(123, lexical_cast("123")); - BOOST_CHECK_THROW(lexical_cast(""), boost::bad_lexical_cast); - BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast); BOOST_CHECK_EQUAL(123,lexical_cast(std::string("123"))); BOOST_CHECK_THROW( lexical_cast(std::string(" 123")), boost::bad_lexical_cast); @@ -134,9 +130,6 @@ void test_conversion_to_double() BOOST_CHECK_EQUAL(1.23, lexical_cast("1.23")); BOOST_CHECK_THROW(lexical_cast(""), boost::bad_lexical_cast); BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast); - BOOST_CHECK_EQUAL(1.23, lexical_cast("1.23")); - BOOST_CHECK_THROW(lexical_cast(""), boost::bad_lexical_cast); - BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast); BOOST_CHECK_EQUAL(1.23, lexical_cast(std::string("1.23"))); BOOST_CHECK_THROW( lexical_cast(std::string("")), boost::bad_lexical_cast); @@ -162,8 +155,6 @@ void test_conversion_to_bool() BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast); BOOST_CHECK_EQUAL(true, lexical_cast("1")); BOOST_CHECK_EQUAL(false, lexical_cast("0")); - BOOST_CHECK_THROW(lexical_cast(""), boost::bad_lexical_cast); - BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast); BOOST_CHECK_EQUAL(true, lexical_cast(std::string("1"))); BOOST_CHECK_EQUAL(false, lexical_cast(std::string("0"))); BOOST_CHECK_THROW( @@ -184,9 +175,6 @@ void test_conversion_to_string() BOOST_CHECK_EQUAL("Test", lexical_cast("Test")); BOOST_CHECK_EQUAL(" ", lexical_cast(" ")); BOOST_CHECK_EQUAL("", lexical_cast("")); - BOOST_CHECK_EQUAL("Test", lexical_cast("Test")); - BOOST_CHECK_EQUAL(" ", lexical_cast(" ")); - BOOST_CHECK_EQUAL("", lexical_cast("")); BOOST_CHECK_EQUAL("Test", lexical_cast(std::string("Test"))); BOOST_CHECK_EQUAL(" ", lexical_cast(std::string(" "))); BOOST_CHECK_EQUAL("", lexical_cast(std::string(""))); @@ -206,9 +194,6 @@ void test_conversion_from_wchar_t() BOOST_CHECK_EQUAL(1, lexical_cast(L'1')); BOOST_CHECK_THROW(lexical_cast(L'A'), boost::bad_lexical_cast); - BOOST_CHECK_EQUAL(123, lexical_cast(L"123")); - BOOST_CHECK_THROW(lexical_cast(L""), boost::bad_lexical_cast); - BOOST_CHECK_THROW(lexical_cast(L"Test"), boost::bad_lexical_cast); BOOST_CHECK_EQUAL(123, lexical_cast(L"123")); BOOST_CHECK_THROW(lexical_cast(L""), boost::bad_lexical_cast); BOOST_CHECK_THROW(lexical_cast(L"Test"), boost::bad_lexical_cast); @@ -216,9 +201,6 @@ void test_conversion_from_wchar_t() BOOST_CHECK_EQUAL(1.0, lexical_cast(L'1')); BOOST_CHECK_THROW(lexical_cast(L'A'), boost::bad_lexical_cast); - BOOST_CHECK_EQUAL(1.23, lexical_cast(L"1.23")); - BOOST_CHECK_THROW(lexical_cast(L""), boost::bad_lexical_cast); - BOOST_CHECK_THROW(lexical_cast(L"Test"), boost::bad_lexical_cast); BOOST_CHECK_EQUAL(1.23, lexical_cast(L"1.23")); BOOST_CHECK_THROW(lexical_cast(L""), boost::bad_lexical_cast); BOOST_CHECK_THROW(lexical_cast(L"Test"), boost::bad_lexical_cast); @@ -230,10 +212,6 @@ void test_conversion_from_wchar_t() BOOST_CHECK_EQUAL(false, lexical_cast(L"0")); BOOST_CHECK_THROW(lexical_cast(L""), boost::bad_lexical_cast); BOOST_CHECK_THROW(lexical_cast(L"Test"), boost::bad_lexical_cast); - BOOST_CHECK_EQUAL(true, lexical_cast(L"1")); - BOOST_CHECK_EQUAL(false, lexical_cast(L"0")); - BOOST_CHECK_THROW(lexical_cast(L""), boost::bad_lexical_cast); - BOOST_CHECK_THROW(lexical_cast(L"Test"), boost::bad_lexical_cast); #endif } @@ -242,7 +220,9 @@ void test_conversion_to_wchar_t() #ifndef DISABLE_WIDE_CHAR_SUPPORT BOOST_CHECK_EQUAL(L'1', lexical_cast(1)); BOOST_CHECK_EQUAL(L'0', lexical_cast(0)); + #if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1200)) BOOST_CHECK_THROW(lexical_cast(123), boost::bad_lexical_cast); + #endif BOOST_CHECK_EQUAL(L'1', lexical_cast(1.0)); BOOST_CHECK_EQUAL(L'0', lexical_cast(0.0)); BOOST_CHECK_EQUAL(L'1', lexical_cast(true)); @@ -252,18 +232,18 @@ void test_conversion_to_wchar_t() BOOST_CHECK_EQUAL(L'A', lexical_cast(L"A")); BOOST_CHECK_EQUAL(L' ', lexical_cast(L" ")); BOOST_CHECK_THROW(lexical_cast(L""), boost::bad_lexical_cast); + #if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1200)) BOOST_CHECK_THROW(lexical_cast(L"Test"), boost::bad_lexical_cast); - BOOST_CHECK_EQUAL(L'A', lexical_cast(L"A")); - BOOST_CHECK_EQUAL(L' ', lexical_cast(L" ")); - BOOST_CHECK_THROW(lexical_cast(L""), boost::bad_lexical_cast); - BOOST_CHECK_THROW(lexical_cast(L"Test"), boost::bad_lexical_cast); + #endif BOOST_CHECK_EQUAL(L'A', lexical_cast(std::wstring(L"A"))); BOOST_CHECK_EQUAL(L' ', lexical_cast(std::wstring(L" "))); BOOST_CHECK_THROW( lexical_cast(std::wstring(L"")), boost::bad_lexical_cast); + #if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1200)) BOOST_CHECK_THROW( lexical_cast(std::wstring(L"Test")), boost::bad_lexical_cast); #endif + #endif } void test_conversion_from_wstring() @@ -275,12 +255,6 @@ void test_conversion_from_wstring() BOOST_CHECK_THROW( lexical_cast(std::wstring(L"Test")), boost::bad_lexical_cast); - BOOST_CHECK_EQUAL(1.23, lexical_cast(std::wstring(L"1.23"))); - BOOST_CHECK_THROW( - lexical_cast(std::wstring(L"")), boost::bad_lexical_cast); - BOOST_CHECK_THROW( - lexical_cast(std::wstring(L"Test")), boost::bad_lexical_cast); - BOOST_CHECK_EQUAL(true, lexical_cast(std::wstring(L"1"))); BOOST_CHECK_EQUAL(false, lexical_cast(std::wstring(L"0"))); BOOST_CHECK_THROW( @@ -303,9 +277,6 @@ void test_conversion_to_wstring() BOOST_CHECK(L"Test" == lexical_cast(L"Test")); BOOST_CHECK(L" " == lexical_cast(L" ")); BOOST_CHECK(L"" == lexical_cast(L"")); - BOOST_CHECK(L"Test" == lexical_cast(L"Test")); - BOOST_CHECK(L" " == lexical_cast(L" ")); - BOOST_CHECK(L"" == lexical_cast(L"")); BOOST_CHECK(L"Test" == lexical_cast(std::wstring(L"Test"))); BOOST_CHECK(L" " == lexical_cast(std::wstring(L" "))); BOOST_CHECK(L"" == lexical_cast(std::wstring(L""))); From d9eed4150b80800c6a6fd62e285aa5f945063321 Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Wed, 19 Mar 2003 12:14:32 +0000 Subject: [PATCH 08/12] BOOST_MSVC<=1200 fix from Terje [SVN r18002] --- include/boost/lexical_cast.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index b7d6a63..a247649 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -29,7 +29,8 @@ #if defined(BOOST_NO_STRINGSTREAM) || \ defined(BOOST_NO_STD_WSTRING) || \ defined(BOOST_NO_STD_LOCALE) || \ - defined(BOOST_NO_CWCHAR) + defined(BOOST_NO_CWCHAR) || \ + defined(BOOST_MSVC) && (BOOST_MSVC <= 1200) #define DISABLE_WIDE_CHAR_SUPPORT #endif From 6e077f97fcbe3bb12a0e39a89cfb1cc077960005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Terje=20Sletteb=C3=B8?= Date: Wed, 19 Mar 2003 21:25:45 +0000 Subject: [PATCH 09/12] BOOST_MSVC<=1200 fix from Terje [SVN r18019] --- lexical_cast_test.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/lexical_cast_test.cpp b/lexical_cast_test.cpp index 7444199..523d5fe 100644 --- a/lexical_cast_test.cpp +++ b/lexical_cast_test.cpp @@ -21,12 +21,12 @@ #include #include #include -#include #if defined(BOOST_NO_STRINGSTREAM) || \ defined(BOOST_NO_STD_WSTRING) || \ defined(BOOST_NO_STD_LOCALE) || \ - defined(BOOST_NO_CWCHAR) + defined(BOOST_NO_CWCHAR) || \ + defined(BOOST_MSVC) && (BOOST_MSVC <= 1200) #define DISABLE_WIDE_CHAR_SUPPORT #endif @@ -220,9 +220,7 @@ void test_conversion_to_wchar_t() #ifndef DISABLE_WIDE_CHAR_SUPPORT BOOST_CHECK_EQUAL(L'1', lexical_cast(1)); BOOST_CHECK_EQUAL(L'0', lexical_cast(0)); - #if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1200)) BOOST_CHECK_THROW(lexical_cast(123), boost::bad_lexical_cast); - #endif BOOST_CHECK_EQUAL(L'1', lexical_cast(1.0)); BOOST_CHECK_EQUAL(L'0', lexical_cast(0.0)); BOOST_CHECK_EQUAL(L'1', lexical_cast(true)); @@ -232,18 +230,14 @@ void test_conversion_to_wchar_t() BOOST_CHECK_EQUAL(L'A', lexical_cast(L"A")); BOOST_CHECK_EQUAL(L' ', lexical_cast(L" ")); BOOST_CHECK_THROW(lexical_cast(L""), boost::bad_lexical_cast); - #if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1200)) BOOST_CHECK_THROW(lexical_cast(L"Test"), boost::bad_lexical_cast); - #endif BOOST_CHECK_EQUAL(L'A', lexical_cast(std::wstring(L"A"))); BOOST_CHECK_EQUAL(L' ', lexical_cast(std::wstring(L" "))); BOOST_CHECK_THROW( lexical_cast(std::wstring(L"")), boost::bad_lexical_cast); - #if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1200)) BOOST_CHECK_THROW( lexical_cast(std::wstring(L"Test")), boost::bad_lexical_cast); #endif - #endif } void test_conversion_from_wstring() From fdd5ca33537c7f08eb024fcda6c3dbf74a599de9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Terje=20Sletteb=C3=B8?= Date: Fri, 11 Apr 2003 22:15:04 +0000 Subject: [PATCH 10/12] Merged from trunk [SVN r18237] --- include/boost/lexical_cast.hpp | 64 ++++++++++++++++------------------ 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index a247649..33c0851 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #ifdef BOOST_NO_STRINGSTREAM @@ -29,51 +30,47 @@ #if defined(BOOST_NO_STRINGSTREAM) || \ defined(BOOST_NO_STD_WSTRING) || \ defined(BOOST_NO_STD_LOCALE) || \ - defined(BOOST_NO_CWCHAR) || \ - defined(BOOST_MSVC) && (BOOST_MSVC <= 1200) + defined(BOOST_NO_INTRINSIC_WCHAR_T) #define DISABLE_WIDE_CHAR_SUPPORT #endif -#ifdef BOOST_NO_INTRINSIC_WCHAR_T -#include -#endif - namespace boost { // exception used to indicate runtime lexical_cast failure class bad_lexical_cast : public std::bad_cast { public: + bad_lexical_cast() : + source(&typeid(void)), target(&typeid(void)) + { + } + bad_lexical_cast( + const std::type_info &s, + const std::type_info &t) : + source(&s), target(&t) + { + } + const std::type_info &source_type() const + { + return *source; + } + const std::type_info &target_type() const + { + return *target; + } + virtual const char *what() const throw() + { + return "bad lexical cast: " + "source type value could not be interpreted as target"; + } virtual ~bad_lexical_cast() throw() { } + private: + const std::type_info *source; + const std::type_info *target; }; - namespace detail // actual underlying concrete exception type - { - template - class no_lexical_conversion : public bad_lexical_cast - { - public: - no_lexical_conversion() - : description( - std::string() + "bad lexical cast: " + - "source type value could not be interpreted as target, Target=" + - typeid(Target).name() + ", Source=" + typeid(Source).name()) - { - } - virtual ~no_lexical_conversion() throw() - { - } - virtual const char *what() const throw() - { - return description.c_str(); - } - private: - const std::string description; // static initialization fails on MSVC6 - }; - } - namespace detail // selectors for choosing stream character type { template @@ -144,7 +141,7 @@ namespace boost } bool operator<<(const Source &input) { - return stream << input; + return !(stream << input).fail(); } template bool operator>>(InputStreamable &output) @@ -190,7 +187,7 @@ namespace boost Target result; if(!(interpreter << arg && interpreter >> result)) - throw detail::no_lexical_conversion(); + throw_exception(detail::no_lexical_conversion()); return result; } } @@ -205,3 +202,4 @@ namespace boost #undef DISABLE_WIDE_CHAR_SUPPORT #endif + From 3804825f6cbc420f6668d23c6ff7aee1e2b1b80f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Terje=20Sletteb=C3=B8?= Date: Sat, 12 Apr 2003 08:02:14 +0000 Subject: [PATCH 11/12] no message [SVN r18238] --- include/boost/lexical_cast.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index 33c0851..135ef07 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -187,7 +187,7 @@ namespace boost Target result; if(!(interpreter << arg && interpreter >> result)) - throw_exception(detail::no_lexical_conversion()); + throw_exception(bad_lexical_cast(typeid(Target), typeid(Source))); return result; } } From f0c79866ad82061c87e740f10515998d36836745 Mon Sep 17 00:00:00 2001 From: Aleksey Gurtovoy Date: Sun, 17 Aug 2003 21:02:53 +0000 Subject: [PATCH 12/12] merge changes from the main trunk to get in sync with the header [SVN r19669] --- lexical_cast_test.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lexical_cast_test.cpp b/lexical_cast_test.cpp index 523d5fe..a3df60d 100644 --- a/lexical_cast_test.cpp +++ b/lexical_cast_test.cpp @@ -25,8 +25,7 @@ #if defined(BOOST_NO_STRINGSTREAM) || \ defined(BOOST_NO_STD_WSTRING) || \ defined(BOOST_NO_STD_LOCALE) || \ - defined(BOOST_NO_CWCHAR) || \ - defined(BOOST_MSVC) && (BOOST_MSVC <= 1200) + defined(BOOST_NO_INTRINSIC_WCHAR_T) #define DISABLE_WIDE_CHAR_SUPPORT #endif @@ -37,6 +36,7 @@ void test_conversion_to_int(); void test_conversion_to_double(); void test_conversion_to_bool(); void test_conversion_to_string(); +void test_conversion_from_to_wchar_t_alias(); void test_conversion_to_pointer(); void test_conversion_from_wchar_t(); void test_conversion_to_wchar_t(); @@ -51,6 +51,7 @@ unit_test_framework::test_suite *init_unit_test_suite(int, char **) suite->add(BOOST_TEST_CASE(test_conversion_to_int)); suite->add(BOOST_TEST_CASE(test_conversion_to_double)); suite->add(BOOST_TEST_CASE(test_conversion_to_bool)); + suite->add(BOOST_TEST_CASE(test_conversion_from_to_wchar_t_alias)); suite->add(BOOST_TEST_CASE(test_conversion_to_pointer)); suite->add(BOOST_TEST_CASE(test_conversion_to_string)); #ifndef DISABLE_WIDE_CHAR_SUPPORT @@ -180,6 +181,17 @@ void test_conversion_to_string() BOOST_CHECK_EQUAL("", lexical_cast(std::string(""))); } +void test_conversion_from_to_wchar_t_alias() +{ + BOOST_CHECK_EQUAL(123u, lexical_cast("123")); + BOOST_CHECK_EQUAL(123u, lexical_cast("123")); + BOOST_CHECK_EQUAL(123u, lexical_cast("123")); + BOOST_CHECK_EQUAL(std::string("123"), + lexical_cast(static_cast(123))); + BOOST_CHECK_EQUAL(std::string("123"), lexical_cast(123u)); + BOOST_CHECK_EQUAL(std::string("123"), lexical_cast(123ul)); +} + void test_conversion_to_pointer() { BOOST_CHECK_THROW(lexical_cast("Test"), boost::bad_lexical_cast);