#ifndef SPROUT_STRING_FLOAT_TO_STRING_HPP #define SPROUT_STRING_FLOAT_TO_STRING_HPP #include #include #include #include #include #include #include #include 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 FloatType float_pow10(int exponent) { return exponent ? FloatType(10) * sprout::detail::float_pow10(exponent - 1) : FloatType(1) ; } template inline SPROUT_CONSTEXPR int float_digits_impl(FloatType val) { return !(val < 1 && val > -1) ? 1 + sprout::detail::float_digits_impl(val / 10) : 0 ; } template inline SPROUT_CONSTEXPR int float_digits(FloatType val) { return !(val < 1 && val > -1) ? 1 + sprout::detail::float_digits_impl(val / 10) : 1 ; } template inline SPROUT_CONSTEXPR int float_digit_of_impl(FloatType val) { using std::floor; return static_cast((val - floor(val)) * 10); } template inline SPROUT_CONSTEXPR int float_digit_of(FloatType val, int digits) { return digits < 0 ? sprout::detail::float_digit_of_impl(val * sprout::detail::float_pow10(-digits - 1)) : sprout::detail::float_digit_of_impl(val / sprout::detail::float_pow10(digits + 1)) ; } template inline SPROUT_CONSTEXPR FloatType float_round_impl(FloatType val, FloatType p10) { using std::round; return round(val * p10) / p10; } template inline SPROUT_CONSTEXPR FloatType float_round(FloatType val, int digits) { return sprout::detail::float_round_impl(val, sprout::detail::float_pow10(digits)); } template inline SPROUT_CONSTEXPR sprout::basic_string::value> float_to_string(FloatType val, bool negative, int digits, sprout::index_tuple) { return negative ? sprout::basic_string::value>{ { static_cast('-'), (Indexes < digits ? sprout::detail::int_to_char(sprout::detail::float_digit_of(val, digits - 1 - Indexes)) : Indexes == digits ? static_cast('.') : Indexes < digits + 1 + sprout::detail::decimal_places_length ? sprout::detail::int_to_char(sprout::detail::float_digit_of(val, digits - 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_of(val, digits - 1 - Indexes)) : Indexes == digits ? static_cast('.') : Indexes < digits + 1 + sprout::detail::decimal_places_length ? sprout::detail::int_to_char(sprout::detail::float_digit_of(val, digits - Indexes)) : Elem() )... }, static_cast(digits + 1 + sprout::detail::decimal_places_length) } ; } } // 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(val < 0 ? -val : val, sprout::detail::decimal_places_length), val < 0, sprout::detail::float_digits(val), sprout::index_range<0, sprout::printed_float_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 // // inline SPROUT_CONSTEXPR sprout::basic_string::value> // to_string(float val) { // return sprout::to_string_of(val); // } // inline SPROUT_CONSTEXPR sprout::basic_string::value> // to_string(double val) { // return sprout::to_string_of(val); // } // inline SPROUT_CONSTEXPR sprout::basic_string::value> // to_string(long double val) { // return sprout::to_string_of(val); // } template::value>::type = sprout::enabler> inline SPROUT_CONSTEXPR sprout::basic_string::value> to_string(FloatType val) { return sprout::to_string_of(val); } // // to_wstring // // inline SPROUT_CONSTEXPR sprout::basic_string::value> // to_wstring(float val) { // return sprout::to_string_of(val); // } // inline SPROUT_CONSTEXPR sprout::basic_string::value> // to_wstring(double val) { // return sprout::to_string_of(val); // } // inline SPROUT_CONSTEXPR sprout::basic_string::value> // to_wstring(long double val) { // return sprout::to_string_of(val); // } template::value>::type = sprout::enabler> inline SPROUT_CONSTEXPR sprout::basic_string::value> to_wstring(FloatType val) { return sprout::to_string_of(val); } // // to_u16string // // inline SPROUT_CONSTEXPR sprout::basic_string::value> // to_u16string(float val) { // return sprout::to_string_of(val); // } // inline SPROUT_CONSTEXPR sprout::basic_string::value> // to_u16string(double val) { // return sprout::to_string_of(val); // } // inline SPROUT_CONSTEXPR sprout::basic_string::value> // to_u16string(long double val) { // return sprout::to_string_of(val); // } template::value>::type = sprout::enabler> inline SPROUT_CONSTEXPR sprout::basic_string::value> to_u16string(FloatType val) { return sprout::to_string_of(val); } // // to_u32string // // inline SPROUT_CONSTEXPR sprout::basic_string::value> // to_u32string(float val) { // return sprout::to_string_of(val); // } // inline SPROUT_CONSTEXPR sprout::basic_string::value> // to_u32string(double val) { // return sprout::to_string_of(val); // } // inline SPROUT_CONSTEXPR sprout::basic_string::value> // to_u32string(long double val) { // return sprout::to_string_of(val); // } 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