diff options
Diffstat (limited to 'boost/lexical_cast/detail')
5 files changed, 6 insertions, 353 deletions
diff --git a/boost/lexical_cast/detail/converter_lexical.hpp b/boost/lexical_cast/detail/converter_lexical.hpp index ee9f5f132e..961dbde277 100644 --- a/boost/lexical_cast/detail/converter_lexical.hpp +++ b/boost/lexical_cast/detail/converter_lexical.hpp @@ -321,30 +321,6 @@ namespace boost { typedef const T * type; }; } - - namespace detail // is_this_float_conversion_optimized<Float, Char> - { - // this metafunction evaluates to true, if we have optimized comnversion - // from Float type to Char array. - // Must be in sync with lexical_stream_limited_src<Char, ...>::shl_real_type(...) - template <typename Float, typename Char> - struct is_this_float_conversion_optimized - { - typedef boost::type_traits::ice_and< - boost::is_float<Float>::value, -#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_SWPRINTF) && !defined(__MINGW32__) - boost::type_traits::ice_or< - boost::type_traits::ice_eq<sizeof(Char), sizeof(char) >::value, - boost::is_same<Char, wchar_t>::value - >::value -#else - boost::type_traits::ice_eq<sizeof(Char), sizeof(char) >::value -#endif - > result_type; - - BOOST_STATIC_CONSTANT(bool, value = (result_type::value) ); - }; - } namespace detail // lcast_src_length { @@ -457,7 +433,6 @@ namespace boost { typedef boost::type_traits::ice_not< boost::type_traits::ice_or< boost::is_integral<no_cv_src>::value, - boost::detail::is_this_float_conversion_optimized<no_cv_src, char_type >::value, boost::detail::is_character< BOOST_DEDUCED_TYPENAME deduce_src_char_metafunc::stage1_type // if we did not get character type at stage1 >::value // then we have no optimization for that type diff --git a/boost/lexical_cast/detail/converter_lexical_streams.hpp b/boost/lexical_cast/detail/converter_lexical_streams.hpp index 7f8cfd946e..2d6617dadd 100644 --- a/boost/lexical_cast/detail/converter_lexical_streams.hpp +++ b/boost/lexical_cast/detail/converter_lexical_streams.hpp @@ -62,7 +62,6 @@ #include <boost/lexical_cast/detail/lcast_char_constants.hpp> #include <boost/lexical_cast/detail/lcast_unsigned_converters.hpp> #include <boost/lexical_cast/detail/inf_nan.hpp> -#include <boost/lexical_cast/detail/lcast_float_converters.hpp> #include <istream> @@ -739,12 +738,10 @@ namespace boost { return true; } - bool operator>>(float& output) { return lcast_ret_float<Traits>(output,start,finish); } - private: // Not optimised converter template <class T> - bool float_types_converter_internal(T& output, int /*tag*/) { + bool float_types_converter_internal(T& output) { if (parse_inf_nan(start, finish, output)) return true; bool const return_value = shr_using_base_class(output); @@ -770,36 +767,10 @@ namespace boost { return return_value; } - // Optimised converter - bool float_types_converter_internal(double& output, char /*tag*/) { - return lcast_ret_float<Traits>(output, start, finish); - } public: - - bool operator>>(double& output) { - /* - * Some compilers implement long double as double. In that case these types have - * same size, same precision, same max and min values... And it means, - * that current implementation of lcast_ret_float cannot be used for type - * double, because it will give a big precision loss. - * */ - boost::mpl::if_c< -#if (defined(BOOST_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64)) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) - boost::type_traits::ice_eq< sizeof(double), sizeof(long double) >::value, -#else - 1, -#endif - int, - char - >::type tag = 0; - - return float_types_converter_internal(output, tag); - } - - bool operator>>(long double& output) { - int tag = 0; - return float_types_converter_internal(output, tag); - } + bool operator>>(float& output) { return float_types_converter_internal(output); } + bool operator>>(double& output) { return float_types_converter_internal(output); } + bool operator>>(long double& output) { return float_types_converter_internal(output); } // Generic istream-based algorithm. // lcast_streambuf_for_target<InputStreamable>::value is true. diff --git a/boost/lexical_cast/detail/converter_numeric.hpp b/boost/lexical_cast/detail/converter_numeric.hpp index 83600f7e0b..54f7a35ff4 100644 --- a/boost/lexical_cast/detail/converter_numeric.hpp +++ b/boost/lexical_cast/detail/converter_numeric.hpp @@ -31,6 +31,7 @@ #include <boost/type_traits/is_integral.hpp> #include <boost/type_traits/is_arithmetic.hpp> #include <boost/type_traits/is_base_of.hpp> +#include <boost/type_traits/is_float.hpp> #include <boost/numeric/conversion/cast.hpp> diff --git a/boost/lexical_cast/detail/lcast_float_converters.hpp b/boost/lexical_cast/detail/lcast_float_converters.hpp deleted file mode 100644 index 9ef7126865..0000000000 --- a/boost/lexical_cast/detail/lcast_float_converters.hpp +++ /dev/null @@ -1,294 +0,0 @@ -// Copyright Kevlin Henney, 2000-2005. -// Copyright Alexander Nasonov, 2006-2010. -// Copyright Antony Polukhin, 2011-2014. -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// what: lexical_cast custom keyword cast -// who: contributed by Kevlin Henney, -// enhanced with contributions from Terje Slettebo, -// 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, Pavel Korzh and other Boosters -// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014 - -#ifndef BOOST_LEXICAL_CAST_DETAIL_LCAST_FLOAT_CONVERTERS_HPP -#define BOOST_LEXICAL_CAST_DETAIL_LCAST_FLOAT_CONVERTERS_HPP - -#include <boost/config.hpp> -#ifdef BOOST_HAS_PRAGMA_ONCE -# pragma once -#endif - -#include <cstddef> -#include <cmath> -#include <boost/limits.hpp> -#include <boost/detail/workaround.hpp> - -#ifndef BOOST_NO_STD_LOCALE -# include <locale> -#else -# ifndef 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 <locale> header. Define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE to force " -# error "boost::lexical_cast to use only 'C' locale during conversions." -# endif -#endif - -#include <boost/lexical_cast/detail/lcast_char_constants.hpp> - -#include <boost/math/special_functions/sign.hpp> -#include <boost/math/special_functions/fpclassify.hpp> - -namespace boost { - - namespace detail // lcast_ret_float - { - -// Silence buggy MS warnings like C4244: '+=' : conversion from 'int' to 'unsigned short', possible loss of data -#if defined(_MSC_VER) && (_MSC_VER == 1400) -# pragma warning(push) -# pragma warning(disable:4244) -#endif - template <class T> - struct mantissa_holder_type - { - /* Can not be used with this type */ - }; - - template <> - struct mantissa_holder_type<float> - { - typedef unsigned int type; - typedef double wide_result_t; - }; - - template <> - struct mantissa_holder_type<double> - { -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - typedef long double wide_result_t; -#if defined(BOOST_HAS_LONG_LONG) - typedef boost::ulong_long_type type; -#elif defined(BOOST_HAS_MS_INT64) - typedef unsigned __int64 type; -#endif -#endif - }; - - template<class Traits, class T, class CharT> - inline bool lcast_ret_float(T& value, const CharT* begin, const CharT* const end) - { - value = static_cast<T>(0); - if (begin == end) return false; - if (parse_inf_nan(begin, end, value)) return true; - - CharT const czero = lcast_char_constants<CharT>::zero; - CharT const minus = lcast_char_constants<CharT>::minus; - CharT const plus = lcast_char_constants<CharT>::plus; - CharT const capital_e = lcast_char_constants<CharT>::capital_e; - CharT const lowercase_e = lcast_char_constants<CharT>::lowercase_e; - - /* Getting the plus/minus sign */ - bool const has_minus = Traits::eq(*begin, minus); - if (has_minus || Traits::eq(*begin, plus)) { - ++ begin; - if (begin == end) return false; - } - -#ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE - std::locale loc; - typedef std::numpunct<CharT> numpunct; - numpunct const& np = BOOST_USE_FACET(numpunct, loc); - std::string const grouping( - (loc == std::locale::classic()) - ? std::string() - : np.grouping() - ); - std::string::size_type const grouping_size = grouping.size(); - CharT const thousands_sep = static_cast<CharT>(grouping_size ? np.thousands_sep() : 0); - CharT const decimal_point = np.decimal_point(); - bool found_grouping = false; - std::string::size_type last_grouping_pos = grouping_size - 1; -#else - CharT const decimal_point = lcast_char_constants<CharT>::c_decimal_separator; -#endif - - bool found_decimal = false; - bool found_number_before_exp = false; - typedef int pow_of_10_t; - pow_of_10_t pow_of_10 = 0; - - typedef BOOST_DEDUCED_TYPENAME mantissa_holder_type<T>::type mantissa_type; - mantissa_type mantissa=0; - bool is_mantissa_full = false; - char length_since_last_delim = 0; - - while (begin != end) { - if (found_decimal) { - /* We allow no thousand_separators after decimal point */ - - const mantissa_type tmp_sub_value = static_cast<mantissa_type>(*begin - czero); - if (Traits::eq(*begin, lowercase_e) || Traits::eq(*begin, capital_e)) break; - if ( *begin < czero || *begin >= czero + 10 ) return false; - if ( is_mantissa_full - || ((std::numeric_limits<mantissa_type>::max)() - tmp_sub_value) / 10u < mantissa - ) { - is_mantissa_full = true; - ++ begin; - continue; - } - - -- pow_of_10; - mantissa = static_cast<mantissa_type>(mantissa * 10 + tmp_sub_value); - - found_number_before_exp = true; - } else { - - if (*begin >= czero && *begin < czero + 10) { - - /* Checking for mantissa overflow. If overflow will - * occur, them we only increase multiplyer - */ - const mantissa_type tmp_sub_value = static_cast<mantissa_type>(*begin - czero); - if( is_mantissa_full - || ((std::numeric_limits<mantissa_type>::max)() - tmp_sub_value) / 10u < mantissa - ) - { - is_mantissa_full = true; - ++ pow_of_10; - } else { - mantissa = static_cast<mantissa_type>(mantissa * 10 + tmp_sub_value); - } - - found_number_before_exp = true; - ++ length_since_last_delim; - } 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 - * or grouping position is incorrect - * or we are using the grouping position 0 twice - * ) - * ) then return error - */ - if( grouping_size && found_grouping - && ( - length_since_last_delim != grouping[0] - || last_grouping_pos>1 - || (last_grouping_pos==0 && grouping_size>1) - ) - ) return false; -#endif - - if (Traits::eq(*begin, decimal_point)) { - ++ begin; - found_decimal = true; - if (!found_number_before_exp && begin==end) return false; - continue; - } else { - if (!found_number_before_exp) return false; - break; - } - } -#ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE - else if (grouping_size && Traits::eq(*begin, thousands_sep)){ - if(found_grouping) - { - /* It is not he first time, when we find thousands separator, - * so we need to chek, is the distance between two groupings - * equal to grouping[last_grouping_pos] */ - - if (length_since_last_delim != grouping[last_grouping_pos] ) - { - if (!last_grouping_pos) return false; - else - { - -- last_grouping_pos; - if (length_since_last_delim != grouping[last_grouping_pos]) return false; - } - } else - /* We are calling the grouping[0] twice, when grouping size is more than 1 */ - if (grouping_size>1u && last_grouping_pos+1<grouping_size) return false; - - } else { - /* Delimiter at the begining ',000' */ - if (!length_since_last_delim) return false; - - found_grouping = true; - if (length_since_last_delim > grouping[last_grouping_pos] ) return false; - } - - length_since_last_delim = 0; - ++ begin; - - /* Delimiter at the end '100,' */ - if (begin == end) return false; - continue; - } -#endif - else return false; - } - - ++begin; - } - - // Exponent found - if (begin != end && (Traits::eq(*begin, lowercase_e) || Traits::eq(*begin, capital_e))) { - ++ begin; - if (begin == end) return false; - - bool const exp_has_minus = Traits::eq(*begin, minus); - if (exp_has_minus || Traits::eq(*begin, plus)) { - ++ begin; - if (begin == end) return false; - } - - pow_of_10_t exp_pow_of_10 = 0; - while (begin != end) { - pow_of_10_t const sub_value = *begin - czero; - - if ( *begin < czero || *begin >= czero + 10 - || ((std::numeric_limits<pow_of_10_t>::max)() - sub_value) / 10 < exp_pow_of_10) - return false; - - exp_pow_of_10 *= 10; - exp_pow_of_10 += sub_value; - ++ begin; - }; - - if (exp_has_minus) { - if ((std::numeric_limits<pow_of_10_t>::min)() + exp_pow_of_10 > pow_of_10) - return false; // failed overflow check - pow_of_10 -= exp_pow_of_10; - } else { - if ((std::numeric_limits<pow_of_10_t>::max)() - exp_pow_of_10 < pow_of_10) - return false; // failed overflow check - pow_of_10 += exp_pow_of_10; - } - } - - /* We need a more accurate algorithm... We can not use current algorithm - * with long doubles (and with doubles if sizeof(double)==sizeof(long double)). - */ - typedef BOOST_DEDUCED_TYPENAME mantissa_holder_type<T>::wide_result_t wide_result_t; - const wide_result_t result = std::pow(static_cast<wide_result_t>(10.0), pow_of_10) * mantissa; - value = static_cast<T>( has_minus ? (boost::math::changesign)(result) : result); - - return !((boost::math::isinf)(value) || (boost::math::isnan)(value)); - } -// Unsilence buggy MS warnings like C4244: '+=' : conversion from 'int' to 'unsigned short', possible loss of data -#if defined(_MSC_VER) && (_MSC_VER == 1400) -# pragma warning(pop) -#endif - } -} // namespace boost - -#endif // BOOST_LEXICAL_CAST_DETAIL_LCAST_FLOAT_CONVERTERS_HPP - diff --git a/boost/lexical_cast/detail/lcast_unsigned_converters.hpp b/boost/lexical_cast/detail/lcast_unsigned_converters.hpp index f75b419d2f..efe91ede9a 100644 --- a/boost/lexical_cast/detail/lcast_unsigned_converters.hpp +++ b/boost/lexical_cast/detail/lcast_unsigned_converters.hpp @@ -144,7 +144,7 @@ namespace boost int_type const digit = static_cast<int_type>(m_value % 10U); Traits::assign(*m_finish, Traits::to_char_type(m_zero + digit)); m_value /= 10; - return !!m_value; // supressing warnings + return !!m_value; // suppressing warnings } inline CharT* main_convert_loop() BOOST_NOEXCEPT { |