#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 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 + 3*/ sprout::integer_digits::value + sprout::detail::decimal_places_length + 3 > {}; namespace detail { template inline SPROUT_CONSTEXPR unsigned float_extract_rounded_impl(FloatType val) { return static_cast(val * 1000000) + (static_cast(val * 10000000) % 10 >= 5 ? 1 : 0) ; } template inline SPROUT_CONSTEXPR unsigned float_extract_rounded(FloatType val) { using std::floor; return sprout::detail::float_extract_rounded_impl(val - floor(val)); } template< typename Elem, typename FloatType, typename... Args, typename sprout::enabler_if<(sizeof...(Args) == sprout::printed_float_digits::value - 1)>::type = sprout::enabler > inline SPROUT_CONSTEXPR sprout::basic_string::value> float_to_string_impl_1(FloatType val, bool negative, Args... args) { return negative ? sprout::make_string_as(static_cast('-'), args...) : sprout::make_string_as(args...) ; } template< typename Elem, typename FloatType, typename... Args, typename sprout::enabler_if<(sizeof...(Args) < sprout::printed_float_digits::value - 1)>::type = sprout::enabler > inline SPROUT_CONSTEXPR sprout::basic_string::value> float_to_string_impl_1(FloatType val, bool negative, Args... args) { return !(val < 1) ? sprout::detail::float_to_string_impl_1( val / 10, negative, sprout::detail::int_to_char(static_cast(val) % 10), args... ) : negative ? sprout::make_string_as(static_cast('-'), args...) : sprout::make_string_as(args...) ; } template< typename Elem, typename FloatType, typename... Args, typename sprout::enabler_if<(sizeof...(Args) == sprout::printed_float_digits::value - 3)>::type = sprout::enabler > inline SPROUT_CONSTEXPR sprout::basic_string::value> float_to_string_impl(FloatType val, bool negative, unsigned temp, std::size_t decimal_digits, Args... args) { return negative ? sprout::make_string_as(static_cast('-'), static_cast('0'), static_cast('.'), args...) : sprout::make_string_as(static_cast('0'), static_cast('.'), args...) ; } template< typename Elem, typename FloatType, typename... Args, typename sprout::enabler_if<(sizeof...(Args) < sprout::printed_float_digits::value - 3)>::type = sprout::enabler > inline SPROUT_CONSTEXPR sprout::basic_string::value> float_to_string_impl(FloatType val, bool negative, unsigned temp, std::size_t decimal_digits, Args... args) { return decimal_digits ? sprout::detail::float_to_string_impl( val, negative, temp / 10, decimal_digits - 1, sprout::detail::int_to_char(temp % 10), args... ) : !(val < 1) ? sprout::detail::float_to_string_impl_1( val, negative, static_cast('.'), args... ) : negative ? sprout::make_string_as(static_cast('-'), static_cast('0'), static_cast('.'), args...) : sprout::make_string_as(static_cast('0'), static_cast('.'), args...) ; } template< typename Elem, typename FloatType > inline SPROUT_CONSTEXPR sprout::basic_string::value> float_to_string(FloatType val) { using std::floor; return val < 0 ? sprout::detail::float_to_string_impl( -val, true, sprout::detail::float_extract_rounded(-val), sprout::detail::decimal_places_length ) : sprout::detail::float_to_string_impl( val, false, sprout::detail::float_extract_rounded(val), 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(val); } // // 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