+/************************************ OPERATORS >> ( ... ) ********************************/
+ public:
+ bool operator>>(unsigned short& output) { return shr_unsigned(output); }
+ bool operator>>(unsigned int& output) { return shr_unsigned(output); }
+ bool operator>>(unsigned long int& output) { return shr_unsigned(output); }
+ bool operator>>(short& output) { return shr_signed(output); }
+ bool operator>>(int& output) { return shr_signed(output); }
+ bool operator>>(long int& output) { return shr_signed(output); }
+#if defined(BOOST_HAS_LONG_LONG)
+ bool operator>>(boost::ulong_long_type& output) { return shr_unsigned(output); }
+ bool operator>>(boost::long_long_type& output) { return shr_signed(output); }
+#elif defined(BOOST_HAS_MS_INT64)
+ bool operator>>(unsigned __int64& output) { return shr_unsigned(output); }
+ bool operator>>(__int64& output) { return shr_signed(output); }
+#endif
+
+#ifdef BOOST_HAS_INT128
+ bool operator>>(boost::uint128_type& output) { return shr_unsigned(output); }
+ bool operator>>(boost::int128_type& output) { return shr_signed(output); }
+#endif
+
+ bool operator>>(char& output) { return shr_xchar(output); }
+ bool operator>>(unsigned char& output) { return shr_xchar(output); }
+ bool operator>>(signed char& output) { return shr_xchar(output); }
+#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
+ bool operator>>(wchar_t& output) { return shr_xchar(output); }
+#endif
+#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
+ bool operator>>(char16_t& output) { return shr_xchar(output); }
+#endif
+#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
+ bool operator>>(char32_t& output) { return shr_xchar(output); }
+#endif
+ template<class Alloc>
+ bool operator>>(std::basic_string<CharT,Traits,Alloc>& str) { str.assign(start, finish); return true; }
+
+ template<class Alloc>
+ bool operator>>(boost::container::basic_string<CharT,Traits,Alloc>& str) { str.assign(start, finish); return true; }
+
+
+ private:
+ template <std::size_t N, class ArrayT>
+ bool shr_std_array(ArrayT& output) BOOST_NOEXCEPT
+ {
+ using namespace std;
+ const std::size_t size = finish - start;
+ if (size > N - 1) { // `-1` because we need to store \0 at the end
+ return false;
+ }
+
+ memcpy(&output[0], start, size * sizeof(CharT));
+ output[size] = Traits::to_char_type(0);
+ return true;
+ }
+
+ public:
+
+ template <std::size_t N>
+ bool operator>>(boost::array<CharT, N>& output) BOOST_NOEXCEPT
+ {
+ return shr_std_array<N>(output);
+ }
+
+ template <std::size_t N>
+ bool operator>>(boost::array<unsigned char, N>& output)
+ {
+ return ((*this) >> reinterpret_cast<boost::array<char, N>& >(output));
+ }
+
+ template <std::size_t N>
+ bool operator>>(boost::array<signed char, N>& output)
+ {
+ return ((*this) >> reinterpret_cast<boost::array<char, N>& >(output));
+ }
+
+#ifndef BOOST_NO_CXX11_HDR_ARRAY
+ template <std::size_t N>
+ bool operator>>(std::array<CharT, N>& output) BOOST_NOEXCEPT
+ {
+ return shr_std_array<N>(output);
+ }
+
+ template <std::size_t N>
+ bool operator>>(std::array<unsigned char, N>& output)
+ {
+ return ((*this) >> reinterpret_cast<std::array<char, N>& >(output));
+ }
+
+ template <std::size_t N>
+ bool operator>>(std::array<signed char, N>& output)
+ {
+ return ((*this) >> reinterpret_cast<std::array<char, N>& >(output));
+ }
+#endif
+
+
+ /*
+ * case "-0" || "0" || "+0" : output = false; return true;
+ * case "1" || "+1": output = true; return true;
+ * default: return false;
+ */
+ bool operator>>(bool& output) BOOST_NOEXCEPT
+ {
+ CharT const zero = lcast_char_constants<CharT>::zero;
+ CharT const plus = lcast_char_constants<CharT>::plus;
+ CharT const minus = lcast_char_constants<CharT>::minus;
+
+ switch(finish-start)
+ {
+ case 1:
+ output = Traits::eq(start[0], zero+1);
+ return output || Traits::eq(start[0], zero );
+ case 2:
+ if ( Traits::eq( plus, *start) )
+ {
+ ++start;
+ output = Traits::eq(start[0], zero +1);
+ return output || Traits::eq(start[0], zero );
+ } else
+ {
+ output = false;
+ return Traits::eq( minus, *start)
+ && Traits::eq( zero, start[1]);
+ }
+ default:
+ output = false; // Suppress warning about uninitalized variable
+ return false;
+ }
+ }
+
+ bool operator>>(float& output) { return lcast_ret_float<Traits>(output,start,finish); }
+
+ private:
+ // Not optimised converter
+ template <class T>
+ bool float_types_converter_internal(T& output, int /*tag*/) {
+ if (parse_inf_nan(start, finish, output)) return true;
+ bool return_value = shr_using_base_class(output);
+
+ /* Some compilers and libraries successfully
+ * parse 'inf', 'INFINITY', '1.0E', '1.0E-'...
+ * We are trying to provide a unified behaviour,
+ * so we just forbid such conversions (as some
+ * of the most popular compilers/libraries do)
+ * */
+ CharT const minus = lcast_char_constants<CharT>::minus;
+ CharT const plus = lcast_char_constants<CharT>::plus;
+ CharT const capital_e = lcast_char_constants<CharT>::capital_e;
+ CharT const lowercase_e = lcast_char_constants<CharT>::lowercase_e;
+ if ( return_value &&
+ (
+ Traits::eq(*(finish-1), lowercase_e) // 1.0e
+ || Traits::eq(*(finish-1), capital_e) // 1.0E
+ || Traits::eq(*(finish-1), minus) // 1.0e- or 1.0E-
+ || Traits::eq(*(finish-1), plus) // 1.0e+ or 1.0E+
+ )
+ ) return false;
+
+ return return_value;
+ }
+
+ // Optimised converter
+ bool float_types_converter_internal(double& output,char /*tag*/) {
+ return lcast_ret_float<Traits>(output,start,finish);
+ }
+ public:
+
+ bool operator>>(double& output)
+ {
+ /*
+ * Some compilers implement long double as double. In that case these types have
+ * same size, same precision, same max and min values... And it means,
+ * that current implementation of lcast_ret_float cannot be used for type
+ * double, because it will give a big precision loss.
+ * */
+ boost::mpl::if_c<
+#if (defined(BOOST_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64)) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
+ boost::type_traits::ice_eq< sizeof(double), sizeof(long double) >::value,
+#else
+ 1,
+#endif
+ int,
+ char
+ >::type tag = 0;
+
+ return float_types_converter_internal(output, tag);
+ }
+
+ bool operator>>(long double& output)
+ {
+ int tag = 0;
+ return float_types_converter_internal(output, tag);
+ }
+
+ // Generic istream-based algorithm.
+ // lcast_streambuf_for_target<InputStreamable>::value is true.
+ template<typename InputStreamable>
+ bool operator>>(InputStreamable& output) { return shr_using_base_class(output); }
+ };
+ }
+
+ namespace detail
+ {
+ template<typename T>
+ struct is_stdstring
+ {
+ BOOST_STATIC_CONSTANT(bool, value = false );
+ };
+
+ template<typename CharT, typename Traits, typename Alloc>
+ struct is_stdstring< std::basic_string<CharT, Traits, Alloc> >
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true );
+ };
+
+ template<typename CharT, typename Traits, typename Alloc>
+ struct is_stdstring< boost::container::basic_string<CharT, Traits, Alloc> >
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true );
+ };
+
+ template<typename Target, typename Source>
+ struct is_arithmetic_and_not_xchars
+ {
+ 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<
+ detail::is_char_or_wchar<Target>::value
+ >::value,
+ boost::type_traits::ice_not<
+ detail::is_char_or_wchar<Source>::value
+ >::value
+ >::value
+ )
+ );
+ };
+
+ /*
+ * is_xchar_to_xchar<Target, Source>::value is true, when
+ * Target and Souce are the same char types, or when
+ * Target and Souce are char types of the same size.
+ */
+ template<typename Target, typename Source>
+ struct is_xchar_to_xchar
+ {
+ BOOST_STATIC_CONSTANT(bool, value =
+ (
+ 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,
+ is_char_or_wchar<Target>::value,
+ is_char_or_wchar<Source>::value
+ >::value
+ >::value
+ )
+ );
+ };
+
+ template<typename Target, typename Source>
+ struct is_char_array_to_stdstring
+ {
+ BOOST_STATIC_CONSTANT(bool, value = false );
+ };
+
+ template<typename CharT, typename Traits, typename Alloc>
+ struct is_char_array_to_stdstring< std::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< std::basic_string<CharT, Traits, Alloc>, const 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>, 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* >
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true );
+ };
+
+#if (defined _MSC_VER)
+# pragma warning( push )
+# pragma warning( disable : 4701 ) // possible use of ... before initialization
+# pragma warning( disable : 4702 ) // unreachable code
+# pragma warning( disable : 4267 ) // conversion from 'size_t' to 'unsigned int'
+#endif
+ template<typename Target, typename Source>
+ struct lexical_cast_do_cast
+ {
+ static inline Target lexical_cast_impl(const Source& arg)
+ {
+ typedef lexical_cast_stream_traits<Source, Target> stream_trait;
+
+ typedef detail::lexical_stream_limited_src<
+ BOOST_DEDUCED_TYPENAME stream_trait::char_type,
+ BOOST_DEDUCED_TYPENAME stream_trait::traits,
+ stream_trait::requires_stringbuf
+ > interpreter_type;
+
+ // Target type must be default constructible
+ Target result;