Boost logo

Boost-Commit :

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;
 }
 
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk