diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index acfc3e8..892dd9c 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -18,7 +18,7 @@ // with additional fixes and suggestions from Gennaro Prota, // Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov, // Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann, -// Cheng Yang, Matthew Bradbury, David W. Birdsall and other Boosters +// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters // when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2012 #include @@ -47,8 +47,12 @@ # include #else # ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE -# warning "Unable to use header. boost::lexical_cast will use the 'C' locale." -# define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE + // Getting error at this point means, that your STL library is old/lame/misconfigured. + // If nothing can be done with STL library, define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE, + // but beware: lexical_cast will understand only 'C' locale delimeters and thousands + // separators. +# error "Unable to use header. Define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE to force " +# error "boost::lexical_cast to use only 'C' locale during conversions." # endif #endif @@ -83,7 +87,7 @@ namespace boost { public: - bad_lexical_cast() : + bad_lexical_cast() BOOST_NOEXCEPT : #ifndef BOOST_NO_TYPEID source(&typeid(void)), target(&typeid(void)) #else @@ -94,7 +98,7 @@ namespace boost bad_lexical_cast( const std::type_info &source_type_arg, - const std::type_info &target_type_arg) : + const std::type_info &target_type_arg) BOOST_NOEXCEPT : source(&source_type_arg), target(&target_type_arg) { } @@ -108,14 +112,22 @@ namespace boost return *target; } +#ifndef BOOST_NO_NOEXCEPT + virtual const char *what() noexcept +#else virtual const char *what() const throw() +#endif { return "bad lexical cast: " "source type value could not be interpreted as target"; } + +#ifndef BOOST_NO_NOEXCEPT + virtual ~bad_lexical_cast() BOOST_NOEXCEPT +#else virtual ~bad_lexical_cast() throw() - { - } +#endif + {} private: const std::type_info *source; const std::type_info *target; @@ -570,10 +582,10 @@ namespace boost { #endif template inline - BOOST_DEDUCED_TYPENAME make_unsigned::type lcast_to_unsigned(T value) + BOOST_DEDUCED_TYPENAME make_unsigned::type lcast_to_unsigned(T value) BOOST_NOEXCEPT { typedef BOOST_DEDUCED_TYPENAME make_unsigned::type result_type; - result_type uvalue = static_cast(value); + const result_type uvalue = static_cast(value); return value < 0 ? -uvalue : uvalue; } #if (defined _MSC_VER) @@ -777,7 +789,7 @@ namespace boost { namespace detail { template - bool lc_iequal(const CharT* val, const CharT* lcase, const CharT* ucase, unsigned int len) { + bool lc_iequal(const CharT* val, const CharT* lcase, const CharT* ucase, unsigned int len) BOOST_NOEXCEPT { for( unsigned int i=0; i < len; ++i ) { if ( val[i] != lcase[i] && val[i] != ucase[i] ) return false; } @@ -790,7 +802,7 @@ namespace boost { inline bool parse_inf_nan_impl(const CharT* begin, const CharT* end, T& value , const CharT* lc_NAN, const CharT* lc_nan , const CharT* lc_INFINITY, const CharT* lc_infinity - , const CharT opening_brace, const CharT closing_brace) + , const CharT opening_brace, const CharT closing_brace) BOOST_NOEXCEPT { using namespace std; if (begin == end) return false; @@ -846,7 +858,7 @@ namespace boost { template bool put_inf_nan_impl(CharT* begin, CharT*& end, const T& value , const CharT* lc_nan - , const CharT* lc_infinity) + , const CharT* lc_infinity) BOOST_NOEXCEPT { using namespace std; const CharT minus = lcast_char_constants::minus; @@ -880,7 +892,7 @@ namespace boost { #ifndef BOOST_LCAST_NO_WCHAR_T template - bool parse_inf_nan(const wchar_t* begin, const wchar_t* end, T& value) + bool parse_inf_nan(const wchar_t* begin, const wchar_t* end, T& value) BOOST_NOEXCEPT { return parse_inf_nan_impl(begin, end, value , L"NAN", L"nan" @@ -889,7 +901,7 @@ namespace boost { } template - bool put_inf_nan(wchar_t* begin, wchar_t*& end, const T& value) + bool put_inf_nan(wchar_t* begin, wchar_t*& end, const T& value) BOOST_NOEXCEPT { return put_inf_nan_impl(begin, end, value, L"nan", L"infinity"); } @@ -897,7 +909,7 @@ namespace boost { #endif #if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS) template - bool parse_inf_nan(const char16_t* begin, const char16_t* end, T& value) + bool parse_inf_nan(const char16_t* begin, const char16_t* end, T& value) BOOST_NOEXCEPT { return parse_inf_nan_impl(begin, end, value , u"NAN", u"nan" @@ -906,14 +918,14 @@ namespace boost { } template - bool put_inf_nan(char16_t* begin, char16_t*& end, const T& value) + bool put_inf_nan(char16_t* begin, char16_t*& end, const T& value) BOOST_NOEXCEPT { return put_inf_nan_impl(begin, end, value, u"nan", u"infinity"); } #endif #if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS) template - bool parse_inf_nan(const char32_t* begin, const char32_t* end, T& value) + bool parse_inf_nan(const char32_t* begin, const char32_t* end, T& value) BOOST_NOEXCEPT { return parse_inf_nan_impl(begin, end, value , U"NAN", U"nan" @@ -922,14 +934,14 @@ namespace boost { } template - bool put_inf_nan(char32_t* begin, char32_t*& end, const T& value) + bool put_inf_nan(char32_t* begin, char32_t*& end, const T& value) BOOST_NOEXCEPT { return put_inf_nan_impl(begin, end, value, U"nan", U"infinity"); } #endif template - bool parse_inf_nan(const CharT* begin, const CharT* end, T& value) + bool parse_inf_nan(const CharT* begin, const CharT* end, T& value) BOOST_NOEXCEPT { return parse_inf_nan_impl(begin, end, value , "NAN", "nan" @@ -938,7 +950,7 @@ namespace boost { } template - bool put_inf_nan(CharT* begin, CharT*& end, const T& value) + bool put_inf_nan(CharT* begin, CharT*& end, const T& value) BOOST_NOEXCEPT { return put_inf_nan_impl(begin, end, value, "nan", "infinity"); } @@ -1008,11 +1020,11 @@ namespace boost { /* Getting the plus/minus sign */ bool has_minus = false; - if ( *begin == minus ) { + if (Traits::eq(*begin, minus) ) { ++ begin; has_minus = true; if (begin == end) return false; - } else if ( *begin == plus ) { + } else if (Traits::eq(*begin, plus) ) { ++begin; if (begin == end) return false; } @@ -1031,7 +1043,7 @@ namespace boost { /* We allow no thousand_separators after decimal point */ mantissa_type tmp_mantissa = mantissa * 10u; - if ( *begin == lowercase_e || *begin == capital_e ) break; + if (Traits::eq(*begin, lowercase_e) || Traits::eq(*begin, capital_e)) break; if ( *begin < czero || *begin >= czero + 10 ) return false; if ( is_mantissa_full || tmp_mantissa / 10u != mantissa @@ -1070,7 +1082,7 @@ namespace boost { found_number_before_exp = true; ++ length_since_last_delim; - } else if ( *begin == decimal_point || *begin == lowercase_e || *begin == capital_e) { + } else if (Traits::eq(*begin, decimal_point) || Traits::eq(*begin, lowercase_e) || Traits::eq(*begin, capital_e)) { #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE /* If ( we need to check grouping * and ( grouping missmatches @@ -1088,7 +1100,7 @@ namespace boost { ) return false; #endif - if(*begin == decimal_point) { + if(Traits::eq(*begin, decimal_point)) { ++ begin; found_decimal = true; if (!found_number_before_exp && begin==end) return false; @@ -1099,7 +1111,7 @@ namespace boost { } } #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE - else if (grouping_size && *begin == thousands_sep){ + else if (grouping_size && Traits::eq(*begin, thousands_sep)){ if(found_grouping) { /* It is not he first time, when we find thousands separator, @@ -1141,16 +1153,16 @@ namespace boost { } // Exponent found - if ( begin != end && ( *begin == lowercase_e || *begin == capital_e ) ) { + if ( begin != end && (Traits::eq(*begin, lowercase_e) || Traits::eq(*begin, capital_e)) ) { ++ begin; if ( begin == end ) return false; bool exp_has_minus = false; - if( *begin == minus ) { + if(Traits::eq(*begin, minus)) { exp_has_minus = true; ++ begin; if ( begin == end ) return false; - } else if (*begin == plus ) { + } else if (Traits::eq(*begin, plus)) { ++ begin; if ( begin == end ) return false; } @@ -1258,7 +1270,7 @@ namespace boost { void operator=(lexical_stream_limited_src const&); /************************************ HELPER FUNCTIONS FOR OPERATORS << ( ... ) ********************************/ - bool shl_char(CharT ch) + bool shl_char(CharT ch) BOOST_NOEXCEPT { Traits::assign(*start, ch); finish = start + 1; @@ -1270,13 +1282,13 @@ namespace boost { bool shl_char(T ch) { BOOST_STATIC_ASSERT_MSG(( sizeof(T) <= sizeof(CharT)) , - "boost::lexical_cast does not support conversions from wide character to char types." + "boost::lexical_cast does not support narrowing of char types." "Use boost::locale instead" ); #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE std::locale loc; - wchar_t w = BOOST_USE_FACET(std::ctype, loc).widen(ch); + CharT const w = BOOST_USE_FACET(std::ctype, loc).widen(ch); #else - wchar_t w = ch; + CharT const w = ch; #endif Traits::assign(*start, w); finish = start + 1; @@ -1284,7 +1296,7 @@ namespace boost { } #endif - bool shl_char_array(CharT const* str) + bool shl_char_array(CharT const* str) BOOST_NOEXCEPT { start = const_cast(str); finish = start + Traits::length(str); @@ -1295,15 +1307,15 @@ namespace boost { bool shl_char_array(T const* str) { BOOST_STATIC_ASSERT_MSG(( sizeof(T) <= sizeof(CharT)), - "boost::lexical_cast does not support conversions from wide characters to char types." + "boost::lexical_cast does not support narrowing of char types." "Use boost::locale instead" ); return shl_input_streamable(str); } - bool shl_char_array_limited(CharT const* str, std::size_t max_size) + bool shl_char_array_limited(CharT const* str, std::size_t max_size) BOOST_NOEXCEPT { start = const_cast(str); - finish = std::find(start, start + max_size, static_cast(0)); + finish = std::find(start, start + max_size, Traits::to_char_type(0)); return true; } @@ -1349,7 +1361,7 @@ namespace boost { if (put_inf_nan(begin, end, val)) return true; const double val_as_double = val; end = begin + -#if (defined _MSC_VER) +#if defined(_MSC_VER) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) sprintf_s(begin, end-begin, #else sprintf(begin, @@ -1362,7 +1374,7 @@ namespace boost { { using namespace std; if (put_inf_nan(begin, end, val)) return true; end = begin + -#if (defined _MSC_VER) +#if defined(_MSC_VER) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) sprintf_s(begin, end-begin, #else sprintf(begin, @@ -1376,7 +1388,7 @@ namespace boost { { using namespace std; if (put_inf_nan(begin, end, val)) return true; end = begin + -#if (defined _MSC_VER) +#if defined(_MSC_VER) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) sprintf_s(begin, end-begin, #else sprintf(begin, @@ -1419,7 +1431,7 @@ namespace boost { /************************************ OPERATORS << ( ... ) ********************************/ public: template - bool operator<<(std::basic_string const& str) + bool operator<<(std::basic_string const& str) BOOST_NOEXCEPT { start = const_cast(str.data()); finish = start + str.length(); @@ -1427,14 +1439,14 @@ namespace boost { } template - bool operator<<(::boost::container::basic_string const& str) + bool operator<<(::boost::container::basic_string const& str) BOOST_NOEXCEPT { start = const_cast(str.data()); finish = start + str.length(); return true; } - bool operator<<(bool value) + bool operator<<(bool value) BOOST_NOEXCEPT { CharT const czero = lcast_char_constants::zero; Traits::assign(*start, Traits::to_char_type(czero + value)); @@ -1442,21 +1454,21 @@ namespace boost { return true; } - bool operator<<(const iterator_range& rng) + bool operator<<(const iterator_range& rng) BOOST_NOEXCEPT { start = rng.begin(); finish = rng.end(); return true; } - bool operator<<(const iterator_range& rng) + bool operator<<(const iterator_range& rng) BOOST_NOEXCEPT { start = const_cast(rng.begin()); finish = const_cast(rng.end()); return true; } - bool operator<<(const iterator_range& rng) + bool operator<<(const iterator_range& rng) BOOST_NOEXCEPT { return (*this) << iterator_range( const_cast(reinterpret_cast(rng.begin())), @@ -1464,7 +1476,7 @@ namespace boost { ); } - bool operator<<(const iterator_range& rng) + bool operator<<(const iterator_range& rng) BOOST_NOEXCEPT { return (*this) << iterator_range( const_cast(reinterpret_cast(rng.begin())), @@ -1472,7 +1484,7 @@ namespace boost { ); } - bool operator<<(const iterator_range& rng) + bool operator<<(const iterator_range& rng) BOOST_NOEXCEPT { return (*this) << iterator_range( reinterpret_cast(rng.begin()), @@ -1480,7 +1492,7 @@ namespace boost { ); } - bool operator<<(const iterator_range& rng) + bool operator<<(const iterator_range& rng) BOOST_NOEXCEPT { return (*this) << iterator_range( reinterpret_cast(rng.begin()), @@ -1539,52 +1551,52 @@ namespace boost { } template - bool operator<<(boost::array const& input) + bool operator<<(boost::array const& input) BOOST_NOEXCEPT { return shl_char_array_limited(input.begin(), N); } template - bool operator<<(boost::array const& input) + bool operator<<(boost::array const& input) BOOST_NOEXCEPT { return ((*this) << reinterpret_cast const& >(input)); } template - bool operator<<(boost::array const& input) + bool operator<<(boost::array const& input) BOOST_NOEXCEPT { return ((*this) << reinterpret_cast const& >(input)); } template - bool operator<<(boost::array const& input) + bool operator<<(boost::array const& input) BOOST_NOEXCEPT { return shl_char_array_limited(input.begin(), N); } template - bool operator<<(boost::array const& input) + bool operator<<(boost::array const& input) BOOST_NOEXCEPT { return ((*this) << reinterpret_cast const& >(input)); } template - bool operator<<(boost::array const& input) + bool operator<<(boost::array const& input) BOOST_NOEXCEPT { return ((*this) << reinterpret_cast const& >(input)); } #if !defined(BOOST_NO_CXX11_HDR_ARRAY) && defined(BOOST_HAS_TR1_ARRAY) template - bool operator<<(std::array const& input) + bool operator<<(std::array const& input) BOOST_NOEXCEPT { return shl_char_array_limited(input.begin(), N); } template - bool operator<<(std::array const& input) + bool operator<<(std::array const& input) BOOST_NOEXCEPT { return ((*this) << reinterpret_cast const& >(input)); } template - bool operator<<(std::array const& input) + bool operator<<(std::array const& input) BOOST_NOEXCEPT { return ((*this) << reinterpret_cast const& >(input)); } template - bool operator<<(std::array const& input) + bool operator<<(std::array const& input) BOOST_NOEXCEPT { return shl_char_array_limited(input.begin(), N); } template - bool operator<<(std::array const& input) + bool operator<<(std::array const& input) BOOST_NOEXCEPT { return ((*this) << reinterpret_cast const& >(input)); } template - bool operator<<(std::array const& input) + bool operator<<(std::array const& input) BOOST_NOEXCEPT { return ((*this) << reinterpret_cast const& >(input)); } #endif // !defined(BOOST_NO_CXX11_HDR_ARRAY) && defined(BOOST_HAS_TR1_ARRAY) @@ -1723,10 +1735,10 @@ namespace boost { inline bool shr_xchar(T& output) { BOOST_STATIC_ASSERT_MSG(( sizeof(CharT) == sizeof(T) ), - "boost::lexical_cast does not support conversions from wchar_t to char types." + "boost::lexical_cast does not support narrowing of character types." "Use boost::locale instead" ); bool const ok = (finish - start == 1); - if(ok) { + if (ok) { CharT out; Traits::assign(out, *start); output = static_cast(out); @@ -1770,7 +1782,7 @@ namespace boost { private: template - bool shr_std_array(ArrayT& output, boost::mpl::bool_ /*is_T_char_tag*/) + bool shr_std_array(ArrayT& output) BOOST_NOEXCEPT { using namespace std; const std::size_t size = finish - start; @@ -1779,22 +1791,16 @@ namespace boost { } memcpy(output.begin(), start, size * sizeof(CharT)); - *(output.begin() + size) = static_cast(0); + *(output.begin() + size) = Traits::to_char_type(0); return true; } - template - bool shr_std_array(ArrayT& output, boost::mpl::bool_ /*is_T_char_tag*/) - { - return shr_using_base_class(output); // Array consist of non character types or unmatching character type - } public: template - bool operator>>(boost::array& output) + bool operator>>(boost::array& output) BOOST_NOEXCEPT { - typedef boost::mpl::bool_ tag_type; - return shr_std_array(output, tag_type()); + return shr_std_array(output); } template @@ -1811,10 +1817,9 @@ namespace boost { #if !defined(BOOST_NO_CXX11_HDR_ARRAY) && defined(BOOST_HAS_TR1_ARRAY) template - bool operator>>(std::array& output) + bool operator>>(std::array& output) BOOST_NOEXCEPT { - typedef boost::mpl::bool_ tag_type; - return shr_std_array(output, tag_type()); + return shr_std_array(output); } template @@ -1836,7 +1841,7 @@ namespace boost { * case "1" || "+1": output = true; return true; * default: return false; */ - bool operator>>(bool& output) + bool operator>>(bool& output) BOOST_NOEXCEPT { CharT const zero = lcast_char_constants::zero; CharT const plus = lcast_char_constants::plus; @@ -1886,10 +1891,10 @@ namespace boost { CharT const lowercase_e = lcast_char_constants::lowercase_e; if ( return_value && ( - *(finish-1) == lowercase_e // 1.0e - || *(finish-1) == capital_e // 1.0E - || *(finish-1) == minus // 1.0e- or 1.0E- - || *(finish-1) == plus // 1.0e+ or 1.0E+ + Traits::eq(*(finish-1), lowercase_e) // 1.0e + || Traits::eq(*(finish-1), capital_e) // 1.0E + || Traits::eq(*(finish-1), minus) // 1.0e- or 1.0E- + || Traits::eq(*(finish-1), plus) // 1.0e+ or 1.0E+ ) ) return false; @@ -2145,7 +2150,7 @@ namespace boost { template struct lexical_cast_copy { - static inline Source lexical_cast_impl(const Source &arg) + static inline const Source& lexical_cast_impl(const Source &arg) BOOST_NOEXCEPT { return arg; }