Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r81278 - in trunk: boost libs/conversion/test
From: antoshkka_at_[hidden]
Date: 2012-11-10 02:42:06


Author: apolukhin
Date: 2012-11-10 02:42:04 EST (Sat, 10 Nov 2012)
New Revision: 81278
URL: http://svn.boost.org/trac/boost/changeset/81278

Log:
Stream type detection metafunctions were rewritten so that now they can detect stream type for user defined types (refs #6786)
Removed unrequired `::`
Added:
   trunk/libs/conversion/test/lexical_cast_stream_detection_test.cpp (contents, props changed)
Text files modified:
   trunk/boost/lexical_cast.hpp | 574 ++++++++++++++++++++++-----------------
   trunk/libs/conversion/test/Jamfile.v2 | 1
   2 files changed, 319 insertions(+), 256 deletions(-)

Modified: trunk/boost/lexical_cast.hpp
==============================================================================
--- trunk/boost/lexical_cast.hpp (original)
+++ trunk/boost/lexical_cast.hpp 2012-11-10 02:42:04 EST (Sat, 10 Nov 2012)
@@ -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,236 +173,331 @@
 #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,
+ boost::is_same< T, char16_t >::value,
                     #endif
                     #ifndef BOOST_NO_CHAR32_T
- ::boost::is_same< T, char32_t >::value,
+ 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;
@@ -518,7 +615,7 @@
 
     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>
@@ -1247,7 +1344,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 +1385,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 +1536,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();
@@ -1777,7 +1874,7 @@
             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 +2014,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
@@ -1968,7 +2065,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 +2075,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 +2099,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
@@ -2025,15 +2122,15 @@
         template <typename Float, typename Char>
         struct is_this_float_conversion_optimized
         {
- typedef ::boost::type_traits::ice_and<
- ::boost::is_float<Float>::value,
+ 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
+ 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
+ boost::type_traits::ice_eq<sizeof(Char), sizeof(char) >::value
 #endif
> result_type;
 
@@ -2059,13 +2156,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,51 +2178,58 @@
         {
             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
+ 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_type>::value
- && !::boost::is_same<char16_t, target_char_t>::value),
+ 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_type>::value
- && !::boost::is_same<char32_t, target_char_t>::value),
+ 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<
+ 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
+ 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_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 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;
 
                 // Target type must be default constructible
                 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;
+ 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;
 
@@ -2163,7 +2267,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 +2351,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,85 +2377,43 @@
     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)
- {
- return ::boost::lexical_cast<Target>(
- ::boost::iterator_range<const unsigned char*>(chars, chars + count)
- );
- }
-
- template <typename Target>
- inline Target lexical_cast(const signed 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 signed 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");
 
-#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)
+ return boost::lexical_cast<Target>(
+ boost::iterator_range<const CharType*>(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
 

Modified: trunk/libs/conversion/test/Jamfile.v2
==============================================================================
--- trunk/libs/conversion/test/Jamfile.v2 (original)
+++ trunk/libs/conversion/test/Jamfile.v2 2012-11-10 02:42:04 EST (Sat, 10 Nov 2012)
@@ -49,5 +49,6 @@
     [ 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 ]
   ;
 

Added: trunk/libs/conversion/test/lexical_cast_stream_detection_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/conversion/test/lexical_cast_stream_detection_test.cpp 2012-11-10 02:42:04 EST (Sat, 10 Nov 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);
+}


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