BVB Source Codes

mars Show converter_lexical_streams.hpp Source code

Return Download mars: download converter_lexical_streams.hpp Source code - Download mars Source code - Type:.hpp
  1. // Copyright Kevlin Henney, 2000-2005.
  2. // Copyright Alexander Nasonov, 2006-2010.
  3. // Copyright Antony Polukhin, 2011-2014.
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // what:  lexical_cast custom keyword cast
  10. // who:   contributed by Kevlin Henney,
  11. //        enhanced with contributions from Terje Slettebo,
  12. //        with additional fixes and suggestions from Gennaro Prota,
  13. //        Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
  14. //        Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
  15. //        Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
  16. // when:  November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
  17.  
  18. #ifndef BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_STREAMS_HPP
  19. #define BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_STREAMS_HPP
  20.  
  21. #include <boost/config.hpp>
  22. #ifdef BOOST_HAS_PRAGMA_ONCE
  23. #   pragma once
  24. #endif
  25.  
  26.  
  27. #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
  28. #define BOOST_LCAST_NO_WCHAR_T
  29. #endif
  30.  
  31. #include <cstddef>
  32. #include <string>
  33. #include <cstring>
  34. #include <cstdio>
  35. #include <boost/limits.hpp>
  36. #include <boost/mpl/if.hpp>
  37. #include <boost/type_traits/is_pointer.hpp>
  38. #include <boost/static_assert.hpp>
  39. #include <boost/detail/workaround.hpp>
  40.  
  41.  
  42. #ifndef BOOST_NO_STD_LOCALE
  43. #   include <locale>
  44. #else
  45. #   ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
  46.         // Getting error at this point means, that your STL library is old/lame/misconfigured.
  47.         // If nothing can be done with STL library, define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE,
  48.         // but beware: lexical_cast will understand only 'C' locale delimeters and thousands
  49.         // separators.
  50. #       error "Unable to use <locale> header. Define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE to force "
  51. #       error "mars_boost::lexical_cast to use only 'C' locale during conversions."
  52. #   endif
  53. #endif
  54.  
  55. #ifdef BOOST_NO_STRINGSTREAM
  56. #include <strstream>
  57. #else
  58. #include <sstream>
  59. #endif
  60.  
  61. #include <boost/lexical_cast/detail/lcast_char_constants.hpp>
  62. #include <boost/lexical_cast/detail/lcast_unsigned_converters.hpp>
  63. #include <boost/lexical_cast/detail/inf_nan.hpp>
  64.  
  65. #include <istream>
  66.  
  67. #ifndef BOOST_NO_CXX11_HDR_ARRAY
  68. #include <array>
  69. #endif
  70.  
  71. #include <boost/array.hpp>
  72. #include <boost/type_traits/make_unsigned.hpp>
  73. #include <boost/type_traits/is_integral.hpp>
  74. #include <boost/type_traits/is_float.hpp>
  75. #include <boost/range/iterator_range_core.hpp>
  76. #include <boost/container/container_fwd.hpp>
  77. #include <boost/integer.hpp>
  78. #include <boost/detail/basic_pointerbuf.hpp>
  79. #include <boost/noncopyable.hpp>
  80. #ifndef BOOST_NO_CWCHAR
  81. #   include <cwchar>
  82. #endif
  83.  
  84. namespace mars_boost {} namespace boost = mars_boost; namespace mars_boost {
  85.  
  86.     namespace detail // basic_unlockedbuf
  87.     {
  88.         // acts as a stream buffer which wraps around a pair of pointers
  89.         // and gives acces to internals
  90.         template <class BufferType, class CharT>
  91.         class basic_unlockedbuf : public basic_pointerbuf<CharT, BufferType> {
  92.         public:
  93.            typedef basic_pointerbuf<CharT, BufferType> base_type;
  94.            typedef BOOST_DEDUCED_TYPENAME base_type::streamsize streamsize;
  95.  
  96. #ifndef BOOST_NO_USING_TEMPLATE
  97.             using base_type::pptr;
  98.             using base_type::pbase;
  99.             using base_type::setbuf;
  100. #else
  101.             charT* pptr() const { return base_type::pptr(); }
  102.             charT* pbase() const { return base_type::pbase(); }
  103.             BufferType* setbuf(char_type* s, streamsize n) { return base_type::setbuf(s, n); }
  104. #endif
  105.         };
  106.     }
  107.  
  108.     namespace detail
  109.     {
  110.         struct do_not_construct_out_stream_t{};
  111.        
  112.         template <class CharT, class Traits>
  113.         struct out_stream_helper_trait {
  114. #if defined(BOOST_NO_STRINGSTREAM)
  115.             typedef std::ostrstream                                 out_stream_t;
  116.             typedef void                                            buffer_t;
  117. #elif defined(BOOST_NO_STD_LOCALE)
  118.             typedef std::ostringstream                              out_stream_t;
  119.             typedef basic_unlockedbuf<std::streambuf, char>         buffer_t;
  120. #else
  121.             typedef std::basic_ostringstream<CharT, Traits>
  122.                 out_stream_t;
  123.             typedef basic_unlockedbuf<std::basic_streambuf<CharT, Traits>, CharT>  
  124.                 buffer_t;
  125. #endif
  126.         };  
  127.     }
  128.  
  129.     namespace detail // optimized stream wrappers
  130.     {
  131.         template< class CharT // a result of widest_char transformation
  132.                 , class Traits
  133.                 , bool RequiresStringbuffer
  134.                 , std::size_t CharacterBufferSize
  135.                 >
  136.         class lexical_istream_limited_src: mars_boost::noncopyable {
  137.             typedef BOOST_DEDUCED_TYPENAME out_stream_helper_trait<CharT, Traits>::buffer_t
  138.                 buffer_t;
  139.  
  140.             typedef BOOST_DEDUCED_TYPENAME out_stream_helper_trait<CharT, Traits>::out_stream_t
  141.                 out_stream_t;
  142.    
  143.             typedef BOOST_DEDUCED_TYPENAME mars_boost::mpl::if_c<
  144.                 RequiresStringbuffer,
  145.                 out_stream_t,
  146.                 do_not_construct_out_stream_t
  147.             >::type deduced_out_stream_t;
  148.  
  149.             // A string representation of Source is written to `buffer`.
  150.             deduced_out_stream_t out_stream;
  151.             CharT   buffer[CharacterBufferSize];
  152.  
  153.             // After the `operator <<`  finishes, `[start, finish)` is
  154.             // the range to output by `operator >>`
  155.             const CharT*  start;
  156.             const CharT*  finish;
  157.  
  158.         public:
  159.             lexical_istream_limited_src() BOOST_NOEXCEPT
  160.               : start(buffer)
  161.               , finish(buffer + CharacterBufferSize)
  162.             {}
  163.    
  164.             const CharT* cbegin() const BOOST_NOEXCEPT {
  165.                 return start;
  166.             }
  167.  
  168.             const CharT* cend() const BOOST_NOEXCEPT {
  169.                 return finish;
  170.             }
  171.  
  172.         private:
  173.             // Undefined:
  174.             lexical_istream_limited_src(lexical_istream_limited_src const&);
  175.             void operator=(lexical_istream_limited_src const&);
  176.  
  177. /************************************ HELPER FUNCTIONS FOR OPERATORS << ( ... ) ********************************/
  178.             bool shl_char(CharT ch) BOOST_NOEXCEPT {
  179.                 Traits::assign(buffer[0], ch);
  180.                 finish = start + 1;
  181.                 return true;
  182.             }
  183.  
  184. #ifndef BOOST_LCAST_NO_WCHAR_T
  185.             template <class T>
  186.             bool shl_char(T ch) {
  187.                 BOOST_STATIC_ASSERT_MSG(( sizeof(T) <= sizeof(CharT)) ,
  188.                     "mars_boost::lexical_cast does not support narrowing of char types."
  189.                     "Use mars_boost::locale instead" );
  190. #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
  191.                 std::locale loc;
  192.                 CharT const w = BOOST_USE_FACET(std::ctype<CharT>, loc).widen(ch);
  193. #else
  194.                 CharT const w = static_cast<CharT>(ch);
  195. #endif
  196.                 Traits::assign(buffer[0], w);
  197.                 finish = start + 1;
  198.                 return true;
  199.             }
  200. #endif
  201.  
  202.             bool shl_char_array(CharT const* str) BOOST_NOEXCEPT {
  203.                 start = str;
  204.                 finish = start + Traits::length(str);
  205.                 return true;
  206.             }
  207.  
  208.             template <class T>
  209.             bool shl_char_array(T const* str) {
  210.                 BOOST_STATIC_ASSERT_MSG(( sizeof(T) <= sizeof(CharT)),
  211.                     "mars_boost::lexical_cast does not support narrowing of char types."
  212.                     "Use mars_boost::locale instead" );
  213.                 return shl_input_streamable(str);
  214.             }
  215.            
  216.             bool shl_char_array_limited(CharT const* str, std::size_t max_size) BOOST_NOEXCEPT {
  217.                 start = str;
  218.                 finish = std::find(start, start + max_size, Traits::to_char_type(0));
  219.                 return true;
  220.             }
  221.  
  222.             template<typename InputStreamable>
  223.             bool shl_input_streamable(InputStreamable& input) {
  224. #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_LOCALE)
  225.                 // If you have compilation error at this point, than your STL library
  226.                 // does not support such conversions. Try updating it.
  227.                 BOOST_STATIC_ASSERT((mars_boost::is_same<char, CharT>::value));
  228. #endif
  229.  
  230. #ifndef BOOST_NO_EXCEPTIONS
  231.                 out_stream.exceptions(std::ios::badbit);
  232.                 try {
  233. #endif
  234.                 bool const result = !(out_stream << input).fail();
  235.                 const buffer_t* const p = static_cast<buffer_t*>(
  236.                     static_cast<std::basic_streambuf<CharT, Traits>*>(out_stream.rdbuf())
  237.                 );
  238.                 start = p->pbase();
  239.                 finish = p->pptr();
  240.                 return result;
  241. #ifndef BOOST_NO_EXCEPTIONS
  242.                 } catch (const ::std::ios_base::failure& /*f*/) {
  243.                     return false;
  244.                 }
  245. #endif
  246.             }
  247.  
  248.             template <class T>
  249.             inline bool shl_unsigned(const T n) {
  250.                 CharT* tmp_finish = buffer + CharacterBufferSize;
  251.                 start = lcast_put_unsigned<Traits, T, CharT>(n, tmp_finish).convert();
  252.                 finish = tmp_finish;
  253.                 return true;
  254.             }
  255.  
  256.             template <class T>
  257.             inline bool shl_signed(const T n) {
  258.                 CharT* tmp_finish = buffer + CharacterBufferSize;
  259.                 typedef BOOST_DEDUCED_TYPENAME mars_boost::make_unsigned<T>::type utype;
  260.                 CharT* tmp_start = lcast_put_unsigned<Traits, utype, CharT>(lcast_to_unsigned(n), tmp_finish).convert();
  261.                 if (n < 0) {
  262.                     --tmp_start;
  263.                     CharT const minus = lcast_char_constants<CharT>::minus;
  264.                     Traits::assign(*tmp_start, minus);
  265.                 }
  266.                 start = tmp_start;
  267.                 finish = tmp_finish;
  268.                 return true;
  269.             }
  270.  
  271.             template <class T, class SomeCharT>
  272.             bool shl_real_type(const T& val, SomeCharT* /*begin*/) {
  273.                 lcast_set_precision(out_stream, &val);
  274.                 return shl_input_streamable(val);
  275.             }
  276.  
  277.             bool shl_real_type(float val, char* begin) {
  278.                 using namespace std;
  279.                 const double val_as_double = val;
  280.                 finish = start +
  281. #if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
  282.                     sprintf_s(begin, CharacterBufferSize,
  283. #else
  284.                     sprintf(begin,
  285. #endif
  286.                     "%.*g", static_cast<int>(mars_boost::detail::lcast_get_precision<float>()), val_as_double);
  287.                 return finish > start;
  288.             }
  289.  
  290.             bool shl_real_type(double val, char* begin) {
  291.                 using namespace std;
  292.                 finish = start +
  293. #if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
  294.                     sprintf_s(begin, CharacterBufferSize,
  295. #else
  296.                     sprintf(begin,
  297. #endif
  298.                     "%.*g", static_cast<int>(mars_boost::detail::lcast_get_precision<double>()), val);
  299.                 return finish > start;
  300.             }
  301.  
  302. #ifndef __MINGW32__
  303.             bool shl_real_type(long double val, char* begin) {
  304.                 using namespace std;
  305.                 finish = start +
  306. #if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
  307.                     sprintf_s(begin, CharacterBufferSize,
  308. #else
  309.                     sprintf(begin,
  310. #endif
  311.                     "%.*Lg", static_cast<int>(mars_boost::detail::lcast_get_precision<long double>()), val );
  312.                 return finish > start;
  313.             }
  314. #endif
  315.  
  316.  
  317. #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_SWPRINTF) && !defined(__MINGW32__)
  318.             bool shl_real_type(float val, wchar_t* begin) {
  319.                 using namespace std;
  320.                 const double val_as_double = val;
  321.                 finish = start + swprintf(begin, CharacterBufferSize,
  322.                                        L"%.*g",
  323.                                        static_cast<int>(mars_boost::detail::lcast_get_precision<float >()),
  324.                                        val_as_double );
  325.                 return finish > start;
  326.             }
  327.  
  328.             bool shl_real_type(double val, wchar_t* begin) {
  329.                 using namespace std;
  330.                 finish = start + swprintf(begin, CharacterBufferSize,
  331.                                           L"%.*g", static_cast<int>(mars_boost::detail::lcast_get_precision<double >()), val );
  332.                 return finish > start;
  333.             }
  334.  
  335.             bool shl_real_type(long double val, wchar_t* begin) {
  336.                 using namespace std;
  337.                 finish = start + swprintf(begin, CharacterBufferSize,
  338.                                           L"%.*Lg", static_cast<int>(mars_boost::detail::lcast_get_precision<long double >()), val );
  339.                 return finish > start;
  340.             }
  341. #endif
  342.             template <class T>
  343.             bool shl_real(T val) {
  344.                 CharT* tmp_finish = buffer + CharacterBufferSize;
  345.                 if (put_inf_nan(buffer, tmp_finish, val)) {
  346.                     finish = tmp_finish;
  347.                     return true;
  348.                 }
  349.  
  350.                 return shl_real_type(val, static_cast<CharT*>(buffer));
  351.             }
  352.  
  353. /************************************ OPERATORS << ( ... ) ********************************/
  354.         public:
  355.             template<class Alloc>
  356.             bool operator<<(std::basic_string<CharT,Traits,Alloc> const& str) BOOST_NOEXCEPT {
  357.                 start = str.data();
  358.                 finish = start + str.length();
  359.                 return true;
  360.             }
  361.  
  362.             template<class Alloc>
  363.             bool operator<<(mars_boost::container::basic_string<CharT,Traits,Alloc> const& str) BOOST_NOEXCEPT {
  364.                 start = str.data();
  365.                 finish = start + str.length();
  366.                 return true;
  367.             }
  368.  
  369.             bool operator<<(bool value) BOOST_NOEXCEPT {
  370.                 CharT const czero = lcast_char_constants<CharT>::zero;
  371.                 Traits::assign(buffer[0], Traits::to_char_type(czero + value));
  372.                 finish = start + 1;
  373.                 return true;
  374.             }
  375.  
  376.             template <class C>
  377.             BOOST_DEDUCED_TYPENAME mars_boost::disable_if<mars_boost::is_const<C>, bool>::type
  378.             operator<<(const iterator_range<C*>& rng) BOOST_NOEXCEPT {
  379.                 return (*this) << iterator_range<const C*>(rng.begin(), rng.end());
  380.             }
  381.            
  382.             bool operator<<(const iterator_range<const CharT*>& rng) BOOST_NOEXCEPT {
  383.                 start = rng.begin();
  384.                 finish = rng.end();
  385.                 return true;
  386.             }
  387.  
  388.             bool operator<<(const iterator_range<const signed char*>& rng) BOOST_NOEXCEPT {
  389.                 return (*this) << iterator_range<const char*>(
  390.                     reinterpret_cast<const char*>(rng.begin()),
  391.                     reinterpret_cast<const char*>(rng.end())
  392.                 );
  393.             }
  394.  
  395.             bool operator<<(const iterator_range<const unsigned char*>& rng) BOOST_NOEXCEPT {
  396.                 return (*this) << iterator_range<const char*>(
  397.                     reinterpret_cast<const char*>(rng.begin()),
  398.                     reinterpret_cast<const char*>(rng.end())
  399.                 );
  400.             }
  401.  
  402.             bool operator<<(char ch)                    { return shl_char(ch); }
  403.             bool operator<<(unsigned char ch)           { return ((*this) << static_cast<char>(ch)); }
  404.             bool operator<<(signed char ch)             { return ((*this) << static_cast<char>(ch)); }
  405. #if !defined(BOOST_LCAST_NO_WCHAR_T)
  406.             bool operator<<(wchar_t const* str)         { return shl_char_array(str); }
  407.             bool operator<<(wchar_t * str)              { return shl_char_array(str); }
  408. #ifndef BOOST_NO_INTRINSIC_WCHAR_T
  409.             bool operator<<(wchar_t ch)                 { return shl_char(ch); }
  410. #endif
  411. #endif
  412. #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
  413.             bool operator<<(char16_t ch)                { return shl_char(ch); }
  414.             bool operator<<(char16_t * str)             { return shl_char_array(str); }
  415.             bool operator<<(char16_t const * str)       { return shl_char_array(str); }
  416. #endif
  417. #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
  418.             bool operator<<(char32_t ch)                { return shl_char(ch); }
  419.             bool operator<<(char32_t * str)             { return shl_char_array(str); }
  420.             bool operator<<(char32_t const * str)       { return shl_char_array(str); }
  421. #endif
  422.             bool operator<<(unsigned char const* ch)    { return ((*this) << reinterpret_cast<char const*>(ch)); }
  423.             bool operator<<(unsigned char * ch)         { return ((*this) << reinterpret_cast<char *>(ch)); }
  424.             bool operator<<(signed char const* ch)      { return ((*this) << reinterpret_cast<char const*>(ch)); }
  425.             bool operator<<(signed char * ch)           { return ((*this) << reinterpret_cast<char *>(ch)); }
  426.             bool operator<<(char const* str)            { return shl_char_array(str); }
  427.             bool operator<<(char* str)                  { return shl_char_array(str); }
  428.             bool operator<<(short n)                    { return shl_signed(n); }
  429.             bool operator<<(int n)                      { return shl_signed(n); }
  430.             bool operator<<(long n)                     { return shl_signed(n); }
  431.             bool operator<<(unsigned short n)           { return shl_unsigned(n); }
  432.             bool operator<<(unsigned int n)             { return shl_unsigned(n); }
  433.             bool operator<<(unsigned long n)            { return shl_unsigned(n); }
  434.  
  435. #if defined(BOOST_HAS_LONG_LONG)
  436.             bool operator<<(mars_boost::ulong_long_type n)   { return shl_unsigned(n); }
  437.             bool operator<<(mars_boost::long_long_type n)    { return shl_signed(n); }
  438. #elif defined(BOOST_HAS_MS_INT64)
  439.             bool operator<<(unsigned __int64 n)         { return shl_unsigned(n); }
  440.             bool operator<<(         __int64 n)         { return shl_signed(n); }
  441. #endif
  442.  
  443. #ifdef BOOST_HAS_INT128
  444.             bool operator<<(const mars_boost::uint128_type& n)   { return shl_unsigned(n); }
  445.             bool operator<<(const mars_boost::int128_type& n)    { return shl_signed(n); }
  446. #endif
  447.             bool operator<<(float val)                  { return shl_real(val); }
  448.             bool operator<<(double val)                 { return shl_real(val); }
  449.             bool operator<<(long double val)            {
  450. #ifndef __MINGW32__
  451.                 return shl_real(val);
  452. #else
  453.                 return shl_real(static_cast<double>(val));
  454. #endif
  455.             }
  456.            
  457.             // Adding constness to characters. Constness does not change layout
  458.             template <class C, std::size_t N>
  459.             BOOST_DEDUCED_TYPENAME mars_boost::disable_if<mars_boost::is_const<C>, bool>::type
  460.             operator<<(mars_boost::array<C, N> const& input) BOOST_NOEXCEPT {
  461.                 BOOST_STATIC_ASSERT_MSG(
  462.                     (sizeof(mars_boost::array<const C, N>) == sizeof(mars_boost::array<C, N>)),
  463.                     "mars_boost::array<C, N> and mars_boost::array<const C, N> must have exactly the same layout."
  464.                 );
  465.                 return ((*this) << reinterpret_cast<mars_boost::array<const C, N> const& >(input));
  466.             }
  467.  
  468.             template <std::size_t N>
  469.             bool operator<<(mars_boost::array<const CharT, N> const& input) BOOST_NOEXCEPT {
  470.                 return shl_char_array_limited(input.begin(), N);
  471.             }
  472.  
  473.             template <std::size_t N>
  474.             bool operator<<(mars_boost::array<const unsigned char, N> const& input) BOOST_NOEXCEPT {
  475.                 return ((*this) << reinterpret_cast<mars_boost::array<const char, N> const& >(input));
  476.             }
  477.  
  478.             template <std::size_t N>
  479.             bool operator<<(mars_boost::array<const signed char, N> const& input) BOOST_NOEXCEPT {
  480.                 return ((*this) << reinterpret_cast<mars_boost::array<const char, N> const& >(input));
  481.             }
  482.  
  483. #ifndef BOOST_NO_CXX11_HDR_ARRAY
  484.             // Making a Boost.Array from std::array
  485.             template <class C, std::size_t N>
  486.             bool operator<<(std::array<C, N> const& input) BOOST_NOEXCEPT {
  487.                 BOOST_STATIC_ASSERT_MSG(
  488.                     (sizeof(std::array<C, N>) == sizeof(mars_boost::array<C, N>)),
  489.                     "std::array and mars_boost::array must have exactly the same layout. "
  490.                     "Bug in implementation of std::array or mars_boost::array."
  491.                 );
  492.                 return ((*this) << reinterpret_cast<mars_boost::array<C, N> const& >(input));
  493.             }
  494. #endif
  495.             template <class InStreamable>
  496.             bool operator<<(const InStreamable& input)  { return shl_input_streamable(input); }
  497.         };
  498.  
  499.  
  500.         template <class CharT, class Traits>
  501.         class lexical_ostream_limited_src: mars_boost::noncopyable {
  502.             //`[start, finish)` is the range to output by `operator >>`
  503.             const CharT*        start;
  504.             const CharT* const  finish;
  505.  
  506.         public:
  507.             lexical_ostream_limited_src(const CharT* begin, const CharT* end) BOOST_NOEXCEPT
  508.               : start(begin)
  509.               , finish(end)
  510.             {}
  511.  
  512. /************************************ HELPER FUNCTIONS FOR OPERATORS >> ( ... ) ********************************/
  513.         private:
  514.             template <typename Type>
  515.             bool shr_unsigned(Type& output) {
  516.                 if (start == finish) return false;
  517.                 CharT const minus = lcast_char_constants<CharT>::minus;
  518.                 CharT const plus = lcast_char_constants<CharT>::plus;
  519.                 bool const has_minus = Traits::eq(minus, *start);
  520.  
  521.                 /* We won`t use `start' any more, so no need in decrementing it after */
  522.                 if (has_minus || Traits::eq(plus, *start)) {
  523.                     ++start;
  524.                 }
  525.  
  526.                 bool const succeed = lcast_ret_unsigned<Traits, Type, CharT>(output, start, finish).convert();
  527.  
  528.                 if (has_minus) {
  529.                     output = static_cast<Type>(0u - output);
  530.                 }
  531.  
  532.                 return succeed;
  533.             }
  534.  
  535.             template <typename Type>
  536.             bool shr_signed(Type& output) {
  537.                 if (start == finish) return false;
  538.                 CharT const minus = lcast_char_constants<CharT>::minus;
  539.                 CharT const plus = lcast_char_constants<CharT>::plus;
  540.                 typedef BOOST_DEDUCED_TYPENAME make_unsigned<Type>::type utype;
  541.                 utype out_tmp = 0;
  542.                 bool const has_minus = Traits::eq(minus, *start);
  543.  
  544.                 /* We won`t use `start' any more, so no need in decrementing it after */
  545.                 if (has_minus || Traits::eq(plus, *start)) {
  546.                     ++start;
  547.                 }
  548.  
  549.                 bool succeed = lcast_ret_unsigned<Traits, utype, CharT>(out_tmp, start, finish).convert();
  550.                 if (has_minus) {
  551.                     utype const comp_val = (static_cast<utype>(1) << std::numeric_limits<Type>::digits);
  552.                     succeed = succeed && out_tmp<=comp_val;
  553.                     output = static_cast<Type>(0u - out_tmp);
  554.                 } else {
  555.                     utype const comp_val = static_cast<utype>((std::numeric_limits<Type>::max)());
  556.                     succeed = succeed && out_tmp<=comp_val;
  557.                     output = static_cast<Type>(out_tmp);
  558.                 }
  559.                 return succeed;
  560.             }
  561.  
  562.             template<typename InputStreamable>
  563.             bool shr_using_base_class(InputStreamable& output)
  564.             {
  565.                 BOOST_STATIC_ASSERT_MSG(
  566.                     (!mars_boost::is_pointer<InputStreamable>::value),
  567.                     "mars_boost::lexical_cast can not convert to pointers"
  568.                 );
  569.  
  570. #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_LOCALE)
  571.                 BOOST_STATIC_ASSERT_MSG((mars_boost::is_same<char, CharT>::value),
  572.                     "mars_boost::lexical_cast can not convert, because your STL library does not "
  573.                     "support such conversions. Try updating it."
  574.                 );
  575. #endif
  576.                 typedef BOOST_DEDUCED_TYPENAME out_stream_helper_trait<CharT, Traits>::buffer_t
  577.                     buffer_t;
  578.  
  579. #if defined(BOOST_NO_STRINGSTREAM)
  580.                 std::istrstream stream(start, finish - start);
  581. #else
  582.  
  583.                 buffer_t buf;
  584.                 // Usually `istream` and `basic_istream` do not modify
  585.                 // content of buffer; `buffer_t` assures that this is true
  586.                 buf.setbuf(const_cast<CharT*>(start), finish - start);
  587. #if defined(BOOST_NO_STD_LOCALE)
  588.                 std::istream stream(&buf);
  589. #else
  590.                 std::basic_istream<CharT, Traits> stream(&buf);
  591. #endif // BOOST_NO_STD_LOCALE
  592. #endif // BOOST_NO_STRINGSTREAM
  593.  
  594. #ifndef BOOST_NO_EXCEPTIONS
  595.                 stream.exceptions(std::ios::badbit);
  596.                 try {
  597. #endif
  598.                 stream.unsetf(std::ios::skipws);
  599.                 lcast_set_precision(stream, static_cast<InputStreamable*>(0));
  600.  
  601.                 return (stream >> output)
  602.                     && (stream.get() == Traits::eof());
  603.  
  604. #ifndef BOOST_NO_EXCEPTIONS
  605.                 } catch (const ::std::ios_base::failure& /*f*/) {
  606.                     return false;
  607.                 }
  608. #endif
  609.             }
  610.  
  611.             template<class T>
  612.             inline bool shr_xchar(T& output) BOOST_NOEXCEPT {
  613.                 BOOST_STATIC_ASSERT_MSG(( sizeof(CharT) == sizeof(T) ),
  614.                     "mars_boost::lexical_cast does not support narrowing of character types."
  615.                     "Use mars_boost::locale instead" );
  616.                 bool const ok = (finish - start == 1);
  617.                 if (ok) {
  618.                     CharT out;
  619.                     Traits::assign(out, *start);
  620.                     output = static_cast<T>(out);
  621.                 }
  622.                 return ok;
  623.             }
  624.  
  625.             template <std::size_t N, class ArrayT>
  626.             bool shr_std_array(ArrayT& output) BOOST_NOEXCEPT {
  627.                 using namespace std;
  628.                 const std::size_t size = static_cast<std::size_t>(finish - start);
  629.                 if (size > N - 1) { // `-1` because we need to store \0 at the end
  630.                     return false;
  631.                 }
  632.  
  633.                 memcpy(&output[0], start, size * sizeof(CharT));
  634.                 output[size] = Traits::to_char_type(0);
  635.                 return true;
  636.             }
  637.  
  638. /************************************ OPERATORS >> ( ... ) ********************************/
  639.         public:
  640.             bool operator>>(unsigned short& output)             { return shr_unsigned(output); }
  641.             bool operator>>(unsigned int& output)               { return shr_unsigned(output); }
  642.             bool operator>>(unsigned long int& output)          { return shr_unsigned(output); }
  643.             bool operator>>(short& output)                      { return shr_signed(output); }
  644.             bool operator>>(int& output)                        { return shr_signed(output); }
  645.             bool operator>>(long int& output)                   { return shr_signed(output); }
  646. #if defined(BOOST_HAS_LONG_LONG)
  647.             bool operator>>(mars_boost::ulong_long_type& output)     { return shr_unsigned(output); }
  648.             bool operator>>(mars_boost::long_long_type& output)      { return shr_signed(output); }
  649. #elif defined(BOOST_HAS_MS_INT64)
  650.             bool operator>>(unsigned __int64& output)           { return shr_unsigned(output); }
  651.             bool operator>>(__int64& output)                    { return shr_signed(output); }
  652. #endif
  653.  
  654. #ifdef BOOST_HAS_INT128
  655.             bool operator>>(mars_boost::uint128_type& output)        { return shr_unsigned(output); }
  656.             bool operator>>(mars_boost::int128_type& output)         { return shr_signed(output); }
  657. #endif
  658.  
  659.             bool operator>>(char& output)                       { return shr_xchar(output); }
  660.             bool operator>>(unsigned char& output)              { return shr_xchar(output); }
  661.             bool operator>>(signed char& output)                { return shr_xchar(output); }
  662. #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
  663.             bool operator>>(wchar_t& output)                    { return shr_xchar(output); }
  664. #endif
  665. #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
  666.             bool operator>>(char16_t& output)                   { return shr_xchar(output); }
  667. #endif
  668. #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
  669.             bool operator>>(char32_t& output)                   { return shr_xchar(output); }
  670. #endif
  671.             template<class Alloc>
  672.             bool operator>>(std::basic_string<CharT,Traits,Alloc>& str) {
  673.                 str.assign(start, finish); return true;
  674.             }
  675.  
  676.             template<class Alloc>
  677.             bool operator>>(mars_boost::container::basic_string<CharT,Traits,Alloc>& str) {
  678.                 str.assign(start, finish); return true;
  679.             }
  680.  
  681.             template <std::size_t N>
  682.             bool operator>>(mars_boost::array<CharT, N>& output) BOOST_NOEXCEPT {
  683.                 return shr_std_array<N>(output);
  684.             }
  685.  
  686.             template <std::size_t N>
  687.             bool operator>>(mars_boost::array<unsigned char, N>& output) BOOST_NOEXCEPT {
  688.                 return ((*this) >> reinterpret_cast<mars_boost::array<char, N>& >(output));
  689.             }
  690.  
  691.             template <std::size_t N>
  692.             bool operator>>(mars_boost::array<signed char, N>& output) BOOST_NOEXCEPT {
  693.                 return ((*this) >> reinterpret_cast<mars_boost::array<char, N>& >(output));
  694.             }
  695.  
  696. #ifndef BOOST_NO_CXX11_HDR_ARRAY
  697.             template <class C, std::size_t N>
  698.             bool operator>>(std::array<C, N>& output) BOOST_NOEXCEPT {
  699.                 BOOST_STATIC_ASSERT_MSG(
  700.                     (sizeof(mars_boost::array<C, N>) == sizeof(mars_boost::array<C, N>)),
  701.                     "std::array<C, N> and mars_boost::array<C, N> must have exactly the same layout."
  702.                 );
  703.                 return ((*this) >> reinterpret_cast<mars_boost::array<C, N>& >(output));
  704.             }
  705. #endif
  706.  
  707.             bool operator>>(bool& output) BOOST_NOEXCEPT {
  708.                 output = false; // Suppress warning about uninitalized variable
  709.  
  710.                 if (start == finish) return false;
  711.                 CharT const zero = lcast_char_constants<CharT>::zero;
  712.                 CharT const plus = lcast_char_constants<CharT>::plus;
  713.                 CharT const minus = lcast_char_constants<CharT>::minus;
  714.  
  715.                 const CharT* const dec_finish = finish - 1;
  716.                 output = Traits::eq(*dec_finish, zero + 1);
  717.                 if (!output && !Traits::eq(*dec_finish, zero)) {
  718.                     return false; // Does not ends on '0' or '1'
  719.                 }
  720.  
  721.                 if (start == dec_finish) return true;
  722.  
  723.                 // We may have sign at the beginning
  724.                 if (Traits::eq(plus, *start) || (Traits::eq(minus, *start) && !output)) {
  725.                     ++ start;
  726.                 }
  727.  
  728.                 // Skipping zeros
  729.                 while (start != dec_finish) {
  730.                     if (!Traits::eq(zero, *start)) {
  731.                         return false; // Not a zero => error
  732.                     }
  733.  
  734.                     ++ start;
  735.                 }
  736.  
  737.                 return true;
  738.             }
  739.  
  740.         private:
  741.             // Not optimised converter
  742.             template <class T>
  743.             bool float_types_converter_internal(T& output) {
  744.                 if (parse_inf_nan(start, finish, output)) return true;
  745.                 bool const return_value = shr_using_base_class(output);
  746.  
  747.                 /* Some compilers and libraries successfully
  748.                  * parse 'inf', 'INFINITY', '1.0E', '1.0E-'...
  749.                  * We are trying to provide a unified behaviour,
  750.                  * so we just forbid such conversions (as some
  751.                  * of the most popular compilers/libraries do)
  752.                  * */
  753.                 CharT const minus = lcast_char_constants<CharT>::minus;
  754.                 CharT const plus = lcast_char_constants<CharT>::plus;
  755.                 CharT const capital_e = lcast_char_constants<CharT>::capital_e;
  756.                 CharT const lowercase_e = lcast_char_constants<CharT>::lowercase_e;
  757.                 if ( return_value &&
  758.                      (
  759.                         Traits::eq(*(finish-1), lowercase_e)                   // 1.0e
  760.                         || Traits::eq(*(finish-1), capital_e)                  // 1.0E
  761.                         || Traits::eq(*(finish-1), minus)                      // 1.0e- or 1.0E-
  762.                         || Traits::eq(*(finish-1), plus)                       // 1.0e+ or 1.0E+
  763.                      )
  764.                 ) return false;
  765.  
  766.                 return return_value;
  767.             }
  768.  
  769.         public:
  770.             bool operator>>(float& output) { return float_types_converter_internal(output); }
  771.             bool operator>>(double& output) { return float_types_converter_internal(output); }
  772.             bool operator>>(long double& output) { return float_types_converter_internal(output); }
  773.  
  774.             // Generic istream-based algorithm.
  775.             // lcast_streambuf_for_target<InputStreamable>::value is true.
  776.             template <typename InputStreamable>
  777.             bool operator>>(InputStreamable& output) {
  778.                 return shr_using_base_class(output);
  779.             }
  780.         };
  781.     }
  782. } // namespace mars_boost
  783.  
  784. #undef BOOST_LCAST_NO_WCHAR_T
  785.  
  786. #endif // BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_HPP
  787.  
  788.  
downloadconverter_lexical_streams.hpp Source code - Download mars Source code
Related Source Codes/Software:
Hero - Elegant transition library for iOS & tvOS 2017-06-09
deep-photo-styletransfer - Code and data for paper "Deep Photo Style Transfer... 2017-06-09
mastodon - A GNU Social-compatible microblogging server ... 2017-06-09
plyr - A simple HTML5, YouTube and Vimeo player ... 2017-06-08
prepack - Prepack is a partial evaluator for JavaScript. Pre... 2017-06-08
Public-APIs - 2017-06-09
lottie-ios - An iOS library to natively render After Effects ve... 2017-06-09
Awesome-Hacking - A collection of various awesome lists for hackers,... 2017-06-09
algorithms - Minimal examples of data structures and algorithms... 2017-06-10
lectures - Oxford Deep NLP 2017 course 2017-06-10
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top