mirror of
https://github.com/fmtlib/fmt.git
synced 2025-01-14 03:39:03 +00:00
Optimize parse_nonnegative_int
This commit is contained in:
parent
f28cf3302d
commit
3c8fad126c
@ -8,10 +8,10 @@
|
|||||||
#ifndef FMT_CORE_H_
|
#ifndef FMT_CORE_H_
|
||||||
#define FMT_CORE_H_
|
#define FMT_CORE_H_
|
||||||
|
|
||||||
#include <climits> // INT_MAX
|
#include <cstdio> // std::FILE
|
||||||
#include <cstdio> // std::FILE
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <limits>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
@ -2103,21 +2103,25 @@ template <typename Char, typename ErrorHandler>
|
|||||||
FMT_CONSTEXPR auto parse_nonnegative_int(const Char*& begin, const Char* end,
|
FMT_CONSTEXPR auto parse_nonnegative_int(const Char*& begin, const Char* end,
|
||||||
ErrorHandler&& eh) -> int {
|
ErrorHandler&& eh) -> int {
|
||||||
FMT_ASSERT(begin != end && '0' <= *begin && *begin <= '9', "");
|
FMT_ASSERT(begin != end && '0' <= *begin && *begin <= '9', "");
|
||||||
unsigned value = 0;
|
unsigned value = 0, prev = 0;
|
||||||
// Convert to unsigned to prevent a warning.
|
auto p = begin;
|
||||||
const unsigned max_int = to_unsigned(INT_MAX);
|
|
||||||
unsigned big = max_int / 10;
|
|
||||||
do {
|
do {
|
||||||
// Check for overflow.
|
prev = value;
|
||||||
if (value > big) {
|
value = value * 10 + unsigned(*p - '0');
|
||||||
value = max_int + 1;
|
++p;
|
||||||
break;
|
} while (p != end && '0' <= *p && *p <= '9');
|
||||||
}
|
auto num_digits = p - begin;
|
||||||
value = value * 10 + unsigned(*begin - '0');
|
begin = p;
|
||||||
++begin;
|
if (num_digits <= std::numeric_limits<int>::digits10)
|
||||||
} while (begin != end && '0' <= *begin && *begin <= '9');
|
return static_cast<int>(value);
|
||||||
if (value > max_int) eh.on_error("number is too big");
|
// Check for overflow.
|
||||||
return static_cast<int>(value);
|
const unsigned big = to_unsigned((std::numeric_limits<int>::max)());
|
||||||
|
if (num_digits == std::numeric_limits<int>::digits10 + 1 &&
|
||||||
|
prev * 10ull + unsigned(p[-1] - '0') <= big) {
|
||||||
|
return static_cast<int>(value);
|
||||||
|
}
|
||||||
|
eh.on_error("number is too big");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses fill and alignment.
|
// Parses fill and alignment.
|
||||||
@ -2454,8 +2458,8 @@ class compile_parse_context
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit FMT_CONSTEXPR compile_parse_context(
|
explicit FMT_CONSTEXPR compile_parse_context(
|
||||||
basic_string_view<Char> format_str, int num_args = INT_MAX,
|
basic_string_view<Char> format_str,
|
||||||
ErrorHandler eh = {})
|
int num_args = (std::numeric_limits<int>::max)(), ErrorHandler eh = {})
|
||||||
: base(format_str, eh), num_args_(num_args) {}
|
: base(format_str, eh), num_args_(num_args) {}
|
||||||
|
|
||||||
FMT_CONSTEXPR auto next_arg_id() -> int {
|
FMT_CONSTEXPR auto next_arg_id() -> int {
|
||||||
|
Loading…
Reference in New Issue
Block a user