forked from boostorg/conversion
Stream type detection metafunctions were rewritten so that now they can detect stream type for user defined types (refs #6786)
Removed unrequired `::` [SVN r81278]
This commit is contained in:
@@ -162,6 +162,8 @@ namespace boost
|
||||
#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 @@ namespace boost
|
||||
#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 {};
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
struct stream_char<const CharT*>
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME stream_char<CharT>::type type;
|
||||
};
|
||||
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 CharT>
|
||||
struct stream_char<iterator_range<CharT*> >
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME stream_char<CharT*>::type 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 CharT>
|
||||
struct stream_char<iterator_range<const CharT*> >
|
||||
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 BOOST_DEDUCED_TYPENAME stream_char<const CharT*>::type type;
|
||||
typedef Char type;
|
||||
};
|
||||
|
||||
template <class CharT, class Traits, class Alloc>
|
||||
struct stream_char< std::basic_string<CharT, Traits, Alloc> >
|
||||
template < class Char, class Traits, class Alloc >
|
||||
struct stream_char_common< boost::container::basic_string< Char, Traits, Alloc > >
|
||||
{
|
||||
typedef CharT type;
|
||||
typedef Char type;
|
||||
};
|
||||
|
||||
template <class CharT, class Traits, class Alloc>
|
||||
struct stream_char< ::boost::container::basic_string<CharT, Traits, Alloc> >
|
||||
{
|
||||
typedef CharT 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 CharT, std::size_t N>
|
||||
struct stream_char<boost::array<CharT, N> >
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME stream_char<CharT>::type type;
|
||||
};
|
||||
|
||||
template<typename CharT, std::size_t N>
|
||||
struct stream_char<boost::array<const CharT, N> >
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME stream_char<CharT>::type type;
|
||||
};
|
||||
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 > >
|
||||
> {};
|
||||
|
||||
#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;
|
||||
};
|
||||
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 CharT, std::size_t N>
|
||||
struct stream_char<std::array<const CharT, N> >
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME stream_char<CharT>::type type;
|
||||
};
|
||||
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)
|
||||
|
||||
#if !defined(BOOST_LCAST_NO_WCHAR_T) && defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
template<>
|
||||
struct stream_char<wchar_t>
|
||||
template <>
|
||||
struct stream_char_common< wchar_t >
|
||||
{
|
||||
typedef boost::detail::not_a_character_type type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct stream_char<wchar_t*>
|
||||
{
|
||||
typedef wchar_t type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct stream_char<const wchar_t*>
|
||||
{
|
||||
typedef wchar_t type;
|
||||
typedef char type;
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
};
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
#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
|
||||
};
|
||||
}
|
||||
|
||||
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 < class T >
|
||||
struct deduce_target_char
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME stream_char_common< T >::type stage1_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME deduce_target_char_impl< stage1_type >::type stage2_type;
|
||||
|
||||
typedef stage2_type type;
|
||||
};
|
||||
|
||||
template < class T >
|
||||
struct deduce_source_char
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME stream_char_common< T >::type stage1_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME deduce_source_char_impl< stage1_type >::type stage2_type;
|
||||
|
||||
typedef stage2_type type;
|
||||
};
|
||||
}
|
||||
|
||||
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 boost {
|
||||
|
||||
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 @@ namespace boost {
|
||||
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 @@ namespace boost {
|
||||
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 @@ namespace boost {
|
||||
}
|
||||
|
||||
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 @@ namespace boost {
|
||||
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 @@ namespace boost {
|
||||
* */
|
||||
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 @@ namespace boost {
|
||||
};
|
||||
|
||||
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 @@ namespace boost {
|
||||
{
|
||||
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 @@ namespace boost {
|
||||
{
|
||||
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 @@ namespace boost {
|
||||
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 @@ namespace boost {
|
||||
};
|
||||
|
||||
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 @@ namespace boost {
|
||||
{
|
||||
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 @@ namespace boost {
|
||||
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 @@ namespace boost {
|
||||
{
|
||||
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 +2377,44 @@ namespace boost {
|
||||
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)
|
||||
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 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 unsigned char* chars, std::size_t count)
|
||||
{
|
||||
return ::boost::lexical_cast<Target>(
|
||||
::boost::iterator_range<const unsigned char*>(chars, chars + count)
|
||||
return boost::lexical_cast<Target>(
|
||||
boost::iterator_range<const CharType*>(chars, chars + count)
|
||||
);
|
||||
}
|
||||
|
||||
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)
|
||||
);
|
||||
}
|
||||
|
||||
#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
|
||||
|
@@ -49,5 +49,6 @@ test-suite conversion
|
||||
[ 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 ]
|
||||
;
|
||||
|
||||
|
307
test/lexical_cast_stream_detection_test.cpp
Normal file
307
test/lexical_cast_stream_detection_test.cpp
Normal file
@@ -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);
|
||||
}
|
Reference in New Issue
Block a user