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