summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2022-08-02 13:48:25 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-08-03 11:24:21 +0000
commit8cc10fbb4a54982fa8631f92aa09eb5fe3bed8d9 (patch)
tree131628410a16de8e00c6b8c6e9b283bec21c9af7
parente507cb8fb71753fc4707b7aaba11556a9fe648a2 (diff)
downloadmongo-8cc10fbb4a54982fa8631f92aa09eb5fe3bed8d9.tar.gz
SERVER-68487 add BSONElement::isNaN()
(cherry picked from commit ed25ebe0d87dd2521fbfc5534ba7af7de69aad4d)
-rw-r--r--src/mongo/bson/bsonelement.h20
-rw-r--r--src/mongo/bson/bsonelement_test.cpp19
2 files changed, 39 insertions, 0 deletions
diff --git a/src/mongo/bson/bsonelement.h b/src/mongo/bson/bsonelement.h
index d89e3ceeee8..b1fd8db451a 100644
--- a/src/mongo/bson/bsonelement.h
+++ b/src/mongo/bson/bsonelement.h
@@ -346,6 +346,11 @@ public:
/** True if element is of a numeric type. */
bool isNumber() const;
+ /**
+ * True if element is a NaN double or decimal.
+ */
+ bool isNaN() const;
+
/** Return double value for this field. MUST be NumberDouble type. */
double _numberDouble() const {
return ConstDataView(value()).read<LittleEndian<double>>();
@@ -873,6 +878,21 @@ inline bool BSONElement::isNumber() const {
}
}
+inline bool BSONElement::isNaN() const {
+ switch (type()) {
+ case NumberDouble: {
+ double d = _numberDouble();
+ return std::isnan(d);
+ }
+ case NumberDecimal: {
+ Decimal128 d = _numberDecimal();
+ return d.isNaN();
+ }
+ default:
+ return false;
+ }
+}
+
inline Decimal128 BSONElement::numberDecimal() const {
switch (type()) {
case NumberDouble:
diff --git a/src/mongo/bson/bsonelement_test.cpp b/src/mongo/bson/bsonelement_test.cpp
index 7f999c44705..287142f03a0 100644
--- a/src/mongo/bson/bsonelement_test.cpp
+++ b/src/mongo/bson/bsonelement_test.cpp
@@ -206,6 +206,25 @@ TEST(BSONElement, SafeNumberLongNegativeBound) {
ASSERT_EQ(obj["negativeInfinity"].safeNumberLong(), std::numeric_limits<long long>::lowest());
}
+TEST(BSONElement, IsNaN) {
+ ASSERT(BSON("" << std::numeric_limits<double>::quiet_NaN()).firstElement().isNaN());
+ ASSERT(BSON("" << -std::numeric_limits<double>::quiet_NaN()).firstElement().isNaN());
+ ASSERT(BSON("" << Decimal128::kPositiveNaN).firstElement().isNaN());
+ ASSERT(BSON("" << Decimal128::kNegativeNaN).firstElement().isNaN());
+
+ ASSERT_FALSE(BSON("" << std::numeric_limits<double>::infinity()).firstElement().isNaN());
+ ASSERT_FALSE(BSON("" << -std::numeric_limits<double>::infinity()).firstElement().isNaN());
+ ASSERT_FALSE(BSON("" << Decimal128::kPositiveInfinity).firstElement().isNaN());
+ ASSERT_FALSE(BSON("" << Decimal128::kNegativeInfinity).firstElement().isNaN());
+ ASSERT_FALSE(BSON("" << Decimal128{"9223372036854775808.5"}).firstElement().isNaN());
+ ASSERT_FALSE(BSON("" << Decimal128{"-9223372036854775809.99"}).firstElement().isNaN());
+ ASSERT_FALSE(BSON("" << 12345LL).firstElement().isNaN());
+ ASSERT_FALSE(BSON(""
+ << "foo")
+ .firstElement()
+ .isNaN());
+}
+
TEST(BSONElementIntegerParseTest, ParseIntegerElementToNonNegativeLongRejectsNegative) {
BSONObj query = BSON("" << -2LL);
ASSERT_NOT_OK(query.firstElement().parseIntegerElementToNonNegativeLong());