mirror of
https://github.com/fastfloat/fast_float.git
synced 2025-12-06 16:56:57 +08:00
* Added a config macro FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN and FASTFLOAT_DISALLOW_NAN. This both allow to significantly reduce code size and speedup your code when you use fast_float as a part of your parser.
This commit is contained in:
parent
3c5b166f6c
commit
b0b1954c87
@ -255,7 +255,9 @@ template <typename UC> struct parsed_number_string_t {
|
|||||||
int64_t exponent{0};
|
int64_t exponent{0};
|
||||||
uint64_t mantissa{0};
|
uint64_t mantissa{0};
|
||||||
UC const *lastmatch{nullptr};
|
UC const *lastmatch{nullptr};
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
bool negative{false};
|
bool negative{false};
|
||||||
|
#endif
|
||||||
bool valid{false};
|
bool valid{false};
|
||||||
bool too_many_digits{false};
|
bool too_many_digits{false};
|
||||||
// contains the range of the significant digits
|
// contains the range of the significant digits
|
||||||
@ -290,6 +292,7 @@ parse_number_string(UC const *p, UC const *pend,
|
|||||||
answer.valid = false;
|
answer.valid = false;
|
||||||
answer.too_many_digits = false;
|
answer.too_many_digits = false;
|
||||||
// assume p < pend, so dereference without checks;
|
// assume p < pend, so dereference without checks;
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
answer.negative = (*p == UC('-'));
|
answer.negative = (*p == UC('-'));
|
||||||
// C++17 20.19.3.(7.1) explicitly forbids '+' sign here
|
// C++17 20.19.3.(7.1) explicitly forbids '+' sign here
|
||||||
if ((*p == UC('-')) ||
|
if ((*p == UC('-')) ||
|
||||||
@ -314,6 +317,7 @@ parse_number_string(UC const *p, UC const *pend,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
UC const *const start_digits = p;
|
UC const *const start_digits = p;
|
||||||
|
|
||||||
uint64_t i = 0; // an unsigned int avoids signed overflows (which are bad)
|
uint64_t i = 0; // an unsigned int avoids signed overflows (which are bad)
|
||||||
@ -481,6 +485,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
|
|||||||
|
|
||||||
UC const *const first = p;
|
UC const *const first = p;
|
||||||
|
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
bool const negative = (*p == UC('-'));
|
bool const negative = (*p == UC('-'));
|
||||||
#ifdef FASTFLOAT_VISUAL_STUDIO
|
#ifdef FASTFLOAT_VISUAL_STUDIO
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
@ -498,6 +503,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
|
|||||||
(uint64_t(fmt & chars_format::allow_leading_plus) && (*p == UC('+')))) {
|
(uint64_t(fmt & chars_format::allow_leading_plus) && (*p == UC('+')))) {
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
UC const *const start_num = p;
|
UC const *const start_num = p;
|
||||||
|
|
||||||
@ -553,12 +559,17 @@ parse_int_string(UC const *p, UC const *pend, T &value,
|
|||||||
|
|
||||||
// check other types overflow
|
// check other types overflow
|
||||||
if (!std::is_same<T, uint64_t>::value) {
|
if (!std::is_same<T, uint64_t>::value) {
|
||||||
if (i > uint64_t(std::numeric_limits<T>::max()) + uint64_t(negative)) {
|
if (i > uint64_t(std::numeric_limits<T>::max())
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
|
+ uint64_t(negative)
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
answer.ec = std::errc::result_out_of_range;
|
answer.ec = std::errc::result_out_of_range;
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
if (negative) {
|
if (negative) {
|
||||||
#ifdef FASTFLOAT_VISUAL_STUDIO
|
#ifdef FASTFLOAT_VISUAL_STUDIO
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
@ -576,8 +587,11 @@ parse_int_string(UC const *p, UC const *pend, T &value,
|
|||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
#endif
|
||||||
value = T(i);
|
value = T(i);
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
answer.ec = std::errc();
|
answer.ec = std::errc();
|
||||||
return answer;
|
return answer;
|
||||||
|
|||||||
@ -381,7 +381,11 @@ inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa negative_digit_comp(
|
|||||||
round<T>(am_b,
|
round<T>(am_b,
|
||||||
[](adjusted_mantissa &a, int32_t shift) { round_down(a, shift); });
|
[](adjusted_mantissa &a, int32_t shift) { round_down(a, shift); });
|
||||||
T b;
|
T b;
|
||||||
to_float(false, am_b, b);
|
to_float(
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
|
false,
|
||||||
|
#endif
|
||||||
|
am_b, b);
|
||||||
adjusted_mantissa theor = to_extended_halfway(b);
|
adjusted_mantissa theor = to_extended_halfway(b);
|
||||||
bigint theor_digits(theor.mantissa);
|
bigint theor_digits(theor.mantissa);
|
||||||
int32_t theor_exp = theor.power2;
|
int32_t theor_exp = theor.power2;
|
||||||
|
|||||||
@ -51,8 +51,10 @@ enum class chars_format : uint64_t {
|
|||||||
json_or_infnan = uint64_t(detail::basic_json_fmt) | fixed | scientific,
|
json_or_infnan = uint64_t(detail::basic_json_fmt) | fixed | scientific,
|
||||||
fortran = uint64_t(detail::basic_fortran_fmt) | fixed | scientific,
|
fortran = uint64_t(detail::basic_fortran_fmt) | fixed | scientific,
|
||||||
general = fixed | scientific,
|
general = fixed | scientific,
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
allow_leading_plus = 1 << 7,
|
allow_leading_plus = 1 << 7,
|
||||||
skip_white_space = 1 << 8,
|
skip_white_space = 1 << 8,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename UC> struct from_chars_result_t {
|
template <typename UC> struct from_chars_result_t {
|
||||||
@ -606,6 +608,8 @@ template <> inline constexpr int binary_format<float>::infinite_power() {
|
|||||||
return 0xFF;
|
return 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
|
|
||||||
template <> inline constexpr int binary_format<double>::sign_index() {
|
template <> inline constexpr int binary_format<double>::sign_index() {
|
||||||
return 63;
|
return 63;
|
||||||
}
|
}
|
||||||
@ -614,6 +618,8 @@ template <> inline constexpr int binary_format<float>::sign_index() {
|
|||||||
return 31;
|
return 31;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline constexpr int binary_format<double>::max_exponent_fast_path() {
|
inline constexpr int binary_format<double>::max_exponent_fast_path() {
|
||||||
return 22;
|
return 22;
|
||||||
@ -979,13 +985,19 @@ binary_format<double>::hidden_bit_mask() {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void
|
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void
|
||||||
to_float(bool negative, adjusted_mantissa am, T &value) {
|
to_float(
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
|
bool negative,
|
||||||
|
#endif
|
||||||
|
adjusted_mantissa am, T &value) {
|
||||||
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)
|
||||||
<< binary_format<T>::mantissa_explicit_bits());
|
<< binary_format<T>::mantissa_explicit_bits());
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
word =
|
word =
|
||||||
equiv_uint(word | equiv_uint(negative) << binary_format<T>::sign_index());
|
equiv_uint(word | equiv_uint(negative) << binary_format<T>::sign_index());
|
||||||
|
#endif
|
||||||
#if FASTFLOAT_HAS_BIT_CAST
|
#if FASTFLOAT_HAS_BIT_CAST
|
||||||
value = std::bit_cast<T>(word);
|
value = std::bit_cast<T>(word);
|
||||||
#else
|
#else
|
||||||
@ -993,6 +1005,8 @@ to_float(bool negative, adjusted_mantissa am, T &value) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
|
|
||||||
template <typename = void> struct space_lut {
|
template <typename = void> struct space_lut {
|
||||||
static constexpr bool value[] = {
|
static constexpr bool value[] = {
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
@ -1018,6 +1032,8 @@ template <typename UC> constexpr bool is_space(UC c) {
|
|||||||
return c < 256 && space_lut<>::value[uint8_t(c)];
|
return c < 256 && space_lut<>::value[uint8_t(c)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename UC> static constexpr uint64_t int_cmp_zeros() {
|
template <typename UC> static constexpr uint64_t int_cmp_zeros() {
|
||||||
static_assert((sizeof(UC) == 1) || (sizeof(UC) == 2) || (sizeof(UC) == 4),
|
static_assert((sizeof(UC) == 1) || (sizeof(UC) == 2) || (sizeof(UC) == 4),
|
||||||
"Unsupported character size");
|
"Unsupported character size");
|
||||||
@ -1032,6 +1048,8 @@ template <typename UC> static constexpr int int_cmp_len() {
|
|||||||
return sizeof(uint64_t) / sizeof(UC);
|
return sizeof(uint64_t) / sizeof(UC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_NAN
|
||||||
|
|
||||||
template <typename UC> constexpr UC const *str_const_nan();
|
template <typename UC> constexpr UC const *str_const_nan();
|
||||||
|
|
||||||
template <> constexpr char const *str_const_nan<char>() { return "nan"; }
|
template <> constexpr char const *str_const_nan<char>() { return "nan"; }
|
||||||
@ -1052,6 +1070,8 @@ template <> constexpr char8_t const *str_const_nan<char8_t>() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename UC> constexpr UC const *str_const_inf();
|
template <typename UC> constexpr UC const *str_const_inf();
|
||||||
|
|
||||||
template <> constexpr char const *str_const_inf<char>() { return "infinity"; }
|
template <> constexpr char const *str_const_inf<char>() { return "infinity"; }
|
||||||
@ -1223,7 +1243,12 @@ operator^=(chars_format &lhs, chars_format rhs) noexcept {
|
|||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
// adjust for deprecated feature macros
|
// adjust for deprecated feature macros
|
||||||
constexpr chars_format adjust_for_feature_macros(chars_format fmt) {
|
fastfloat_really_inline constexpr chars_format adjust_for_feature_macros(chars_format fmt) {
|
||||||
|
#if defined(FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN) && \
|
||||||
|
(defined(FASTFLOAT_ALLOWS_LEADING_PLUS) || \
|
||||||
|
defined(FASTFLOAT_SKIP_WHITE_SPACE))
|
||||||
|
#error "FASTFLOAT_ALLOWS_LEADING_PLUS and FASTFLOAT_SKIP_WHITE_SPACE require FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN to be undefined"
|
||||||
|
#endif
|
||||||
return fmt
|
return fmt
|
||||||
#ifdef FASTFLOAT_ALLOWS_LEADING_PLUS
|
#ifdef FASTFLOAT_ALLOWS_LEADING_PLUS
|
||||||
| chars_format::allow_leading_plus
|
| chars_format::allow_leading_plus
|
||||||
|
|||||||
@ -22,11 +22,16 @@ namespace detail {
|
|||||||
template <typename T, typename UC>
|
template <typename T, typename UC>
|
||||||
from_chars_result_t<UC>
|
from_chars_result_t<UC>
|
||||||
FASTFLOAT_CONSTEXPR14 parse_infnan(UC const *first, UC const *last,
|
FASTFLOAT_CONSTEXPR14 parse_infnan(UC const *first, UC const *last,
|
||||||
T &value, chars_format fmt) noexcept {
|
T &value
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
|
, chars_format fmt
|
||||||
|
#endif
|
||||||
|
) noexcept {
|
||||||
from_chars_result_t<UC> answer{};
|
from_chars_result_t<UC> answer{};
|
||||||
answer.ptr = first;
|
answer.ptr = first;
|
||||||
answer.ec = std::errc(); // be optimistic
|
answer.ec = std::errc(); // be optimistic
|
||||||
// assume first < last, so dereference without checks;
|
// assume first < last, so dereference without checks;
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
bool const minusSign = (*first == UC('-'));
|
bool const minusSign = (*first == UC('-'));
|
||||||
// C++17 20.19.3.(7.1) explicitly forbids '+' sign here
|
// C++17 20.19.3.(7.1) explicitly forbids '+' sign here
|
||||||
if ((*first == UC('-')) ||
|
if ((*first == UC('-')) ||
|
||||||
@ -34,11 +39,16 @@ from_chars_result_t<UC>
|
|||||||
(*first == UC('+')))) {
|
(*first == UC('+')))) {
|
||||||
++first;
|
++first;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (last - first >= 3) {
|
if (last - first >= 3) {
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_NAN
|
||||||
if (fastfloat_strncasecmp(first, str_const_nan<UC>(), 3)) {
|
if (fastfloat_strncasecmp(first, str_const_nan<UC>(), 3)) {
|
||||||
answer.ptr = (first += 3);
|
answer.ptr = (first += 3);
|
||||||
value = minusSign ? -std::numeric_limits<T>::quiet_NaN()
|
value =
|
||||||
: std::numeric_limits<T>::quiet_NaN();
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
|
minusSign ? -std::numeric_limits<T>::quiet_NaN() :
|
||||||
|
#endif
|
||||||
|
std::numeric_limits<T>::quiet_NaN();
|
||||||
// Check for possible nan(n-char-seq-opt), C++17 20.19.3.7,
|
// Check for possible nan(n-char-seq-opt), C++17 20.19.3.7,
|
||||||
// C11 7.20.1.3.3. At least MSVC produces nan(ind) and nan(snan).
|
// C11 7.20.1.3.3. At least MSVC produces nan(ind) and nan(snan).
|
||||||
if (first != last && *first == UC('(')) {
|
if (first != last && *first == UC('(')) {
|
||||||
@ -54,6 +64,7 @@ from_chars_result_t<UC>
|
|||||||
}
|
}
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (fastfloat_strncasecmp(first, str_const_inf<UC>(), 3)) {
|
if (fastfloat_strncasecmp(first, str_const_inf<UC>(), 3)) {
|
||||||
if ((last - first >= 8) &&
|
if ((last - first >= 8) &&
|
||||||
fastfloat_strncasecmp(first + 3, str_const_inf<UC>() + 3, 5)) {
|
fastfloat_strncasecmp(first + 3, str_const_inf<UC>() + 3, 5)) {
|
||||||
@ -61,8 +72,11 @@ from_chars_result_t<UC>
|
|||||||
} else {
|
} else {
|
||||||
answer.ptr = first + 3;
|
answer.ptr = first + 3;
|
||||||
}
|
}
|
||||||
value = minusSign ? -std::numeric_limits<T>::infinity()
|
value =
|
||||||
: std::numeric_limits<T>::infinity();
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
|
minusSign ? -std::numeric_limits<T>::infinity() :
|
||||||
|
#endif
|
||||||
|
std::numeric_limits<T>::infinity();
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -231,9 +245,11 @@ from_chars_advanced(parsed_number_string_t<UC> &pns, T &value) noexcept {
|
|||||||
} else {
|
} else {
|
||||||
value = value * binary_format<T>::exact_power_of_ten(pns.exponent);
|
value = value * binary_format<T>::exact_power_of_ten(pns.exponent);
|
||||||
}
|
}
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
if (pns.negative) {
|
if (pns.negative) {
|
||||||
value = -value;
|
value = -value;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -246,15 +262,21 @@ from_chars_advanced(parsed_number_string_t<UC> &pns, T &value) noexcept {
|
|||||||
#if defined(__clang__) || defined(FASTFLOAT_32BIT)
|
#if defined(__clang__) || defined(FASTFLOAT_32BIT)
|
||||||
// Clang may map 0 to -0.0 when fegetround() == FE_DOWNWARD
|
// Clang may map 0 to -0.0 when fegetround() == FE_DOWNWARD
|
||||||
if (pns.mantissa == 0) {
|
if (pns.mantissa == 0) {
|
||||||
value = pns.negative ? T(-0.) : T(0.);
|
value =
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
|
pns.negative ? T(-0.) :
|
||||||
|
#endif
|
||||||
|
T(0.);
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
value = T(pns.mantissa) *
|
value = T(pns.mantissa) *
|
||||||
binary_format<T>::exact_power_of_ten(pns.exponent);
|
binary_format<T>::exact_power_of_ten(pns.exponent);
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
if (pns.negative) {
|
if (pns.negative) {
|
||||||
value = -value;
|
value = -value;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -272,7 +294,11 @@ from_chars_advanced(parsed_number_string_t<UC> &pns, T &value) noexcept {
|
|||||||
if (am.power2 < 0) {
|
if (am.power2 < 0) {
|
||||||
am = digit_comp<T>(pns, am);
|
am = digit_comp<T>(pns, am);
|
||||||
}
|
}
|
||||||
to_float(pns.negative, am, value);
|
to_float(
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
|
pns.negative,
|
||||||
|
#endif
|
||||||
|
am, value);
|
||||||
// Test for over/underflow.
|
// Test for over/underflow.
|
||||||
if ((pns.mantissa != 0 && am.mantissa == 0 && am.power2 == 0) ||
|
if ((pns.mantissa != 0 && am.mantissa == 0 && am.power2 == 0) ||
|
||||||
am.power2 == binary_format<T>::infinite_power()) {
|
am.power2 == binary_format<T>::infinite_power()) {
|
||||||
@ -294,11 +320,13 @@ from_chars_float_advanced(UC const *first, UC const *last, T &value,
|
|||||||
chars_format const fmt = detail::adjust_for_feature_macros(options.format);
|
chars_format const fmt = detail::adjust_for_feature_macros(options.format);
|
||||||
|
|
||||||
from_chars_result_t<UC> answer;
|
from_chars_result_t<UC> answer;
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
if (uint64_t(fmt & chars_format::skip_white_space)) {
|
if (uint64_t(fmt & chars_format::skip_white_space)) {
|
||||||
while ((first != last) && fast_float::is_space(*first)) {
|
while ((first != last) && fast_float::is_space(*first)) {
|
||||||
first++;
|
first++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (first == last) {
|
if (first == last) {
|
||||||
answer.ec = std::errc::invalid_argument;
|
answer.ec = std::errc::invalid_argument;
|
||||||
answer.ptr = first;
|
answer.ptr = first;
|
||||||
@ -312,7 +340,11 @@ from_chars_float_advanced(UC const *first, UC const *last, T &value,
|
|||||||
answer.ptr = first;
|
answer.ptr = first;
|
||||||
return answer;
|
return answer;
|
||||||
} else {
|
} else {
|
||||||
return detail::parse_infnan(first, last, value, fmt);
|
return detail::parse_infnan(first, last, value
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
|
, fmt
|
||||||
|
#endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,11 +380,13 @@ from_chars_int_advanced(UC const *first, UC const *last, T &value,
|
|||||||
int const base = options.base;
|
int const base = options.base;
|
||||||
|
|
||||||
from_chars_result_t<UC> answer;
|
from_chars_result_t<UC> answer;
|
||||||
|
#ifndef FASTFLOAT_DISALLOW_ANY_LEADING_SYMBOLS_INCLUDE_SIGN
|
||||||
if (uint64_t(fmt & chars_format::skip_white_space)) {
|
if (uint64_t(fmt & chars_format::skip_white_space)) {
|
||||||
while ((first != last) && fast_float::is_space(*first)) {
|
while ((first != last) && fast_float::is_space(*first)) {
|
||||||
first++;
|
first++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (first == last || base < 2 || base > 36) {
|
if (first == last || base < 2 || base > 36) {
|
||||||
answer.ec = std::errc::invalid_argument;
|
answer.ec = std::errc::invalid_argument;
|
||||||
answer.ptr = first;
|
answer.ptr = first;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user