$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r72972 - in trunk: boost libs/conversion
From: antoshkka_at_[hidden]
Date: 2011-07-08 13:23:31
Author: apolukhin
Date: 2011-07-08 13:23:31 EDT (Fri, 08 Jul 2011)
New Revision: 72972
URL: http://svn.boost.org/trac/boost/changeset/72972
Log:
Updates #5660.
Removed duplicate tests.
Unified behaviour for float conversions on different compillers
Text files modified: 
   trunk/boost/lexical_cast.hpp                |    51 ++++++++++++++++++++++++++++++++------- 
   trunk/libs/conversion/lexical_cast_test.cpp |    11 --------                                
   2 files changed, 42 insertions(+), 20 deletions(-)
Modified: trunk/boost/lexical_cast.hpp
==============================================================================
--- trunk/boost/lexical_cast.hpp	(original)
+++ trunk/boost/lexical_cast.hpp	2011-07-08 13:23:31 EDT (Fri, 08 Jul 2011)
@@ -1338,15 +1338,39 @@
                 return lcast_ret_float<Traits>(output,start,finish);
             }
 
-#if defined(BOOST_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64)
         private:
-            // we need workaround
-            bool no_long_double_80bit_realization_workaround(double& output, int) {
-                return convert_using_base_class(output);
+            // Not optimised converter
+            template <class T>
+            bool float_types_converter_internal(T& output, int /*tag*/) {
+                bool return_value = convert_using_base_class(output);
+
+                /* Some compilers and libraries successfully
+                 * parse 'inf', 'INFINITY', '1.0E', '1.0E-'...
+                 * We are trying to provide a unified behaviour,
+                 * so we just forbid such conversions (as some
+                 * of the most popular compilers/libraries do)
+                 * */
+                CharT const minus = lcast_char_constants<CharT>::minus;
+                CharT const plus = lcast_char_constants<CharT>::plus;
+                CharT const capital_e = lcast_char_constants<CharT>::capital_e;
+                CharT const lowercase_e = lcast_char_constants<CharT>::lowercase_e;
+                if ( return_value &&
+                     (
+                        output > (std::numeric_limits<T>::max)()     // +inf
+                        || output < -(std::numeric_limits<T>::max)() // -inf
+                        || output != output                          // NaN
+                        || *(finish-1) == lowercase_e                // 1.0e
+                        || *(finish-1) == capital_e                  // 1.0E
+                        || *(finish-1) == minus                      // 1.0e- or 1.0E-
+                        || *(finish-1) == plus                       // 1.0e+ or 1.0E+
+                     )
+                ) return false;
+
+                return return_value;
             }
 
-            // we do not need a workaround
-            bool no_long_double_80bit_realization_workaround(double& output,char) {
+            // Optimised converter
+            bool float_types_converter_internal(double& output,char /*tag*/) {
                 return lcast_ret_float<Traits>(output,start,finish);
             }
         public:
@@ -1360,14 +1384,23 @@
                  * double, because it will give a big precision loss.
                  * */
                 boost::mpl::if_c<
+#if defined(BOOST_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64)
                     ::boost::type_traits::ice_eq< sizeof(double), sizeof(long double) >::value,
+#else
+                     0
+#endif
                     int,
                     char
-                >::type dummy = 0;
+                >::type tag = 0;
 
-                return no_long_double_80bit_realization_workaround(output, dummy);
+                return float_types_converter_internal(output, tag);
+            }
+
+            bool operator>>(long double& output)
+            {
+                int tag = 0;
+                return float_types_converter_internal(output, tag);
             }
-#endif
 
             // Generic istream-based algorithm.
             // lcast_streambuf_for_target<InputStreamable>::value is true.
Modified: trunk/libs/conversion/lexical_cast_test.cpp
==============================================================================
--- trunk/libs/conversion/lexical_cast_test.cpp	(original)
+++ trunk/libs/conversion/lexical_cast_test.cpp	2011-07-08 13:23:31 EDT (Fri, 08 Jul 2011)
@@ -921,17 +921,6 @@
     BOOST_CHECK(boost::lexical_cast<std::wstring>(wc_arr) == std::wstring(wc_arr));
     BOOST_CHECK(boost::lexical_cast<wchar_t>(wc_arr[0]) == wc_arr[0]);
 
-    // Following tests depend on realization of std::locale.
-    // All we need to know, is that this functions must compile
-    BOOST_CHECK(boost::lexical_cast<wchar_t>(c_arr[0]) == wc_arr[0]);
-    BOOST_CHECK(boost::lexical_cast<std::wstring>(c_arr) == std::wstring(wc_arr));
-
-    BOOST_CHECK(boost::lexical_cast<std::wstring>(sc_arr) != std::wstring(wc_arr) );
-    BOOST_CHECK(boost::lexical_cast<std::wstring>(uc_arr) != std::wstring(wc_arr) );
-
-    BOOST_CHECK_THROW(boost::lexical_cast<wchar_t>(uc_arr[0]), bad_lexical_cast);
-    BOOST_CHECK_THROW(boost::lexical_cast<wchar_t>(sc_arr[0]), bad_lexical_cast);
-
 #endif
 }