$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r77077 - in trunk: boost libs/conversion/test
From: antoshkka_at_[hidden]
Date: 2012-02-20 11:20:09
Author: apolukhin
Date: 2012-02-20 11:20:09 EST (Mon, 20 Feb 2012)
New Revision: 77077
URL: http://svn.boost.org/trac/boost/changeset/77077
Log:
Fixes #6441 (compilation error with BOOST_NO_STD_LOCALE defined)
Added:
   trunk/libs/conversion/test/lexical_cast_no_locale_test.cpp   (contents, props changed)
Text files modified: 
   trunk/boost/lexical_cast.hpp                                     |    53 +++++++++++++++++++++++++++------------ 
   trunk/libs/conversion/test/Jamfile.v2                            |     1                                         
   trunk/libs/conversion/test/lexical_cast_typedefed_wchar_test.cpp |     1                                         
   3 files changed, 39 insertions(+), 16 deletions(-)
Modified: trunk/boost/lexical_cast.hpp
==============================================================================
--- trunk/boost/lexical_cast.hpp	(original)
+++ trunk/boost/lexical_cast.hpp	2012-02-20 11:20:09 EST (Mon, 20 Feb 2012)
@@ -1167,7 +1167,7 @@
 
     namespace detail
     {
-        struct do_not_construct_stringbuffer_t{};
+        struct do_not_construct_out_stream_t{};
     }
 
     namespace detail // optimized stream wrapper
@@ -1179,25 +1179,27 @@
                 >
         class lexical_stream_limited_src
         {
-            typedef stl_buf_unlocker<std::basic_streambuf<CharT, Traits>, CharT > local_streambuffer_t;
 
 #if defined(BOOST_NO_STRINGSTREAM)
-            typedef stl_buf_unlocker<std::strstream, CharT > local_stringbuffer_t;
+            typedef std::ostrstream                         out_stream_t;
+            typedef stl_buf_unlocker<std::strstreambuf, char>  unlocked_but_t;
 #elif defined(BOOST_NO_STD_LOCALE)
-            typedef stl_buf_unlocker<std::stringstream, CharT > local_stringbuffer_t;
+            typedef std::ostringstream                      out_stream_t;
+            typedef stl_buf_unlocker<std::stringbuf, char>  unlocked_but_t;
 #else
-            typedef stl_buf_unlocker<std::basic_stringbuf<CharT, Traits>, CharT > local_stringbuffer_t;
+            typedef std::basic_ostringstream<CharT, Traits>       out_stream_t;
+            typedef stl_buf_unlocker<std::basic_stringbuf<CharT, Traits>, CharT> unlocked_but_t;
 #endif
             typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::if_c<
                 RequiresStringbuffer,
-                local_stringbuffer_t,
-                do_not_construct_stringbuffer_t
-            >::type deduced_stringbuffer_t;
+                out_stream_t,
+                do_not_construct_out_stream_t
+            >::type deduced_out_stream_t;
 
             // A string representation of Source is written to [start, finish).
             CharT* start;
             CharT* finish;
-            deduced_stringbuffer_t stringbuffer;
+            deduced_out_stream_t out_stream;
 
         public:
             lexical_stream_limited_src(CharT* sta, CharT* fin)
@@ -1258,10 +1260,16 @@
             template<typename InputStreamable>
             bool shl_input_streamable(InputStreamable& input)
             {
-                std::basic_ostream<CharT> stream(&stringbuffer);
-                bool const result = !(stream << input).fail();
-                start = stringbuffer.pbase();
-                finish = stringbuffer.pptr();
+#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.
+                BOOST_STATIC_ASSERT((boost::is_same<char, CharT>::value));
+#endif
+                bool const result = !(out_stream << input).fail();
+                const unlocked_but_t* const p
+                        = static_cast<unlocked_but_t*>(out_stream.rdbuf()) ;
+                start = p->pbase();
+                finish = p->pptr();
                 return result;
             }
 
@@ -1526,9 +1534,22 @@
                 if(is_pointer<InputStreamable>::value)
                     return false;
 
-                local_streambuffer_t bb;
-                bb.setg(start, start, finish);
-                std::basic_istream<CharT> stream(&bb);
+#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.
+                BOOST_STATIC_ASSERT((boost::is_same<char, CharT>::value));
+#endif
+
+#if defined(BOOST_NO_STRINGSTREAM)
+                std::istrstream stream(start, finish - start);
+#elif defined(BOOST_NO_STD_LOCALE)
+                std::istringstream stream;
+#else
+                std::basic_istringstream<CharT, Traits> stream;
+#endif
+                static_cast<unlocked_but_t*>(stream.rdbuf())
+                        ->setg(start, start, finish);
+
                 stream.unsetf(std::ios::skipws);
                 lcast_set_precision(stream, static_cast<InputStreamable*>(0));
 #if (defined _MSC_VER)
Modified: trunk/libs/conversion/test/Jamfile.v2
==============================================================================
--- trunk/libs/conversion/test/Jamfile.v2	(original)
+++ trunk/libs/conversion/test/Jamfile.v2	2012-02-20 11:20:09 EST (Mon, 20 Feb 2012)
@@ -38,5 +38,6 @@
     [ run lexical_cast_pointers_test.cpp ../../test/build//boost_unit_test_framework/<link>static ]
     [ compile lexical_cast_typedefed_wchar_test.cpp : <toolset>msvc:<nowchar>on ]
     [ run lexical_cast_typedefed_wchar_test_runtime.cpp ../../test/build//boost_unit_test_framework/<link>static : : : <toolset>msvc:<nowchar>on ]
+    [ run lexical_cast_no_locale_test.cpp ../../test/build//boost_unit_test_framework/<link>static : : : <define>BOOST_NO_STD_LOCALE ]
   ;
       
Added: trunk/libs/conversion/test/lexical_cast_no_locale_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/conversion/test/lexical_cast_no_locale_test.cpp	2012-02-20 11:20:09 EST (Mon, 20 Feb 2012)
@@ -0,0 +1,166 @@
+//  Unit test for boost::lexical_cast.
+//
+//  See http://www.boost.org for most recent version, including documentation.
+//
+//  Copyright Antony Polukhin, 2012.
+//
+//  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).
+
+#include <boost/config.hpp>
+
+#if defined(__INTEL_COMPILER)
+#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
+
+#include <boost/lexical_cast.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/range/iterator_range.hpp>
+
+using namespace boost;
+
+// Testing compilation and some basic usage with BOOST_NO_STD_LOCALE
+// Tests are mainly copyied from lexical_cast_empty_input_test.cpp (something 
+// new added to test_empty_3)
+
+#ifndef BOOST_NO_STD_LOCALE
+#error "This test must be compiled with -DBOOST_NO_STD_LOCALE"
+#endif 
+
+
+template <class T>
+void do_test_on_empty_input(T& v)
+{
+    BOOST_CHECK_THROW(lexical_cast<int>(v), bad_lexical_cast);
+    BOOST_CHECK_THROW(lexical_cast<float>(v), bad_lexical_cast);
+    BOOST_CHECK_THROW(lexical_cast<double>(v), bad_lexical_cast);
+    BOOST_CHECK_THROW(lexical_cast<long double>(v), bad_lexical_cast);
+    BOOST_CHECK_THROW(lexical_cast<unsigned int>(v), bad_lexical_cast);
+    BOOST_CHECK_THROW(lexical_cast<unsigned short>(v), bad_lexical_cast);
+#if defined(BOOST_HAS_LONG_LONG)
+    BOOST_CHECK_THROW(lexical_cast<boost::ulong_long_type>(v), bad_lexical_cast);
+    BOOST_CHECK_THROW(lexical_cast<boost::long_long_type>(v), bad_lexical_cast);
+#elif defined(BOOST_HAS_MS_INT64)
+    BOOST_CHECK_THROW(lexical_cast<unsigned __int64>(v), bad_lexical_cast);
+    BOOST_CHECK_THROW(lexical_cast<__int64>(v), bad_lexical_cast);
+#endif
+}
+
+void test_empty_1()
+{
+    boost::iterator_range<char*> v;
+    do_test_on_empty_input(v);
+    BOOST_CHECK_EQUAL(lexical_cast<std::string>(v), std::string());
+    BOOST_CHECK_THROW(lexical_cast<char>(v), bad_lexical_cast);
+    BOOST_CHECK_THROW(lexical_cast<unsigned char>(v), bad_lexical_cast);
+    BOOST_CHECK_THROW(lexical_cast<signed char>(v), bad_lexical_cast);
+
+    boost::iterator_range<const char*> cv;
+    do_test_on_empty_input(cv);
+    BOOST_CHECK_EQUAL(lexical_cast<std::string>(cv), std::string());
+    BOOST_CHECK_THROW(lexical_cast<char>(cv), bad_lexical_cast);
+    BOOST_CHECK_THROW(lexical_cast<unsigned char>(cv), bad_lexical_cast);
+    BOOST_CHECK_THROW(lexical_cast<signed char>(cv), bad_lexical_cast);
+
+    const boost::iterator_range<const char*> ccv;
+    do_test_on_empty_input(ccv);
+    BOOST_CHECK_EQUAL(lexical_cast<std::string>(ccv), std::string());
+    BOOST_CHECK_THROW(lexical_cast<char>(ccv), bad_lexical_cast);
+    BOOST_CHECK_THROW(lexical_cast<unsigned char>(ccv), bad_lexical_cast);
+    BOOST_CHECK_THROW(lexical_cast<signed char>(ccv), bad_lexical_cast);
+}
+
+void test_empty_2()
+{
+    std::string v;
+    do_test_on_empty_input(v);
+    BOOST_CHECK_THROW(lexical_cast<char>(v), bad_lexical_cast);
+    BOOST_CHECK_THROW(lexical_cast<unsigned char>(v), bad_lexical_cast);
+    BOOST_CHECK_THROW(lexical_cast<signed char>(v), bad_lexical_cast);
+}
+
+struct Escape
+{
+    Escape(){}
+    Escape(const std::string& s)
+        : str_(s)
+    {}
+
+    std::string str_;
+};
+
+inline std::ostream& operator<< (std::ostream& o, const Escape& rhs)
+{
+    return o << rhs.str_;
+}
+
+inline std::istream& operator>> (std::istream& i, Escape& rhs)
+{
+    return i >> rhs.str_;
+}
+
+void test_empty_3()
+{
+    Escape v("");
+    do_test_on_empty_input(v);
+            
+    BOOST_CHECK_THROW(lexical_cast<char>(v), bad_lexical_cast);
+    BOOST_CHECK_THROW(lexical_cast<unsigned char>(v), bad_lexical_cast);
+    BOOST_CHECK_THROW(lexical_cast<signed char>(v), bad_lexical_cast);
+    
+    v = lexical_cast<Escape>(100);
+    BOOST_CHECK_EQUAL(lexical_cast<int>(v), 100);
+    BOOST_CHECK_EQUAL(lexical_cast<unsigned int>(v), 100);
+    
+    v = lexical_cast<Escape>(0.0);
+    BOOST_CHECK_EQUAL(lexical_cast<double>(v), 0.0);
+}
+
+namespace std {
+inline std::ostream & operator<<(std::ostream & out, const std::vector<long> & v)
+{
+    std::ostream_iterator<long> it(out);
+    std::copy(v.begin(), v.end(), it);
+    assert(out);
+    return out;
+}
+}
+
+void test_empty_4()
+{
+    std::vector<long> v;
+    do_test_on_empty_input(v);
+    BOOST_CHECK_THROW(lexical_cast<char>(v), bad_lexical_cast);
+    BOOST_CHECK_THROW(lexical_cast<unsigned char>(v), bad_lexical_cast);
+    BOOST_CHECK_THROW(lexical_cast<signed char>(v), bad_lexical_cast);
+}
+
+
+struct my_string {
+    friend std::ostream &operator<<(std::ostream& sout, my_string const&/* st*/) {
+            return sout << "";
+    }
+};
+
+void test_empty_5()
+{
+    my_string st;
+    BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(st), std::string());;
+}
+
+unit_test::test_suite *init_unit_test_suite(int, char *[])
+{
+    unit_test::test_suite *suite =
+        BOOST_TEST_SUITE("lexical_cast. Testing with BOOST_NO_STD_LOCALE");
+    suite->add(BOOST_TEST_CASE(&test_empty_1));
+    suite->add(BOOST_TEST_CASE(&test_empty_2));
+    suite->add(BOOST_TEST_CASE(&test_empty_3));
+    suite->add(BOOST_TEST_CASE(&test_empty_4));
+    suite->add(BOOST_TEST_CASE(&test_empty_5));
+
+    return suite;
+}
+
Modified: trunk/libs/conversion/test/lexical_cast_typedefed_wchar_test.cpp
==============================================================================
--- trunk/libs/conversion/test/lexical_cast_typedefed_wchar_test.cpp	(original)
+++ trunk/libs/conversion/test/lexical_cast_typedefed_wchar_test.cpp	2012-02-20 11:20:09 EST (Mon, 20 Feb 2012)
@@ -23,6 +23,7 @@
   boost::date_time::special_values_parser<boost::gregorian::date, wchar_t> svp;
 
   boost::gregorian::date date = parser.parse_date(L"", L"", svp);
+  (void)date;
 }