Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r81668 - in branches/release: boost libs/conversion libs/conversion/doc libs/conversion/test
From: antoshkka_at_[hidden]
Date: 2012-12-02 04:33:45


Author: apolukhin
Date: 2012-12-02 04:33:42 EST (Sun, 02 Dec 2012)
New Revision: 81668
URL: http://svn.boost.org/trac/boost/changeset/81668

Log:
Merge lexical_cast from trunk:
* Deduce stream character type for user defined classes (fixes #6786)
* Deprecated macros replaced with new ones (thanks to Marshall Clow)
* Updated documentation (refs #6786, fixes #7582)
* More tests and minor bugfixes
Added:
   branches/release/libs/conversion/test/lexical_cast_stream_detection_test.cpp (contents, props changed)
   branches/release/libs/conversion/test/lexical_cast_stream_traits_test.cpp (contents, props changed)
Text files modified:
   branches/release/boost/lexical_cast.hpp | 721 ++++++++++++++++++++++-----------------
   branches/release/libs/conversion/doc/lexical_cast.qbk | 13
   branches/release/libs/conversion/lexical_cast_test.cpp | 38 +
   branches/release/libs/conversion/test/Jamfile.v2 | 2
   branches/release/libs/conversion/test/lexical_cast_arrays_test.cpp | 12
   branches/release/libs/conversion/test/lexical_cast_containers_test.cpp | 4
   branches/release/libs/conversion/test/lexical_cast_empty_input_test.cpp | 4
   branches/release/libs/conversion/test/lexical_cast_float_types_test.cpp | 4
   branches/release/libs/conversion/test/lexical_cast_inf_nan_test.cpp | 4
   branches/release/libs/conversion/test/lexical_cast_integral_types_test.cpp | 4
   branches/release/libs/conversion/test/lexical_cast_iterator_range_test.cpp | 8
   branches/release/libs/conversion/test/lexical_cast_loopback_test.cpp | 4
   branches/release/libs/conversion/test/lexical_cast_wchars_test.cpp | 4
   13 files changed, 464 insertions(+), 358 deletions(-)

Modified: branches/release/boost/lexical_cast.hpp
==============================================================================
--- branches/release/boost/lexical_cast.hpp (original)
+++ branches/release/boost/lexical_cast.hpp 2012-12-02 04:33:42 EST (Sun, 02 Dec 2012)
@@ -112,7 +112,7 @@
             return *target;
         }
 
-#ifndef BOOST_NO_NOEXCEPT
+#ifndef BOOST_NO_CXX11_NOEXCEPT
         virtual const char *what() const noexcept
 #else
         virtual const char *what() const throw()
@@ -122,7 +122,7 @@
                    "source type value could not be interpreted as target";
         }
 
-#ifndef BOOST_NO_NOEXCEPT
+#ifndef BOOST_NO_CXX11_NOEXCEPT
         virtual ~bad_lexical_cast() BOOST_NOEXCEPT
 #else
         virtual ~bad_lexical_cast() throw()
@@ -162,6 +162,8 @@
 #include <boost/type_traits/is_integral.hpp>
 #include <boost/type_traits/is_arithmetic.hpp>
 #include <boost/type_traits/remove_pointer.hpp>
+#include <boost/type_traits/has_left_shift.hpp>
+#include <boost/type_traits/has_right_shift.hpp>
 #include <boost/math/special_functions/sign.hpp>
 #include <boost/math/special_functions/fpclassify.hpp>
 #include <boost/range/iterator_range_core.hpp>
@@ -171,242 +173,376 @@
 #endif
 
 namespace boost {
- namespace detail // widest_char<...> (continuation)
- {
- struct not_a_character_type{};
-
- template <typename CharT>
- struct widest_char<not_a_character_type, CharT >
- {
- typedef CharT type;
- };
-
- template <typename CharT>
- struct widest_char< CharT, not_a_character_type >
- {
- typedef CharT type;
- };
-
- template <>
- struct widest_char< not_a_character_type, not_a_character_type >
- {
- typedef char type;
- };
- }
 
- namespace detail // is_char_or_wchar<...> and stream_char<...> templates
+ namespace detail // is_char_or_wchar<...>
     {
         // returns true, if T is one of the character types
- template <typename T>
+ template < typename T >
         struct is_char_or_wchar
         {
- typedef ::boost::type_traits::ice_or<
- ::boost::is_same< T, char >::value,
+ typedef boost::type_traits::ice_or<
+ boost::is_same< T, char >::value,
                     #ifndef BOOST_LCAST_NO_WCHAR_T
- ::boost::is_same< T, wchar_t >::value,
+ boost::is_same< T, wchar_t >::value,
                     #endif
- #ifndef BOOST_NO_CHAR16_T
- ::boost::is_same< T, char16_t >::value,
+ #ifndef BOOST_NO_CXX11_CHAR16_T
+ boost::is_same< T, char16_t >::value,
                     #endif
- #ifndef BOOST_NO_CHAR32_T
- ::boost::is_same< T, char32_t >::value,
+ #ifndef BOOST_NO_CXX11_CHAR32_T
+ boost::is_same< T, char32_t >::value,
                     #endif
- ::boost::is_same< T, unsigned char >::value,
- ::boost::is_same< T, signed char >::value
+ boost::is_same< T, unsigned char >::value,
+ boost::is_same< T, signed char >::value
> result_type;
 
             BOOST_STATIC_CONSTANT(bool, value = (result_type::value) );
         };
+ }
 
- // selectors for choosing stream character type
- // returns one of char, wchar_t, char16_t, char32_t or not_a_character_type types
- template <typename Type>
- struct stream_char
+ namespace detail // normalize_single_byte_char<Char>
+ {
+ // Converts signed/unsigned char to char
+ template < class Char >
+ struct normalize_single_byte_char
         {
- typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
- is_char_or_wchar<Type >::value,
- Type,
- boost::detail::not_a_character_type
- >::type type;
+ typedef Char type;
         };
 
         template <>
- struct stream_char<unsigned char>
+ struct normalize_single_byte_char< signed char >
         {
             typedef char type;
         };
 
         template <>
- struct stream_char<signed char>
+ struct normalize_single_byte_char< unsigned char >
         {
             typedef char type;
         };
+ }
 
- template <typename CharT>
- struct stream_char<CharT*>
- {
- typedef BOOST_DEDUCED_TYPENAME stream_char<CharT>::type type;
- };
+ namespace detail // deduce_character_type_later<T>
+ {
+ // Helper type, meaning that stram character for T must be deduced
+ // at Stage 2 (See deduce_source_char<T> and deduce_target_char<T>)
+ template < class T > struct deduce_character_type_later {};
+ }
+
+ namespace detail // stream_char_common<T>
+ {
+ // Selectors to choose stream character type (common for Source and Target)
+ // Returns one of char, wchar_t, char16_t, char32_t or deduce_character_type_later<T> types
+ // Executed on Stage 1 (See deduce_source_char<T> and deduce_target_char<T>)
+ template < typename Type >
+ struct stream_char_common: public boost::mpl::if_c<
+ boost::detail::is_char_or_wchar< Type >::value,
+ Type,
+ boost::detail::deduce_character_type_later< Type >
+ > {};
+
+ template < typename Char >
+ struct stream_char_common< Char* >: public boost::mpl::if_c<
+ boost::detail::is_char_or_wchar< Char >::value,
+ Char,
+ boost::detail::deduce_character_type_later< Char* >
+ > {};
+
+ template < typename Char >
+ struct stream_char_common< const Char* >: public boost::mpl::if_c<
+ boost::detail::is_char_or_wchar< Char >::value,
+ Char,
+ boost::detail::deduce_character_type_later< const Char* >
+ > {};
+
+ template < typename Char >
+ struct stream_char_common< boost::iterator_range< Char* > >: public boost::mpl::if_c<
+ boost::detail::is_char_or_wchar< Char >::value,
+ Char,
+ boost::detail::deduce_character_type_later< boost::iterator_range< Char* > >
+ > {};
+
+ template < typename Char >
+ struct stream_char_common< boost::iterator_range< const Char* > >: public boost::mpl::if_c<
+ boost::detail::is_char_or_wchar< Char >::value,
+ Char,
+ boost::detail::deduce_character_type_later< boost::iterator_range< const Char* > >
+ > {};
+
+ template < class Char, class Traits, class Alloc >
+ struct stream_char_common< std::basic_string< Char, Traits, Alloc > >
+ {
+ typedef Char type;
+ };
+
+ template < class Char, class Traits, class Alloc >
+ struct stream_char_common< boost::container::basic_string< Char, Traits, Alloc > >
+ {
+ typedef Char type;
+ };
+
+ template < typename Char, std::size_t N >
+ struct stream_char_common< boost::array< Char, N > >: public boost::mpl::if_c<
+ boost::detail::is_char_or_wchar< Char >::value,
+ Char,
+ boost::detail::deduce_character_type_later< boost::array< Char, N > >
+ > {};
+
+ template < typename Char, std::size_t N >
+ struct stream_char_common< boost::array< const Char, N > >: public boost::mpl::if_c<
+ boost::detail::is_char_or_wchar< Char >::value,
+ Char,
+ boost::detail::deduce_character_type_later< boost::array< const Char, N > >
+ > {};
 
- template <typename CharT>
- struct stream_char<const CharT*>
- {
- typedef BOOST_DEDUCED_TYPENAME stream_char<CharT>::type type;
- };
+#if !defined(BOOST_NO_CXX11_HDR_ARRAY) && defined(BOOST_HAS_TR1_ARRAY)
+ template < typename Char, std::size_t N >
+ struct stream_char_common< std::array<Char, N > >: public boost::mpl::if_c<
+ boost::detail::is_char_or_wchar< Char >::value,
+ Char,
+ boost::detail::deduce_character_type_later< std::array< Char, N > >
+ > {};
+
+ template < typename Char, std::size_t N >
+ struct stream_char_common< std::array< const Char, N > >: public boost::mpl::if_c<
+ boost::detail::is_char_or_wchar< Char >::value,
+ Char,
+ boost::detail::deduce_character_type_later< std::array< const Char, N > >
+ > {};
+#endif // !defined(BOOST_NO_CXX11_HDR_ARRAY) && defined(BOOST_HAS_TR1_ARRAY)
 
- template <typename CharT>
- struct stream_char<iterator_range<CharT*> >
- {
- typedef BOOST_DEDUCED_TYPENAME stream_char<CharT*>::type type;
- };
-
- template <typename CharT>
- struct stream_char<iterator_range<const CharT*> >
+#if !defined(BOOST_LCAST_NO_WCHAR_T) && defined(BOOST_NO_INTRINSIC_WCHAR_T)
+ template <>
+ struct stream_char_common< wchar_t >
         {
- typedef BOOST_DEDUCED_TYPENAME stream_char<const CharT*>::type type;
+ typedef char type;
         };
+#endif
+ }
 
- template <class CharT, class Traits, class Alloc>
- struct stream_char< std::basic_string<CharT, Traits, Alloc> >
- {
- typedef CharT type;
- };
+ namespace detail // deduce_source_char_impl<T>
+ {
+ // If type T is `deduce_character_type_later` type, then tries to deduce
+ // character type using boost::has_left_shift<T> metafunction.
+ // Otherwise supplied type T is a character type, that must be normalized
+ // using normalize_single_byte_char<Char>.
+ // Executed at Stage 2 (See deduce_source_char<T> and deduce_target_char<T>)
+ template < class Char >
+ struct deduce_source_char_impl
+ {
+ typedef BOOST_DEDUCED_TYPENAME boost::detail::normalize_single_byte_char< Char >::type type;
+ };
+
+ template < class T >
+ struct deduce_source_char_impl< deduce_character_type_later< T > >
+ {
+ typedef boost::has_left_shift< std::basic_ostream< char >, T > result_t;
+
+#if defined(BOOST_LCAST_NO_WCHAR_T)
+ BOOST_STATIC_ASSERT_MSG((result_t::value),
+ "Source type is not std::ostream`able and std::wostream`s are not supported by your STL implementation");
+ typedef char type;
+#else
+ typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
+ result_t::value, char, wchar_t
+ >::type type;
 
- template <class CharT, class Traits, class Alloc>
- struct stream_char< ::boost::container::basic_string<CharT, Traits, Alloc> >
- {
- typedef CharT type;
+ BOOST_STATIC_ASSERT_MSG((result_t::value || boost::has_left_shift< std::basic_ostream< type >, T >::value),
+ "Source type is neither std::ostream`able nor std::wostream`able");
+#endif
         };
+ }
 
- template<typename CharT, std::size_t N>
- struct stream_char<boost::array<CharT, N> >
- {
- typedef BOOST_DEDUCED_TYPENAME stream_char<CharT>::type type;
+ namespace detail // deduce_target_char_impl<T>
+ {
+ // If type T is `deduce_character_type_later` type, then tries to deduce
+ // character type using boost::has_right_shift<T> metafunction.
+ // Otherwise supplied type T is a character type, that must be normalized
+ // using normalize_single_byte_char<Char>.
+ // Executed at Stage 2 (See deduce_source_char<T> and deduce_target_char<T>)
+ template < class Char >
+ struct deduce_target_char_impl
+ {
+ typedef BOOST_DEDUCED_TYPENAME normalize_single_byte_char< Char >::type type;
         };
+
+ template < class T >
+ struct deduce_target_char_impl< deduce_character_type_later<T> >
+ {
+ typedef boost::has_right_shift<std::basic_istream<char>, T > result_t;
 
- template<typename CharT, std::size_t N>
- struct stream_char<boost::array<const CharT, N> >
- {
- typedef BOOST_DEDUCED_TYPENAME stream_char<CharT>::type type;
+#if defined(BOOST_LCAST_NO_WCHAR_T)
+ BOOST_STATIC_ASSERT_MSG((result_t::value),
+ "Target type is not std::istream`able and std::wistream`s are not supported by your STL implementation");
+ typedef char type;
+#else
+ typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
+ result_t::value, char, wchar_t
+ >::type type;
+
+ BOOST_STATIC_ASSERT_MSG((result_t::value || boost::has_right_shift<std::basic_istream<wchar_t>, T >::value),
+ "Target type is neither std::istream`able nor std::wistream`able");
+#endif
         };
+ }
 
-#if !defined(BOOST_NO_CXX11_HDR_ARRAY) && defined(BOOST_HAS_TR1_ARRAY)
- template <typename CharT, std::size_t N>
- struct stream_char<std::array<CharT, N> >
- {
- typedef BOOST_DEDUCED_TYPENAME stream_char<CharT>::type type;
- };
+ namespace detail // deduce_target_char<T> and deduce_source_char<T>
+ {
+ // We deduce stream character types in two stages.
+ //
+ // Stage 1 is common for Target and Source. At Stage 1 we get
+ // non normalized character type (may contain unsigned/signed char)
+ // or deduce_character_type_later<T> where T is the original type.
+ // Stage 1 is executed by stream_char_common<T>
+ //
+ // At Stage 2 we normalize character types or try to deduce character
+ // type using metafunctions.
+ // Stage 2 is executed by deduce_target_char_impl<T> and
+ // deduce_source_char_impl<T>
+ //
+ // deduce_target_char<T> and deduce_source_char<T> functions combine
+ // both stages
 
- template <typename CharT, std::size_t N>
- struct stream_char<std::array<const CharT, N> >
+ template < class T >
+ struct deduce_target_char
         {
- typedef BOOST_DEDUCED_TYPENAME stream_char<CharT>::type type;
- };
-#endif // !defined(BOOST_NO_CXX11_HDR_ARRAY) && defined(BOOST_HAS_TR1_ARRAY)
+ typedef BOOST_DEDUCED_TYPENAME stream_char_common< T >::type stage1_type;
+ typedef BOOST_DEDUCED_TYPENAME deduce_target_char_impl< stage1_type >::type stage2_type;
 
-#if !defined(BOOST_LCAST_NO_WCHAR_T) && defined(BOOST_NO_INTRINSIC_WCHAR_T)
- template<>
- struct stream_char<wchar_t>
- {
- typedef boost::detail::not_a_character_type type;
+ typedef stage2_type type;
         };
 
- template<>
- struct stream_char<wchar_t*>
+ template < class T >
+ struct deduce_source_char
         {
- typedef wchar_t type;
- };
+ typedef BOOST_DEDUCED_TYPENAME stream_char_common< T >::type stage1_type;
+ typedef BOOST_DEDUCED_TYPENAME deduce_source_char_impl< stage1_type >::type stage2_type;
 
- template<>
- struct stream_char<const wchar_t*>
- {
- typedef wchar_t type;
+ typedef stage2_type type;
         };
-#endif
     }
 
     namespace detail // deduce_char_traits template
     {
-
- template<class CharT, class Target, class Source>
+ // We are attempting to get char_traits<> from Source or Tagret
+ // template parameter. Otherwise we'll be using std::char_traits<Char>
+ template < class Char, class Target, class Source >
         struct deduce_char_traits
         {
- typedef std::char_traits<CharT> type;
+ typedef std::char_traits< Char > type;
         };
 
- template<class CharT, class Traits, class Alloc, class Source>
- struct deduce_char_traits< CharT
- , std::basic_string<CharT,Traits,Alloc>
+ template < class Char, class Traits, class Alloc, class Source >
+ struct deduce_char_traits< Char
+ , std::basic_string< Char, Traits, Alloc >
                                  , Source
>
         {
             typedef Traits type;
         };
 
- template<class CharT, class Target, class Traits, class Alloc>
- struct deduce_char_traits< CharT
+ template < class Char, class Target, class Traits, class Alloc >
+ struct deduce_char_traits< Char
                                  , Target
- , std::basic_string<CharT,Traits,Alloc>
+ , std::basic_string< Char, Traits, Alloc >
>
         {
             typedef Traits type;
         };
 
- template<class CharT, class Traits, class Alloc, class Source>
- struct deduce_char_traits< CharT
- , ::boost::container::basic_string<CharT,Traits,Alloc>
+ template < class Char, class Traits, class Alloc, class Source >
+ struct deduce_char_traits< Char
+ , boost::container::basic_string< Char, Traits, Alloc >
                                  , Source
>
         {
             typedef Traits type;
         };
 
- template<class CharT, class Target, class Traits, class Alloc>
- struct deduce_char_traits< CharT
+ template < class Char, class Target, class Traits, class Alloc >
+ struct deduce_char_traits< Char
                                  , Target
- , ::boost::container::basic_string<CharT,Traits,Alloc>
+ , boost::container::basic_string< Char, Traits, Alloc >
>
         {
             typedef Traits type;
         };
 
- template<class CharT, class Traits, class Alloc1, class Alloc2>
- struct deduce_char_traits< CharT
- , std::basic_string<CharT,Traits,Alloc1>
- , std::basic_string<CharT,Traits,Alloc2>
+ template < class Char, class Traits, class Alloc1, class Alloc2 >
+ struct deduce_char_traits< Char
+ , std::basic_string< Char, Traits, Alloc1 >
+ , std::basic_string< Char, Traits, Alloc2 >
>
         {
             typedef Traits type;
         };
 
- template<class CharT, class Traits, class Alloc1, class Alloc2>
- struct deduce_char_traits< CharT
- , ::boost::container::basic_string<CharT,Traits,Alloc1>
- , ::boost::container::basic_string<CharT,Traits,Alloc2>
+ template<class Char, class Traits, class Alloc1, class Alloc2>
+ struct deduce_char_traits< Char
+ , boost::container::basic_string< Char, Traits, Alloc1 >
+ , boost::container::basic_string< Char, Traits, Alloc2 >
>
         {
             typedef Traits type;
         };
 
- template<class CharT, class Traits, class Alloc1, class Alloc2>
- struct deduce_char_traits< CharT
- , ::boost::container::basic_string<CharT,Traits,Alloc1>
- , ::std::basic_string<CharT,Traits,Alloc2>
+ template < class Char, class Traits, class Alloc1, class Alloc2 >
+ struct deduce_char_traits< Char
+ , boost::container::basic_string< Char, Traits, Alloc1 >
+ , std::basic_string< Char, Traits, Alloc2 >
>
         {
             typedef Traits type;
         };
 
- template<class CharT, class Traits, class Alloc1, class Alloc2>
- struct deduce_char_traits< CharT
- , ::std::basic_string<CharT,Traits,Alloc1>
- , ::boost::container::basic_string<CharT,Traits,Alloc2>
+ template < class Char, class Traits, class Alloc1, class Alloc2 >
+ struct deduce_char_traits< Char
+ , std::basic_string< Char, Traits, Alloc1 >
+ , boost::container::basic_string< Char, Traits, Alloc2 >
>
         {
             typedef Traits type;
         };
     }
 
+ 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;
@@ -516,9 +652,67 @@
 #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_CXX11_CHAR16_T) && defined(BOOST_NO_CXX11_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_CXX11_CHAR32_T) && defined(BOOST_NO_CXX11_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 CharT> struct lcast_char_constants;
+ template < typename Char > struct lcast_char_constants;
 
         template<>
         struct lcast_char_constants<char>
@@ -544,7 +738,7 @@
         };
 #endif
 
-#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
         template<>
         struct lcast_char_constants<char16_t>
         {
@@ -557,7 +751,7 @@
         };
 #endif
 
-#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
         template<>
         struct lcast_char_constants<char32_t>
         {
@@ -907,7 +1101,7 @@
         }
 
 #endif
-#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
         template <class T>
         bool parse_inf_nan(const char16_t* begin, const char16_t* end, T& value) BOOST_NOEXCEPT
         {
@@ -923,7 +1117,7 @@
             return put_inf_nan_impl(begin, end, value, u"nan", u"infinity");
         }
 #endif
-#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
         template <class T>
         bool parse_inf_nan(const char32_t* begin, const char32_t* end, T& value) BOOST_NOEXCEPT
         {
@@ -1247,7 +1441,7 @@
             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<
+ typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
                 RequiresStringbuffer,
                 out_stream_t,
                 do_not_construct_out_stream_t
@@ -1288,7 +1482,7 @@
                 std::locale loc;
                 CharT const w = BOOST_USE_FACET(std::ctype<CharT>, loc).widen(ch);
 #else
- CharT const w = ch;
+ CharT const w = static_cast<CharT>(ch);
 #endif
                 Traits::assign(*start, w);
                 finish = start + 1;
@@ -1439,7 +1633,7 @@
             }
 
             template<class Alloc>
- bool operator<<(::boost::container::basic_string<CharT,Traits,Alloc> const& str) BOOST_NOEXCEPT
+ bool operator<<(boost::container::basic_string<CharT,Traits,Alloc> const& str) BOOST_NOEXCEPT
             {
                 start = const_cast<CharT*>(str.data());
                 finish = start + str.length();
@@ -1510,12 +1704,12 @@
             bool operator<<(wchar_t ch) { return shl_char(ch); }
 #endif
 #endif
-#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
             bool operator<<(char16_t ch) { return shl_char(ch); }
             bool operator<<(char16_t * str) { return shl_char_array(str); }
             bool operator<<(char16_t const * str) { return shl_char_array(str); }
 #endif
-#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
             bool operator<<(char32_t ch) { return shl_char(ch); }
             bool operator<<(char32_t * str) { return shl_char_array(str); }
             bool operator<<(char32_t const * str) { return shl_char_array(str); }
@@ -1767,17 +1961,17 @@
 #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
             bool operator>>(wchar_t& output) { return shr_xchar(output); }
 #endif
-#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
             bool operator>>(char16_t& output) { return shr_xchar(output); }
 #endif
-#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
             bool operator>>(char32_t& output) { return shr_xchar(output); }
 #endif
             template<class Alloc>
             bool operator>>(std::basic_string<CharT,Traits,Alloc>& str) { str.assign(start, finish); return true; }
 
             template<class Alloc>
- bool operator>>(::boost::container::basic_string<CharT,Traits,Alloc>& str) { str.assign(start, finish); return true; }
+ bool operator>>(boost::container::basic_string<CharT,Traits,Alloc>& str) { str.assign(start, finish); return true; }
 
             
     private:
@@ -1917,7 +2111,7 @@
                  * */
                 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,
+ boost::type_traits::ice_eq< sizeof(double), sizeof(long double) >::value,
 #else
                      0
 #endif
@@ -1943,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
         {
@@ -1968,7 +2150,7 @@
         };
 
         template<typename CharT, typename Traits, typename Alloc>
- struct is_stdstring< ::boost::container::basic_string<CharT, Traits, Alloc> >
+ struct is_stdstring< boost::container::basic_string<CharT, Traits, Alloc> >
         {
             BOOST_STATIC_CONSTANT(bool, value = true );
         };
@@ -1978,13 +2160,13 @@
         {
             BOOST_STATIC_CONSTANT(bool, value =
                (
- ::boost::type_traits::ice_and<
- ::boost::is_arithmetic<Source>::value,
- ::boost::is_arithmetic<Target>::value,
- ::boost::type_traits::ice_not<
+ boost::type_traits::ice_and<
+ boost::is_arithmetic<Source>::value,
+ boost::is_arithmetic<Target>::value,
+ boost::type_traits::ice_not<
                                 detail::is_char_or_wchar<Target>::value
>::value,
- ::boost::type_traits::ice_not<
+ boost::type_traits::ice_not<
                                 detail::is_char_or_wchar<Source>::value
>::value
>::value
@@ -2002,14 +2184,14 @@
         {
             BOOST_STATIC_CONSTANT(bool, value =
                 (
- ::boost::type_traits::ice_or<
- ::boost::type_traits::ice_and<
+ boost::type_traits::ice_or<
+ boost::type_traits::ice_and<
                              is_same<Source,Target>::value,
                              is_char_or_wchar<Target>::value
>::value,
- ::boost::type_traits::ice_and<
- ::boost::type_traits::ice_eq< sizeof(char),sizeof(Target)>::value,
- ::boost::type_traits::ice_eq< sizeof(char),sizeof(Source)>::value,
+ boost::type_traits::ice_and<
+ boost::type_traits::ice_eq< sizeof(char),sizeof(Target)>::value,
+ boost::type_traits::ice_eq< sizeof(char),sizeof(Source)>::value,
                              is_char_or_wchar<Target>::value,
                              is_char_or_wchar<Source>::value
>::value
@@ -2018,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
         {
@@ -2059,13 +2219,13 @@
         };
 
         template<typename CharT, typename Traits, typename Alloc>
- struct is_char_array_to_stdstring< ::boost::container::basic_string<CharT, Traits, Alloc>, CharT* >
+ struct is_char_array_to_stdstring< boost::container::basic_string<CharT, Traits, Alloc>, CharT* >
         {
             BOOST_STATIC_CONSTANT(bool, value = true );
         };
 
         template<typename CharT, typename Traits, typename Alloc>
- struct is_char_array_to_stdstring< ::boost::container::basic_string<CharT, Traits, Alloc>, const CharT* >
+ struct is_char_array_to_stdstring< boost::container::basic_string<CharT, Traits, Alloc>, const CharT* >
         {
             BOOST_STATIC_CONSTANT(bool, value = true );
         };
@@ -2081,60 +2241,21 @@
         {
             static inline Target lexical_cast_impl(const Source& arg)
             {
- typedef BOOST_DEDUCED_TYPENAME detail::array_to_pointer_decay<Source>::type src;
- typedef BOOST_DEDUCED_TYPENAME ::boost::remove_cv<src>::type no_cv_src;
- typedef BOOST_DEDUCED_TYPENAME detail::stream_char<Target>::type target_char_t;
- typedef BOOST_DEDUCED_TYPENAME detail::stream_char<no_cv_src>::type src_char_type;
- typedef BOOST_DEDUCED_TYPENAME detail::widest_char<
- target_char_t, src_char_type
- >::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_type>::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_type>::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::detail::is_char_or_wchar<src_char_type>::value, // source is lexical type
- ::boost::detail::is_char_or_wchar<target_char_t>::value, // target is a lexical type
- ::boost::is_same<char, src_char_type>::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
- > is_string_widening_required_t;
-
- typedef ::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<src_char_type >::value
- > is_source_input_optimized_t;
+ typedef lexical_cast_stream_traits<Source, Target> stream_trait;
+
+ 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;
+ Target result;
 
- // If we have an optimized conversion for
- // Source, we do not need to construct stringbuf.
- const bool requires_stringbuf = ::boost::type_traits::ice_or<
- is_string_widening_required_t::value,
- ::boost::type_traits::ice_not< is_source_input_optimized_t::value >::value
- >::value;
-
- typedef detail::lexical_stream_limited_src<char_type, traits, requires_stringbuf > interpreter_type;
-
- 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)))
@@ -2163,7 +2284,7 @@
          typedef Source source_type ;
 
          typedef BOOST_DEDUCED_TYPENAME mpl::if_<
- ::boost::is_arithmetic<Source>, Source, Source const&
+ boost::is_arithmetic<Source>, Source, Source const&
>::type argument_type ;
 
          static source_type nearbyint ( argument_type s )
@@ -2247,19 +2368,19 @@
         {
             static inline Target lexical_cast_impl(const Source &arg)
             {
- typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::if_c<
- ::boost::type_traits::ice_and<
- ::boost::type_traits::ice_or<
- ::boost::is_signed<Source>::value,
- ::boost::is_float<Source>::value
+ typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
+ boost::type_traits::ice_and<
+ boost::type_traits::ice_or<
+ boost::is_signed<Source>::value,
+ boost::is_float<Source>::value
>::value,
- ::boost::type_traits::ice_not<
- ::boost::is_same<Source, bool>::value
+ boost::type_traits::ice_not<
+ boost::is_same<Source, bool>::value
>::value,
- ::boost::type_traits::ice_not<
- ::boost::is_same<Target, bool>::value
+ boost::type_traits::ice_not<
+ boost::is_same<Target, bool>::value
>::value,
- ::boost::is_unsigned<Target>::value
+ boost::is_unsigned<Target>::value
>::value,
                     lexical_cast_dynamic_num_ignoring_minus<Target, Source>,
                     lexical_cast_dynamic_num_not_ignoring_minus<Target, Source>
@@ -2273,86 +2394,44 @@
     template <typename Target, typename Source>
     inline Target lexical_cast(const Source &arg)
     {
- typedef BOOST_DEDUCED_TYPENAME ::boost::detail::array_to_pointer_decay<Source>::type src;
+ typedef BOOST_DEDUCED_TYPENAME boost::detail::array_to_pointer_decay<Source>::type src;
 
- typedef BOOST_DEDUCED_TYPENAME ::boost::type_traits::ice_or<
- ::boost::detail::is_xchar_to_xchar<Target, src >::value,
- ::boost::detail::is_char_array_to_stdstring<Target, src >::value,
- ::boost::type_traits::ice_and<
- ::boost::is_same<Target, src >::value,
- ::boost::detail::is_stdstring<Target >::value
+ typedef BOOST_DEDUCED_TYPENAME boost::type_traits::ice_or<
+ boost::detail::is_xchar_to_xchar<Target, src >::value,
+ boost::detail::is_char_array_to_stdstring<Target, src >::value,
+ boost::type_traits::ice_and<
+ boost::is_same<Target, src >::value,
+ boost::detail::is_stdstring<Target >::value
>::value
> shall_we_copy_t;
 
         typedef BOOST_DEDUCED_TYPENAME
- ::boost::detail::is_arithmetic_and_not_xchars<Target, src > shall_we_copy_with_dynamic_check_t;
+ boost::detail::is_arithmetic_and_not_xchars<Target, src > shall_we_copy_with_dynamic_check_t;
 
- typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::if_c<
+ typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
             shall_we_copy_t::value,
- ::boost::detail::lexical_cast_copy<src >,
- BOOST_DEDUCED_TYPENAME ::boost::mpl::if_c<
+ boost::detail::lexical_cast_copy<src >,
+ BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
                  shall_we_copy_with_dynamic_check_t::value,
- ::boost::detail::lexical_cast_dynamic_num<Target, src >,
- ::boost::detail::lexical_cast_do_cast<Target, src >
+ boost::detail::lexical_cast_dynamic_num<Target, src >,
+ boost::detail::lexical_cast_do_cast<Target, src >
>::type
>::type caster_type;
 
         return caster_type::lexical_cast_impl(arg);
     }
 
- template <typename Target>
- inline Target lexical_cast(const char* chars, std::size_t count)
- {
- return ::boost::lexical_cast<Target>(
- ::boost::iterator_range<const char*>(chars, chars + count)
- );
- }
-
-
- template <typename Target>
- inline Target lexical_cast(const unsigned char* chars, std::size_t count)
+ template <typename Target, typename CharType>
+ inline Target lexical_cast(const CharType* chars, std::size_t count)
     {
- return ::boost::lexical_cast<Target>(
- ::boost::iterator_range<const unsigned char*>(chars, chars + count)
- );
- }
+ BOOST_STATIC_ASSERT_MSG(boost::detail::is_char_or_wchar<CharType>::value,
+ "CharType must be a character or wide character type");
 
- template <typename Target>
- inline Target lexical_cast(const signed char* chars, std::size_t count)
- {
- return ::boost::lexical_cast<Target>(
- ::boost::iterator_range<const signed char*>(chars, chars + count)
+ return boost::lexical_cast<Target>(
+ boost::iterator_range<const CharType*>(chars, chars + count)
         );
     }
 
-#ifndef BOOST_LCAST_NO_WCHAR_T
- template <typename Target>
- inline Target lexical_cast(const wchar_t* chars, std::size_t count)
- {
- return ::boost::lexical_cast<Target>(
- ::boost::iterator_range<const wchar_t*>(chars, chars + count)
- );
- }
-#endif
-#ifndef BOOST_NO_CHAR16_T
- template <typename Target>
- inline Target lexical_cast(const char16_t* chars, std::size_t count)
- {
- return ::boost::lexical_cast<Target>(
- ::boost::iterator_range<const char16_t*>(chars, chars + count)
- );
- }
-#endif
-#ifndef BOOST_NO_CHAR32_T
- template <typename Target>
- inline Target lexical_cast(const char32_t* chars, std::size_t count)
- {
- return ::boost::lexical_cast<Target>(
- ::boost::iterator_range<const char32_t*>(chars, chars + count)
- );
- }
-#endif
-
 } // namespace boost
 
 #else // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

Modified: branches/release/libs/conversion/doc/lexical_cast.qbk
==============================================================================
--- branches/release/libs/conversion/doc/lexical_cast.qbk (original)
+++ branches/release/libs/conversion/doc/lexical_cast.qbk 2012-12-02 04:33:42 EST (Sun, 02 Dec 2012)
@@ -119,15 +119,14 @@
 * Target is CopyConstructible [20.1.3].
 * Target is DefaultConstructible, meaning that it is possible to default-initialize an object of that type [8.5, 20.1.4].
 
-The character type of the underlying stream is assumed to be `char` unless either the `Source` or the `Target` requires wide-character streaming, in which case the underlying stream uses `wchar_t`, `char16_t` or `char32_t`. Wide-character streaming is currently detected for:
+The character type of the underlying stream is assumed to be `char` unless either the `Source` or the `Target` requires wide-character streaming, in which case the underlying stream uses `wchar_t`. Following types also can use `char16_t` or `char32_t` for wide-character streaming:
 
-* Single character: `wchar_t`, `char16_t`, `char32_t`
-* Arrays of characters: `wchar_t *`, `char16_t *`, `char32_t *`, `const wchar_t *`, `const char16_t *`, `const char32_t *`
+* Single character: `char16_t`, `char32_t`
+* Arrays of characters: `char16_t *`, `char32_t *`, `const char16_t *`, `const char32_t *`
 * Strings: `std::basic_string`, `boost::containers::basic_string`
 * `boost::iterator_range<WideCharPtr>`, where `WideCharPtr` is a pointer to wide-character or pointer to const wide-character
 * `boost::array<CharT, N>` and `std::array<CharT, N>`, `boost::array<const CharT, N>` and `std::array<const CharT, N>`
 
-
 [important Many compilers and runtime libraries fail to make conversions using new Unicode characters. Make sure that the following code compiles and outputs nonzero values, before using new types:
 ``
     std::cout
@@ -235,7 +234,7 @@
   * [*Answer:] May be in a future version. There is no requirement in
 __proposallong__ to reset the flag but
 remember that __proposalshort__ is not yet accepted by the committee. By the way, it's a great opportunity to
-make your `operator>>` conform to the standard.
+make your `operator>>` more general.
 Read a good C++ book, study `std::sentry` and [@boost:libs/io/doc/ios_state.html `ios_state_saver`].
 
 [pre
@@ -273,6 +272,10 @@
 
 [section Changes]
 
+* [*boost 1.53.0 :]
+
+ * Much better input and output streams detection for user defined types.
+
 * [*boost 1.52.0 :]
 
     * Restored compilation on MSVC-2003 (was broken in 1.51.0).

Modified: branches/release/libs/conversion/lexical_cast_test.cpp
==============================================================================
--- branches/release/libs/conversion/lexical_cast_test.cpp (original)
+++ branches/release/libs/conversion/lexical_cast_test.cpp 2012-12-02 04:33:42 EST (Sun, 02 Dec 2012)
@@ -82,10 +82,10 @@
 #endif
 void test_char_types_conversions();
 void operators_overload_test();
-#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
 void test_char16_conversions();
 #endif
-#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
 void test_char32_conversions();
 #endif
 void test_getting_pointer_to_function();
@@ -120,10 +120,10 @@
 
     suite->add(BOOST_TEST_CASE(&test_char_types_conversions));
     suite->add(BOOST_TEST_CASE(&operators_overload_test));
-#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
     suite->add(BOOST_TEST_CASE(&test_char16_conversions));
 #endif
-#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
     suite->add(BOOST_TEST_CASE(&test_char32_conversions));
 #endif
     suite->add(BOOST_TEST_CASE(&test_getting_pointer_to_function));
@@ -243,9 +243,15 @@
     BOOST_CHECK_EQUAL(false, lexical_cast<bool>(0));
     BOOST_CHECK_THROW(lexical_cast<bool>(123), bad_lexical_cast);
     BOOST_CHECK_EQUAL(true, lexical_cast<bool>(1.0));
+ BOOST_CHECK_THROW(lexical_cast<bool>(-123), bad_lexical_cast);
     BOOST_CHECK_EQUAL(false, lexical_cast<bool>(0.0));
+ BOOST_CHECK_THROW(lexical_cast<bool>(1234), bad_lexical_cast);
+#if !defined(_CRAYC)
+ // Looks like a bug in CRAY compiler (throws bad_lexical_cast)
+ // TODO: localize the bug and report it to developers.
     BOOST_CHECK_EQUAL(true, lexical_cast<bool>(true));
     BOOST_CHECK_EQUAL(false, lexical_cast<bool>(false));
+#endif
     BOOST_CHECK_EQUAL(true, lexical_cast<bool>("1"));
     BOOST_CHECK_EQUAL(false, lexical_cast<bool>("0"));
     BOOST_CHECK_THROW(lexical_cast<bool>(""), bad_lexical_cast);
@@ -585,7 +591,7 @@
 }
 
 
-#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
 void test_char16_conversions()
 {
     BOOST_CHECK(u"100" == lexical_cast<std::u16string>(u"100"));
@@ -593,7 +599,7 @@
 }
 #endif
 
-#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
 void test_char32_conversions()
 {
     BOOST_CHECK(U"100" == lexical_cast<std::u32string>(U"100"));
@@ -601,17 +607,21 @@
 }
 #endif
 
-template <class To, class From, class Func>
-To try_cast_by_ptr(const From& from, const Func& f) {
- return f(from);
-};
-
 void test_getting_pointer_to_function()
 {
     // Just checking that &lexical_cast<To, From> is not ambiguous
- BOOST_CHECK_EQUAL(100, try_cast_by_ptr<int>("100", &boost::lexical_cast<int, const char[4]>));
- BOOST_CHECK_EQUAL(100, try_cast_by_ptr<int>("100", &boost::lexical_cast<int, std::string>));
- BOOST_CHECK_EQUAL(std::string("100"), try_cast_by_ptr<std::string>(100, &boost::lexical_cast<std::string, int>));
+ typedef char char_arr[4];
+ typedef int(*f1)(const char_arr&);
+ f1 p1 = &boost::lexical_cast<int, char_arr>;
+ BOOST_CHECK(p1);
+
+ typedef int(*f2)(const std::string&);
+ f2 p2 = &boost::lexical_cast<int, std::string>;
+ BOOST_CHECK(p2);
+
+ typedef std::string(*f3)(const int&);
+ f3 p3 = &boost::lexical_cast<std::string, int>;
+ BOOST_CHECK(p3);
 }
 
 

Modified: branches/release/libs/conversion/test/Jamfile.v2
==============================================================================
--- branches/release/libs/conversion/test/Jamfile.v2 (original)
+++ branches/release/libs/conversion/test/Jamfile.v2 2012-12-02 04:33:42 EST (Sun, 02 Dec 2012)
@@ -49,5 +49,7 @@
     [ run lexical_cast_iterator_range_test.cpp ]
     [ 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 ]
   ;
 

Modified: branches/release/libs/conversion/test/lexical_cast_arrays_test.cpp
==============================================================================
--- branches/release/libs/conversion/test/lexical_cast_arrays_test.cpp (original)
+++ branches/release/libs/conversion/test/lexical_cast_arrays_test.cpp 2012-12-02 04:33:42 EST (Sun, 02 Dec 2012)
@@ -91,7 +91,7 @@
 
 #endif
 
-#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
     typedef ArrayT<char16_t, 300> u16arr_type;
     typedef ArrayT<char16_t, 3> u16short_arr_type;
     std::u16string u16ethalon(u"100");
@@ -109,7 +109,7 @@
     BOOST_CHECK_THROW(lexical_cast<u16short_arr_type>(val), boost::bad_lexical_cast);
 #endif
 
-#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
     typedef ArrayT<char32_t, 300> u32arr_type;
     typedef ArrayT<char32_t, 3> u32short_arr_type;
     std::u32string u32ethalon(U"100");
@@ -190,7 +190,7 @@
 
 #endif
 
-#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
     typedef ArrayT<char16_t, 300> u16arr_type;
     typedef ArrayT<char16_t, 3> u16short_arr_type;
     std::u16string u16ethalon(u"100");
@@ -217,7 +217,7 @@
     BOOST_CHECK_THROW(lexical_cast<u16short_arr_type>(val), boost::bad_lexical_cast);
 #endif
 
-#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
     typedef ArrayT<char32_t, 300> u32arr_type;
     typedef ArrayT<char32_t, 3> u32short_arr_type;
     std::u32string u32ethalon(U"100");
@@ -328,7 +328,7 @@
     }
 #endif
 
-#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
     {
         const ArrayT<const char16_t, 4> var_zero_terminated_const_var_const_char = {{ u'1', u'0', u'0', u'\0'}};
         BOOST_CHECK(lexical_cast<std::u16string>(var_zero_terminated_const_var_const_char) == u"100");
@@ -339,7 +339,7 @@
     }
 #endif
 
-#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
     {
         const ArrayT<const char32_t, 4> var_zero_terminated_const_var_const_char = {{ U'1', U'0', U'0', U'\0'}};
         BOOST_CHECK(lexical_cast<std::u32string>(var_zero_terminated_const_var_const_char) == U"100");

Modified: branches/release/libs/conversion/test/lexical_cast_containers_test.cpp
==============================================================================
--- branches/release/libs/conversion/test/lexical_cast_containers_test.cpp (original)
+++ branches/release/libs/conversion/test/lexical_cast_containers_test.cpp 2012-12-02 04:33:42 EST (Sun, 02 Dec 2012)
@@ -71,12 +71,12 @@
     BOOST_CHECK(boost::lexical_cast<boost::container::wstring>(char_array) == wchar_array);
 #endif
 
-#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
+#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
     const char16_t char16_array[] = u"Test string";
     BOOST_CHECK(boost::lexical_cast<boost::container::basic_string<char16_t> >(char_array) == char16_array);
 #endif
 
-#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
+#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
     const char32_t char32_array[] = U"Test string";
     BOOST_CHECK(boost::lexical_cast<boost::container::basic_string<char32_t> >(char_array) == char32_array);
 #endif

Modified: branches/release/libs/conversion/test/lexical_cast_empty_input_test.cpp
==============================================================================
--- branches/release/libs/conversion/test/lexical_cast_empty_input_test.cpp (original)
+++ branches/release/libs/conversion/test/lexical_cast_empty_input_test.cpp 2012-12-02 04:33:42 EST (Sun, 02 Dec 2012)
@@ -84,12 +84,12 @@
 #endif
 
 // Currently, no compiler and STL library fully support char16_t and char32_t
-//#ifndef BOOST_NO_CHAR16_T
+//#ifndef BOOST_NO_CXX11_CHAR16_T
 // std::basic_string<char16_t> v16w;
 // do_test_on_empty_input(v16w);
 // BOOST_CHECK_THROW(lexical_cast<char16_t>(v16w), bad_lexical_cast);
 //#endif
-//#ifndef BOOST_NO_CHAR32_T
+//#ifndef BOOST_NO_CXX11_CHAR32_T
 // std::basic_string<char32_t> v32w;
 // do_test_on_empty_input(v32w);
 // BOOST_CHECK_THROW(lexical_cast<char32_t>(v32w), bad_lexical_cast);

Modified: branches/release/libs/conversion/test/lexical_cast_float_types_test.cpp
==============================================================================
--- branches/release/libs/conversion/test/lexical_cast_float_types_test.cpp (original)
+++ branches/release/libs/conversion/test/lexical_cast_float_types_test.cpp 2012-12-02 04:33:42 EST (Sun, 02 Dec 2012)
@@ -505,7 +505,11 @@
 }
 void test_conversion_from_to_long_double()
 {
+// We do not run tests on compilers with bugs
+#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
     test_conversion_from_to_float<long double>();
+#endif
+ BOOST_CHECK(true);
 }
 
 

Modified: branches/release/libs/conversion/test/lexical_cast_inf_nan_test.cpp
==============================================================================
--- branches/release/libs/conversion/test/lexical_cast_inf_nan_test.cpp (original)
+++ branches/release/libs/conversion/test/lexical_cast_inf_nan_test.cpp 2012-12-02 04:33:42 EST (Sun, 02 Dec 2012)
@@ -186,7 +186,11 @@
 
 void test_inf_nan_long_double()
 {
+// We do not run tests on compilers with bugs
+#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
     test_inf_nan_templated<long double >();
+#endif
+ BOOST_CHECK(true);
 }
 
 unit_test::test_suite *init_unit_test_suite(int, char *[])

Modified: branches/release/libs/conversion/test/lexical_cast_integral_types_test.cpp
==============================================================================
--- branches/release/libs/conversion/test/lexical_cast_integral_types_test.cpp (original)
+++ branches/release/libs/conversion/test/lexical_cast_integral_types_test.cpp 2012-12-02 04:33:42 EST (Sun, 02 Dec 2012)
@@ -386,12 +386,12 @@
     test_conversion_from_integral_to_char<T>(wzero);
     test_conversion_from_char_to_integral<T>(wzero);
 #endif
-#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
     char16_t const u16zero = u'0';
     test_conversion_from_integral_to_char<T>(u16zero);
     test_conversion_from_char_to_integral<T>(u16zero);
 #endif
-#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
     char32_t const u32zero = u'0';
     test_conversion_from_integral_to_char<T>(u32zero);
     test_conversion_from_char_to_integral<T>(u32zero);

Modified: branches/release/libs/conversion/test/lexical_cast_iterator_range_test.cpp
==============================================================================
--- branches/release/libs/conversion/test/lexical_cast_iterator_range_test.cpp (original)
+++ branches/release/libs/conversion/test/lexical_cast_iterator_range_test.cpp 2012-12-02 04:33:42 EST (Sun, 02 Dec 2012)
@@ -134,7 +134,7 @@
     BOOST_CHECK(lexical_cast<std::wstring>(crng2) == L"1");
 #endif
 
-#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
+#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
     typedef std::basic_string<char16_t> my_char16_string;
     BOOST_CHECK(lexical_cast<my_char16_string>(rng1) == u"1");
     BOOST_CHECK(lexical_cast<my_char16_string>(crng1) == u"1");
@@ -142,7 +142,7 @@
     BOOST_CHECK(lexical_cast<my_char16_string>(crng2) == u"1");
 #endif
 
-#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
+#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
     typedef std::basic_string<char32_t> my_char32_string;
     BOOST_CHECK(lexical_cast<my_char32_string>(rng1) == U"1");
     BOOST_CHECK(lexical_cast<my_char32_string>(crng1) == U"1");
@@ -194,7 +194,7 @@
 
 void test_char16_iterator_ranges()
 {
-#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
     typedef char16_t test_char_type;
     test_char_type data1[] = u"1";
     test_char_type data2[] = u"11";
@@ -206,7 +206,7 @@
 
 void test_char32_iterator_ranges()
 {
-#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS)
+#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
     typedef char32_t test_char_type;
     test_char_type data1[] = U"1";
     test_char_type data2[] = U"11";

Modified: branches/release/libs/conversion/test/lexical_cast_loopback_test.cpp
==============================================================================
--- branches/release/libs/conversion/test/lexical_cast_loopback_test.cpp (original)
+++ branches/release/libs/conversion/test/lexical_cast_loopback_test.cpp 2012-12-02 04:33:42 EST (Sun, 02 Dec 2012)
@@ -86,7 +86,11 @@
 
 void test_round_conversion_long_double()
 {
+// We do not run tests on compilers with bugs
+#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
     test_round_conversion<long double>();
     test_msvc_magic_values<long double>();
+#endif
+ BOOST_CHECK(true);
 }
 

Added: branches/release/libs/conversion/test/lexical_cast_stream_detection_test.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/conversion/test/lexical_cast_stream_detection_test.cpp 2012-12-02 04:33:42 EST (Sun, 02 Dec 2012)
@@ -0,0 +1,307 @@
+// Unit test for boost::lexical_cast.
+//
+// See http://www.boost.org for most recent version, including documentation.
+//
+// Copyright Antony Polukhin, 2011-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/test/unit_test.hpp>
+
+#include <boost/lexical_cast.hpp>
+
+#include <iostream>
+
+
+///////////////////////// char streamable classes ///////////////////////////////////////////
+
+struct streamable_easy { enum ENU {value = 0}; };
+std::ostream& operator << (std::ostream& ostr, const streamable_easy&) {
+ return ostr << streamable_easy::value;
+}
+std::istream& operator >> (std::istream& istr, const streamable_easy&) {
+ int i; istr >> i; BOOST_CHECK_EQUAL(i, streamable_easy::value);
+ return istr;
+}
+
+struct streamable_medium { enum ENU {value = 1}; };
+template <class CharT>
+typename boost::enable_if<boost::is_same<CharT, char>, std::basic_ostream<CharT>&>::type
+operator << (std::basic_ostream<CharT>& ostr, const streamable_medium&) {
+ return ostr << streamable_medium::value;
+}
+template <class CharT>
+typename boost::enable_if<boost::is_same<CharT, char>, std::basic_istream<CharT>&>::type
+operator >> (std::basic_istream<CharT>& istr, const streamable_medium&) {
+ int i; istr >> i; BOOST_CHECK_EQUAL(i, streamable_medium::value);
+ return istr;
+}
+
+struct streamable_hard { enum ENU {value = 2}; };
+template <class CharT, class TraitsT>
+typename boost::enable_if<boost::is_same<CharT, char>, std::basic_ostream<CharT, TraitsT>&>::type
+operator << (std::basic_ostream<CharT, TraitsT>& ostr, const streamable_hard&) {
+ return ostr << streamable_hard::value;
+}
+template <class CharT, class TraitsT>
+typename boost::enable_if<boost::is_same<CharT, char>, std::basic_istream<CharT, TraitsT>&>::type
+operator >> (std::basic_istream<CharT, TraitsT>& istr, const streamable_hard&) {
+ int i; istr >> i; BOOST_CHECK_EQUAL(i, streamable_hard::value);
+ return istr;
+}
+
+struct streamable_hard2 { enum ENU {value = 3}; };
+template <class TraitsT>
+std::basic_ostream<char, TraitsT>& operator << (std::basic_ostream<char, TraitsT>& ostr, const streamable_hard2&) {
+ return ostr << streamable_hard2::value;
+}
+template <class TraitsT>
+std::basic_istream<char, TraitsT>& operator >> (std::basic_istream<char, TraitsT>& istr, const streamable_hard2&) {
+ int i; istr >> i; BOOST_CHECK_EQUAL(i, streamable_hard2::value);
+ return istr;
+}
+
+
+///////////////////////// wchar_t streamable classes ///////////////////////////////////////////
+
+struct wstreamable_easy { enum ENU {value = 4}; };
+std::wostream& operator << (std::wostream& ostr, const wstreamable_easy&) {
+ return ostr << wstreamable_easy::value;
+}
+std::wistream& operator >> (std::wistream& istr, const wstreamable_easy&) {
+ int i; istr >> i; BOOST_CHECK_EQUAL(i, wstreamable_easy::value);
+ return istr;
+}
+
+struct wstreamable_medium { enum ENU {value = 5}; };
+template <class CharT>
+typename boost::enable_if<boost::is_same<CharT, wchar_t>, std::basic_ostream<CharT>& >::type
+operator << (std::basic_ostream<CharT>& ostr, const wstreamable_medium&) {
+ return ostr << wstreamable_medium::value;
+}
+template <class CharT>
+typename boost::enable_if<boost::is_same<CharT, wchar_t>, std::basic_istream<CharT>& >::type
+operator >> (std::basic_istream<CharT>& istr, const wstreamable_medium&) {
+ int i; istr >> i; BOOST_CHECK_EQUAL(i, wstreamable_medium::value);
+ return istr;
+}
+
+struct wstreamable_hard { enum ENU {value = 6}; };
+template <class CharT, class TraitsT>
+typename boost::enable_if<boost::is_same<CharT, wchar_t>, std::basic_ostream<CharT, TraitsT>&>::type
+operator << (std::basic_ostream<CharT, TraitsT>& ostr, const wstreamable_hard&) {
+ return ostr << wstreamable_hard::value;
+}
+template <class CharT, class TraitsT>
+typename boost::enable_if<boost::is_same<CharT, wchar_t>, std::basic_istream<CharT, TraitsT>&>::type
+operator >> (std::basic_istream<CharT, TraitsT>& istr, const wstreamable_hard&) {
+ int i; istr >> i; BOOST_CHECK_EQUAL(i, wstreamable_hard::value);
+ return istr;
+}
+
+struct wstreamable_hard2 { enum ENU {value = 7}; };
+template <class TraitsT>
+std::basic_ostream<wchar_t, TraitsT>& operator << (std::basic_ostream<wchar_t, TraitsT>& ostr, const wstreamable_hard2&) {
+ return ostr << wstreamable_hard2::value;
+}
+template <class TraitsT>
+std::basic_istream<wchar_t, TraitsT>& operator >> (std::basic_istream<wchar_t, TraitsT>& istr, const wstreamable_hard2&) {
+ int i; istr >> i; BOOST_CHECK_EQUAL(i, wstreamable_hard2::value);
+ return istr;
+}
+
+///////////////////////// char and wchar_t streamable classes ///////////////////////////////////////////
+
+
+struct bistreamable_easy { enum ENU {value = 8}; };
+std::ostream& operator << (std::ostream& ostr, const bistreamable_easy&) {
+ return ostr << bistreamable_easy::value;
+}
+std::istream& operator >> (std::istream& istr, const bistreamable_easy&) {
+ int i; istr >> i; BOOST_CHECK_EQUAL(i, bistreamable_easy::value);
+ return istr;
+}
+
+std::wostream& operator << (std::wostream& ostr, const bistreamable_easy&) {
+ return ostr << bistreamable_easy::value + 100;
+}
+std::wistream& operator >> (std::wistream& istr, const bistreamable_easy&) {
+ int i; istr >> i; BOOST_CHECK_EQUAL(i, bistreamable_easy::value + 100);
+ return istr;
+}
+
+struct bistreamable_medium { enum ENU {value = 9}; };
+template <class CharT>
+std::basic_ostream<CharT>& operator << (std::basic_ostream<CharT>& ostr, const bistreamable_medium&) {
+ return ostr << bistreamable_medium::value + (sizeof(CharT) == 1 ? 0 : 100);
+}
+template <class CharT>
+std::basic_istream<CharT>& operator >> (std::basic_istream<CharT>& istr, const bistreamable_medium&) {
+ int i; istr >> i; BOOST_CHECK_EQUAL(i, bistreamable_medium::value + (sizeof(CharT) == 1 ? 0 : 100));
+ return istr;
+}
+
+struct bistreamable_hard { enum ENU {value = 10}; };
+template <class CharT, class TraitsT>
+std::basic_ostream<CharT, TraitsT>& operator << (std::basic_ostream<CharT, TraitsT>& ostr, const bistreamable_hard&) {
+ return ostr << bistreamable_hard::value + (sizeof(CharT) == 1 ? 0 : 100);
+}
+template <class CharT, class TraitsT>
+std::basic_istream<CharT, TraitsT>& operator >> (std::basic_istream<CharT, TraitsT>& istr, const bistreamable_hard&) {
+ int i; istr >> i; BOOST_CHECK_EQUAL(i, bistreamable_hard::value + (sizeof(CharT) == 1 ? 0 : 100));
+ return istr;
+}
+
+struct bistreamable_hard2 { enum ENU {value = 11}; };
+template <class TraitsT>
+std::basic_ostream<char, TraitsT>& operator << (std::basic_ostream<char, TraitsT>& ostr, const bistreamable_hard2&) {
+ return ostr << bistreamable_hard2::value;
+}
+template <class TraitsT>
+std::basic_istream<char, TraitsT>& operator >> (std::basic_istream<char, TraitsT>& istr, const bistreamable_hard2&) {
+ int i; istr >> i; BOOST_CHECK_EQUAL(i, bistreamable_hard2::value);
+ return istr;
+}
+
+template <class TraitsT>
+std::basic_ostream<wchar_t, TraitsT>& operator << (std::basic_ostream<wchar_t, TraitsT>& ostr, const bistreamable_hard2&) {
+ return ostr << bistreamable_hard2::value + 100;
+}
+template <class TraitsT>
+std::basic_istream<wchar_t, TraitsT>& operator >> (std::basic_istream<wchar_t, TraitsT>& istr, const bistreamable_hard2&) {
+ int i; istr >> i; BOOST_CHECK_EQUAL(i, bistreamable_hard2::value + 100);
+ return istr;
+}
+
+
+void test_ostream_character_detection();
+void test_istream_character_detection();
+void test_mixed_stream_character_detection();
+
+boost::unit_test::test_suite *init_unit_test_suite(int, char *[])
+{
+ boost::unit_test::test_suite *suite =
+ BOOST_TEST_SUITE("lexical_cast stream character detection");
+ suite->add(BOOST_TEST_CASE(&test_ostream_character_detection));
+ suite->add(BOOST_TEST_CASE(&test_istream_character_detection));
+ suite->add(BOOST_TEST_CASE(&test_mixed_stream_character_detection));
+
+ return suite;
+}
+
+template <class T>
+static void test_ostr_impl() {
+ T streamable;
+ BOOST_CHECK_EQUAL(T::value, boost::lexical_cast<int>(streamable));
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(T::value), boost::lexical_cast<std::string>(streamable));
+}
+
+template <class T>
+static void test_wostr_impl() {
+ T streamable;
+ BOOST_CHECK_EQUAL(T::value, boost::lexical_cast<int>(streamable));
+ // BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(T::value), boost::lexical_cast<std::string>(streamable)); // Shall not compile???
+ BOOST_CHECK(boost::lexical_cast<std::wstring>(T::value) == boost::lexical_cast<std::wstring>(streamable));
+}
+
+template <class T>
+static void test_bistr_impl() {
+ T streamable;
+
+ BOOST_CHECK_EQUAL(T::value, boost::lexical_cast<int>(streamable));
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(T::value), boost::lexical_cast<std::string>(streamable));
+
+ BOOST_CHECK(boost::lexical_cast<std::wstring>(T::value + 100) == boost::lexical_cast<std::wstring>(streamable));
+}
+
+void test_ostream_character_detection() {
+ test_ostr_impl<streamable_easy>();
+ test_ostr_impl<streamable_medium>();
+ test_ostr_impl<streamable_hard>();
+ test_ostr_impl<streamable_hard2>();
+
+ test_wostr_impl<wstreamable_easy>();
+ test_wostr_impl<wstreamable_medium>();
+ test_wostr_impl<wstreamable_hard>();
+ test_wostr_impl<wstreamable_hard2>();
+
+ test_bistr_impl<bistreamable_easy>();
+ test_bistr_impl<bistreamable_medium>();
+ test_bistr_impl<bistreamable_hard>();
+ test_bistr_impl<bistreamable_hard2>();
+}
+
+
+template <class T>
+static void test_istr_impl() {
+ boost::lexical_cast<T>(T::value);
+ boost::lexical_cast<T>(boost::lexical_cast<std::string>(T::value));
+}
+
+template <class T>
+static void test_wistr_impl() {
+ boost::lexical_cast<T>(T::value);
+ //boost::lexical_cast<T>(boost::lexical_cast<std::string>(T::value)); // Shall not compile???
+ boost::lexical_cast<T>(boost::lexical_cast<std::wstring>(T::value));
+}
+
+template <class T>
+static void test_bistr_instr_impl() {
+ boost::lexical_cast<T>(T::value);
+ boost::lexical_cast<T>(boost::lexical_cast<std::string>(T::value));
+ boost::lexical_cast<T>(boost::lexical_cast<std::wstring>(T::value + 100));
+}
+
+void test_istream_character_detection() {
+ test_istr_impl<streamable_easy>();
+ test_istr_impl<streamable_medium>();
+ test_istr_impl<streamable_hard>();
+ test_istr_impl<streamable_hard2>();
+
+ test_wistr_impl<wstreamable_easy>();
+ test_wistr_impl<wstreamable_medium>();
+ test_wistr_impl<wstreamable_hard>();
+ test_wistr_impl<wstreamable_hard2>();
+
+ test_bistr_instr_impl<bistreamable_easy>();
+ test_bistr_instr_impl<bistreamable_medium>();
+ test_bistr_instr_impl<bistreamable_hard>();
+ test_bistr_instr_impl<bistreamable_hard2>();
+}
+
+
+
+
+
+
+struct wistreamble_ostreamable { enum ENU {value = 200}; };
+std::ostream& operator << (std::ostream& ostr, const wistreamble_ostreamable&) {
+ return ostr << wistreamble_ostreamable::value;
+}
+std::wistream& operator >> (std::wistream& istr, const wistreamble_ostreamable&) {
+ int i; istr >> i; BOOST_CHECK_EQUAL(i, wistreamble_ostreamable::value);
+ return istr;
+}
+
+struct istreamble_wostreamable { enum ENU {value = 201}; };
+std::wostream& operator << (std::wostream& ostr, const istreamble_wostreamable&) {
+ return ostr << istreamble_wostreamable::value;
+}
+std::istream& operator >> (std::istream& istr, const istreamble_wostreamable&) {
+ int i; istr >> i; BOOST_CHECK_EQUAL(i, istreamble_wostreamable::value);
+ return istr;
+}
+
+void test_mixed_stream_character_detection() {
+ //boost::lexical_cast<std::wstring>(std::string("qwe")); // TODO: ALLOW IT AS EXTENSION!
+
+ boost::lexical_cast<wistreamble_ostreamable>(wistreamble_ostreamable::value);
+ BOOST_CHECK_EQUAL(boost::lexical_cast<int>(wistreamble_ostreamable()), wistreamble_ostreamable::value);
+
+ boost::lexical_cast<istreamble_wostreamable>(istreamble_wostreamable::value);
+ BOOST_CHECK_EQUAL(boost::lexical_cast<int>(istreamble_wostreamable()), istreamble_wostreamable::value);
+}

Added: branches/release/libs/conversion/test/lexical_cast_stream_traits_test.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/conversion/test/lexical_cast_stream_traits_test.cpp 2012-12-02 04:33:42 EST (Sun, 02 Dec 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;
+}
+

Modified: branches/release/libs/conversion/test/lexical_cast_wchars_test.cpp
==============================================================================
--- branches/release/libs/conversion/test/lexical_cast_wchars_test.cpp (original)
+++ branches/release/libs/conversion/test/lexical_cast_wchars_test.cpp 2012-12-02 04:33:42 EST (Sun, 02 Dec 2012)
@@ -58,7 +58,7 @@
 
 void test_char_types_conversions_char16_t()
 {
-#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
+#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
     test_impl(u"Test array of chars");
 #endif
 
@@ -67,7 +67,7 @@
 
 void test_char_types_conversions_char32_t()
 {
-#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
+#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
     test_impl(U"Test array of chars");
 #endif
 


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