diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2024-01-01 21:13:58 +0000 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2024-01-02 09:28:44 +0000 |
commit | 93cc4a3144fe833eab4677a2eddc622506d646d6 (patch) | |
tree | 043ef4d3e3c9e7bacfae6ea7aec93db90d65be38 /searchlib/src | |
parent | 4a3ae51391fbcda7d620f7669dac537cbc1b4df4 (diff) |
Use std::from_chars instead of strtoll.
Diffstat (limited to 'searchlib/src')
-rw-r--r-- | searchlib/src/vespa/searchlib/query/query_term_simple.cpp | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/searchlib/src/vespa/searchlib/query/query_term_simple.cpp b/searchlib/src/vespa/searchlib/query/query_term_simple.cpp index 8df7764c183..fb2be58c536 100644 --- a/searchlib/src/vespa/searchlib/query/query_term_simple.cpp +++ b/searchlib/src/vespa/searchlib/query/query_term_simple.cpp @@ -7,6 +7,7 @@ #include <vespa/vespalib/locale/c.h> #include <cmath> #include <limits> +#include <charconv> namespace { @@ -161,24 +162,35 @@ QueryTermSimple::getRange() const return getIntegerRange<int64_t>(); } -template <int B> struct IntDecoder { - static int64_t fromstr(const char * v, char ** end) { return strtoll(v, end, B); } - static int64_t nearestDownwd(int64_t n, int64_t min) { return (n > min ? n - 1 : n); } - static int64_t nearestUpward(int64_t n, int64_t max) { return (n < max ? n + 1 : n); } + static int64_t fromstr(const char * q, const char * qend, char ** end) noexcept { + int64_t v(0); + for (;q < qend && isspace(*q); q++); + std::from_chars_result err = std::from_chars(q, qend, v, 10); + if (err.ec == std::errc::result_out_of_range) { + v = (*q == '-') ? std::numeric_limits<int64_t>::min() : std::numeric_limits<int64_t>::max(); + } + *end = const_cast<char *>(err.ptr); + return v; + } + static int64_t nearestDownwd(int64_t n, int64_t min) noexcept { return (n > min ? n - 1 : n); } + static int64_t nearestUpward(int64_t n, int64_t max) noexcept { return (n < max ? n + 1 : n); } }; struct DoubleDecoder { - static double fromstr(const char * v, char ** end) { return vespalib::locale::c::strtod(v, end); } - static double nearestDownwd(double n, double min) { return std::nextafterf(n, min); } - static double nearestUpward(double n, double max) { return std::nextafterf(n, max); } + static double fromstr(const char * q, const char * qend, char ** end) { + (void) qend; + return vespalib::locale::c::strtod(q, end); + } + static double nearestDownwd(double n, double min) noexcept { return std::nextafterf(n, min); } + static double nearestUpward(double n, double max) noexcept { return std::nextafterf(n, max); } }; bool QueryTermSimple::getAsIntegerTerm(int64_t & lower, int64_t & upper) const { lower = std::numeric_limits<int64_t>::min(); upper = std::numeric_limits<int64_t>::max(); - return getAsNumericTerm(lower, upper, IntDecoder<10>()); + return getAsNumericTerm(lower, upper, IntDecoder()); } bool QueryTermSimple::getAsDoubleTerm(double & lower, double & upper) const @@ -266,11 +278,12 @@ QueryTermSimple::getAsNumericTerm(T & lower, T & upper, D d) const T low(lower); T high(upper); const char * q = _term.c_str(); + const char * qend = q + sz; const char first(q[0]); const char last(q[sz-1]); bool isRange = (first == '<') || (first == '>') || (first == '['); q += isRange ? 1 : 0; - T ll = d.fromstr(q, &err); + T ll = d.fromstr(q, qend, &err); bool valid = isValid() && ((*err == 0) || (*err == ';')); if (!valid) return false; @@ -289,7 +302,7 @@ QueryTermSimple::getAsNumericTerm(T & lower, T & upper, D d) const low = (first == '[') ? ll : d.nearestUpward(ll, upper); } q = err + 1; - T hh = d.fromstr(q, &err); + T hh = d.fromstr(q, qend, &err); bool hasUpperLimit(q != err); if (*err == ';') { err = const_cast<char *>(_term.end() - 1); |