diff options
author | Benety Goh <benety@mongodb.com> | 2022-08-02 13:48:25 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-08-03 11:24:21 +0000 |
commit | 8cc10fbb4a54982fa8631f92aa09eb5fe3bed8d9 (patch) | |
tree | 131628410a16de8e00c6b8c6e9b283bec21c9af7 | |
parent | e507cb8fb71753fc4707b7aaba11556a9fe648a2 (diff) | |
download | mongo-8cc10fbb4a54982fa8631f92aa09eb5fe3bed8d9.tar.gz |
SERVER-68487 add BSONElement::isNaN()
(cherry picked from commit ed25ebe0d87dd2521fbfc5534ba7af7de69aad4d)
-rw-r--r-- | src/mongo/bson/bsonelement.h | 20 | ||||
-rw-r--r-- | src/mongo/bson/bsonelement_test.cpp | 19 |
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()); |