mirror of
https://github.com/fastfloat/fast_float.git
synced 2025-12-07 01:06:48 +08:00
Final functions call optimization.
This commit is contained in:
parent
8ccb5877bd
commit
103f22056b
@ -50,8 +50,8 @@ fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t
|
|||||||
read8_to_u64(UC const *chars) {
|
read8_to_u64(UC const *chars) {
|
||||||
if (cpp20_and_in_constexpr() || !std::is_same<UC, char>::value) {
|
if (cpp20_and_in_constexpr() || !std::is_same<UC, char>::value) {
|
||||||
uint64_t val = 0;
|
uint64_t val = 0;
|
||||||
for (uint8_t i = 0; i != 8; ++i) {
|
for (uint_fast8_t i = 0; i != 8; ++i) {
|
||||||
val |= uint64_t(uint8_t(*chars)) << (i * 8);
|
val |= uint64_t(uint_fast8_t(*chars)) << (i * 8);
|
||||||
++chars;
|
++chars;
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
@ -293,7 +293,7 @@ report_parse_error(UC const *p, parse_error error) noexcept {
|
|||||||
template <bool basic_json_fmt, typename UC>
|
template <bool basic_json_fmt, typename UC>
|
||||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 parsed_number_string_t<UC>
|
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 parsed_number_string_t<UC>
|
||||||
parse_number_string(UC const *p, UC const *pend,
|
parse_number_string(UC const *p, UC const *pend,
|
||||||
parse_options_t<UC> const options) noexcept {
|
parse_options_t<UC> const &options) noexcept {
|
||||||
// Cyclomatic complexity https://en.wikipedia.org/wiki/Cyclomatic_complexity
|
// Cyclomatic complexity https://en.wikipedia.org/wiki/Cyclomatic_complexity
|
||||||
// Consider refactoring the 'parse_number_string' function.
|
// Consider refactoring the 'parse_number_string' function.
|
||||||
// FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN fix this.
|
// FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN fix this.
|
||||||
@ -507,7 +507,7 @@ parse_number_string(UC const *p, UC const *pend,
|
|||||||
template <typename T, typename UC>
|
template <typename T, typename UC>
|
||||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||||
parse_int_string(UC const *p, UC const *pend, T &value,
|
parse_int_string(UC const *p, UC const *pend, T &value,
|
||||||
parse_options_t<UC> const options) noexcept {
|
parse_options_t<UC> const &options) noexcept {
|
||||||
|
|
||||||
from_chars_result_t<UC> answer;
|
from_chars_result_t<UC> answer;
|
||||||
|
|
||||||
@ -549,7 +549,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
|
|||||||
loop_parse_if_eight_digits(p, pend, i); // use SIMD if possible
|
loop_parse_if_eight_digits(p, pend, i); // use SIMD if possible
|
||||||
}
|
}
|
||||||
while (p != pend) {
|
while (p != pend) {
|
||||||
uint8_t const digit = ch_to_digit(*p);
|
uint_fast8_t const digit = ch_to_digit(*p);
|
||||||
if (digit >= options.base) {
|
if (digit >= options.base) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -574,7 +574,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
|
|||||||
answer.ptr = p;
|
answer.ptr = p;
|
||||||
|
|
||||||
// check u64 overflow
|
// check u64 overflow
|
||||||
uint8_t const max_digits = max_digits_u64(options.base);
|
uint_fast8_t const max_digits = max_digits_u64(options.base);
|
||||||
if (digit_count > max_digits) {
|
if (digit_count > max_digits) {
|
||||||
answer.ec = std::errc::result_out_of_range;
|
answer.ec = std::errc::result_out_of_range;
|
||||||
return answer;
|
return answer;
|
||||||
|
|||||||
@ -17,7 +17,7 @@ namespace fast_float {
|
|||||||
// most significant bits and the low part corresponding to the least significant
|
// most significant bits and the low part corresponding to the least significant
|
||||||
// bits.
|
// bits.
|
||||||
//
|
//
|
||||||
template <uint8_t bit_precision>
|
template <uint_fast8_t bit_precision>
|
||||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 value128
|
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 value128
|
||||||
compute_product_approximation(int64_t q, uint64_t w) noexcept {
|
compute_product_approximation(int64_t q, uint64_t w) noexcept {
|
||||||
int const index = 2 * int(q - powers::smallest_power_of_five);
|
int const index = 2 * int(q - powers::smallest_power_of_five);
|
||||||
|
|||||||
@ -116,7 +116,7 @@ fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void round(adjusted_mantissa &am,
|
|||||||
if (-am.power2 >= mantissa_shift) {
|
if (-am.power2 >= mantissa_shift) {
|
||||||
// have a denormal float
|
// have a denormal float
|
||||||
am_pow_t shift = -am.power2 + 1;
|
am_pow_t shift = -am.power2 + 1;
|
||||||
cb(am, std::min<int_fast16_t>(shift, 64));
|
cb(am, std::min<am_pow_t>(shift, 64));
|
||||||
// check for round-up: if rounding-nearest carried us to the hidden bit.
|
// check for round-up: if rounding-nearest carried us to the hidden bit.
|
||||||
am.power2 = (am.mantissa <
|
am.power2 = (am.mantissa <
|
||||||
(am_mant_t(1) << binary_format<T>::mantissa_explicit_bits()))
|
(am_mant_t(1) << binary_format<T>::mantissa_explicit_bits()))
|
||||||
|
|||||||
@ -43,7 +43,7 @@ from_chars(UC const *first, UC const *last, T &value,
|
|||||||
template <typename T, typename UC = char>
|
template <typename T, typename UC = char>
|
||||||
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||||
from_chars_advanced(UC const *first, UC const *last, T &value,
|
from_chars_advanced(UC const *first, UC const *last, T &value,
|
||||||
parse_options_t<UC> const options) noexcept;
|
parse_options_t<UC> const &options) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* from_chars for integer types.
|
* from_chars for integer types.
|
||||||
|
|||||||
@ -89,7 +89,7 @@ template <typename UC> struct parse_options_t {
|
|||||||
/** The character used as decimal point */
|
/** The character used as decimal point */
|
||||||
UC const decimal_point;
|
UC const decimal_point;
|
||||||
/** The base used for integers */
|
/** The base used for integers */
|
||||||
uint8_t const base; /* only allowed from 2 to 36 */
|
uint_fast8_t const base; /* only allowed from 2 to 36 */
|
||||||
FASTFLOAT_ASSUME(base >= 2 && base <= 36);
|
FASTFLOAT_ASSUME(base >= 2 && base <= 36);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -460,11 +460,11 @@ struct adjusted_mantissa {
|
|||||||
am_pow_t power2;
|
am_pow_t power2;
|
||||||
adjusted_mantissa() noexcept = default;
|
adjusted_mantissa() noexcept = default;
|
||||||
|
|
||||||
constexpr bool operator==(adjusted_mantissa const &o) const noexcept {
|
constexpr bool operator==(adjusted_mantissa const o) const noexcept {
|
||||||
return mantissa == o.mantissa && power2 == o.power2;
|
return mantissa == o.mantissa && power2 == o.power2;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool operator!=(adjusted_mantissa const &o) const noexcept {
|
constexpr bool operator!=(adjusted_mantissa const o) const noexcept {
|
||||||
return mantissa != o.mantissa || power2 != o.power2;
|
return mantissa != o.mantissa || power2 != o.power2;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1039,7 +1039,7 @@ fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void to_float(
|
|||||||
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
|
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
|
||||||
bool const negative,
|
bool const negative,
|
||||||
#endif
|
#endif
|
||||||
adjusted_mantissa const &am, T &value) noexcept {
|
adjusted_mantissa const am, T &value) noexcept {
|
||||||
using equiv_uint = equiv_uint_t<T>;
|
using equiv_uint = equiv_uint_t<T>;
|
||||||
equiv_uint word = equiv_uint(am.mantissa);
|
equiv_uint word = equiv_uint(am.mantissa);
|
||||||
word = equiv_uint(word | equiv_uint(am.power2)
|
word = equiv_uint(word | equiv_uint(am.power2)
|
||||||
@ -1195,18 +1195,18 @@ template <typename T> constexpr uint64_t int_luts<T>::min_safe_u64[];
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename UC>
|
template <typename UC>
|
||||||
fastfloat_really_inline constexpr uint8_t ch_to_digit(UC c) noexcept {
|
fastfloat_really_inline constexpr uint_fast8_t ch_to_digit(UC c) noexcept {
|
||||||
return int_luts<>::chdigit[static_cast<unsigned char>(c)];
|
return int_luts<>::chdigit[static_cast<unsigned char>(c)];
|
||||||
}
|
}
|
||||||
|
|
||||||
fastfloat_really_inline constexpr uint8_t
|
fastfloat_really_inline constexpr uint_fast8_t
|
||||||
max_digits_u64(uint8_t base) noexcept {
|
max_digits_u64(uint_fast8_t base) noexcept {
|
||||||
return int_luts<>::maxdigits_u64[base - 2];
|
return int_luts<>::maxdigits_u64[base - 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a u64 is exactly max_digits_u64() in length, this is
|
// If a u64 is exactly max_digits_u64() in length, this is
|
||||||
// the value below which it has definitely overflowed.
|
// the value below which it has definitely overflowed.
|
||||||
fastfloat_really_inline constexpr uint64_t min_safe_u64(uint8_t base) noexcept {
|
fastfloat_really_inline constexpr uint64_t min_safe_u64(uint_fast8_t base) noexcept {
|
||||||
return int_luts<>::min_safe_u64[base - 2];
|
return int_luts<>::min_safe_u64[base - 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -148,7 +148,7 @@ template <typename T> struct from_chars_caller {
|
|||||||
template <typename UC>
|
template <typename UC>
|
||||||
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
|
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
|
||||||
call(UC const *first, UC const *last, T &value,
|
call(UC const *first, UC const *last, T &value,
|
||||||
parse_options_t<UC> const options) noexcept {
|
parse_options_t<UC> const &options) noexcept {
|
||||||
return from_chars_advanced(first, last, value, options);
|
return from_chars_advanced(first, last, value, options);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -307,7 +307,7 @@ from_chars_advanced(parsed_number_string_t<UC> const &pns, T &value) noexcept {
|
|||||||
template <typename T, typename UC>
|
template <typename T, typename UC>
|
||||||
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||||
from_chars_float_advanced(UC const *first, UC const *last, T &value,
|
from_chars_float_advanced(UC const *first, UC const *last, T &value,
|
||||||
parse_options_t<UC> const options) noexcept {
|
parse_options_t<UC> const &options) noexcept {
|
||||||
|
|
||||||
static_assert(is_supported_float_type<T>::value,
|
static_assert(is_supported_float_type<T>::value,
|
||||||
"only some floating-point types are supported");
|
"only some floating-point types are supported");
|
||||||
@ -371,7 +371,7 @@ from_chars(UC const *first, UC const *last, T &value, int const base) noexcept {
|
|||||||
template <typename T, typename UC>
|
template <typename T, typename UC>
|
||||||
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||||
from_chars_int_advanced(UC const *first, UC const *last, T &value,
|
from_chars_int_advanced(UC const *first, UC const *last, T &value,
|
||||||
parse_options_t<UC> const options) noexcept {
|
parse_options_t<UC> const &options) noexcept {
|
||||||
|
|
||||||
static_assert(is_supported_integer_type<T>::value,
|
static_assert(is_supported_integer_type<T>::value,
|
||||||
"only integer types are supported");
|
"only integer types are supported");
|
||||||
@ -407,7 +407,7 @@ template <> struct from_chars_advanced_caller<1> {
|
|||||||
template <typename T, typename UC>
|
template <typename T, typename UC>
|
||||||
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
|
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
|
||||||
call(UC const *first, UC const *last, T &value,
|
call(UC const *first, UC const *last, T &value,
|
||||||
parse_options_t<UC> const options) noexcept {
|
parse_options_t<UC> const &options) noexcept {
|
||||||
return from_chars_float_advanced(first, last, value, options);
|
return from_chars_float_advanced(first, last, value, options);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -416,7 +416,7 @@ template <> struct from_chars_advanced_caller<2> {
|
|||||||
template <typename T, typename UC>
|
template <typename T, typename UC>
|
||||||
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
|
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
|
||||||
call(UC const *first, UC const *last, T &value,
|
call(UC const *first, UC const *last, T &value,
|
||||||
parse_options_t<UC> const options) noexcept {
|
parse_options_t<UC> const &options) noexcept {
|
||||||
return from_chars_int_advanced(first, last, value, options);
|
return from_chars_int_advanced(first, last, value, options);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -424,7 +424,7 @@ template <> struct from_chars_advanced_caller<2> {
|
|||||||
template <typename T, typename UC>
|
template <typename T, typename UC>
|
||||||
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||||
from_chars_advanced(UC const *first, UC const *last, T &value,
|
from_chars_advanced(UC const *first, UC const *last, T &value,
|
||||||
parse_options_t<UC> const options) noexcept {
|
parse_options_t<UC> const &options) noexcept {
|
||||||
return from_chars_advanced_caller<
|
return from_chars_advanced_caller<
|
||||||
size_t(is_supported_float_type<T>::value) +
|
size_t(is_supported_float_type<T>::value) +
|
||||||
2 * size_t(is_supported_integer_type<T>::value)>::call(first, last, value,
|
2 * size_t(is_supported_integer_type<T>::value)>::call(first, last, value,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user