#ifndef SPROUT_STRING_FLOAT_TO_STRING_HPP #define SPROUT_STRING_FLOAT_TO_STRING_HPP #include #include #include #include #include #include #include #include #include #include #include #include HDR_ALGORITHM_MIN_MAX_SSCRISK_CEL_OR_SPROUT namespace sprout { namespace detail { SPROUT_STATIC_CONSTEXPR std::size_t decimal_places_length = 6; } // namespace detail // // printed_float_digits // template struct printed_float_digits : public std::integral_constant< std::size_t, std::numeric_limits::max_exponent10 + sprout::detail::decimal_places_length + 2 > {}; namespace detail { template inline SPROUT_CONSTEXPR sprout::basic_string::value> float_to_string_impl(FloatType val, bool negative, int digits, int v, sprout::index_tuple) { return negative ? sprout::basic_string::value>{ { static_cast('-'), (Indexes < digits ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, digits - 1 - Indexes)) : Indexes == digits ? static_cast('.') : Indexes < digits + 1 + sprout::detail::decimal_places_length ? sprout::detail::int_to_char(sprout::detail::int_digit_at(v, digits + sprout::detail::decimal_places_length - Indexes)) : Elem() )... }, static_cast(digits + 2 + sprout::detail::decimal_places_length) } : sprout::basic_string::value>{ { (Indexes < digits ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, digits - 1 - Indexes)) : Indexes == digits ? static_cast('.') : Indexes < digits + 1 + sprout::detail::decimal_places_length ? sprout::detail::int_to_char(sprout::detail::int_digit_at(v, digits + sprout::detail::decimal_places_length - Indexes)) : Elem() )... }, static_cast(digits + 1 + sprout::detail::decimal_places_length) } ; } template inline SPROUT_CONSTEXPR sprout::basic_string::value> float_to_string(FloatType val, bool negative, int digits) { return sprout::detail::float_to_string_impl( val, negative, digits, static_cast((val - sprout::floor(val)) * sprout::detail::int_pow(sprout::detail::decimal_places_length)), sprout::index_range<0, sprout::printed_float_digits::value - 1>::make() ); } } // namespace detail // // float_to_string // template< typename Elem, typename FloatType, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR sprout::basic_string::value> float_to_string(FloatType val) { return sprout::detail::float_to_string( sprout::detail::float_round_at(val < 0 ? -val : val, sprout::detail::decimal_places_length), val < 0, sprout::detail::float_digits(val) ); } namespace detail { template struct printed_float_exponent10_digits : public std::integral_constant< std::size_t, NS_SSCRISK_CEL_OR_SPROUT::max(sprout::detail::int_digits(std::numeric_limits::max_exponent10), 2) > {}; } // namespace detail // // printed_float_exp_digits // template struct printed_float_exp_digits : public std::integral_constant< std::size_t, 5 + sprout::detail::decimal_places_length + sprout::detail::printed_float_exponent10_digits::value > {}; namespace detail { template inline SPROUT_CONSTEXPR sprout::basic_string::value> float_to_string_exp(FloatType val, bool negative, int exponent10, int e10_digits, sprout::index_tuple) { return negative ? sprout::basic_string::value>{ { static_cast('-'), (Indexes == 0 ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, 0)) : Indexes == 1 ? static_cast('.') : Indexes < 2 + sprout::detail::decimal_places_length ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, 1 - Indexes)) : Indexes == 2 + sprout::detail::decimal_places_length ? static_cast('e') : Indexes == 3 + sprout::detail::decimal_places_length ? static_cast(exponent10 < 0 ? '-' : '+') : Indexes < 4 + sprout::detail::decimal_places_length + e10_digits ? sprout::detail::int_to_char(sprout::detail::int_digit_at(exponent10, 3 + sprout::detail::decimal_places_length + e10_digits - Indexes)) : Elem() )... }, static_cast(5 + sprout::detail::decimal_places_length + e10_digits) } : sprout::basic_string::value>{ { (Indexes == 0 ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, 0)) : Indexes == 1 ? static_cast('.') : Indexes < 2 + sprout::detail::decimal_places_length ? sprout::detail::int_to_char(sprout::detail::float_digit_at(val, 1 - Indexes)) : Indexes == 2 + sprout::detail::decimal_places_length ? static_cast('e') : Indexes == 3 + sprout::detail::decimal_places_length ? static_cast(exponent10 < 0 ? '-' : '+') : Indexes < 4 + sprout::detail::decimal_places_length + e10_digits ? sprout::detail::int_to_char(sprout::detail::int_digit_at(exponent10, 3 + sprout::detail::decimal_places_length + e10_digits - Indexes)) : Elem() )... }, static_cast(4 + sprout::detail::decimal_places_length + e10_digits) } ; } } // namespace detail // // float_to_string_exp // template< typename Elem, typename FloatType, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR sprout::basic_string::value> float_to_string_exp(FloatType val) { return sprout::detail::float_to_string_exp( sprout::detail::float_round_at( (val < 0 ? -val : val) / sprout::detail::float_pow10(sprout::detail::float_exponent10(val)), sprout::detail::decimal_places_length ), val < 0, sprout::detail::float_exponent10(val), NS_SSCRISK_CEL_OR_SPROUT::max(sprout::detail::int_digits(sprout::detail::float_exponent10(val)), 2), sprout::index_range<0, sprout::printed_float_exp_digits::value - 1>::make() ); } // // to_string_of // template::value>::type = sprout::enabler> inline SPROUT_CONSTEXPR sprout::basic_string::value> to_string_of(FloatType val) { return sprout::float_to_string(val); } // // to_string // template::value>::type = sprout::enabler> inline SPROUT_CONSTEXPR sprout::basic_string::value> to_string(FloatType val) { return sprout::to_string_of(val); } // // to_wstring // template::value>::type = sprout::enabler> inline SPROUT_CONSTEXPR sprout::basic_string::value> to_wstring(FloatType val) { return sprout::to_string_of(val); } // // to_u16string // template::value>::type = sprout::enabler> inline SPROUT_CONSTEXPR sprout::basic_string::value> to_u16string(FloatType val) { return sprout::to_string_of(val); } // // to_u32string // template::value>::type = sprout::enabler> inline SPROUT_CONSTEXPR sprout::basic_string::value> to_u32string(FloatType val) { return sprout::to_string_of(val); } } // namespace sprout #endif // #ifndef SPROUT_STRING_FLOAT_TO_STRING_HPP