diff options
author | Kris Satya <kris.satya@mongodb.com> | 2021-06-08 14:00:18 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-06-10 21:03:29 +0000 |
commit | 4b43aaaa4b4974322d6ed5f2e0883b6de3d384e3 (patch) | |
tree | 4e36676f4814e20e28f61beaa1ddd8af8684ce56 | |
parent | 0d7c224fc2671e939ea97d94237003dd74805b54 (diff) | |
download | mongo-4b43aaaa4b4974322d6ed5f2e0883b6de3d384e3.tar.gz |
SERVER-56300 Add append functionality for iterator ranges in BSONObjBuilder
-rw-r--r-- | src/mongo/bson/bsonobjbuilder.h | 63 | ||||
-rw-r--r-- | src/mongo/bson/bsonobjbuilder_test.cpp | 110 |
2 files changed, 141 insertions, 32 deletions
diff --git a/src/mongo/bson/bsonobjbuilder.h b/src/mongo/bson/bsonobjbuilder.h index a7860a45588..8eeddc49ebd 100644 --- a/src/mongo/bson/bsonobjbuilder.h +++ b/src/mongo/bson/bsonobjbuilder.h @@ -542,6 +542,11 @@ public: template <class K, class T> Derived& append(StringData fieldName, const std::map<K, T>& vals); + + /** Append a range of values between two iterators. */ + template <class It> + Derived& append(StringData fieldName, It begin, It end); + /** * Resets this BSONObjBulder to an empty state. All previously added fields are lost. If this * BSONObjBuilderBase is using an externally provided BufBuilder, this method does not affect @@ -926,6 +931,9 @@ public: template <class T> Derived& append(const std::set<T>& vals); + template <class It> + Derived& append(It begin, It end); + // These two just use next position auto& subobjStart() { return _b.subobjStart(_fieldCount++); @@ -1045,42 +1053,21 @@ template <class Derived, class B> template <class T> inline Derived& BSONObjBuilderBase<Derived, B>::append(StringData fieldName, const std::vector<T>& vals) { - Derived arrBuilder(subarrayStart(fieldName)); - DecimalCounter<size_t> n; - for (unsigned int i = 0; i < vals.size(); ++i) { - arrBuilder.append(StringData{n}, vals[i]); - ++n; - } - return static_cast<Derived&>(*this); -} - -template <class Builder, class L> -inline void _appendIt(Builder& _this, StringData fieldName, const L& vals) { - typename std::remove_reference<Builder>::type arrBuilder; - DecimalCounter<size_t> n; - for (typename L::const_iterator i = vals.begin(); i != vals.end(); i++) { - arrBuilder.append(StringData{n}, *i); - ++n; - } - _this.appendArray(fieldName, arrBuilder.done()); + return append(fieldName, vals.begin(), vals.end()); } template <class Derived, class B> template <class T> inline Derived& BSONObjBuilderBase<Derived, B>::append(StringData fieldName, const std::list<T>& vals) { - auto& derivedThis = static_cast<Derived&>(*this); - _appendIt<Derived, std::list<T>>(derivedThis, fieldName, vals); - return derivedThis; + return append(fieldName, vals.begin(), vals.end()); } template <class Derived, class B> template <class T> inline Derived& BSONObjBuilderBase<Derived, B>::append(StringData fieldName, const std::set<T>& vals) { - auto& derivedThis = static_cast<Derived&>(*this); - _appendIt<Derived, std::set<T>>(derivedThis, fieldName, vals); - return derivedThis; + return append(fieldName, vals.begin(), vals.end()); } template <class Derived, class BufBuilderType> @@ -1095,26 +1082,38 @@ inline Derived& BSONObjBuilderBase<Derived, BufBuilderType>::append(StringData f return static_cast<Derived&>(*this); } -template <class BSONArrayBuilderType, class L> -inline void _appendArrayIt(BSONArrayBuilderType& arrBuilder, const L& vals) { - for (typename L::const_iterator i = vals.begin(); i != vals.end(); i++) - arrBuilder.append(*i); +template <class Derived, class B> +template <class It> +inline Derived& BSONObjBuilderBase<Derived, B>::append(StringData fieldName, It begin, It end) { + Derived arrBuilder(subarrayStart(fieldName)); + DecimalCounter<size_t> n; + for (; begin != end; ++begin) { + arrBuilder.append(StringData{n}, *begin); + ++n; + } + return static_cast<Derived&>(*this); } template <class Derived, class BSONObjBuilderType> template <class T> inline Derived& BSONArrayBuilderBase<Derived, BSONObjBuilderType>::append( const std::list<T>& vals) { - auto& derivedThis = static_cast<Derived&>(*this); - _appendArrayIt<Derived, std::list<T>>(derivedThis, vals); - return derivedThis; + return append(vals.begin(), vals.end()); } template <class Derived, class BSONObjBuilderType> template <class T> inline Derived& BSONArrayBuilderBase<Derived, BSONObjBuilderType>::append(const std::set<T>& vals) { + return append(vals.begin(), vals.end()); +} + +template <class Derived, class BSONObjBuilderType> +template <class It> +inline Derived& BSONArrayBuilderBase<Derived, BSONObjBuilderType>::append(It begin, It end) { auto& derivedThis = static_cast<Derived&>(*this); - _appendArrayIt<Derived, std::set<T>>(derivedThis, vals); + for (; begin != end; ++begin) { + derivedThis.append(*begin); + } return derivedThis; } diff --git a/src/mongo/bson/bsonobjbuilder_test.cpp b/src/mongo/bson/bsonobjbuilder_test.cpp index 08f0fb43fbd..386b68f99c4 100644 --- a/src/mongo/bson/bsonobjbuilder_test.cpp +++ b/src/mongo/bson/bsonobjbuilder_test.cpp @@ -232,6 +232,56 @@ TEST(BSONObjBuilderTest, MovingAnOwningBSONObjBuilderWorks) { ASSERT_BSONOBJ_EQ(bob.obj(), BSON("a" << 1 << "b" << 2 << "c" << 3)); } +TEST(BSONObjBuilderTest, BSONObjBuilderAppendSet) { + BSONObjBuilder initial; + std::set<int> testSet = {10, 20, 30}; + + initial.append("a", testSet); + ASSERT_BSONOBJ_EQ(initial.obj(), BSON("a" << BSON_ARRAY(10 << 20 << 30))); +} + +TEST(BSONObjBuilderTest, BSONObjBuilderAppendList) { + BSONObjBuilder initial; + std::list<int> testList = {10, 20, 30}; + + initial.append("a", testList); + ASSERT_BSONOBJ_EQ(initial.obj(), BSON("a" << BSON_ARRAY(10 << 20 << 30))); +} + +TEST(BSONObjBuilderTest, BSONObjBuilderAppendVector) { + BSONObjBuilder initial; + std::vector<int> vect = {10, 20, 30}; + + initial.append("a", vect); + ASSERT_BSONOBJ_EQ(initial.obj(), BSON("a" << BSON_ARRAY(10 << 20 << 30))); +} + +TEST(BSONObjBuilderTest, BSONObjBuilderAppendVectorIterator) { + BSONObjBuilder initial; + std::vector<int> vect = {10, 20, 30}; + + initial.append("a", vect.begin(), vect.end()); + ASSERT_BSONOBJ_EQ(initial.obj(), BSON("a" << BSON_ARRAY(10 << 20 << 30))); +} + +TEST(BSONObjBuilderTest, BSONObjBuilderAppendSetIterator) { + BSONObjBuilder initial; + + std::set<int> testSet = {30, 20, 10}; + + initial.append("a", testSet.begin(), testSet.end()); + ASSERT_BSONOBJ_EQ(initial.obj(), BSON("a" << BSON_ARRAY(10 << 20 << 30))); +} + +TEST(BSONObjBuilderTest, BSONObjBuilderAppendBoostVectorIterator) { + BSONObjBuilder initial; + + auto vect = boost::container::small_vector<int, 3>{10, 20, 30}; + + initial.append("a", vect.begin(), vect.end()); + ASSERT_BSONOBJ_EQ(initial.obj(), BSON("a" << BSON_ARRAY(10 << 20 << 30))); +} + TEST(BSONObjBuilderTest, MovingANonOwningBSONObjBuilderWorks) { BSONObjBuilder outer; { @@ -266,6 +316,66 @@ TEST(BSONArrayBuilderTest, MovingABSONArrayBuilderWorks) { ASSERT_BSONOBJ_EQ(bob.obj(), BSON("a" << 1 << "array" << BSON_ARRAY(1 << "2" << 3 << "4"))); } +TEST(BSONArrayBuilderTest, BSONArrayBuilderAppendSet) { + BSONObjBuilder initial; + + { + BSONArrayBuilder arr(initial.subarrayStart("a")); + std::set<int> testSet = {10, 20, 30}; + arr.append(testSet); + } + + ASSERT_BSONOBJ_EQ(initial.obj(), BSON("a" << BSON_ARRAY(10 << 20 << 30))); +} + +TEST(BSONArrayBuilderTest, BSONArrayBuilderAppendList) { + BSONObjBuilder initial; + + { + BSONArrayBuilder arr(initial.subarrayStart("a")); + std::list<int> testList = {10, 20, 30}; + arr.append(testList); + } + + ASSERT_BSONOBJ_EQ(initial.obj(), BSON("a" << BSON_ARRAY(10 << 20 << 30))); +} + +TEST(BSONArrayBuilderTest, BSONArrayBuilderAppendVectorIterator) { + BSONObjBuilder initial; + + { + BSONArrayBuilder arr(initial.subarrayStart("a")); + std::vector<int> vect = {10, 20, 30}; + arr.append(vect.begin(), vect.end()); + } + + ASSERT_BSONOBJ_EQ(initial.obj(), BSON("a" << BSON_ARRAY(10 << 20 << 30))); +} + +TEST(BSONArrayBuilderTest, BSONArrayBuilderAppendSetIterator) { + BSONObjBuilder initial; + + { + BSONArrayBuilder arr(initial.subarrayStart("a")); + std::set<int> testSet = {10, 20, 30}; + arr.append(testSet.begin(), testSet.end()); + } + + ASSERT_BSONOBJ_EQ(initial.obj(), BSON("a" << BSON_ARRAY(10 << 20 << 30))); +} + +TEST(BSONObjBuilderTest, BSONArrayBuilderAppendBoostVectorIterator) { + BSONObjBuilder initial; + + { + BSONArrayBuilder arr(initial.subarrayStart("a")); + auto vect = boost::container::small_vector<int, 3>{10, 20, 30}; + arr.append(vect.begin(), vect.end()); + } + + ASSERT_BSONOBJ_EQ(initial.obj(), BSON("a" << BSON_ARRAY(10 << 20 << 30))); +} + TEST(BSONObjBuilderTest, SeedingBSONObjBuilderWithRootedUnsharedOwnedBsonWorks) { auto origObj = BSON("a" << 1); auto origObjPtr = origObj.objdata(); |