diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index fb1808f..61501d6 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -26,27 +26,6 @@ #define BOOST_LCAST_NO_WCHAR_T #endif -#if (defined(__MINGW32__) || defined(__MINGW64__)) && (__GNUC__ == 4) \ - && ((__GNUC_MINOR__ == 4) || (__GNUC_MINOR__ == 5)) && defined(__STRICT_ANSI__) \ - && !defined(BOOST_LCAST_NO_WCHAR_T) - -// workaround for a mingw bug -// http://sourceforge.net/tracker/index.php?func=detail&aid=2373234&group_id=2435&atid=102435 -#include <_mingw.h> -#if (__GNUC_MINOR__ == 4) -extern "C" { -_CRTIMP int __cdecl swprintf(wchar_t * __restrict__ , const wchar_t * __restrict__ , ...); -_CRTIMP int __cdecl vswprintf(wchar_t * __restrict__ , const wchar_t * __restrict__ , ...); -} -#endif -#if (__GNUC_MINOR__ == 5) -extern "C" { -_CRTIMP int __cdecl swprintf(wchar_t * __restrict__ , const wchar_t * __restrict__ , ...); -_CRTIMP int __cdecl vswprintf(wchar_t * __restrict__ , const wchar_t * __restrict__ , va_list); -} -#endif -#endif - #include #include #include @@ -501,7 +480,7 @@ namespace boost }; #endif -#ifndef BOOST_NO_CHAR16_T +#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS) template<> struct lcast_char_constants { @@ -514,7 +493,7 @@ namespace boost }; #endif -#ifndef BOOST_NO_CHAR32_T +#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS) template<> struct lcast_char_constants { @@ -864,7 +843,7 @@ namespace boost } #endif -#ifndef BOOST_NO_CHAR16_T +#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS) template bool parse_inf_nan(const char16_t* begin, const char16_t* end, T& value) { @@ -880,7 +859,7 @@ namespace boost return put_inf_nan_impl(begin, end, value, u"nan", u"infinity"); } #endif -#ifndef BOOST_NO_CHAR32_T +#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS) template bool parse_inf_nan(const char32_t* begin, const char32_t* end, T& value) { @@ -1275,7 +1254,7 @@ namespace boost { #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_LOCALE) // If you have compilation error at this point, than your STL library - // unsupports such conversions. Try updating it. + // does not support such conversions. Try updating it. BOOST_STATIC_ASSERT((boost::is_same::value)); #endif bool const result = !(out_stream << input).fail(); @@ -1299,34 +1278,42 @@ namespace boost return true; } + template + bool shl_real_type(const T& val, SomeCharT* begin, SomeCharT*& end) + { + if (put_inf_nan(begin, end, val)) return true; + lcast_set_precision(out_stream, &val); + return shl_input_streamable(val); + } + #if (defined _MSC_VER) # pragma warning( push ) // C4996: This function or variable may be unsafe. Consider using sprintf_s instead # pragma warning( disable : 4996 ) #endif - - template - bool shl_float(float val,T* out) + static bool shl_real_type(float val, char* begin, char*& end) { using namespace std; - if (put_inf_nan(start,finish,val)) return true; - finish = start + sprintf(out,"%.*g", static_cast(boost::detail::lcast_get_precision()), val ); - return finish > start; + if (put_inf_nan(begin, end, val)) return true; + end = begin; + end += sprintf(begin,"%.*g", static_cast(boost::detail::lcast_get_precision()), val); + return end > begin; } - template - bool shl_double(double val,T* out) + static bool shl_real_type(double val, char* begin, char*& end) { using namespace std; - if (put_inf_nan(start,finish,val)) return true; - finish = start + sprintf(out,"%.*lg", static_cast(boost::detail::lcast_get_precision()), val ); - return finish > start; + if (put_inf_nan(begin, end, val)) return true; + end = begin; + end += sprintf(begin,"%.*lg", static_cast(boost::detail::lcast_get_precision()), val); + return end > begin; } + #ifndef __MINGW32__ - template - bool shl_long_double(long double val,T* out) + static bool shl_real_type(long double val, char* begin, char*& end) { using namespace std; - if (put_inf_nan(start,finish,val)) return true; - finish = start + sprintf(out,"%.*Lg", static_cast(boost::detail::lcast_get_precision()), val ); - return finish > start; + if (put_inf_nan(begin, end, val)) return true; + end = begin; + end += sprintf(begin,"%.*Lg", static_cast(boost::detail::lcast_get_precision()), val ); + return end > begin; } #endif @@ -1335,54 +1322,32 @@ namespace boost #endif -#ifndef BOOST_LCAST_NO_WCHAR_T - bool shl_float(float val,wchar_t* out) +#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_SWPRINTF) && !defined(__MINGW32__) + static bool shl_real_type(float val, wchar_t* begin, wchar_t*& end) { using namespace std; - if (put_inf_nan(start,finish,val)) return true; - finish = start + swprintf(out, -#if !defined(__MINGW32__) && !defined(UNDER_CE) - finish-start, -#endif + if (put_inf_nan(begin, end, val)) return true; + end = begin + swprintf(begin, end-begin, L"%.*g", static_cast(boost::detail::lcast_get_precision()), val ); - - return finish > start; + return end > begin; } - - bool shl_double(double val,wchar_t* out) + static bool shl_real_type(double val, wchar_t* begin, wchar_t*& end) { using namespace std; - if (put_inf_nan(start,finish,val)) return true; - /* __MINGW32__ is defined for both mingw.org and for mingw-w64. - * For mingw-w64, __MINGW64__ is defined, too, when targetting - * 64 bits. - * - * swprintf realization in MinGW and under WinCE does not conform - * to the ISO C - * Standard. - */ - finish = start + swprintf(out, -#if !defined(__MINGW32__) && !defined(UNDER_CE) - finish-start, -#endif + if (put_inf_nan(begin, end, val)) return true; + end = begin + swprintf(begin, end-begin, L"%.*lg", static_cast(boost::detail::lcast_get_precision()), val ); - return finish > start; + return end > begin; } -#ifndef __MINGW32__ - bool shl_long_double(long double val,wchar_t* out) + static bool shl_real_type(long double val, wchar_t* begin, wchar_t*& end) { using namespace std; - if (put_inf_nan(start,finish,val)) return true; - finish = start + swprintf(out, -#if !defined(UNDER_CE) - finish-start, -#endif + if (put_inf_nan(begin, end, val)) return true; + end = begin + swprintf(begin, end-begin, L"%.*Lg", static_cast(boost::detail::lcast_get_precision()), val ); - return finish > start; + return end > begin; } #endif -#endif - /************************************ OPERATORS << ( ... ) ********************************/ public: template @@ -1486,13 +1451,13 @@ namespace boost bool operator<<(unsigned __int64 n) { start = lcast_put_unsigned(n, finish); return true; } bool operator<<( __int64 n) { return shl_signed(n); } #endif - bool operator<<(float val) { return shl_float(val,start); } - bool operator<<(double val) { return shl_double(val,start); } + bool operator<<(float val) { return shl_real_type(val, start, finish); } + bool operator<<(double val) { return shl_real_type(val, start, finish); } bool operator<<(long double val) { #ifndef __MINGW32__ - return shl_long_double(val,start); + return shl_real_type(val, start, finish); #else - return shl_double(val,start); + return shl_real_type(static_cast(val), start, finish); #endif } @@ -1663,10 +1628,10 @@ namespace boost #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T) bool operator>>(wchar_t& output) { return shr_xchar(output); } #endif -#ifndef BOOST_NO_CHAR16_T +#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS) bool operator>>(char16_t& output) { return shr_xchar(output); } #endif -#ifndef BOOST_NO_CHAR32_T +#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS) bool operator>>(char32_t& output) { return shr_xchar(output); } #endif #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION @@ -1884,8 +1849,8 @@ namespace boost BOOST_STATIC_CONSTANT(bool, value = ( ::boost::type_traits::ice_and< - is_arithmetic::value, - is_arithmetic::value, + ::boost::is_arithmetic::value, + ::boost::is_arithmetic::value, ::boost::type_traits::ice_not< detail::is_char_or_wchar::value >::value, @@ -1923,6 +1888,28 @@ namespace boost ); }; + + // this metafunction evaluates to true, if we have optimized comnversion + // from Float type to Char array. + // Must be in sync with lexical_stream_limited_src::shl_real_type(...) + template + struct is_this_float_conversion_optimized + { + typedef ::boost::type_traits::ice_and< + ::boost::is_float::value, +#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_SWPRINTF) && !defined(__MINGW32__) + ::boost::type_traits::ice_or< + ::boost::type_traits::ice_eq::value, + ::boost::is_same::value + >::value +#else + ::boost::type_traits::ice_eq::value +#endif + > result_type; + + BOOST_STATIC_CONSTANT(bool, value = (result_type::value) ); + }; + template struct is_char_array_to_stdstring { @@ -1972,6 +1959,17 @@ namespace boost target_char_t, src_char_type >::type char_type; +#if !defined(BOOST_NO_CHAR16_T) && defined(BOOST_NO_UNICODE_LITERALS) + BOOST_STATIC_ASSERT_MSG(( !::boost::is_same::value + && !::boost::is_same::value), + "Your compiler does not have full support for char16_t" ); +#endif +#if !defined(BOOST_NO_CHAR32_T) && defined(BOOST_NO_UNICODE_LITERALS) + BOOST_STATIC_ASSERT_MSG(( !::boost::is_same::value + && !::boost::is_same::value), + "Your compiler does not have full support for char32_t" ); +#endif + typedef detail::lcast_src_length lcast_src_length; std::size_t const src_len = lcast_src_length::value; char_type buf[src_len + 1]; @@ -1997,21 +1995,22 @@ namespace boost ::boost::is_same::value >::value >::value, - is_same::value + ::boost::is_same::value >::value); const bool requires_stringbuf = !( ::boost::type_traits::ice_or< - is_stdstring::value, - is_arithmetic::value, + ::boost::detail::is_stdstring::value, + ::boost::is_integral::value, + ::boost::detail::is_this_float_conversion_optimized::value, ::boost::type_traits::ice_and< - is_char_iterator_range::value, + ::boost::detail::is_char_iterator_range::value, is_char_types_match >::value, ::boost::type_traits::ice_and< - is_pointer::value, - is_char_or_wchar::value, + ::boost::is_pointer::value, + ::boost::detail::is_char_or_wchar::value, is_char_types_match >::value >::value @@ -2047,7 +2046,7 @@ namespace boost typedef Source source_type ; typedef BOOST_DEDUCED_TYPENAME mpl::if_< - is_arithmetic, Source, Source const& + ::boost::is_arithmetic, Source, Source const& >::type argument_type ; static source_type nearbyint ( argument_type s ) @@ -2138,10 +2137,10 @@ namespace boost ::boost::is_float::value >::value, ::boost::type_traits::ice_not< - is_same::value + ::boost::is_same::value >::value, ::boost::type_traits::ice_not< - is_same::value + ::boost::is_same::value >::value, ::boost::is_unsigned::value >::value, @@ -2157,27 +2156,27 @@ namespace boost template inline Target lexical_cast(const Source &arg) { - typedef BOOST_DEDUCED_TYPENAME detail::array_to_pointer_decay::type src; + typedef BOOST_DEDUCED_TYPENAME ::boost::detail::array_to_pointer_decay::type src; typedef BOOST_DEDUCED_TYPENAME ::boost::type_traits::ice_or< - detail::is_xchar_to_xchar::value, - detail::is_char_array_to_stdstring::value, + ::boost::detail::is_xchar_to_xchar::value, + ::boost::detail::is_char_array_to_stdstring::value, ::boost::type_traits::ice_and< - is_same::value, - detail::is_stdstring::value + ::boost::is_same::value, + ::boost::detail::is_stdstring::value >::value > do_copy_type; typedef BOOST_DEDUCED_TYPENAME - detail::is_arithmetic_and_not_xchars do_copy_with_dynamic_check_type; + ::boost::detail::is_arithmetic_and_not_xchars do_copy_with_dynamic_check_type; typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::if_c< do_copy_type::value, detail::lexical_cast_copy, BOOST_DEDUCED_TYPENAME ::boost::mpl::if_c< do_copy_with_dynamic_check_type::value, - detail::lexical_cast_dynamic_num, - detail::lexical_cast_do_cast + ::boost::detail::lexical_cast_dynamic_num, + ::boost::detail::lexical_cast_do_cast >::type >::type caster_type; diff --git a/lexical_cast_test.cpp b/lexical_cast_test.cpp index 4e9ec90..4e70bdd 100644 --- a/lexical_cast_test.cpp +++ b/lexical_cast_test.cpp @@ -100,10 +100,10 @@ void test_wallocator(); #endif void test_char_types_conversions(); void operators_overload_test(); -#ifndef BOOST_NO_CHAR16_T +#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS) void test_char16_conversions(); #endif -#ifndef BOOST_NO_CHAR32_T +#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS) void test_char32_conversions(); #endif @@ -149,10 +149,10 @@ unit_test::test_suite *init_unit_test_suite(int, char *[]) suite->add(BOOST_TEST_CASE(&test_char_types_conversions)); suite->add(BOOST_TEST_CASE(&operators_overload_test)); -#ifndef BOOST_NO_CHAR16_T +#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS) suite->add(BOOST_TEST_CASE(&test_char16_conversions)); #endif -#ifndef BOOST_NO_CHAR32_T +#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS) suite->add(BOOST_TEST_CASE(&test_char32_conversions)); #endif @@ -756,12 +756,12 @@ void test_conversion_from_to_integral() test_conversion_from_integral_to_char(wzero); test_conversion_from_char_to_integral(wzero); #endif -#ifndef BOOST_NO_CHAR16_T +#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS) char16_t const u16zero = u'0'; test_conversion_from_integral_to_char(u16zero); test_conversion_from_char_to_integral(u16zero); #endif -#ifndef BOOST_NO_CHAR32_T +#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS) char32_t const u32zero = u'0'; test_conversion_from_integral_to_char(u32zero); test_conversion_from_char_to_integral(u32zero); @@ -1025,7 +1025,7 @@ void operators_overload_test() } -#ifndef BOOST_NO_CHAR16_T +#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS) void test_char16_conversions() { BOOST_CHECK(u"100" == lexical_cast(u"100")); @@ -1033,7 +1033,7 @@ void test_char16_conversions() } #endif -#ifndef BOOST_NO_CHAR32_T +#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS) void test_char32_conversions() { BOOST_CHECK(U"100" == lexical_cast(U"100")); diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 131fa3e..2673009 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -1,50 +1,50 @@ -# Signals library - # Copyright (C) 2001-2003 Douglas Gregor +# Copyright (C) 2011-2012 Antony Polukhin +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +# -# Permission to copy, use, sell and distribute this software is granted -# provided this copyright notice appears in all copies. Permission to modify -# the code and to distribute modified code is granted provided this copyright -# notice appears in all copies, and a notice that the code was modified is -# included with the copyright notice. This software is provided "as is" -# without express or implied warranty, and with no claim as to its suitability -# for any purpose. - -# For more information, see http://www.boost.org/ - -# bring in rules for testing import testing ; import feature ; +project + : requirements + /boost/test//boost_unit_test_framework + static + ; + +# Thanks to Steven Watanabe for helping with feature feature.feature nowchar : on : composite optional propagated link-incompatible ; -feature.compose on : /Zc:wchar_t- ; +feature.compose on : /Zc:wchar_t- ; test-suite conversion : [ run implicit_cast.cpp ] [ compile-fail implicit_cast_fail.cpp ] [ run ../cast_test.cpp ] [ run ../numeric_cast_test.cpp ] - [ run ../lexical_cast_test.cpp ../../test/build//boost_unit_test_framework/static ] - [ run lexical_cast_loopback_test.cpp ../../test/build//boost_unit_test_framework/static ] - [ run lexical_cast_abstract_test.cpp ../../test/build//boost_unit_test_framework/static ] - [ run lexical_cast_noncopyable_test.cpp ../../test/build//boost_unit_test_framework/static ] - [ run lexical_cast_vc8_bug_test.cpp ../../test/build//boost_unit_test_framework/static ] - [ run lexical_cast_wchars_test.cpp ../../test/build//boost_unit_test_framework/static ] - [ run lexical_cast_float_types_test.cpp ../../test/build//boost_unit_test_framework/static ] - [ run lexical_cast_inf_nan_test.cpp ../../test/build//boost_unit_test_framework/static ] - [ run lexical_cast_containers_test.cpp ../../test/build//boost_unit_test_framework/static ] - [ run lexical_cast_empty_input_test.cpp ../../test/build//boost_unit_test_framework/static ] - [ run lexical_cast_pointers_test.cpp ../../test/build//boost_unit_test_framework/static ] + [ run ../lexical_cast_test.cpp ] + [ run lexical_cast_loopback_test.cpp ] + [ run lexical_cast_abstract_test.cpp ] + [ run lexical_cast_noncopyable_test.cpp ] + [ run lexical_cast_vc8_bug_test.cpp ] + [ run lexical_cast_wchars_test.cpp ] + [ run lexical_cast_float_types_test.cpp ] + [ run lexical_cast_inf_nan_test.cpp ] + [ run lexical_cast_containers_test.cpp ] + [ run lexical_cast_empty_input_test.cpp ] + [ run lexical_cast_pointers_test.cpp ] [ compile lexical_cast_typedefed_wchar_test.cpp : msvc:on ] - [ run lexical_cast_typedefed_wchar_test_runtime.cpp ../../test/build//boost_unit_test_framework/static : : : msvc:on ] - [ run lexical_cast_no_locale_test.cpp ../../test/build//boost_unit_test_framework/static : : : BOOST_NO_STD_LOCALE BOOST_LEXICAL_CAST_ASSUME_C_LOCALE ] - [ run lexical_cast_no_exceptions_test.cpp ../../test/build//boost_unit_test_framework/static : : : BOOST_NO_EXCEPTIONS + [ run lexical_cast_typedefed_wchar_test_runtime.cpp : : : msvc:on msvc,stlport:no ] + [ run lexical_cast_no_locale_test.cpp : : : BOOST_NO_STD_LOCALE BOOST_LEXICAL_CAST_ASSUME_C_LOCALE ] + [ run lexical_cast_no_exceptions_test.cpp : : : BOOST_NO_EXCEPTIONS gcc-4.3:-fno-exceptions gcc-4.4:-fno-exceptions gcc-4.5:-fno-exceptions gcc-4.6:-fno-exceptions + gcc-4.7:-fno-exceptions ] - [ run lexical_cast_iterator_range_test.cpp ../../test/build//boost_unit_test_framework/static ] - ; + [ run lexical_cast_iterator_range_test.cpp ] + ; diff --git a/test/lexical_cast_no_exceptions_test.cpp b/test/lexical_cast_no_exceptions_test.cpp index 8431c3a..dbec8ea 100755 --- a/test/lexical_cast_no_exceptions_test.cpp +++ b/test/lexical_cast_no_exceptions_test.cpp @@ -29,7 +29,7 @@ bool g_was_exception = false; namespace boost { void throw_exception(std::exception const & ) { - g_was_exception = true; + g_was_exception = true; } }