diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index b9bc984..cec2c50 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -19,7 +19,7 @@ // Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov, // Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann, // Cheng Yang, Matthew Bradbury and other Boosters -// when: November 2000, March 2003, June 2005, June 2006, March 2011 +// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2012 #include #include @@ -1822,6 +1822,24 @@ namespace boost deduce_char_traits::type traits; typedef BOOST_DEDUCED_TYPENAME remove_pointer::type removed_ptr_t; + + // is_char_types_match variable value can be computed via + // sizeof(char_type) == sizeof(removed_ptr_t). But when + // removed_ptr_t is an incomplete type or void*, compilers + // produce warnings or errors. + const bool is_char_types_match = + (::boost::type_traits::ice_or< + ::boost::type_traits::ice_and< + ::boost::type_traits::ice_eq::value, + ::boost::type_traits::ice_or< + ::boost::is_same::value, + ::boost::is_same::value, + ::boost::is_same::value + >::value + >::value, + is_same::value + >::value); + const bool requires_stringbuf = !( ::boost::type_traits::ice_or< @@ -1830,10 +1848,7 @@ namespace boost ::boost::type_traits::ice_and< is_pointer::value, is_char_or_wchar::value, - ::boost::type_traits::ice_eq< - sizeof(char_type), - sizeof(removed_ptr_t) - >::value + is_char_types_match >::value >::value ); @@ -2111,7 +2126,7 @@ namespace boost // Copyright Kevlin Henney, 2000-2005. // Copyright Alexander Nasonov, 2006-2010. -// Copyright Antony Polukhin, 2011. +// Copyright Antony Polukhin, 2011-2012. // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 8718301..c311420 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -35,6 +35,7 @@ test-suite conversion [ 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 ] [ 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 ] ; diff --git a/test/lexical_cast_pointers_test.cpp b/test/lexical_cast_pointers_test.cpp new file mode 100755 index 0000000..d24a895 --- /dev/null +++ b/test/lexical_cast_pointers_test.cpp @@ -0,0 +1,96 @@ +// 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 + +#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 +#include + +using namespace boost; + +#if defined(BOOST_NO_STRINGSTREAM) + typedef std::strstream ss_t; +#else + typedef std::stringstream ss_t; +#endif + +void test_void_pointers_conversions() +{ + void *p_to_null = NULL; + const void *cp_to_data = "Some data"; + char nonconst_data[5]; + void *p_to_data = nonconst_data; + ss_t ss; + + ss << p_to_null; + BOOST_CHECK_EQUAL(boost::lexical_cast(p_to_null), ss.str()); + ss.str(std::string()); + + ss << cp_to_data; + BOOST_CHECK_EQUAL(boost::lexical_cast(cp_to_data), ss.str()); + ss.str(std::string()); + + ss << p_to_data; + BOOST_CHECK_EQUAL(boost::lexical_cast(p_to_data), ss.str()); + ss.str(std::string()); +} + +struct incomplete_type; + +void test_incomplete_type_pointers_conversions() +{ + incomplete_type *p_to_null = NULL; + const incomplete_type *cp_to_data = NULL; + char nonconst_data[5]; + incomplete_type *p_to_data = reinterpret_cast(nonconst_data); + ss_t ss; + + ss << p_to_null; + BOOST_CHECK_EQUAL(boost::lexical_cast(p_to_null), ss.str()); + ss.str(std::string()); + + ss << cp_to_data; + BOOST_CHECK_EQUAL(boost::lexical_cast(cp_to_data), ss.str()); + ss.str(std::string()); + + ss << p_to_data; + BOOST_CHECK_EQUAL(boost::lexical_cast(p_to_data), ss.str()); + ss.str(std::string()); +} + +struct ble; +typedef struct ble *meh; +std::ostream& operator <<(std::ostream &o, meh) { + o << "yay"; + return o; +} + +void test_inomplete_type_with_overloaded_ostream_op() { + meh heh = NULL; + ss_t ss; + ss << heh; + BOOST_CHECK_EQUAL(boost::lexical_cast(heh), ss.str()); +} + +unit_test::test_suite *init_unit_test_suite(int, char *[]) +{ + unit_test::test_suite *suite = + BOOST_TEST_SUITE("lexical_cast pinters test"); + suite->add(BOOST_TEST_CASE(&test_void_pointers_conversions)); + suite->add(BOOST_TEST_CASE(&test_incomplete_type_pointers_conversions)); + suite->add(BOOST_TEST_CASE(&test_inomplete_type_with_overloaded_ostream_op)); + return suite; +}