diff --git a/include/fast_float/fast_float.h b/include/fast_float/fast_float.h index a190d7c..eb822f5 100644 --- a/include/fast_float/fast_float.h +++ b/include/fast_float/fast_float.h @@ -63,6 +63,20 @@ integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept; FASTFLOAT_CONSTEXPR20 inline double integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept; +/** + * This function is a template overload of `integer_times_pow10()` + * that returns a floating-point value of type `T` that is one of + * supported floating-point types (e.g. `double`, `float`). + */ +template +FASTFLOAT_CONSTEXPR20 + typename std::enable_if::value, T>::type + integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept; +template +FASTFLOAT_CONSTEXPR20 + typename std::enable_if::value, T>::type + integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept; + /** * from_chars for integer types. */ diff --git a/include/fast_float/parse_number.h b/include/fast_float/parse_number.h index a44fef0..d453c14 100644 --- a/include/fast_float/parse_number.h +++ b/include/fast_float/parse_number.h @@ -344,44 +344,79 @@ from_chars(UC const *first, UC const *last, T &value, int base) noexcept { return from_chars_advanced(first, last, value, options); } -FASTFLOAT_CONSTEXPR20 inline double -integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept { - double value; +template +FASTFLOAT_CONSTEXPR20 + typename std::enable_if::value, T>::type + integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept { + T value; if (clinger_fast_path_impl(mantissa, decimal_exponent, false, value)) return value; adjusted_mantissa am = - compute_float>(decimal_exponent, mantissa); + compute_float>(decimal_exponent, mantissa); to_float(false, am, value); return value; } -FASTFLOAT_CONSTEXPR20 inline double -integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept { +template +FASTFLOAT_CONSTEXPR20 + typename std::enable_if::value, T>::type + integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept { const bool is_negative = mantissa < 0; const uint64_t m = static_cast(is_negative ? -mantissa : mantissa); - double value; + T value; if (clinger_fast_path_impl(m, decimal_exponent, is_negative, value)) return value; - adjusted_mantissa am = - compute_float>(decimal_exponent, m); + adjusted_mantissa am = compute_float>(decimal_exponent, m); to_float(is_negative, am, value); return value; } +FASTFLOAT_CONSTEXPR20 inline double +integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept { + return integer_times_pow10(mantissa, decimal_exponent); +} + +FASTFLOAT_CONSTEXPR20 inline double +integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept { + return integer_times_pow10(mantissa, decimal_exponent); +} + // the following overloads are here to avoid surprising ambiguity for int, // unsigned, etc. +template +FASTFLOAT_CONSTEXPR20 + typename std::enable_if::value && + std::is_integral::value && + !std::is_signed::value, + T>::type + integer_times_pow10(Int mantissa, int decimal_exponent) noexcept { + return integer_times_pow10(static_cast(mantissa), + decimal_exponent); +} + +template +FASTFLOAT_CONSTEXPR20 + typename std::enable_if::value && + std::is_integral::value && + std::is_signed::value, + T>::type + integer_times_pow10(Int mantissa, int decimal_exponent) noexcept { + return integer_times_pow10(static_cast(mantissa), + decimal_exponent); +} + template -FASTFLOAT_CONSTEXPR20 inline typename std::enable_if< +FASTFLOAT_CONSTEXPR20 typename std::enable_if< std::is_integral::value && !std::is_signed::value, double>::type integer_times_pow10(Int mantissa, int decimal_exponent) noexcept { return integer_times_pow10(static_cast(mantissa), decimal_exponent); } template -FASTFLOAT_CONSTEXPR20 inline typename std::enable_if< +FASTFLOAT_CONSTEXPR20 typename std::enable_if< std::is_integral::value && std::is_signed::value, double>::type integer_times_pow10(Int mantissa, int decimal_exponent) noexcept { return integer_times_pow10(static_cast(mantissa), decimal_exponent);