summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKris Satya <kris.satya@mongodb.com>2021-06-08 14:00:18 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-06-10 21:03:29 +0000
commit4b43aaaa4b4974322d6ed5f2e0883b6de3d384e3 (patch)
tree4e36676f4814e20e28f61beaa1ddd8af8684ce56
parent0d7c224fc2671e939ea97d94237003dd74805b54 (diff)
downloadmongo-4b43aaaa4b4974322d6ed5f2e0883b6de3d384e3.tar.gz
SERVER-56300 Add append functionality for iterator ranges in BSONObjBuilder
-rw-r--r--src/mongo/bson/bsonobjbuilder.h63
-rw-r--r--src/mongo/bson/bsonobjbuilder_test.cpp110
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();