Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r81354 - in trunk: boost libs/conversion/test
From: antoshkka_at_[hidden]
Date: 2012-11-15 02:26:24


Author: apolukhin
Date: 2012-11-15 02:26:23 EST (Thu, 15 Nov 2012)
New Revision: 81354
URL: http://svn.boost.org/trac/boost/changeset/81354

Log:
Move all the stream specific metafunctions to lexical_cast_stream_traits<Source, Target>
Test stream traits for correctness and correct optimization detection
Added:
   trunk/libs/conversion/test/lexical_cast_stream_traits_test.cpp (contents, props changed)
Text files modified:
   trunk/boost/lexical_cast.hpp | 197 +++++++++++++++++++++------------------
   trunk/libs/conversion/test/Jamfile.v2 | 1
   2 files changed, 108 insertions(+), 90 deletions(-)

Modified: trunk/boost/lexical_cast.hpp
==============================================================================
--- trunk/boost/lexical_cast.hpp (original)
+++ trunk/boost/lexical_cast.hpp 2012-11-15 02:26:23 EST (Thu, 15 Nov 2012)
@@ -504,6 +504,45 @@
         };
     }
 
+ namespace detail // array_to_pointer_decay<T>
+ {
+ template<class T>
+ struct array_to_pointer_decay
+ {
+ typedef T type;
+ };
+
+ template<class T, std::size_t N>
+ struct array_to_pointer_decay<T[N]>
+ {
+ typedef const T * type;
+ };
+ }
+
+ namespace detail // is_this_float_conversion_optimized<Float, Char>
+ {
+ // 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<Char, ...>::shl_real_type(...)
+ template <typename Float, typename Char>
+ struct is_this_float_conversion_optimized
+ {
+ typedef boost::type_traits::ice_and<
+ boost::is_float<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<sizeof(Char), sizeof(char) >::value,
+ boost::is_same<Char, wchar_t>::value
+ >::value
+#else
+ boost::type_traits::ice_eq<sizeof(Char), sizeof(char) >::value
+#endif
+ > result_type;
+
+ BOOST_STATIC_CONSTANT(bool, value = (result_type::value) );
+ };
+ }
+
     namespace detail // lcast_src_length
     {
         // Return max. length of string representation of Source;
@@ -613,6 +652,64 @@
 #endif // #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
     }
 
+ namespace detail // lexical_cast_stream_traits<Source, Target>
+ {
+ template <class Source, class Target>
+ struct lexical_cast_stream_traits {
+ typedef BOOST_DEDUCED_TYPENAME boost::detail::array_to_pointer_decay<Source>::type src;
+ typedef BOOST_DEDUCED_TYPENAME boost::remove_cv<src>::type no_cv_src;
+
+ typedef boost::detail::deduce_source_char<no_cv_src> deduce_src_char_metafunc;
+ typedef BOOST_DEDUCED_TYPENAME deduce_src_char_metafunc::type src_char_t;
+ typedef BOOST_DEDUCED_TYPENAME boost::detail::deduce_target_char<Target>::type target_char_t;
+
+ typedef BOOST_DEDUCED_TYPENAME boost::detail::widest_char<
+ target_char_t, src_char_t
+ >::type char_type;
+
+#if !defined(BOOST_NO_CHAR16_T) && defined(BOOST_NO_UNICODE_LITERALS)
+ BOOST_STATIC_ASSERT_MSG(( !boost::is_same<char16_t, src_char_t>::value
+ && !boost::is_same<char16_t, target_char_t>::value),
+ "Your compiler does not have full support for char16_t" );
+#endif
+#if !defined(BOOST_NO_CHAR32_T) && defined(BOOST_NO_UNICODE_LITERALS)
+ BOOST_STATIC_ASSERT_MSG(( !boost::is_same<char32_t, src_char_t>::value
+ && !boost::is_same<char32_t, target_char_t>::value),
+ "Your compiler does not have full support for char32_t" );
+#endif
+
+ typedef BOOST_DEDUCED_TYPENAME boost::detail::deduce_char_traits<
+ char_type, Target, no_cv_src
+ >::type traits;
+
+ typedef boost::type_traits::ice_and<
+ boost::is_same<char, src_char_t>::value, // source is not a wide character based type
+ boost::type_traits::ice_ne<sizeof(char), sizeof(target_char_t) >::value, // target type is based on wide character
+ boost::type_traits::ice_not<
+ boost::detail::is_char_or_wchar<no_cv_src>::value // single character widening is optimized
+ >::value // and does not requires stringbuffer
+ > is_string_widening_required_t;
+
+ typedef boost::type_traits::ice_not< boost::type_traits::ice_or<
+ boost::is_integral<no_cv_src>::value,
+ boost::detail::is_this_float_conversion_optimized<no_cv_src, char_type >::value,
+ boost::detail::is_char_or_wchar<
+ BOOST_DEDUCED_TYPENAME deduce_src_char_metafunc::stage1_type // if we did not get character type at stage1
+ >::value // then we have no optimization for that type
+ >::value > is_source_input_not_optimized_t;
+
+ // If we have an optimized conversion for
+ // Source, we do not need to construct stringbuf.
+ BOOST_STATIC_CONSTANT(bool, requires_stringbuf =
+ (boost::type_traits::ice_or<
+ is_string_widening_required_t::value, is_source_input_not_optimized_t::value
+ >::value)
+ );
+
+ typedef boost::detail::lcast_src_length<no_cv_src> len_t;
+ };
+ }
+
     namespace detail // '0', '+' and '-' constants
     {
         template < typename Char > struct lcast_char_constants;
@@ -2040,18 +2137,6 @@
 
     namespace detail
     {
- template<class T>
- struct array_to_pointer_decay
- {
- typedef T type;
- };
-
- template<class T, std::size_t N>
- struct array_to_pointer_decay<T[N]>
- {
- typedef const T * type;
- };
-
         template<typename T>
         struct is_stdstring
         {
@@ -2115,28 +2200,6 @@
             );
         };
 
-
- // 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<Char, ...>::shl_real_type(...)
- template <typename Float, typename Char>
- struct is_this_float_conversion_optimized
- {
- typedef boost::type_traits::ice_and<
- boost::is_float<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<sizeof(Char), sizeof(char) >::value,
- boost::is_same<Char, wchar_t>::value
- >::value
-#else
- boost::type_traits::ice_eq<sizeof(Char), sizeof(char) >::value
-#endif
- > result_type;
-
- BOOST_STATIC_CONSTANT(bool, value = (result_type::value) );
- };
-
         template<typename Target, typename Source>
         struct is_char_array_to_stdstring
         {
@@ -2178,67 +2241,21 @@
         {
             static inline Target lexical_cast_impl(const Source& arg)
             {
- typedef BOOST_DEDUCED_TYPENAME boost::detail::array_to_pointer_decay<Source>::type src;
- typedef BOOST_DEDUCED_TYPENAME boost::remove_cv<src>::type no_cv_src;
-
- typedef boost::detail::deduce_source_char<no_cv_src> deduce_src_char_metafunc;
- typedef BOOST_DEDUCED_TYPENAME deduce_src_char_metafunc::type src_char_t;
- typedef BOOST_DEDUCED_TYPENAME boost::detail::deduce_target_char<Target>::type target_char_t;
+ typedef lexical_cast_stream_traits<Source, Target> stream_trait;
                 
- typedef BOOST_DEDUCED_TYPENAME boost::detail::widest_char<
- target_char_t, src_char_t
- >::type char_type;
-
-#if !defined(BOOST_NO_CHAR16_T) && defined(BOOST_NO_UNICODE_LITERALS)
- BOOST_STATIC_ASSERT_MSG(( !boost::is_same<char16_t, src_char_t>::value
- && !boost::is_same<char16_t, target_char_t>::value),
- "Your compiler does not have full support for char16_t" );
-#endif
-#if !defined(BOOST_NO_CHAR32_T) && defined(BOOST_NO_UNICODE_LITERALS)
- BOOST_STATIC_ASSERT_MSG(( !boost::is_same<char32_t, src_char_t>::value
- && !boost::is_same<char32_t, target_char_t>::value),
- "Your compiler does not have full support for char32_t" );
-#endif
-
- typedef BOOST_DEDUCED_TYPENAME boost::detail::deduce_char_traits<
- char_type, Target, no_cv_src
- >::type traits;
-
- typedef boost::type_traits::ice_and<
- boost::is_same<char, src_char_t>::value, // source is not a wide character based type
- boost::type_traits::ice_ne<sizeof(char), sizeof(target_char_t) >::value, // target type is based on wide character
- boost::type_traits::ice_not<
- boost::detail::is_char_or_wchar<no_cv_src>::value // single character widening is optimized
- >::value // and does not requires stringbuffer
- > is_string_widening_required_t;
-
- typedef boost::type_traits::ice_not< boost::type_traits::ice_or<
- boost::is_integral<no_cv_src>::value,
- boost::detail::is_this_float_conversion_optimized<no_cv_src, char_type >::value,
- boost::detail::is_char_or_wchar<
- BOOST_DEDUCED_TYPENAME deduce_src_char_metafunc::stage1_type // if we did not get character type at stage1
- >::value // then we have no optimization for that type
- >::value > is_source_input_not_optimized_t;
+ typedef detail::lexical_stream_limited_src<
+ BOOST_DEDUCED_TYPENAME stream_trait::char_type,
+ BOOST_DEDUCED_TYPENAME stream_trait::traits,
+ stream_trait::requires_stringbuf
+ > interpreter_type;
 
                 // Target type must be default constructible
- Target result;
-
- // If we have an optimized conversion for
- // Source, we do not need to construct stringbuf.
- BOOST_STATIC_CONSTANT(bool, requires_stringbuf =
- (boost::type_traits::ice_or<
- is_string_widening_required_t::value, is_source_input_not_optimized_t::value
- >::value)
- );
-
- typedef detail::lexical_stream_limited_src<char_type, traits, requires_stringbuf > interpreter_type;
+ Target result;
 
- typedef detail::lcast_src_length<no_cv_src> lcast_src_length;
- std::size_t const src_len = lcast_src_length::value;
- char_type buf[src_len + 1];
- lcast_src_length::check_coverage();
+ BOOST_DEDUCED_TYPENAME stream_trait::char_type buf[stream_trait::len_t::value + 1];
+ stream_trait::len_t::check_coverage();
 
- interpreter_type interpreter(buf, buf + src_len);
+ interpreter_type interpreter(buf, buf + stream_trait::len_t::value + 1);
 
                 // Disabling ADL, by directly specifying operators.
                 if(!(interpreter.operator <<(arg) && interpreter.operator >>(result)))

Modified: trunk/libs/conversion/test/Jamfile.v2
==============================================================================
--- trunk/libs/conversion/test/Jamfile.v2 (original)
+++ trunk/libs/conversion/test/Jamfile.v2 2012-11-15 02:26:23 EST (Thu, 15 Nov 2012)
@@ -50,5 +50,6 @@
     [ run lexical_cast_arrays_test.cpp ]
     [ run lexical_cast_integral_types_test.cpp ]
     [ run lexical_cast_stream_detection_test.cpp ]
+ [ run lexical_cast_stream_traits_test.cpp ]
   ;
 

Added: trunk/libs/conversion/test/lexical_cast_stream_traits_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/conversion/test/lexical_cast_stream_traits_test.cpp 2012-11-15 02:26:23 EST (Thu, 15 Nov 2012)
@@ -0,0 +1,155 @@
+// 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>
+
+#include <boost/lexical_cast.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+template <class T>
+static void test_optimized_types_to_string_const()
+{
+ namespace de = boost::detail;
+ typedef de::lexical_cast_stream_traits<T, std::string> trait_1;
+ BOOST_CHECK(!trait_1::is_source_input_not_optimized_t::value);
+ BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_1::src_char_t, char>::value));
+ BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_1::target_char_t, char>::value));
+ BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_1::char_type, char>::value));
+ BOOST_CHECK(!trait_1::is_string_widening_required_t::value);
+ BOOST_CHECK(!trait_1::is_source_input_not_optimized_t::value);
+
+ typedef de::lexical_cast_stream_traits<const T, std::string> trait_2;
+ BOOST_CHECK(!trait_2::is_source_input_not_optimized_t::value);
+ BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_2::src_char_t, char>::value));
+ BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_2::target_char_t, char>::value));
+ BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_2::char_type, char>::value));
+ BOOST_CHECK(!trait_2::is_string_widening_required_t::value);
+ BOOST_CHECK(!trait_2::is_source_input_not_optimized_t::value);
+
+ typedef de::lexical_cast_stream_traits<T, std::wstring> trait_3;
+ BOOST_CHECK(!trait_3::is_source_input_not_optimized_t::value);
+ BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_3::src_char_t, char>::value));
+ BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_3::target_char_t, wchar_t>::value));
+ BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_3::char_type, wchar_t>::value));
+
+ BOOST_CHECK((boost::detail::is_char_or_wchar<BOOST_DEDUCED_TYPENAME trait_3::no_cv_src>::value != trait_3::is_string_widening_required_t::value));
+
+ BOOST_CHECK(!trait_3::is_source_input_not_optimized_t::value);
+}
+
+
+template <class T>
+static void test_optimized_types_to_string()
+{
+ test_optimized_types_to_string_const<T>();
+
+ namespace de = boost::detail;
+ typedef de::lexical_cast_stream_traits<std::string, T> trait_4;
+ BOOST_CHECK(!trait_4::is_source_input_not_optimized_t::value);
+ BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_4::src_char_t, char>::value));
+ BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_4::target_char_t, char>::value));
+ BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_4::char_type, char>::value));
+ BOOST_CHECK(!trait_4::is_string_widening_required_t::value);
+ BOOST_CHECK(!trait_4::is_source_input_not_optimized_t::value);
+
+ typedef de::lexical_cast_stream_traits<const std::string, T> trait_5;
+ BOOST_CHECK(!trait_5::is_source_input_not_optimized_t::value);
+ BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_5::src_char_t, char>::value));
+ BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_5::target_char_t, char>::value));
+ BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_5::char_type, char>::value));
+ BOOST_CHECK(!trait_5::is_string_widening_required_t::value);
+ BOOST_CHECK(!trait_5::is_source_input_not_optimized_t::value);
+
+ typedef de::lexical_cast_stream_traits<const std::wstring, T> trait_6;
+ BOOST_CHECK(!trait_6::is_source_input_not_optimized_t::value);
+ BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_6::src_char_t, wchar_t>::value));
+ BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_6::target_char_t, char>::value));
+ BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_6::char_type, wchar_t>::value));
+ BOOST_CHECK(!trait_6::is_string_widening_required_t::value);
+}
+
+void test_metafunctions()
+{
+ test_optimized_types_to_string<bool>();
+ test_optimized_types_to_string<char>();
+ test_optimized_types_to_string<unsigned char>();
+ test_optimized_types_to_string<signed char>();
+ test_optimized_types_to_string<short>();
+ test_optimized_types_to_string<unsigned short>();
+ test_optimized_types_to_string<int>();
+ test_optimized_types_to_string<unsigned int>();
+ test_optimized_types_to_string<long>();
+ test_optimized_types_to_string<unsigned long>();
+
+#if defined(BOOST_HAS_LONG_LONG)
+ test_optimized_types_to_string<boost::ulong_long_type>();
+ test_optimized_types_to_string<boost::long_long_type>();
+#elif defined(BOOST_HAS_MS_INT64)
+ test_optimized_types_to_string<unsigned __int64>();
+ test_optimized_types_to_string<__int64>();
+#endif
+
+ test_optimized_types_to_string<float>();
+ test_optimized_types_to_string<std::string>();
+ test_optimized_types_to_string<char*>();
+ test_optimized_types_to_string<char[5]>();
+ test_optimized_types_to_string<char[1]>();
+ test_optimized_types_to_string<unsigned char*>();
+ test_optimized_types_to_string<unsigned char[5]>();
+ test_optimized_types_to_string<unsigned char[1]>();
+ test_optimized_types_to_string<signed char*>();
+ test_optimized_types_to_string<signed char[5]>();
+ test_optimized_types_to_string<signed char[1]>();
+ test_optimized_types_to_string<boost::array<char, 1> >();
+ test_optimized_types_to_string<boost::array<char, 5> >();
+ test_optimized_types_to_string<boost::array<unsigned char, 1> >();
+ test_optimized_types_to_string<boost::array<unsigned char, 5> >();
+ test_optimized_types_to_string<boost::array<signed char, 1> >();
+ test_optimized_types_to_string<boost::array<signed char, 5> >();
+ test_optimized_types_to_string<boost::iterator_range<char*> >();
+ test_optimized_types_to_string<boost::iterator_range<unsigned char*> >();
+ test_optimized_types_to_string<boost::iterator_range<signed char*> >();
+
+ test_optimized_types_to_string_const<boost::array<const char, 1> >();
+ test_optimized_types_to_string_const<boost::array<const char, 5> >();
+ test_optimized_types_to_string_const<boost::array<const unsigned char, 1> >();
+ test_optimized_types_to_string_const<boost::array<const unsigned char, 5> >();
+ test_optimized_types_to_string_const<boost::array<const signed char, 1> >();
+ test_optimized_types_to_string_const<boost::array<const signed char, 5> >();
+ test_optimized_types_to_string_const<boost::iterator_range<const char*> >();
+ test_optimized_types_to_string_const<boost::iterator_range<const unsigned char*> >();
+ test_optimized_types_to_string_const<boost::iterator_range<const signed char*> >();
+
+#if !defined(BOOST_NO_CXX11_HDR_ARRAY) && defined(BOOST_HAS_TR1_ARRAY)
+ test_optimized_types_to_string<std::array<char, 1> >();
+ test_optimized_types_to_string<std::array<char, 5> >();
+ test_optimized_types_to_string<std::array<unsigned char, 1> >();
+ test_optimized_types_to_string<std::array<unsigned char, 5> >();
+ test_optimized_types_to_string<std::array<signed char, 1> >();
+ test_optimized_types_to_string<std::array<signed char, 5> >();
+
+ test_optimized_types_to_string_const<std::array<const char, 1> >();
+ test_optimized_types_to_string_const<std::array<const char, 5> >();
+ test_optimized_types_to_string_const<std::array<const unsigned char, 1> >();
+ test_optimized_types_to_string_const<std::array<const unsigned char, 5> >();
+ test_optimized_types_to_string_const<std::array<const signed char, 1> >();
+ test_optimized_types_to_string_const<std::array<const signed char, 5> >();
+#endif
+}
+
+boost::unit_test::test_suite *init_unit_test_suite(int, char *[])
+{
+ boost::unit_test::test_suite *suite =
+ BOOST_TEST_SUITE("lexical_cast traits tests");
+ suite->add(BOOST_TEST_CASE(&test_metafunctions));
+ return suite;
+}
+


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