From 0d6a924f94ad0cefbdabfc09d6dd9376aef043d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20M=20L=C3=B3pez=20Mu=C3=B1oz?= Date: Thu, 18 Oct 2007 06:57:25 +0000 Subject: [PATCH 01/16] applied workaround for MSVC++ 6.5/7.0 problem with static constants inside templates, see http://lists.boost.org/Archives/boost/2007/10/128392.php [SVN r40146] --- include/boost/detail/lcast_precision.hpp | 12 +++++++++--- include/boost/lexical_cast.hpp | 4 ++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/boost/detail/lcast_precision.hpp b/include/boost/detail/lcast_precision.hpp index 5bd96fd..ef23c8a 100644 --- a/include/boost/detail/lcast_precision.hpp +++ b/include/boost/detail/lcast_precision.hpp @@ -21,7 +21,13 @@ #include #endif -#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +#if defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || \ + (defined(BOOST_MSVC) && (BOOST_MSVC<1310)) + +#define BOOST_LCAST_NO_COMPILE_TIME_PRECISION +#endif + +#ifdef BOOST_LCAST_NO_COMPILE_TIME_PRECISION #include #else #include @@ -31,7 +37,7 @@ namespace boost { namespace detail { class lcast_abstract_stub {}; -#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION // Calculate an argument to pass to std::ios_base::precision from // lexical_cast. See alternative implementation for broken standard // libraries in lcast_get_precision below. Keep them in sync, please. @@ -92,7 +98,7 @@ struct lcast_precision template inline std::streamsize lcast_get_precision(T* = 0) { -#if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) +#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION return lcast_precision::value; #else // Follow lcast_precision algorithm at run-time: diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index 1cd23f7..8f40d47 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -307,7 +307,7 @@ namespace boost #undef BOOST_AUX_LEXICAL_CAST_DEF #undef BOOST_AUX_LEXICAL_CAST_DEF1 -#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION // This #if is in sync with lcast_precision // Helper for floating point types. @@ -376,7 +376,7 @@ namespace boost }; #endif // #ifndef DISABLE_WIDE_CHAR_SUPPORT -#endif // #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +#endif // #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION } namespace detail // '0' and '-' constants From e70cf014ad5c293ac192be41d7d9056ea52ed401 Mon Sep 17 00:00:00 2001 From: Alexander Nasonov Date: Mon, 5 Nov 2007 22:22:48 +0000 Subject: [PATCH 02/16] #839 fixed: local variable shadow patch [SVN r40816] --- include/boost/lexical_cast.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index 8f40d47..5a29e85 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -52,9 +52,9 @@ namespace boost { } bad_lexical_cast( - const std::type_info &source_type, - const std::type_info &target_type) : - source(&source_type), target(&target_type) + const std::type_info &source_type_arg, + const std::type_info &target_type_arg) : + source(&source_type_arg), target(&target_type_arg) { } const std::type_info &source_type() const From 726f188aa498f7a0e100013f0085a55c8fd68a16 Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Sat, 17 Nov 2007 20:13:16 +0000 Subject: [PATCH 03/16] // Add or correct comment identifying Boost library this header is associated with. [SVN r41173] --- 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 5a29e85..4428275 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -3,7 +3,7 @@ // Boost lexical_cast.hpp header -------------------------------------------// // -// See http://www.boost.org/ for most recent version including documentation. +// See http://www.boost.org/libs/converston for documentation. // See end of this header for rights and permissions. // // what: lexical_cast custom keyword cast From 340f9b9e45c4fe43076cdf98997e57cf3d32d928 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Tue, 20 Nov 2007 16:52:43 +0000 Subject: [PATCH 04/16] fix warning in gcc-4.3 [SVN r41258] --- include/boost/detail/lcast_precision.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/detail/lcast_precision.hpp b/include/boost/detail/lcast_precision.hpp index ef23c8a..d40ca21 100644 --- a/include/boost/detail/lcast_precision.hpp +++ b/include/boost/detail/lcast_precision.hpp @@ -83,9 +83,9 @@ struct lcast_precision ); BOOST_STATIC_ASSERT(!is_specialized_bin || - limits::digits + 0UL < ULONG_MAX / 30103UL && + (limits::digits + 0UL < ULONG_MAX / 30103UL && precision_bin > limits::digits10 + 0UL && - precision_bin <= streamsize_max + 0UL + precision_bin <= streamsize_max + 0UL) ); BOOST_STATIC_CONSTANT(std::streamsize, value = From 2cc7aedd284d91f0eacca834c045dc4fc9ae42b5 Mon Sep 17 00:00:00 2001 From: Alexander Nasonov Date: Sat, 24 Nov 2007 15:22:52 +0000 Subject: [PATCH 05/16] minor changes [SVN r41331] --- include/boost/lexical_cast.hpp | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index 4428275..754aecf 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -267,14 +267,15 @@ namespace boost template struct lcast_src_length_integral { -#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x581 +#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS BOOST_STATIC_CONSTANT(std::size_t, value = std::numeric_limits::is_signed + std::numeric_limits::is_specialized + // == 1 std::numeric_limits::digits10 * 2 ); #else - BOOST_STATIC_CONSTANT(std::size_t, value = 156); // 256bit integers + BOOST_STATIC_CONSTANT(std::size_t, value = 156); + BOOST_STATIC_ASSERT(sizeof(Source) * CHAR_BIT <= 256); #endif }; @@ -400,14 +401,8 @@ namespace boost #endif } - namespace detail // lexical_streambuf and lexical_streambuf_fake + namespace detail // lexical_streambuf_fake { - template - class lexical_streambuf : public std::basic_streambuf - { - }; - - template struct lexical_streambuf_fake { }; @@ -448,7 +443,8 @@ namespace boost #endif #if (defined _MSC_VER) -# pragma warning( pop ) // C4146: unary minus operator applied to unsigned type, result still unsigned +# pragma warning( pop ) // C4146: unary minus operator applied to unsigned type, + // result still unsigned #endif } @@ -459,6 +455,9 @@ namespace boost template CharT* lcast_put_unsigned(T n, CharT* finish) { +#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + BOOST_STATIC_ASSERT(!std::numeric_limits::is_signed); +#endif CharT thousands_sep = 0; #ifdef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE @@ -586,7 +585,7 @@ namespace boost { // String representation of Source has an upper limit. template< class CharT // a result of widest_char transformation - , class Base // lexical_streambuf or lexical_streambuf_fake + , class Base // lexical_streambuf_fake or basic_streambuf > class lexical_stream_limited_src : public Base { @@ -913,7 +912,7 @@ namespace boost namespace detail // lcast_streambuf_for_source { - // Returns true if optimized stream wrapper uses ostream for formatting. + // Returns true if optimized stream wrapper needs ostream for writing. template struct lcast_streambuf_for_source { @@ -941,7 +940,7 @@ namespace boost namespace detail // lcast_streambuf_for_target { - // Returns true if optimized stream wrapper use istream for reading. + // Returns true if optimized stream wrapper needs istream for reading. template struct lcast_streambuf_for_target { @@ -1025,8 +1024,8 @@ namespace boost typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c< lcast_streambuf_for_target::value || lcast_streambuf_for_source::value - , lexical_streambuf - , lexical_streambuf_fake + , std::basic_streambuf + , lexical_streambuf_fake >::type base; BOOST_DEDUCED_TYPENAME boost::mpl::if_c< @@ -1091,7 +1090,7 @@ namespace boost } // Copyright Kevlin Henney, 2000-2005. -// Copyright Alexander Nasonov, 2006. +// Copyright Alexander Nasonov, 2006-2007. // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at From 159b045ad79f163b3b03ee01fd358f70870611f2 Mon Sep 17 00:00:00 2001 From: Alexander Nasonov Date: Sun, 25 Nov 2007 22:28:16 +0000 Subject: [PATCH 06/16] Pass unsigned type to lcast_put_unsigned. [SVN r41385] --- 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 754aecf..12a89f8 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -811,7 +811,7 @@ namespace boost inline bool lexical_stream_limited_src::operator<<( unsigned short n) { - start = lcast_put_unsigned(+n, finish); + start = lcast_put_unsigned(lcast_to_unsigned(n), finish); return true; } From 05036d3ae16fedffe164b457e3bf7ab49241a063 Mon Sep 17 00:00:00 2001 From: Alexander Nasonov Date: Sun, 25 Nov 2007 23:08:50 +0000 Subject: [PATCH 07/16] Support for string with non-default char_traits and allocator. [SVN r41387] --- include/boost/lexical_cast.hpp | 260 +++++++++++++++++++++++---------- lexical_cast_test.cpp | 245 ++++++++++++++++++++++++------- 2 files changed, 375 insertions(+), 130 deletions(-) diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index 12a89f8..4f68452 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -86,6 +86,14 @@ namespace boost typedef char type; }; +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template + struct stream_char< std::basic_string > + { + typedef CharT type; + }; +#endif + #ifndef DISABLE_WIDE_CHAR_SUPPORT #ifndef BOOST_NO_INTRINSIC_WCHAR_T template<> @@ -107,11 +115,13 @@ namespace boost typedef wchar_t type; }; +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template<> struct stream_char { typedef wchar_t type; }; +#endif #endif template @@ -127,6 +137,44 @@ namespace boost }; } + namespace detail // deduce_char_traits template + { +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template + struct deduce_char_traits + { + typedef std::char_traits type; + }; + + template + struct deduce_char_traits< CharT + , std::basic_string + , Source + > + { + typedef Traits type; + }; + + template + struct deduce_char_traits< CharT + , Target + , std::basic_string + > + { + typedef Traits type; + }; + + template + struct deduce_char_traits< CharT + , std::basic_string + , std::basic_string + > + { + typedef Traits type; + }; +#endif + } + namespace detail // lcast_src_length { // Return max. length of string representation of Source; @@ -309,8 +357,6 @@ namespace boost #undef BOOST_AUX_LEXICAL_CAST_DEF1 #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION -// This #if is in sync with lcast_precision - // Helper for floating point types. // -1.23456789e-123456 // ^ sign @@ -450,9 +496,7 @@ namespace boost namespace detail // lcast_put_unsigned { - // I'd personally put lcast_put_unsigned in .cpp file if not - // boost practice for header-only libraries (Alexander Nasonov). - template + template CharT* lcast_put_unsigned(T n, CharT* finish) { #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS @@ -482,6 +526,9 @@ namespace boost #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS BOOST_STATIC_ASSERT(std::numeric_limits::digits10 < CHAR_MAX); #endif + typedef typename Traits::int_type int_type; + CharT const czero = lcast_char_constants::zero; + int_type const zero = Traits::to_int_type(czero); char left = last_grp_size; @@ -498,14 +545,13 @@ namespace boost left = last_grp_size; --finish; - *finish = thousands_sep; + Traits::assign(*finish, thousands_sep); } --left; --finish; - int const digit = static_cast(n % 10); - int const cdigit = digit + lcast_char_constants::zero; - *finish = static_cast(cdigit); + int_type const digit = static_cast(n % 10U); + Traits::assign(*finish, Traits::to_char_type(zero + digit)); n /= 10; } while(n); @@ -515,7 +561,7 @@ namespace boost namespace detail // stream wrapper for handling lexical conversions { - template + template class lexical_stream { private: @@ -523,6 +569,8 @@ namespace boost typename stream_char::type, typename stream_char::type>::type char_type; + typedef Traits traits_type; + public: lexical_stream(char_type* = 0, char_type* = 0) { @@ -552,9 +600,12 @@ namespace boost EOF; #else - std::char_traits::eof(); + traits_type::eof(); #endif } + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + bool operator>>(std::string &output) { #if defined(BOOST_NO_STRINGSTREAM) @@ -570,13 +621,29 @@ namespace boost return true; } #endif + +#else + bool operator>>(std::basic_string& output) + { + stream.str().swap(output); + return true; + } + + template + bool operator>>(std::basic_string& out) + { + std::basic_string str(stream.str()); + out.assign(str.begin(), str.end()); + return true; + } +#endif private: #if defined(BOOST_NO_STRINGSTREAM) std::strstream stream; #elif defined(BOOST_NO_STD_LOCALE) std::stringstream stream; #else - std::basic_stringstream stream; + std::basic_stringstream stream; #endif }; } @@ -586,6 +653,7 @@ namespace boost // String representation of Source has an upper limit. template< class CharT // a result of widest_char transformation , class Base // lexical_streambuf_fake or basic_streambuf + , class Traits // usually char_traits > class lexical_stream_limited_src : public Base { @@ -599,19 +667,20 @@ namespace boost static void widen_and_assign(char*p, char ch) { - *p = ch; + Traits::assign(*p, ch); } #ifndef DISABLE_WIDE_CHAR_SUPPORT static void widen_and_assign(wchar_t* p, char ch) { std::locale loc; - *p = BOOST_USE_FACET(std::ctype, loc).widen(ch); + wchar_t w = BOOST_USE_FACET(std::ctype, loc).widen(ch); + Traits::assign(*p, w); } static void widen_and_assign(wchar_t* p, wchar_t ch) { - *p = ch; + Traits::assign(*p, ch); } static void widen_and_assign(char*, wchar_t ch); // undefined @@ -641,8 +710,8 @@ namespace boost public: // output - template - bool operator<<(std::basic_string const& str) + template + bool operator<<(std::basic_string const& str) { start = const_cast(str.data()); finish = start + str.length(); @@ -705,7 +774,7 @@ namespace boost EOF; #else - std::char_traits::eof(); + Traits::eof(); #endif } @@ -721,7 +790,7 @@ namespace boost #endif #else - template + template bool operator>>(std::basic_string& str) { str.assign(start, finish); @@ -730,17 +799,21 @@ namespace boost #endif }; - template - inline bool lexical_stream_limited_src::operator<<( + template + inline bool lexical_stream_limited_src::operator<<( bool value) { - *start = value + lcast_char_constants::zero; + typedef typename Traits::int_type int_type; + CharT const czero = lcast_char_constants::zero; + int_type const zero = Traits::to_int_type(czero); + Traits::assign(*start, Traits::to_char_type(zero + value)); finish = start + 1; return true; } - template - inline bool lexical_stream_limited_src::operator<<(char ch) + template + inline bool lexical_stream_limited_src::operator<<( + char ch) { widen_and_assign(start, ch); finish = start + 1; @@ -748,8 +821,8 @@ namespace boost } #if !defined(DISABLE_WIDE_CHAR_SUPPORT) && !defined(BOOST_NO_INTRINSIC_WCHAR_T) - template - inline bool lexical_stream_limited_src::operator<<( + template + inline bool lexical_stream_limited_src::operator<<( wchar_t ch) { widen_and_assign(start, ch); @@ -758,140 +831,163 @@ namespace boost } #endif - template - inline bool lexical_stream_limited_src::operator<<(short n) + template + inline bool lexical_stream_limited_src::operator<<( + short n) { - start = lcast_put_unsigned(lcast_to_unsigned(n), finish); + start = lcast_put_unsigned(lcast_to_unsigned(n), finish); if(n < 0) - *--start = lcast_char_constants::minus; + { + --start; + CharT const minus = lcast_char_constants::minus; + Traits::assign(*start, minus); + } return true; } - template - inline bool lexical_stream_limited_src::operator<<(int n) + template + inline bool lexical_stream_limited_src::operator<<( + int n) { - start = lcast_put_unsigned(lcast_to_unsigned(n), finish); + start = lcast_put_unsigned(lcast_to_unsigned(n), finish); if(n < 0) - *--start = lcast_char_constants::minus; + { + --start; + CharT const minus = lcast_char_constants::minus; + Traits::assign(*start, minus); + } return true; } - template - inline bool lexical_stream_limited_src::operator<<(long n) + template + inline bool lexical_stream_limited_src::operator<<( + long n) { - start = lcast_put_unsigned(lcast_to_unsigned(n), finish); + start = lcast_put_unsigned(lcast_to_unsigned(n), finish); if(n < 0) - *--start = lcast_char_constants::minus; + { + --start; + CharT const minus = lcast_char_constants::minus; + Traits::assign(*start, minus); + } return true; } #if defined(BOOST_HAS_LONG_LONG) - template - inline bool lexical_stream_limited_src::operator<<( + template + inline bool lexical_stream_limited_src::operator<<( boost::long_long_type n) { - start = lcast_put_unsigned(lcast_to_unsigned(n), finish); + start = lcast_put_unsigned(lcast_to_unsigned(n), finish); if(n < 0) - *--start = lcast_char_constants::minus; + { + --start; + CharT const minus = lcast_char_constants::minus; + Traits::assign(*start, minus); + } return true; } #elif defined(BOOST_HAS_MS_INT64) - template - inline bool lexical_stream_limited_src::operator<<( + template + inline bool lexical_stream_limited_src::operator<<( __int64 n) { - start = lcast_put_unsigned(lcast_to_unsigned(n), finish); + start = lcast_put_unsigned(lcast_to_unsigned(n), finish); if(n < 0) - *--start = lcast_char_constants::minus; + { + --start; + CharT const minus = lcast_char_constants::minus; + Traits::assign(*start, minus); + } return true; } #endif - template - inline bool lexical_stream_limited_src::operator<<( + template + inline bool lexical_stream_limited_src::operator<<( unsigned short n) { - start = lcast_put_unsigned(lcast_to_unsigned(n), finish); + start = lcast_put_unsigned(lcast_to_unsigned(n), finish); return true; } - template - inline bool lexical_stream_limited_src::operator<<( + template + inline bool lexical_stream_limited_src::operator<<( unsigned int n) { - start = lcast_put_unsigned(n, finish); + start = lcast_put_unsigned(n, finish); return true; } - template - inline bool lexical_stream_limited_src::operator<<( + template + inline bool lexical_stream_limited_src::operator<<( unsigned long n) { - start = lcast_put_unsigned(n, finish); + start = lcast_put_unsigned(n, finish); return true; } #if defined(BOOST_HAS_LONG_LONG) - template - inline bool lexical_stream_limited_src::operator<<( + template + inline bool lexical_stream_limited_src::operator<<( boost::ulong_long_type n) { - start = lcast_put_unsigned(n, finish); + start = lcast_put_unsigned(n, finish); return true; } #elif defined(BOOST_HAS_MS_INT64) - template - inline bool lexical_stream_limited_src::operator<<( + template + inline bool lexical_stream_limited_src::operator<<( unsigned __int64 n) { - start = lcast_put_unsigned(n, finish); + start = lcast_put_unsigned(n, finish); return true; } #endif - template - inline bool lexical_stream_limited_src::operator<<( + template + inline bool lexical_stream_limited_src::operator<<( float val) { return this->lcast_put(val); } - template - inline bool lexical_stream_limited_src::operator<<( + template + inline bool lexical_stream_limited_src::operator<<( double val) { return this->lcast_put(val); } - template - inline bool lexical_stream_limited_src::operator<<( + template + inline bool lexical_stream_limited_src::operator<<( long double val) { return this->lcast_put(val); } - template - inline bool lexical_stream_limited_src::operator<<( + template + inline bool lexical_stream_limited_src::operator<<( CharT const* str) { start = const_cast(str); - finish = start + std::char_traits::length(str); + finish = start + Traits::length(str); return true; } - template - inline bool lexical_stream_limited_src::operator>>( + template + inline bool lexical_stream_limited_src::operator>>( CharT& output) { bool const ok = (finish - start == 1); if(ok) - output = *start; + Traits::assign(output, *start); return ok; } #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - inline bool lexical_stream_limited_src::operator>>( + template + inline bool lexical_stream_limited_src::operator>>( std::string& str) { str.assign(start, finish); @@ -899,8 +995,8 @@ namespace boost } #ifndef DISABLE_WIDE_CHAR_SUPPORT - template - inline bool lexical_stream_limited_src::operator>>( + template + inline bool lexical_stream_limited_src::operator>>( std::wstring& str) { str.assign(start, finish); @@ -1021,6 +1117,12 @@ namespace boost BOOST_DEDUCED_TYPENAME boost::call_traits::param_type arg, CharT* buf, std::size_t src_len) { +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + typedef BOOST_DEDUCED_TYPENAME + deduce_char_traits::type traits; +#else + typedef std::char_traits traits; +#endif typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c< lcast_streambuf_for_target::value || lcast_streambuf_for_source::value @@ -1030,8 +1132,8 @@ namespace boost BOOST_DEDUCED_TYPENAME boost::mpl::if_c< Unlimited - , detail::lexical_stream - , detail::lexical_stream_limited_src + , detail::lexical_stream + , detail::lexical_stream_limited_src >::type interpreter(buf, buf + src_len); // The original form, reproduced below, is more elegant diff --git a/lexical_cast_test.cpp b/lexical_cast_test.cpp index 6ba26a3..04478e0 100644 --- a/lexical_cast_test.cpp +++ b/lexical_cast_test.cpp @@ -24,6 +24,9 @@ #include #include +#include +#include + #if defined(BOOST_NO_STRINGSTREAM) || \ defined(BOOST_NO_STD_WSTRING) || \ defined(BOOST_NO_STD_LOCALE) @@ -35,6 +38,16 @@ #define LCAST_TEST_LONGLONG #endif +template +struct my_traits : std::char_traits +{ +}; + +template +struct my_allocator : std::allocator +{ +}; + // Test all 65536 values if true: bool const lcast_test_small_integral_types_completely = false; @@ -57,15 +70,21 @@ void test_conversion_from_wstring(); void test_conversion_to_wstring(); void test_bad_lexical_cast(); void test_no_whitespace_stripping(); -void test_conversion_from_short(); -void test_conversion_from_ushort(); -void test_conversion_from_int(); -void test_conversion_from_uint(); -void test_conversion_from_long(); -void test_conversion_from_ulong(); +void test_conversion_from_to_short(); +void test_conversion_from_to_ushort(); +void test_conversion_from_to_int(); +void test_conversion_from_to_uint(); +void test_conversion_from_to_long(); +void test_conversion_from_to_ulong(); #ifdef LCAST_TEST_LONGLONG -void test_conversion_from_longlong(); -void test_conversion_from_ulonglong(); +void test_conversion_from_to_longlong(); +void test_conversion_from_to_ulonglong(); +#endif +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +void test_traits(); +void test_wtraits(); +void test_allocator(); +void test_wallocator(); #endif unit_test::test_suite *init_unit_test_suite(int, char *[]) @@ -87,15 +106,21 @@ unit_test::test_suite *init_unit_test_suite(int, char *[]) #endif suite->add(BOOST_TEST_CASE(test_bad_lexical_cast)); suite->add(BOOST_TEST_CASE(test_no_whitespace_stripping)); - suite->add(BOOST_TEST_CASE(&test_conversion_from_short)); - suite->add(BOOST_TEST_CASE(&test_conversion_from_ushort)); - suite->add(BOOST_TEST_CASE(&test_conversion_from_int)); - suite->add(BOOST_TEST_CASE(&test_conversion_from_uint)); - suite->add(BOOST_TEST_CASE(&test_conversion_from_ulong)); - suite->add(BOOST_TEST_CASE(&test_conversion_from_long)); + suite->add(BOOST_TEST_CASE(&test_conversion_from_to_short)); + suite->add(BOOST_TEST_CASE(&test_conversion_from_to_ushort)); + suite->add(BOOST_TEST_CASE(&test_conversion_from_to_int)); + suite->add(BOOST_TEST_CASE(&test_conversion_from_to_uint)); + suite->add(BOOST_TEST_CASE(&test_conversion_from_to_ulong)); + suite->add(BOOST_TEST_CASE(&test_conversion_from_to_long)); #ifdef LCAST_TEST_LONGLONG - suite->add(BOOST_TEST_CASE(&test_conversion_from_longlong)); - suite->add(BOOST_TEST_CASE(&test_conversion_from_ulonglong)); + suite->add(BOOST_TEST_CASE(&test_conversion_from_to_longlong)); + suite->add(BOOST_TEST_CASE(&test_conversion_from_to_ulonglong)); + #endif + #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + suite->add(BOOST_TEST_CASE(&test_traits)); + suite->add(BOOST_TEST_CASE(&test_wtraits)); + suite->add(BOOST_TEST_CASE(&test_allocator)); + suite->add(BOOST_TEST_CASE(&test_wallocator)); #endif return suite; @@ -129,10 +154,15 @@ void test_conversion_to_int() BOOST_CHECK_EQUAL(0, lexical_cast('0')); BOOST_CHECK_THROW(lexical_cast('A'), bad_lexical_cast); BOOST_CHECK_EQUAL(1, lexical_cast(1)); + BOOST_CHECK_EQUAL(1, lexical_cast(1.0)); + BOOST_CHECK_EQUAL( (std::numeric_limits::max)(), lexical_cast((std::numeric_limits::max)())); - BOOST_CHECK_EQUAL(1, lexical_cast(1.0)); + + BOOST_CHECK_EQUAL( + (std::numeric_limits::min)(), + lexical_cast((std::numeric_limits::min)())); BOOST_CHECK_THROW(lexical_cast(1.23), bad_lexical_cast); @@ -407,7 +437,7 @@ void test_conversion_from_integral_to_char(CharT zero) BOOST_CHECK_THROW(lexical_cast(static_cast(10)), bad_lexical_cast); - T t = std::numeric_limits::max(); + T t = (std::numeric_limits::max)(); BOOST_CHECK_THROW(lexical_cast(t), bad_lexical_cast); } @@ -427,10 +457,10 @@ void test_conversion_from_integral_to_integral() BOOST_CHECK(lexical_cast(t) == st); BOOST_CHECK(lexical_cast(t) == ut); - t = std::numeric_limits::max(); + t = (std::numeric_limits::max)(); BOOST_CHECK(lexical_cast(t) == t); - t = std::numeric_limits::min(); + t = (std::numeric_limits::min)(); BOOST_CHECK(lexical_cast(t) == t); } @@ -442,19 +472,20 @@ void test_conversion_from_integral_to_string(CharT) T t; - t = limits::min(); + t = (limits::min)(); BOOST_CHECK(lexical_cast(t) == to_str(t)); - t = limits::max(); + t = (limits::max)(); BOOST_CHECK(lexical_cast(t) == to_str(t)); if(limits::digits <= 16 && lcast_test_small_integral_types_completely) - for(t = 1 + limits::min(); t != limits::max(); ++t) + // min and max have already been tested. + for(t = 1 + (limits::min)(); t != (limits::max)(); ++t) BOOST_CHECK(lexical_cast(t) == to_str(t)); else { - T const min_val = limits::min(); - T const max_val = limits::max(); + T const min_val = (limits::min)(); + T const max_val = (limits::max)(); T const half_max_val = max_val / 2; T const cnt = lcast_integral_test_counter; // to supress warnings unsigned int const counter = cnt < half_max_val ? cnt : half_max_val; @@ -480,20 +511,75 @@ void test_conversion_from_integral_to_string(CharT) T ten_power = 100; for(int e = 2; e <= limits::digits10; ++e, ten_power *= 10) { - // I believe that (ten_power + 100) never overflows + // ten_power + 100 probably never overflows for(t = ten_power - 100; t != ten_power + 100; ++t) BOOST_CHECK(lexical_cast(t) == to_str(t)); } } } +template +void test_conversion_from_string_to_integral(CharT) +{ + typedef std::numeric_limits limits; + + T t; + + t = (limits::min)(); + BOOST_CHECK(lexical_cast(to_str(t)) == t); + + t = (limits::max)(); + BOOST_CHECK(lexical_cast(to_str(t)) == t); + + if(limits::digits <= 16 && lcast_test_small_integral_types_completely) + // min and max have already been tested. + for(t = 1 + (limits::min)(); t != (limits::max)(); ++t) + BOOST_CHECK(lexical_cast(to_str(t)) == t); + else + { + T const min_val = (limits::min)(); + T const max_val = (limits::max)(); + T const half_max_val = max_val / 2; + T const cnt = lcast_integral_test_counter; // to supress warnings + unsigned int const counter = cnt < half_max_val ? cnt : half_max_val; + + unsigned int i; + + // Test values around min: + t = min_val; + for(i = 0; i < counter; ++i, ++t) + BOOST_CHECK(lexical_cast(to_str(t)) == t); + + // Test values around max: + t = max_val; + for(i = 0; i < counter; ++i, --t) + BOOST_CHECK(lexical_cast(to_str(t)) == t); + + // Test values around zero: + if(limits::is_signed) + for(t = -counter; t < static_cast(counter); ++t) + BOOST_CHECK(lexical_cast(to_str(t)) == t); + + // Test values around 100, 1000, 10000, ... + T ten_power = 100; + for(int e = 2; e <= limits::digits10; ++e, ten_power *= 10) + { + // ten_power + 100 probably never overflows + for(t = ten_power - 100; t != ten_power + 100; ++t) + BOOST_CHECK(lexical_cast(to_str(t)) == t); + } + } +} + template -void test_conversion_from_integral_for_locale() +void test_conversion_from_to_integral_for_locale() { test_conversion_from_integral_to_integral(); test_conversion_from_integral_to_string('0'); + test_conversion_from_string_to_integral('0'); #if !defined(DISABLE_WIDE_CHAR_SUPPORT) && !defined(BOOST_NO_INTRINSIC_WCHAR_T) test_conversion_from_integral_to_string(L'0'); + test_conversion_from_string_to_integral(L'0'); #endif } @@ -504,7 +590,7 @@ struct restore_oldloc }; template -void test_conversion_from_integral() +void test_conversion_from_to_integral() { char const zero = '0'; signed char const szero = '0'; @@ -517,7 +603,7 @@ void test_conversion_from_integral() test_conversion_from_integral_to_char(wzero); #endif - // test_conversion_from_integral_for_locale + // test_conversion_from_to_integral_for_locale typedef std::numpunct numpunct; @@ -527,7 +613,7 @@ void test_conversion_from_integral() std::string grouping1 = BOOST_USE_FACET(numpunct, oldloc).grouping(); std::string grouping2(grouping1); - test_conversion_from_integral_for_locale(); + test_conversion_from_to_integral_for_locale(); try { @@ -544,64 +630,121 @@ void test_conversion_from_integral() } if(grouping1 != grouping2) - test_conversion_from_integral_for_locale(); + test_conversion_from_to_integral_for_locale(); if(grouping1.empty() && grouping2.empty()) BOOST_TEST_MESSAGE("Formatting with thousands_sep has not been tested"); } -void test_conversion_from_short() +void test_conversion_from_to_short() { - test_conversion_from_integral(); + test_conversion_from_to_integral(); } -void test_conversion_from_ushort() +void test_conversion_from_to_ushort() { - test_conversion_from_integral(); + test_conversion_from_to_integral(); } -void test_conversion_from_int() +void test_conversion_from_to_int() { - test_conversion_from_integral(); + test_conversion_from_to_integral(); } -void test_conversion_from_uint() +void test_conversion_from_to_uint() { - test_conversion_from_integral(); + test_conversion_from_to_integral(); } -void test_conversion_from_ulong() +void test_conversion_from_to_ulong() { - test_conversion_from_integral(); + test_conversion_from_to_integral(); } -void test_conversion_from_long() +void test_conversion_from_to_long() { - test_conversion_from_integral(); + test_conversion_from_to_integral(); } #if defined(BOOST_HAS_LONG_LONG) -void test_conversion_from_longlong() +void test_conversion_from_to_longlong() { - test_conversion_from_integral(); + test_conversion_from_to_integral(); } -void test_conversion_from_ulonglong() +void test_conversion_from_to_ulonglong() { - test_conversion_from_integral(); + test_conversion_from_to_integral(); } #elif defined(LCAST_TEST_LONGLONG) -void test_conversion_from_longlong() +void test_conversion_from_to_longlong() { - test_conversion_from_integral<__int64>(); + test_conversion_from_to_integral<__int64>(); } -void test_conversion_from_ulonglong() +void test_conversion_from_to_ulonglong() { - test_conversion_from_integral(); + test_conversion_from_to_integral(); +} + +#endif + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +void test_traits() +{ + typedef std::basic_string > my_string; + + my_string const s("s"); + BOOST_CHECK(boost::lexical_cast(s) == s[0]); + BOOST_CHECK(boost::lexical_cast(s) == s); + BOOST_CHECK(boost::lexical_cast(-1) == "-1"); +} + +void test_wtraits() +{ + typedef std::basic_string > my_string; + + my_string const s(L"s"); + BOOST_CHECK(boost::lexical_cast(s) == s[0]); + BOOST_CHECK(boost::lexical_cast(s) == s); + //BOOST_CHECK(boost::lexical_cast(-1) == L"-1"); + // Commented out because gcc 3.3 doesn't support this: + // basic_ostream > o; o << -1; +} + +void test_allocator() +{ + typedef std::basic_string< char + , std::char_traits + , my_allocator + > my_string; + + my_string s("s"); + BOOST_CHECK(boost::lexical_cast(s) == s[0]); + BOOST_CHECK(boost::lexical_cast(s) == "s"); + BOOST_CHECK(boost::lexical_cast(s) == s); + BOOST_CHECK(boost::lexical_cast(1) == "1"); + BOOST_CHECK(boost::lexical_cast("s") == s); + BOOST_CHECK(boost::lexical_cast(std::string("s")) == s); +} + +void test_wallocator() +{ + typedef std::basic_string< wchar_t + , std::char_traits + , my_allocator + > my_string; + + my_string s(L"s"); + BOOST_CHECK(boost::lexical_cast(s) == s[0]); + BOOST_CHECK(boost::lexical_cast(s) == L"s"); + BOOST_CHECK(boost::lexical_cast(s) == s); + BOOST_CHECK(boost::lexical_cast(1) == L"1"); + BOOST_CHECK(boost::lexical_cast(L"s") == s); + BOOST_CHECK(boost::lexical_cast(std::wstring(L"s")) == s); } #endif From ec8665d1149e07c23acc95146a6c99888ad22a7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20M=20L=C3=B3pez=20Mu=C3=B1oz?= Date: Mon, 26 Nov 2007 11:52:03 +0000 Subject: [PATCH 08/16] added missing traits template arg to a lexical_stream instantiation [SVN r41394] --- include/boost/lexical_cast.hpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index 4f68452..cb2fa50 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -1180,7 +1180,13 @@ namespace boost template Target lexical_cast(Source arg) { - detail::lexical_stream interpreter; + typedef typename detail::widest_char< + BOOST_DEDUCED_TYPENAME detail::stream_char::type + , BOOST_DEDUCED_TYPENAME detail::stream_char::type + >::type char_type; + + typedef std::char_traits traits; + detail::lexical_stream interpreter; Target result; if(!(interpreter << arg && interpreter >> result)) From 69cf3b2766a907906962079239a47d39a347c29f Mon Sep 17 00:00:00 2001 From: Alexander Nasonov Date: Mon, 26 Nov 2007 21:29:04 +0000 Subject: [PATCH 09/16] Remove redundant BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION. [SVN r41406] --- include/boost/lexical_cast.hpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index cb2fa50..2794c86 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -1117,12 +1117,9 @@ namespace boost BOOST_DEDUCED_TYPENAME boost::call_traits::param_type arg, CharT* buf, std::size_t src_len) { -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION typedef BOOST_DEDUCED_TYPENAME deduce_char_traits::type traits; -#else - typedef std::char_traits traits; -#endif + typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c< lcast_streambuf_for_target::value || lcast_streambuf_for_source::value From 808f210c0d396d9c209b4a98ada1eb2ae64973c5 Mon Sep 17 00:00:00 2001 From: Alexander Nasonov Date: Tue, 4 Dec 2007 21:49:51 +0000 Subject: [PATCH 10/16] Link to html version of [Tuning] and BOOST_LEXICAL_CAST_ASSUME_C_LOCALE synopsis [SVN r41703] --- lexical_cast.htm | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/lexical_cast.htm b/lexical_cast.htm index 2a08541..6e38014 100644 --- a/lexical_cast.htm +++ b/lexical_cast.htm @@ -194,7 +194,18 @@ public: Exception used to indicate runtime lexical_cast failure. -
+ +
+

BOOST_LEXICAL_CAST_ASSUME_C_LOCALE

+
#define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
+
+or,
+
+g++ -DBOOST_LEXICAL_CAST_ASSUME_C_LOCALE ...  (gcc on Linux/Unix)
+cl.exe /DBOOST_LEXICAL_CAST_ASSUME_C_LOCALE ... (Visual C++ on Windows)
+
+Eliminate an overhead of std::locale if your program runs in the "C" locale. If the option is set but a program runs in other locale, lexical_cast result is unspecified. +

Frequently Asked Questions

Q: Why does lexical_cast<int8_t>("127") throw bad_lexical_cast? @@ -219,7 +230,7 @@ public:

  • [N1973] Kevlin Henney, Beman Dawes, Lexical Conversion Library Proposal for TR2, N1973.
  • [Tuning] Alexander Nasonov, Fine Tuning for lexical_cast, - Overload #74, + Overload #74 (PDF), August 2006.
  • Changes

    From 408cbf0dcb435dc38dc808ca441a3995338103d3 Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Sat, 15 Dec 2007 14:26:16 +0000 Subject: [PATCH 11/16] Correct misspelling of library name [SVN r42069] --- 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 2794c86..44c7a66 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -3,7 +3,7 @@ // Boost lexical_cast.hpp header -------------------------------------------// // -// See http://www.boost.org/libs/converston for documentation. +// See http://www.boost.org/libs/conversion for documentation. // See end of this header for rights and permissions. // // what: lexical_cast custom keyword cast From 0ad888867f00c42e5c7f47748c2f976fc0208f49 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 10 Feb 2008 14:56:22 +0000 Subject: [PATCH 12/16] Link to people pages on the website, as they've been removed from the download. [SVN r43209] --- cast.htm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cast.htm b/cast.htm index 587d08a..cb8add6 100644 --- a/cast.htm +++ b/cast.htm @@ -120,10 +120,10 @@ void f( Fruit * fruit ) {

    polymorphic_cast was suggested by Bjarne Stroustrup in "The C++ Programming Language".
    polymorphic_downcast was contributed by Dave Abrahams.
    + "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams.
    An old numeric_cast
    that was contributed by Kevlin Henney is now superseeded by the Boost Numeric Conversion Library

    + "http://www.boost.org/people/kevlin_henney.htm">Kevlin Henney is now superseeded by the Boost Numeric Conversion Library


    Revised From e1dbc6ef04c042c42fb676a94ad88b046de29ef0 Mon Sep 17 00:00:00 2001 From: Alexander Nasonov Date: Wed, 16 Apr 2008 21:13:25 +0000 Subject: [PATCH 13/16] Use make_unsigned and get rid of gcc warnings when -DBOOST_LEXICAL_CAST_ASSUME_C_LOCALE [SVN r44474] --- include/boost/lexical_cast.hpp | 58 +++++++++++----------------------- 1 file changed, 18 insertions(+), 40 deletions(-) diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index 44c7a66..a1276d6 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -461,36 +462,16 @@ namespace boost // C4146: unary minus operator applied to unsigned type, result still unsigned # pragma warning( disable : 4146 ) #endif - - inline unsigned int lcast_to_unsigned(int value) + template + inline + BOOST_DEDUCED_TYPENAME make_unsigned::type lcast_to_unsigned(T value) { - unsigned int uval = value; - return value < 0 ? -uval : uval; + typedef BOOST_DEDUCED_TYPENAME make_unsigned::type result_type; + result_type uvalue = static_cast(value); + return value < 0 ? -uvalue : uvalue; } - - inline unsigned long lcast_to_unsigned(long value) - { - unsigned long uval = value; - return value < 0 ? -uval : uval; - } - -#if defined(BOOST_HAS_LONG_LONG) - inline boost::ulong_long_type lcast_to_unsigned(boost::long_long_type v) - { - boost::ulong_long_type uval = v; - return v < 0 ? -uval : uval; - } -#elif defined(BOOST_HAS_MS_INT64) - inline unsigned __int64 lcast_to_unsigned(__int64 value) - { - unsigned __int64 uval = value; - return value < 0 ? -uval : uval; - } -#endif - #if (defined _MSC_VER) -# pragma warning( pop ) // C4146: unary minus operator applied to unsigned type, - // result still unsigned +# pragma warning( pop ) #endif } @@ -502,22 +483,14 @@ namespace boost #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS BOOST_STATIC_ASSERT(!std::numeric_limits::is_signed); #endif - CharT thousands_sep = 0; -#ifdef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE - char const* grouping = ""; - std::size_t const grouping_size = 0; -#else +#ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE std::locale loc; typedef std::numpunct numpunct; numpunct const& np = BOOST_USE_FACET(numpunct, loc); std::string const& grouping = np.grouping(); std::string::size_type const grouping_size = grouping.size(); - - if(grouping_size) - thousands_sep = np.thousands_sep(); -#endif - + CharT thousands_sep = grouping_size ? np.thousands_sep() : 0; std::string::size_type group = 0; // current group number char last_grp_size = grouping[0] <= 0 ? CHAR_MAX : grouping[0]; // a) Since grouping is const, grouping[grouping.size()] returns 0. @@ -526,14 +499,17 @@ namespace boost #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS BOOST_STATIC_ASSERT(std::numeric_limits::digits10 < CHAR_MAX); #endif + + char left = last_grp_size; +#endif + typedef typename Traits::int_type int_type; CharT const czero = lcast_char_constants::zero; int_type const zero = Traits::to_int_type(czero); - char left = last_grp_size; - do { +#ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE if(left == 0) { ++group; @@ -549,6 +525,8 @@ namespace boost } --left; +#endif + --finish; int_type const digit = static_cast(n % 10U); Traits::assign(*finish, Traits::to_char_type(zero + digit)); @@ -907,7 +885,7 @@ namespace boost inline bool lexical_stream_limited_src::operator<<( unsigned short n) { - start = lcast_put_unsigned(lcast_to_unsigned(n), finish); + start = lcast_put_unsigned(n, finish); return true; } From ae5cbbbec84bd81369b475a787473498ffce5a86 Mon Sep 17 00:00:00 2001 From: Alexander Nasonov Date: Wed, 7 May 2008 19:43:55 +0000 Subject: [PATCH 14/16] Fixes #1847 Can't compile without header, boost::lexical_cast problem [SVN r45201] --- include/boost/lexical_cast.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index a1276d6..fc3f742 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -30,6 +29,10 @@ #include #include +#ifndef BOOST_NO_STD_LOCALE +#include +#endif + #ifdef BOOST_NO_STRINGSTREAM #include #else @@ -485,6 +488,7 @@ namespace boost #endif #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE + // TODO: use BOOST_NO_STD_LOCALE std::locale loc; typedef std::numpunct numpunct; numpunct const& np = BOOST_USE_FACET(numpunct, loc); @@ -651,6 +655,7 @@ namespace boost #ifndef DISABLE_WIDE_CHAR_SUPPORT static void widen_and_assign(wchar_t* p, char ch) { + // TODO: use BOOST_NO_STD_LOCALE std::locale loc; wchar_t w = BOOST_USE_FACET(std::ctype, loc).widen(ch); Traits::assign(*p, w); From 0d258ff7b15bb7a41667fa7fed4b4f4c9c0ccacb Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 21 May 2008 21:13:22 +0000 Subject: [PATCH 15/16] Largely pointless Borland 5.5.1 changes. :-) [SVN r45627] --- include/boost/lexical_cast.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index fc3f742..9fddb70 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,7 @@ #include #include #include +#include #ifndef BOOST_NO_STD_LOCALE #include @@ -49,6 +51,12 @@ namespace boost { // exception used to indicate runtime lexical_cast failure class bad_lexical_cast : public std::bad_cast + +#if defined(__BORLANDC__) && BOOST_WORKAROUND( __BORLANDC__, < 0x560 ) + // under bcc32 5.5.1 bad_cast doesn't derive from exception + , public std::exception +#endif + { public: bad_lexical_cast() : From ae273a3e7b47845f3ce5d87038895fdd9265e574 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Wed, 6 Aug 2008 15:28:17 +0000 Subject: [PATCH 16/16] Fix link to numeric conversion library. [SVN r48003] --- cast.htm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cast.htm b/cast.htm index cb8add6..a1580c3 100644 --- a/cast.htm +++ b/cast.htm @@ -123,7 +123,7 @@ void f( Fruit * fruit ) { "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams.
    An old numeric_cast
    that was contributed by Kevlin Henney is now superseeded by the Boost Numeric Conversion Library

    + "http://www.boost.org/people/kevlin_henney.htm">Kevlin Henney is now superseeded by the Boost Numeric Conversion Library


    Revised