Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:13

0001 // Copyright Kevlin Henney, 2000-2005.
0002 // Copyright Alexander Nasonov, 2006-2010.
0003 // Copyright Antony Polukhin, 2011-2023.
0004 //
0005 // Distributed under the Boost Software License, Version 1.0. (See
0006 // accompanying file LICENSE_1_0.txt or copy at
0007 // http://www.boost.org/LICENSE_1_0.txt)
0008 //
0009 // what:  lexical_cast custom keyword cast
0010 // who:   contributed by Kevlin Henney,
0011 //        enhanced with contributions from Terje Slettebo,
0012 //        with additional fixes and suggestions from Gennaro Prota,
0013 //        Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
0014 //        Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
0015 //        Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
0016 // when:  November 2000, March 2003, June 2005, June 2006, March 2011 - 2014, Nowember 2016
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         // Getting error at this point means, that your STL library is old/lame/misconfigured.
0047         // If nothing can be done with STL library, define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE,
0048         // but beware: lexical_cast will understand only 'C' locale delimeters and thousands
0049         // separators.
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     // Forward declaration
0085     template<class T, std::size_t N>
0086     class array;
0087     template<class IteratorT>
0088     class iterator_range;
0089 
0090     namespace detail // basic_unlockedbuf
0091     {
0092         // acts as a stream buffer which wraps around a pair of pointers
0093         // and gives acces to internals
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 // optimized stream wrappers
0137     {
0138         template< class CharT // a result of widest_char transformation
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             // After the `operator <<`  finishes, `[start, finish)` is
0161             // the range to output by `operator >>`
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 /************************************ HELPER FUNCTIONS FOR OPERATORS << ( ... ) ********************************/
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                 // If you have compilation error at this point, than your STL library
0235                 // does not support such conversions. Try updating it.
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& /*f*/) {
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* /*begin*/) {
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 /************************************ OPERATORS << ( ... ) ********************************/
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             // Adding constness to characters. Constness does not change layout
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             // Making a Boost.Array from std::array
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             //`[start, finish)` is the range to output by `operator >>`
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 /************************************ HELPER FUNCTIONS FOR OPERATORS >> ( ... ) ********************************/
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                 /* We won`t use `start' any more, so no need in decrementing it after */
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                 /* We won`t use `start' any more, so no need in decrementing it after */
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                 // Usually `istream` and `basic_istream` do not modify
0565                 // content of buffer; `buffer_t` assures that this is true
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 // BOOST_NO_STD_LOCALE
0572 #endif // BOOST_NO_STRINGSTREAM
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& /*f*/) {
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) { // `-1` because we need to store \0 at the end
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 /************************************ OPERATORS >> ( ... ) ********************************/
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; // Suppress warning about uninitalized variable
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; // Does not ends on '0' or '1'
0697                 }
0698 
0699                 if (start == dec_finish) return true;
0700 
0701                 // We may have sign at the beginning
0702                 if (Traits::eq(plus, *start) || (Traits::eq(minus, *start) && !output)) {
0703                     ++ start;
0704                 }
0705 
0706                 // Skipping zeros
0707                 while (start != dec_finish) {
0708                     if (!Traits::eq(zero, *start)) {
0709                         return false; // Not a zero => error
0710                     }
0711 
0712                     ++ start;
0713                 }
0714 
0715                 return true;
0716             }
0717 
0718         private:
0719             // Not optimised converter
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                 /* Some compilers and libraries successfully
0726                  * parse 'inf', 'INFINITY', '1.0E', '1.0E-'...
0727                  * We are trying to provide a unified behaviour,
0728                  * so we just forbid such conversions (as some
0729                  * of the most popular compilers/libraries do)
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)                   // 1.0e
0738                         || Traits::eq(*(finish-1), capital_e)                  // 1.0E
0739                         || Traits::eq(*(finish-1), minus)                      // 1.0e- or 1.0E-
0740                         || Traits::eq(*(finish-1), plus)                       // 1.0e+ or 1.0E+
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             // Generic istream-based algorithm.
0753             // lcast_streambuf_for_target<InputStreamable>::value is true.
0754             template <typename InputStreamable>
0755             bool operator>>(InputStreamable& output) {
0756                 return shr_using_base_class(output);
0757             }
0758         };
0759     }
0760 } // namespace boost
0761 
0762 #undef BOOST_LCAST_NO_WCHAR_T
0763 
0764 #endif // BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_HPP
0765