diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index fb1808f..d79e50a 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 @@ -1299,34 +1278,40 @@ namespace boost return true; } + template + bool shl_real_type(const T& val, SomeCharT*, SomeCharT*) + { + 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 +1320,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 +1449,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 } @@ -1884,8 +1847,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 +1886,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 { @@ -2003,15 +1988,16 @@ namespace boost 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 +2033,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 +2124,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 +2143,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;