summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2024-01-03 18:02:24 +0100
committerGitHub <noreply@github.com>2024-01-03 18:02:24 +0100
commitec85223814c612a4cf2abb4e99c30e7a53605b38 (patch)
tree87ffea2b9e5e394eb229d07973c64ba0b09226d5
parent7c357a7731240e0fcb1d496e457bbad6648cbeae (diff)
parent9da9d445a93a008f1623ce0719e99be813bd1a71 (diff)
Merge pull request #29774 from vespa-engine/balder/strtod-2-from_chars
Use std::from_chars instead of strtod. Also improve handling of float…
-rw-r--r--searchlib/src/tests/query/streaming_query_test.cpp91
-rw-r--r--searchlib/src/vespa/searchlib/query/query_term_simple.cpp146
-rw-r--r--searchlib/src/vespa/searchlib/query/query_term_simple.h59
3 files changed, 161 insertions, 135 deletions
diff --git a/searchlib/src/tests/query/streaming_query_test.cpp b/searchlib/src/tests/query/streaming_query_test.cpp
index 0a751e96222..f5370785167 100644
--- a/searchlib/src/tests/query/streaming_query_test.cpp
+++ b/searchlib/src/tests/query/streaming_query_test.cpp
@@ -38,7 +38,7 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, 7);
EXPECT_EQ(ib, 7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, 7);
EXPECT_EQ(db, 7);
}
@@ -48,15 +48,24 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -7);
EXPECT_EQ(ib, -7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, -7);
EXPECT_EQ(db, -7);
}
+ {
+ QueryTerm q(factory.create(), "+7", "index", TermType::WORD);
+ EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
+ EXPECT_EQ(ia, 7);
+ EXPECT_EQ(ib, 7);
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, 7);
+ EXPECT_EQ(db, 7);
+ }
{
QueryTerm q(factory.create(), "7.5", "index", TermType::WORD);
EXPECT_TRUE(!q.getAsIntegerTerm(ia, ib));
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, 7.5);
EXPECT_EQ(db, 7.5);
}
@@ -64,7 +73,7 @@ TEST(StreamingQueryTest, test_query_language)
{
QueryTerm q(factory.create(), "-7.5", "index", TermType::WORD);
EXPECT_TRUE(!q.getAsIntegerTerm(ia, ib));
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, -7.5);
EXPECT_EQ(db, -7.5);
}
@@ -74,8 +83,8 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, 6);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, -std::numeric_limits<double>::max());
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, -std::numeric_limits<double>::infinity());
EXPECT_LT(db, 7);
EXPECT_GT(db, 6.99);
}
@@ -85,8 +94,8 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, 7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, -std::numeric_limits<double>::max());
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, -std::numeric_limits<double>::infinity());
EXPECT_EQ(db, 7);
}
@@ -95,10 +104,10 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, 8);
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_GT(da, 7);
EXPECT_LT(da, 7.01);
- EXPECT_EQ(db, std::numeric_limits<double>::max());
+ EXPECT_EQ(db, std::numeric_limits<double>::infinity());
}
{
@@ -106,9 +115,9 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, 7);
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, 7);
- EXPECT_EQ(db, std::numeric_limits<double>::max());
+ EXPECT_EQ(db, std::numeric_limits<double>::infinity());
}
{
@@ -116,7 +125,7 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -7);
EXPECT_EQ(ib, 7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, -7);
EXPECT_EQ(db, 7);
}
@@ -126,7 +135,7 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_FALSE(q.getAsIntegerTerm(ia, ib)); // This is dubious and perhaps a regression.
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, -7.1);
EXPECT_EQ(db, 7.1);
}
@@ -136,7 +145,7 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_FALSE(q.getAsIntegerTerm(ia, ib)); // This is dubious and perhaps a regression.
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, 500.0);
EXPECT_EQ(db, std::numeric_limits<double>::max());
}
@@ -147,8 +156,8 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -6);
EXPECT_EQ(ib, 7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, std::nextafterf(minusSeven, seven));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, std::nextafter(minusSeven, seven));
EXPECT_EQ(db, seven);
}
@@ -157,9 +166,9 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -6);
EXPECT_EQ(ib, 6);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, std::nextafterf(minusSeven, seven));
- EXPECT_EQ(db, std::nextafterf(seven, minusSeven));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, std::nextafter(minusSeven, seven));
+ EXPECT_EQ(db, std::nextafter(seven, minusSeven));
}
{
@@ -174,9 +183,9 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -7);
EXPECT_EQ(ib, 6);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, minusSeven);
- EXPECT_EQ(db, std::nextafterf(seven, minusSeven));
+ EXPECT_EQ(db, std::nextafter(seven, minusSeven));
}
{
@@ -184,8 +193,8 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, -8);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, -std::numeric_limits<double>::max());
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, -std::numeric_limits<double>::infinity());
EXPECT_LT(db, -7);
EXPECT_GT(db, -7.01);
}
@@ -195,8 +204,8 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, -7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, -std::numeric_limits<double>::max());
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, -std::numeric_limits<double>::infinity());
EXPECT_EQ(db, -7);
}
@@ -205,8 +214,8 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, -7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, -std::numeric_limits<double>::max());
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, -std::numeric_limits<double>::infinity());
EXPECT_EQ(db, -7);
}
@@ -215,10 +224,10 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -6);
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_GT(da, -7);
EXPECT_LT(da, -6.99);
- EXPECT_EQ(db, std::numeric_limits<double>::max());
+ EXPECT_EQ(db, std::numeric_limits<double>::infinity());
}
{
@@ -226,9 +235,9 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -7);
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, -7);
- EXPECT_EQ(db, std::numeric_limits<double>::max());
+ EXPECT_EQ(db, std::numeric_limits<double>::infinity());
}
{
@@ -236,15 +245,15 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -7);
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, -7);
- EXPECT_EQ(db, std::numeric_limits<double>::max());
+ EXPECT_EQ(db, std::numeric_limits<double>::infinity());
}
{
QueryTerm q(factory.create(), "a", "index", TermType::WORD);
EXPECT_TRUE(!q.getAsIntegerTerm(ia, ib));
- EXPECT_TRUE(!q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(!q.getAsFloatTerm(da, db));
}
{
@@ -645,11 +654,11 @@ TEST(StreamingQueryTest, require_that_ascending_range_can_be_specified_with_limi
QueryTerm ascending_query(eqnr.create(), "[;;500]", "index", TermType::WORD);
EXPECT_TRUE(ascending_query.getAsIntegerTerm(low_integer, high_integer));
- EXPECT_TRUE(ascending_query.getAsDoubleTerm(low_double, high_double));
+ EXPECT_TRUE(ascending_query.getAsFloatTerm(low_double, high_double));
EXPECT_EQ(std::numeric_limits<int64_t>::min(), low_integer);
EXPECT_EQ(std::numeric_limits<int64_t>::max(), high_integer);
- EXPECT_EQ(-std::numeric_limits<double>::max(), low_double);
- EXPECT_EQ(std::numeric_limits<double>::max(), high_double);
+ EXPECT_EQ(-std::numeric_limits<double>::infinity(), low_double);
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), high_double);
EXPECT_EQ(500, ascending_query.getRangeLimit());
}
@@ -664,11 +673,11 @@ TEST(StreamingQueryTest, require_that_descending_range_can_be_specified_with_lim
QueryTerm descending_query(eqnr.create(), "[;;-500]", "index", TermType::WORD);
EXPECT_TRUE(descending_query.getAsIntegerTerm(low_integer, high_integer));
- EXPECT_TRUE(descending_query.getAsDoubleTerm(low_double, high_double));
+ EXPECT_TRUE(descending_query.getAsFloatTerm(low_double, high_double));
EXPECT_EQ(std::numeric_limits<int64_t>::min(), low_integer);
EXPECT_EQ(std::numeric_limits<int64_t>::max(), high_integer);
- EXPECT_EQ(-std::numeric_limits<double>::max(), low_double);
- EXPECT_EQ(std::numeric_limits<double>::max(), high_double);
+ EXPECT_EQ(-std::numeric_limits<double>::infinity(), low_double);
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), high_double);
EXPECT_EQ(-500, descending_query.getRangeLimit());
}
diff --git a/searchlib/src/vespa/searchlib/query/query_term_simple.cpp b/searchlib/src/vespa/searchlib/query/query_term_simple.cpp
index fb2be58c536..e6cea9c752b 100644
--- a/searchlib/src/vespa/searchlib/query/query_term_simple.cpp
+++ b/searchlib/src/vespa/searchlib/query/query_term_simple.cpp
@@ -4,7 +4,6 @@
#include "base.h"
#include <vespa/vespalib/objects/visit.h>
#include <vespa/vespalib/util/classname.h>
-#include <vespa/vespalib/locale/c.h>
#include <cmath>
#include <limits>
#include <charconv>
@@ -12,11 +11,59 @@
namespace {
template <typename N>
-bool isValidInteger(int64_t value)
+constexpr bool isValidInteger(int64_t value) noexcept
{
- return value >= std::numeric_limits<N>::min() && value <= std::numeric_limits<N>::max();
+ return (value >= std::numeric_limits<N>::min()) &&
+ (value <= std::numeric_limits<N>::max());
}
+constexpr bool isRepresentableByInt64(double d) noexcept {
+ return (d > double(std::numeric_limits<int64_t>::min())) &&
+ (d < double(std::numeric_limits<int64_t>::max()));
+}
+
+bool isFullRange(vespalib::stringref s) noexcept {
+ const size_t sz(s.size());
+ return (sz >= 3u) &&
+ (s[0] == '<' || s[0] == '[') &&
+ (s[sz-1] == '>' || s[sz-1] == ']');
+}
+
+struct IntDecoder {
+ static int64_t fromstr(const char * q, const char * qend, const char ** end) noexcept {
+ int64_t v(0);
+ for (;q < qend && (isspace(*q) || (*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 = 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); }
+};
+
+template <typename T>
+struct FloatDecoder {
+ static T fromstr(const char * q, const char * qend, const char ** end) noexcept {
+ T v(0);
+ for (;q < qend && (isspace(*q) || (*q == '+')); q++);
+ std::from_chars_result err = std::from_chars(q, qend, v);
+ if (err.ec == std::errc::result_out_of_range) {
+ v = (*q == '-') ? -std::numeric_limits<T>::infinity() : std::numeric_limits<T>::infinity();
+ }
+ *end = err.ptr;
+ return v;
+ }
+ static T nearestDownwd(T n, T min) noexcept {
+ return std::nextafter(n, min);
+ }
+ static T nearestUpward(T n, T max) noexcept {
+ return std::nextafter(n, max);
+ }
+};
+
}
namespace search {
@@ -30,15 +77,15 @@ QueryTermSimple::visitMembers(vespalib::ObjectVisitor & visitor) const
template <typename N>
QueryTermSimple::RangeResult<N>
-QueryTermSimple::getFloatRange() const
+QueryTermSimple::getFloatRange() const noexcept
{
- double lowRaw, highRaw;
- bool valid = getAsDoubleTerm(lowRaw, highRaw);
+ N lowRaw, highRaw;
+ bool valid = getAsFloatTerm(lowRaw, highRaw);
RangeResult<N> res;
res.valid = valid;
if (!valid) {
- res.low = std::numeric_limits<N>::max();
- res.high = - std::numeric_limits<N>::max();
+ res.low = std::numeric_limits<N>::infinity();
+ res.high = -std::numeric_limits<N>::infinity();
res.adjusted = true;
} else {
res.low = lowRaw;
@@ -47,25 +94,16 @@ QueryTermSimple::getFloatRange() const
return res;
}
-namespace {
-
-bool isRepresentableByInt64(double d) {
- return (d > double(std::numeric_limits<int64_t>::min()))
- && (d < double(std::numeric_limits<int64_t>::max()));
-}
-
-}
-
bool
-QueryTermSimple::getRangeInternal(int64_t & low, int64_t & high) const
+QueryTermSimple::getRangeInternal(int64_t & low, int64_t & high) const noexcept
{
bool valid = getAsIntegerTerm(low, high);
if ( ! valid ) {
double l(0), h(0);
- valid = getAsDoubleTerm(l, h);
+ valid = getAsFloatTerm(l, h);
if (valid) {
if ((l == h) && isRepresentableByInt64(l)) {
- low = high = std::round(l);
+ low = high = static_cast<int64_t>(std::round(l));
} else {
if (l > double(std::numeric_limits<int64_t>::min())) {
if (l < double(std::numeric_limits<int64_t>::max())) {
@@ -89,7 +127,7 @@ QueryTermSimple::getRangeInternal(int64_t & low, int64_t & high) const
template <typename N>
QueryTermSimple::RangeResult<N>
-QueryTermSimple::getIntegerRange() const
+QueryTermSimple::getIntegerRange() const noexcept
{
int64_t lowRaw, highRaw;
bool valid = getRangeInternal(lowRaw, highRaw);
@@ -122,94 +160,72 @@ QueryTermSimple::getIntegerRange() const
template <>
QueryTermSimple::RangeResult<float>
-QueryTermSimple::getRange() const
+QueryTermSimple::getRange() const noexcept
{
return getFloatRange<float>();
}
template <>
QueryTermSimple::RangeResult<double>
-QueryTermSimple::getRange() const
+QueryTermSimple::getRange() const noexcept
{
return getFloatRange<double>();
}
template <>
QueryTermSimple::RangeResult<int8_t>
-QueryTermSimple::getRange() const
+QueryTermSimple::getRange() const noexcept
{
return getIntegerRange<int8_t>();
}
template <>
QueryTermSimple::RangeResult<int16_t>
-QueryTermSimple::getRange() const
+QueryTermSimple::getRange() const noexcept
{
return getIntegerRange<int16_t>();
}
template <>
QueryTermSimple::RangeResult<int32_t>
-QueryTermSimple::getRange() const
+QueryTermSimple::getRange() const noexcept
{
return getIntegerRange<int32_t>();
}
template <>
QueryTermSimple::RangeResult<int64_t>
-QueryTermSimple::getRange() const
+QueryTermSimple::getRange() const noexcept
{
return getIntegerRange<int64_t>();
}
-struct IntDecoder {
- 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 * 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
+bool QueryTermSimple::getAsIntegerTerm(int64_t & lower, int64_t & upper) const noexcept
{
lower = std::numeric_limits<int64_t>::min();
upper = std::numeric_limits<int64_t>::max();
return getAsNumericTerm(lower, upper, IntDecoder());
}
-bool QueryTermSimple::getAsDoubleTerm(double & lower, double & upper) const
+bool QueryTermSimple::getAsFloatTerm(double & lower, double & upper) const noexcept
+{
+ lower = -std::numeric_limits<double>::infinity();
+ upper = std::numeric_limits<double>::infinity();
+ return getAsNumericTerm(lower, upper, FloatDecoder<double>());
+}
+
+bool QueryTermSimple::getAsFloatTerm(float & lower, float & upper) const noexcept
{
- lower = - std::numeric_limits<double>::max();
- upper = std::numeric_limits<double>::max();
- return getAsNumericTerm(lower, upper, DoubleDecoder());
+ lower = -std::numeric_limits<float>::infinity();
+ upper = std::numeric_limits<float>::infinity();
+ return getAsNumericTerm(lower, upper, FloatDecoder<float>());
}
QueryTermSimple::~QueryTermSimple() = default;
namespace {
-bool isFullRange(vespalib::stringref s) {
- const size_t sz(s.size());
- return (sz >= 3u) &&
- (s[0] == '<' || s[0] == '[') &&
- (s[sz-1] == '>' || s[sz-1] == ']');
-}
+
}
@@ -244,7 +260,7 @@ QueryTermSimple::QueryTermSimple(const string & term_, Type type)
}
_valid = (numParts >= 2) && (numParts < NELEMS(parts));
if (_valid && numParts > 2) {
- _rangeLimit = strtol(parts[2].data(), nullptr, 0);
+ _rangeLimit = static_cast<int32_t>(strtol(parts[2].data(), nullptr, 0));
if (numParts > 3) {
_valid = (numParts >= 5);
if (_valid) {
@@ -269,12 +285,12 @@ QueryTermSimple::QueryTermSimple(const string & term_, Type type)
template <typename T, typename D>
bool
-QueryTermSimple::getAsNumericTerm(T & lower, T & upper, D d) const
+QueryTermSimple::getAsNumericTerm(T & lower, T & upper, D d) const noexcept
{
if (empty()) return false;
size_t sz(_term.size());
- char *err(nullptr);
+ const char *err(nullptr);
T low(lower);
T high(upper);
const char * q = _term.c_str();
diff --git a/searchlib/src/vespa/searchlib/query/query_term_simple.h b/searchlib/src/vespa/searchlib/query/query_term_simple.h
index 2b64e3812ab..87bf7c26b80 100644
--- a/searchlib/src/vespa/searchlib/query/query_term_simple.h
+++ b/searchlib/src/vespa/searchlib/query/query_term_simple.h
@@ -33,8 +33,8 @@ public:
N high;
bool valid; // Whether parsing of the range was successful
bool adjusted; // Whether the low and high was adjusted according to min and max limits of the given type.
- RangeResult() : low(), high(), valid(true), adjusted(false) {}
- bool isEqual() const { return low == high; }
+ RangeResult() noexcept : low(), high(), valid(true), adjusted(false) {}
+ bool isEqual() const noexcept { return low == high; }
};
QueryTermSimple(const QueryTermSimple &) = delete;
@@ -47,39 +47,40 @@ public:
* Extracts the content of this query term as a range with low and high values.
*/
template <typename N>
- RangeResult<N> getRange() const;
- int getRangeLimit() const { return _rangeLimit; }
- size_t getMaxPerGroup() const { return _maxPerGroup; }
- size_t getDiversityCutoffGroups() const { return _diversityCutoffGroups; }
- bool getDiversityCutoffStrict() const { return _diversityCutoffStrict; }
- vespalib::stringref getDiversityAttribute() const { return _diversityAttribute; }
- size_t getFuzzyMaxEditDistance() const { return _fuzzyMaxEditDistance; }
- size_t getFuzzyPrefixLength() const { return _fuzzyPrefixLength; }
- bool getAsIntegerTerm(int64_t & lower, int64_t & upper) const;
- bool getAsDoubleTerm(double & lower, double & upper) const;
- const char * getTerm() const { return _term.c_str(); }
- bool isPrefix() const { return (_type == Type::PREFIXTERM); }
- bool isSubstring() const { return (_type == Type::SUBSTRINGTERM); }
- bool isExactstring() const { return (_type == Type::EXACTSTRINGTERM); }
- bool isSuffix() const { return (_type == Type::SUFFIXTERM); }
- bool isWord() const { return (_type == Type::WORD); }
- bool isRegex() const { return (_type == Type::REGEXP); }
- bool isGeoLoc() const { return (_type == Type::GEO_LOCATION); }
- bool isFuzzy() const { return (_type == Type::FUZZYTERM); }
+ RangeResult<N> getRange() const noexcept;
+ int getRangeLimit() const noexcept { return _rangeLimit; }
+ size_t getMaxPerGroup() const noexcept { return _maxPerGroup; }
+ size_t getDiversityCutoffGroups() const noexcept { return _diversityCutoffGroups; }
+ bool getDiversityCutoffStrict() const noexcept { return _diversityCutoffStrict; }
+ vespalib::stringref getDiversityAttribute() const noexcept { return _diversityAttribute; }
+ size_t getFuzzyMaxEditDistance() const noexcept { return _fuzzyMaxEditDistance; }
+ size_t getFuzzyPrefixLength() const noexcept { return _fuzzyPrefixLength; }
+ bool getAsIntegerTerm(int64_t & lower, int64_t & upper) const noexcept;
+ bool getAsFloatTerm(double & lower, double & upper) const noexcept;
+ bool getAsFloatTerm(float & lower, float & upper) const noexcept;
+ const char * getTerm() const noexcept { return _term.c_str(); }
+ bool isPrefix() const noexcept { return (_type == Type::PREFIXTERM); }
+ bool isSubstring() const noexcept { return (_type == Type::SUBSTRINGTERM); }
+ bool isExactstring() const noexcept { return (_type == Type::EXACTSTRINGTERM); }
+ bool isSuffix() const noexcept { return (_type == Type::SUFFIXTERM); }
+ bool isWord() const noexcept { return (_type == Type::WORD); }
+ bool isRegex() const noexcept { return (_type == Type::REGEXP); }
+ bool isGeoLoc() const noexcept { return (_type == Type::GEO_LOCATION); }
+ bool isFuzzy() const noexcept { return (_type == Type::FUZZYTERM); }
bool is_nearest_neighbor() const noexcept { return (_type == Type::NEAREST_NEIGHBOR); }
- bool empty() const { return _term.empty(); }
+ bool empty() const noexcept { return _term.empty(); }
virtual void visitMembers(vespalib::ObjectVisitor &visitor) const;
vespalib::string getClassName() const;
- bool isValid() const { return _valid; }
- const string & getTermString() const { return _term; }
+ bool isValid() const noexcept { return _valid; }
+ const string & getTermString() const noexcept { return _term; }
private:
- bool getRangeInternal(int64_t & low, int64_t & high) const;
+ bool getRangeInternal(int64_t & low, int64_t & high) const noexcept;
template <typename N>
- RangeResult<N> getIntegerRange() const;
+ RangeResult<N> getIntegerRange() const noexcept;
template <typename N>
- RangeResult<N> getFloatRange() const;
- int _rangeLimit;
+ RangeResult<N> getFloatRange() const noexcept;
+ int32_t _rangeLimit;
uint32_t _maxPerGroup;
uint32_t _diversityCutoffGroups;
Type _type;
@@ -88,7 +89,7 @@ private:
string _term;
stringref _diversityAttribute;
template <typename T, typename D>
- bool getAsNumericTerm(T & lower, T & upper, D d) const;
+ bool getAsNumericTerm(T & lower, T & upper, D d) const noexcept;
protected:
uint32_t _fuzzyMaxEditDistance; // set in QueryTerm