File indexing completed on 2025-01-18 09:39:13
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #ifndef BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_STREAMS_HPP
0019 #define BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_STREAMS_HPP
0020
0021 #include <boost/config.hpp>
0022 #ifdef BOOST_HAS_PRAGMA_ONCE
0023 # pragma once
0024 #endif
0025
0026
0027 #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
0028 #define BOOST_LCAST_NO_WCHAR_T
0029 #endif
0030
0031 #include <cstddef>
0032 #include <string>
0033 #include <cstring>
0034 #include <cstdio>
0035 #include <boost/limits.hpp>
0036 #include <boost/type_traits/conditional.hpp>
0037 #include <boost/type_traits/is_pointer.hpp>
0038 #include <boost/detail/lcast_precision.hpp>
0039 #include <boost/detail/workaround.hpp>
0040 #include <boost/core/snprintf.hpp>
0041
0042 #ifndef BOOST_NO_STD_LOCALE
0043 # include <locale>
0044 #else
0045 # ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
0046
0047
0048
0049
0050 # error "Unable to use <locale> header. Define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE to force "
0051 # error "boost::lexical_cast to use only 'C' locale during conversions."
0052 # endif
0053 #endif
0054
0055 #ifdef BOOST_NO_STRINGSTREAM
0056 #include <strstream>
0057 #else
0058 #include <sstream>
0059 #endif
0060
0061 #include <boost/lexical_cast/detail/lcast_char_constants.hpp>
0062 #include <boost/lexical_cast/detail/lcast_unsigned_converters.hpp>
0063 #include <boost/lexical_cast/detail/inf_nan.hpp>
0064
0065 #include <istream>
0066
0067 #include <array>
0068
0069 #include <boost/type_traits/make_unsigned.hpp>
0070 #include <boost/type_traits/is_integral.hpp>
0071 #include <boost/type_traits/is_float.hpp>
0072 #include <boost/lexical_cast/detail/buffer_view.hpp>
0073 #include <boost/container/container_fwd.hpp>
0074 #include <boost/integer.hpp>
0075 #include <boost/detail/basic_pointerbuf.hpp>
0076 #include <boost/core/noncopyable.hpp>
0077 #include <boost/core/enable_if.hpp>
0078 #ifndef BOOST_NO_CWCHAR
0079 # include <cwchar>
0080 #endif
0081
0082 namespace boost {
0083
0084
0085 template<class T, std::size_t N>
0086 class array;
0087 template<class IteratorT>
0088 class iterator_range;
0089
0090 namespace detail
0091 {
0092
0093
0094 template <class BufferType, class CharT>
0095 class basic_unlockedbuf : public basic_pointerbuf<CharT, BufferType> {
0096 public:
0097 typedef basic_pointerbuf<CharT, BufferType> base_type;
0098 typedef typename base_type::streamsize streamsize;
0099
0100 #ifndef BOOST_NO_USING_TEMPLATE
0101 using base_type::pptr;
0102 using base_type::pbase;
0103 using base_type::setbuf;
0104 #else
0105 charT* pptr() const { return base_type::pptr(); }
0106 charT* pbase() const { return base_type::pbase(); }
0107 BufferType* setbuf(char_type* s, streamsize n) { return base_type::setbuf(s, n); }
0108 #endif
0109 };
0110 }
0111
0112 namespace detail
0113 {
0114 struct do_not_construct_out_buffer_t{};
0115 struct do_not_construct_out_stream_t{
0116 do_not_construct_out_stream_t(do_not_construct_out_buffer_t*){}
0117 };
0118
0119 template <class CharT, class Traits>
0120 struct out_stream_helper_trait {
0121 #if defined(BOOST_NO_STRINGSTREAM)
0122 typedef std::ostream out_stream_t;
0123 typedef basic_unlockedbuf<std::strstreambuf, char> stringbuffer_t;
0124 #elif defined(BOOST_NO_STD_LOCALE)
0125 typedef std::ostream out_stream_t;
0126 typedef basic_unlockedbuf<std::stringbuf, char> stringbuffer_t;
0127 typedef basic_unlockedbuf<std::streambuf, char> buffer_t;
0128 #else
0129 typedef std::basic_ostream<CharT, Traits> out_stream_t;
0130 typedef basic_unlockedbuf<std::basic_stringbuf<CharT, Traits>, CharT> stringbuffer_t;
0131 typedef basic_unlockedbuf<std::basic_streambuf<CharT, Traits>, CharT> buffer_t;
0132 #endif
0133 };
0134 }
0135
0136 namespace detail
0137 {
0138 template< class CharT
0139 , class Traits
0140 , bool RequiresStringbuffer
0141 , std::size_t CharacterBufferSize
0142 >
0143 class lexical_istream_limited_src: boost::noncopyable {
0144 typedef typename boost::conditional<
0145 RequiresStringbuffer,
0146 typename out_stream_helper_trait<CharT, Traits>::out_stream_t,
0147 do_not_construct_out_stream_t
0148 >::type deduced_out_stream_t;
0149
0150 typedef typename boost::conditional<
0151 RequiresStringbuffer,
0152 typename out_stream_helper_trait<CharT, Traits>::stringbuffer_t,
0153 do_not_construct_out_buffer_t
0154 >::type deduced_out_buffer_t;
0155
0156 deduced_out_buffer_t out_buffer;
0157 deduced_out_stream_t out_stream;
0158 CharT buffer[CharacterBufferSize];
0159
0160
0161
0162 const CharT* start;
0163 const CharT* finish;
0164
0165 public:
0166 lexical_istream_limited_src() noexcept
0167 : out_buffer()
0168 , out_stream(&out_buffer)
0169 , start(buffer)
0170 , finish(buffer + CharacterBufferSize)
0171 {}
0172
0173 const CharT* cbegin() const noexcept {
0174 return start;
0175 }
0176
0177 const CharT* cend() const noexcept {
0178 return finish;
0179 }
0180
0181 private:
0182
0183 bool shl_char(CharT ch) noexcept {
0184 Traits::assign(buffer[0], ch);
0185 finish = start + 1;
0186 return true;
0187 }
0188
0189 #ifndef BOOST_LCAST_NO_WCHAR_T
0190 template <class T>
0191 bool shl_char(T ch) {
0192 static_assert(sizeof(T) <= sizeof(CharT),
0193 "boost::lexical_cast does not support narrowing of char types."
0194 "Use boost::locale instead" );
0195 #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
0196 std::locale loc;
0197 CharT const w = BOOST_USE_FACET(std::ctype<CharT>, loc).widen(ch);
0198 #else
0199 CharT const w = static_cast<CharT>(ch);
0200 #endif
0201 Traits::assign(buffer[0], w);
0202 finish = start + 1;
0203 return true;
0204 }
0205 #endif
0206
0207 bool shl_char_array(CharT const* str_value) noexcept {
0208 start = str_value;
0209 finish = start + Traits::length(str_value);
0210 return true;
0211 }
0212
0213 template <class T>
0214 bool shl_char_array(T const* str_value) {
0215 static_assert(sizeof(T) <= sizeof(CharT),
0216 "boost::lexical_cast does not support narrowing of char types."
0217 "Use boost::locale instead" );
0218 return shl_input_streamable(str_value);
0219 }
0220
0221 bool shl_char_array_limited(CharT const* str, std::size_t max_size) noexcept {
0222 start = str;
0223 finish = start;
0224 const auto zero = Traits::to_char_type(0);
0225 while (finish < start + max_size && zero != *finish) {
0226 ++ finish;
0227 }
0228 return true;
0229 }
0230
0231 template<typename InputStreamable>
0232 bool shl_input_streamable(InputStreamable& input) {
0233 #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_LOCALE)
0234
0235
0236 static_assert(boost::is_same<char, CharT>::value, "");
0237 #endif
0238
0239 #ifndef BOOST_NO_EXCEPTIONS
0240 out_stream.exceptions(std::ios::badbit);
0241 try {
0242 #endif
0243 bool const result = !(out_stream << input).fail();
0244 const deduced_out_buffer_t* const p = static_cast<deduced_out_buffer_t*>(
0245 out_stream.rdbuf()
0246 );
0247 start = p->pbase();
0248 finish = p->pptr();
0249 return result;
0250 #ifndef BOOST_NO_EXCEPTIONS
0251 } catch (const ::std::ios_base::failure& ) {
0252 return false;
0253 }
0254 #endif
0255 }
0256
0257 template <class T>
0258 inline bool shl_unsigned(const T n) {
0259 CharT* tmp_finish = buffer + CharacterBufferSize;
0260 start = lcast_put_unsigned<Traits, T, CharT>(n, tmp_finish).convert();
0261 finish = tmp_finish;
0262 return true;
0263 }
0264
0265 template <class T>
0266 inline bool shl_signed(const T n) {
0267 CharT* tmp_finish = buffer + CharacterBufferSize;
0268 typedef typename boost::make_unsigned<T>::type utype;
0269 CharT* tmp_start = lcast_put_unsigned<Traits, utype, CharT>(lcast_to_unsigned(n), tmp_finish).convert();
0270 if (n < 0) {
0271 --tmp_start;
0272 CharT const minus = lcast_char_constants<CharT>::minus;
0273 Traits::assign(*tmp_start, minus);
0274 }
0275 start = tmp_start;
0276 finish = tmp_finish;
0277 return true;
0278 }
0279
0280 template <class T, class SomeCharT>
0281 bool shl_real_type(const T& val, SomeCharT* ) {
0282 lcast_set_precision(out_stream, &val);
0283 return shl_input_streamable(val);
0284 }
0285
0286 bool shl_real_type(float val, char* begin) {
0287 using namespace std;
0288 const double val_as_double = val;
0289 finish = start +
0290 boost::core::snprintf(begin, CharacterBufferSize,
0291 "%.*g", static_cast<int>(boost::detail::lcast_get_precision<float>()), val_as_double);
0292 return finish > start;
0293 }
0294
0295 bool shl_real_type(double val, char* begin) {
0296 using namespace std;
0297 finish = start +
0298 boost::core::snprintf(begin, CharacterBufferSize,
0299 "%.*g", static_cast<int>(boost::detail::lcast_get_precision<double>()), val);
0300 return finish > start;
0301 }
0302
0303 #ifndef __MINGW32__
0304 bool shl_real_type(long double val, char* begin) {
0305 using namespace std;
0306 finish = start +
0307 boost::core::snprintf(begin, CharacterBufferSize,
0308 "%.*Lg", static_cast<int>(boost::detail::lcast_get_precision<long double>()), val );
0309 return finish > start;
0310 }
0311 #endif
0312
0313
0314 #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_SWPRINTF) && !defined(__MINGW32__)
0315 bool shl_real_type(float val, wchar_t* begin) {
0316 using namespace std;
0317 const double val_as_double = val;
0318 finish = start + swprintf(begin, CharacterBufferSize,
0319 L"%.*g",
0320 static_cast<int>(boost::detail::lcast_get_precision<float >()),
0321 val_as_double );
0322 return finish > start;
0323 }
0324
0325 bool shl_real_type(double val, wchar_t* begin) {
0326 using namespace std;
0327 finish = start + swprintf(begin, CharacterBufferSize,
0328 L"%.*g", static_cast<int>(boost::detail::lcast_get_precision<double >()), val );
0329 return finish > start;
0330 }
0331
0332 bool shl_real_type(long double val, wchar_t* begin) {
0333 using namespace std;
0334 finish = start + swprintf(begin, CharacterBufferSize,
0335 L"%.*Lg", static_cast<int>(boost::detail::lcast_get_precision<long double >()), val );
0336 return finish > start;
0337 }
0338 #endif
0339 template <class T>
0340 bool shl_real(T val) {
0341 CharT* tmp_finish = buffer + CharacterBufferSize;
0342 if (put_inf_nan(buffer, tmp_finish, val)) {
0343 finish = tmp_finish;
0344 return true;
0345 }
0346
0347 return shl_real_type(val, static_cast<CharT*>(buffer));
0348 }
0349
0350
0351 public:
0352 template<class Alloc>
0353 bool operator<<(std::basic_string<CharT,Traits,Alloc> const& str) noexcept {
0354 start = str.data();
0355 finish = start + str.length();
0356 return true;
0357 }
0358
0359 template<class Alloc>
0360 bool operator<<(boost::container::basic_string<CharT,Traits,Alloc> const& str) noexcept {
0361 start = str.data();
0362 finish = start + str.length();
0363 return true;
0364 }
0365
0366 bool operator<<(bool value) noexcept {
0367 CharT const czero = lcast_char_constants<CharT>::zero;
0368 Traits::assign(buffer[0], Traits::to_char_type(czero + value));
0369 finish = start + 1;
0370 return true;
0371 }
0372
0373 bool operator<<(boost::conversion::detail::buffer_view<CharT> rng) noexcept {
0374 start = rng.begin;
0375 finish = rng.end;
0376 return true;
0377 }
0378
0379 template <class C>
0380 bool operator<<(const iterator_range<C*>& rng) noexcept {
0381 return (*this) << boost::conversion::detail::make_buffer_view(rng.begin(), rng.end());
0382 }
0383
0384 bool operator<<(char ch) { return shl_char(ch); }
0385 bool operator<<(unsigned char ch) { return ((*this) << static_cast<char>(ch)); }
0386 bool operator<<(signed char ch) { return ((*this) << static_cast<char>(ch)); }
0387 #if !defined(BOOST_LCAST_NO_WCHAR_T)
0388 bool operator<<(wchar_t const* str) { return shl_char_array(str); }
0389 bool operator<<(wchar_t * str) { return shl_char_array(str); }
0390 #ifndef BOOST_NO_INTRINSIC_WCHAR_T
0391 bool operator<<(wchar_t ch) { return shl_char(ch); }
0392 #endif
0393 #endif
0394 #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
0395 bool operator<<(char16_t ch) { return shl_char(ch); }
0396 bool operator<<(char16_t * str) { return shl_char_array(str); }
0397 bool operator<<(char16_t const * str) { return shl_char_array(str); }
0398 #endif
0399 #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
0400 bool operator<<(char32_t ch) { return shl_char(ch); }
0401 bool operator<<(char32_t * str) { return shl_char_array(str); }
0402 bool operator<<(char32_t const * str) { return shl_char_array(str); }
0403 #endif
0404 bool operator<<(unsigned char const* ch) { return ((*this) << reinterpret_cast<char const*>(ch)); }
0405 bool operator<<(unsigned char * ch) { return ((*this) << reinterpret_cast<char *>(ch)); }
0406 bool operator<<(signed char const* ch) { return ((*this) << reinterpret_cast<char const*>(ch)); }
0407 bool operator<<(signed char * ch) { return ((*this) << reinterpret_cast<char *>(ch)); }
0408 bool operator<<(char const* str_value) { return shl_char_array(str_value); }
0409 bool operator<<(char* str_value) { return shl_char_array(str_value); }
0410 bool operator<<(short n) { return shl_signed(n); }
0411 bool operator<<(int n) { return shl_signed(n); }
0412 bool operator<<(long n) { return shl_signed(n); }
0413 bool operator<<(unsigned short n) { return shl_unsigned(n); }
0414 bool operator<<(unsigned int n) { return shl_unsigned(n); }
0415 bool operator<<(unsigned long n) { return shl_unsigned(n); }
0416
0417 #if defined(BOOST_HAS_LONG_LONG)
0418 bool operator<<(boost::ulong_long_type n) { return shl_unsigned(n); }
0419 bool operator<<(boost::long_long_type n) { return shl_signed(n); }
0420 #elif defined(BOOST_HAS_MS_INT64)
0421 bool operator<<(unsigned __int64 n) { return shl_unsigned(n); }
0422 bool operator<<( __int64 n) { return shl_signed(n); }
0423 #endif
0424
0425 #ifdef BOOST_HAS_INT128
0426 bool operator<<(const boost::uint128_type& n) { return shl_unsigned(n); }
0427 bool operator<<(const boost::int128_type& n) { return shl_signed(n); }
0428 #endif
0429 bool operator<<(float val) { return shl_real(val); }
0430 bool operator<<(double val) { return shl_real(val); }
0431 bool operator<<(long double val) {
0432 #ifndef __MINGW32__
0433 return shl_real(val);
0434 #else
0435 return shl_real(static_cast<double>(val));
0436 #endif
0437 }
0438
0439
0440 template <class C, std::size_t N>
0441 typename boost::disable_if<boost::is_const<C>, bool>::type
0442 operator<<(boost::array<C, N> const& input) noexcept {
0443 static_assert(
0444 sizeof(boost::array<const C, N>) == sizeof(boost::array<C, N>),
0445 "boost::array<C, N> and boost::array<const C, N> must have exactly the same layout."
0446 );
0447 return ((*this) << reinterpret_cast<boost::array<const C, N> const& >(input));
0448 }
0449
0450 template <std::size_t N>
0451 bool operator<<(boost::array<const CharT, N> const& input) noexcept {
0452 return shl_char_array_limited(input.data(), N);
0453 }
0454
0455 template <std::size_t N>
0456 bool operator<<(boost::array<const unsigned char, N> const& input) noexcept {
0457 return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input));
0458 }
0459
0460 template <std::size_t N>
0461 bool operator<<(boost::array<const signed char, N> const& input) noexcept {
0462 return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input));
0463 }
0464
0465 #ifndef BOOST_NO_CXX11_HDR_ARRAY
0466
0467 template <class C, std::size_t N>
0468 bool operator<<(std::array<C, N> const& input) noexcept {
0469 static_assert(
0470 sizeof(std::array<C, N>) == sizeof(boost::array<C, N>),
0471 "std::array and boost::array must have exactly the same layout. "
0472 "Bug in implementation of std::array or boost::array."
0473 );
0474 return ((*this) << reinterpret_cast<boost::array<C, N> const& >(input));
0475 }
0476 #endif
0477 template <class InStreamable>
0478 bool operator<<(const InStreamable& input) { return shl_input_streamable(input); }
0479 };
0480
0481
0482 template <class CharT, class Traits>
0483 class lexical_ostream_limited_src: boost::noncopyable {
0484
0485 const CharT* start;
0486 const CharT* const finish;
0487
0488 public:
0489 lexical_ostream_limited_src(const CharT* begin, const CharT* end) noexcept
0490 : start(begin)
0491 , finish(end)
0492 {}
0493
0494
0495 private:
0496 template <typename Type>
0497 bool shr_unsigned(Type& output) {
0498 if (start == finish) return false;
0499 CharT const minus = lcast_char_constants<CharT>::minus;
0500 CharT const plus = lcast_char_constants<CharT>::plus;
0501 bool const has_minus = Traits::eq(minus, *start);
0502
0503
0504 if (has_minus || Traits::eq(plus, *start)) {
0505 ++start;
0506 }
0507
0508 bool const succeed = lcast_ret_unsigned<Traits, Type, CharT>(output, start, finish).convert();
0509
0510 if (has_minus) {
0511 output = static_cast<Type>(0u - output);
0512 }
0513
0514 return succeed;
0515 }
0516
0517 template <typename Type>
0518 bool shr_signed(Type& output) {
0519 if (start == finish) return false;
0520 CharT const minus = lcast_char_constants<CharT>::minus;
0521 CharT const plus = lcast_char_constants<CharT>::plus;
0522 typedef typename make_unsigned<Type>::type utype;
0523 utype out_tmp = 0;
0524 bool const has_minus = Traits::eq(minus, *start);
0525
0526
0527 if (has_minus || Traits::eq(plus, *start)) {
0528 ++start;
0529 }
0530
0531 bool succeed = lcast_ret_unsigned<Traits, utype, CharT>(out_tmp, start, finish).convert();
0532 if (has_minus) {
0533 utype const comp_val = (static_cast<utype>(1) << std::numeric_limits<Type>::digits);
0534 succeed = succeed && out_tmp<=comp_val;
0535 output = static_cast<Type>(0u - out_tmp);
0536 } else {
0537 utype const comp_val = static_cast<utype>((std::numeric_limits<Type>::max)());
0538 succeed = succeed && out_tmp<=comp_val;
0539 output = static_cast<Type>(out_tmp);
0540 }
0541 return succeed;
0542 }
0543
0544 template<typename InputStreamable>
0545 bool shr_using_base_class(InputStreamable& output)
0546 {
0547 static_assert(
0548 !boost::is_pointer<InputStreamable>::value,
0549 "boost::lexical_cast can not convert to pointers"
0550 );
0551
0552 #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_LOCALE)
0553 static_assert(boost::is_same<char, CharT>::value,
0554 "boost::lexical_cast can not convert, because your STL library does not "
0555 "support such conversions. Try updating it."
0556 );
0557 #endif
0558
0559 #if defined(BOOST_NO_STRINGSTREAM)
0560 std::istrstream stream(start, static_cast<std::istrstream::streamsize>(finish - start));
0561 #else
0562 typedef typename out_stream_helper_trait<CharT, Traits>::buffer_t buffer_t;
0563 buffer_t buf;
0564
0565
0566 buf.setbuf(const_cast<CharT*>(start), static_cast<typename buffer_t::streamsize>(finish - start));
0567 #if defined(BOOST_NO_STD_LOCALE)
0568 std::istream stream(&buf);
0569 #else
0570 std::basic_istream<CharT, Traits> stream(&buf);
0571 #endif
0572 #endif
0573
0574 #ifndef BOOST_NO_EXCEPTIONS
0575 stream.exceptions(std::ios::badbit);
0576 try {
0577 #endif
0578 stream.unsetf(std::ios::skipws);
0579 lcast_set_precision(stream, static_cast<InputStreamable*>(0));
0580
0581 return (stream >> output)
0582 && (stream.get() == Traits::eof());
0583
0584 #ifndef BOOST_NO_EXCEPTIONS
0585 } catch (const ::std::ios_base::failure& ) {
0586 return false;
0587 }
0588 #endif
0589 }
0590
0591 template<class T>
0592 inline bool shr_xchar(T& output) noexcept {
0593 static_assert(sizeof(CharT) == sizeof(T),
0594 "boost::lexical_cast does not support narrowing of character types."
0595 "Use boost::locale instead" );
0596 bool const ok = (finish - start == 1);
0597 if (ok) {
0598 CharT out;
0599 Traits::assign(out, *start);
0600 output = static_cast<T>(out);
0601 }
0602 return ok;
0603 }
0604
0605 template <std::size_t N, class ArrayT>
0606 bool shr_std_array(ArrayT& output) noexcept {
0607 using namespace std;
0608 const std::size_t size = static_cast<std::size_t>(finish - start);
0609 if (size > N - 1) {
0610 return false;
0611 }
0612
0613 memcpy(&output[0], start, size * sizeof(CharT));
0614 output[size] = Traits::to_char_type(0);
0615 return true;
0616 }
0617
0618
0619 public:
0620 bool operator>>(unsigned short& output) { return shr_unsigned(output); }
0621 bool operator>>(unsigned int& output) { return shr_unsigned(output); }
0622 bool operator>>(unsigned long int& output) { return shr_unsigned(output); }
0623 bool operator>>(short& output) { return shr_signed(output); }
0624 bool operator>>(int& output) { return shr_signed(output); }
0625 bool operator>>(long int& output) { return shr_signed(output); }
0626 #if defined(BOOST_HAS_LONG_LONG)
0627 bool operator>>(boost::ulong_long_type& output) { return shr_unsigned(output); }
0628 bool operator>>(boost::long_long_type& output) { return shr_signed(output); }
0629 #elif defined(BOOST_HAS_MS_INT64)
0630 bool operator>>(unsigned __int64& output) { return shr_unsigned(output); }
0631 bool operator>>(__int64& output) { return shr_signed(output); }
0632 #endif
0633
0634 #ifdef BOOST_HAS_INT128
0635 bool operator>>(boost::uint128_type& output) { return shr_unsigned(output); }
0636 bool operator>>(boost::int128_type& output) { return shr_signed(output); }
0637 #endif
0638
0639 bool operator>>(char& output) { return shr_xchar(output); }
0640 bool operator>>(unsigned char& output) { return shr_xchar(output); }
0641 bool operator>>(signed char& output) { return shr_xchar(output); }
0642 #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
0643 bool operator>>(wchar_t& output) { return shr_xchar(output); }
0644 #endif
0645 #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
0646 bool operator>>(char16_t& output) { return shr_xchar(output); }
0647 #endif
0648 #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
0649 bool operator>>(char32_t& output) { return shr_xchar(output); }
0650 #endif
0651 template<class Alloc>
0652 bool operator>>(std::basic_string<CharT,Traits,Alloc>& str) {
0653 str.assign(start, finish); return true;
0654 }
0655
0656 template<class Alloc>
0657 bool operator>>(boost::container::basic_string<CharT,Traits,Alloc>& str) {
0658 str.assign(start, finish); return true;
0659 }
0660
0661 template <std::size_t N>
0662 bool operator>>(std::array<CharT, N>& output) noexcept {
0663 return shr_std_array<N>(output);
0664 }
0665
0666 template <std::size_t N>
0667 bool operator>>(std::array<unsigned char, N>& output) noexcept {
0668 return ((*this) >> reinterpret_cast<std::array<char, N>& >(output));
0669 }
0670
0671 template <std::size_t N>
0672 bool operator>>(std::array<signed char, N>& output) noexcept {
0673 return ((*this) >> reinterpret_cast<std::array<char, N>& >(output));
0674 }
0675
0676 template <class C, std::size_t N>
0677 bool operator>>(boost::array<C, N>& output) noexcept {
0678 static_assert(
0679 sizeof(std::array<C, N>) == sizeof(boost::array<C, N>),
0680 "std::array<C, N> and boost::array<C, N> must have exactly the same layout."
0681 );
0682 return ((*this) >> reinterpret_cast<std::array<C, N>& >(output));
0683 }
0684
0685 bool operator>>(bool& output) noexcept {
0686 output = false;
0687
0688 if (start == finish) return false;
0689 CharT const zero = lcast_char_constants<CharT>::zero;
0690 CharT const plus = lcast_char_constants<CharT>::plus;
0691 CharT const minus = lcast_char_constants<CharT>::minus;
0692
0693 const CharT* const dec_finish = finish - 1;
0694 output = Traits::eq(*dec_finish, zero + 1);
0695 if (!output && !Traits::eq(*dec_finish, zero)) {
0696 return false;
0697 }
0698
0699 if (start == dec_finish) return true;
0700
0701
0702 if (Traits::eq(plus, *start) || (Traits::eq(minus, *start) && !output)) {
0703 ++ start;
0704 }
0705
0706
0707 while (start != dec_finish) {
0708 if (!Traits::eq(zero, *start)) {
0709 return false;
0710 }
0711
0712 ++ start;
0713 }
0714
0715 return true;
0716 }
0717
0718 private:
0719
0720 template <class T>
0721 bool float_types_converter_internal(T& output) {
0722 if (parse_inf_nan(start, finish, output)) return true;
0723 bool const return_value = shr_using_base_class(output);
0724
0725
0726
0727
0728
0729
0730
0731 CharT const minus = lcast_char_constants<CharT>::minus;
0732 CharT const plus = lcast_char_constants<CharT>::plus;
0733 CharT const capital_e = lcast_char_constants<CharT>::capital_e;
0734 CharT const lowercase_e = lcast_char_constants<CharT>::lowercase_e;
0735 if ( return_value &&
0736 (
0737 Traits::eq(*(finish-1), lowercase_e)
0738 || Traits::eq(*(finish-1), capital_e)
0739 || Traits::eq(*(finish-1), minus)
0740 || Traits::eq(*(finish-1), plus)
0741 )
0742 ) return false;
0743
0744 return return_value;
0745 }
0746
0747 public:
0748 bool operator>>(float& output) { return float_types_converter_internal(output); }
0749 bool operator>>(double& output) { return float_types_converter_internal(output); }
0750 bool operator>>(long double& output) { return float_types_converter_internal(output); }
0751
0752
0753
0754 template <typename InputStreamable>
0755 bool operator>>(InputStreamable& output) {
0756 return shr_using_base_class(output);
0757 }
0758 };
0759 }
0760 }
0761
0762 #undef BOOST_LCAST_NO_WCHAR_T
0763
0764 #endif
0765