summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharlie Swanson <cswanson310@gmail.com>2016-03-28 10:21:22 -0400
committerCharlie Swanson <cswanson310@gmail.com>2016-03-30 13:48:25 -0400
commite64e2aca73f7b3b7184c1b5cc8b6c3ff3af79f21 (patch)
tree9654aa5e488aaac4cbd5861e1f6cea404cbeced5
parent25d43de2204dadb2cf2a4bf7eed3a7d374fc98db (diff)
downloadmongo-e64e2aca73f7b3b7184c1b5cc8b6c3ff3af79f21.tar.gz
SERVER-23371 Add initializer_list constructor for Documents.
-rw-r--r--src/mongo/db/pipeline/document.cpp10
-rw-r--r--src/mongo/db/pipeline/document.h7
-rw-r--r--src/mongo/db/pipeline/document_value_test.cpp56
-rw-r--r--src/mongo/db/pipeline/value.h11
4 files changed, 57 insertions, 27 deletions
diff --git a/src/mongo/db/pipeline/document.cpp b/src/mongo/db/pipeline/document.cpp
index 6b2cf793aba..f7c8b179094 100644
--- a/src/mongo/db/pipeline/document.cpp
+++ b/src/mongo/db/pipeline/document.cpp
@@ -227,6 +227,16 @@ Document::Document(const BSONObj& bson) {
*this = md.freeze();
}
+Document::Document(std::initializer_list<std::pair<StringData, ImplicitValue>> initializerList) {
+ MutableDocument mutableDoc(initializerList.size());
+
+ for (auto&& pair : initializerList) {
+ mutableDoc.addField(pair.first, pair.second);
+ }
+
+ *this = mutableDoc.freeze();
+}
+
BSONObjBuilder& operator<<(BSONObjBuilderValueStream& builder, const Document& doc) {
BSONObjBuilder subobj(builder.subobjStart());
doc.toBson(&subobj);
diff --git a/src/mongo/db/pipeline/document.h b/src/mongo/db/pipeline/document.h
index 9b2857a011d..c0bf581110e 100644
--- a/src/mongo/db/pipeline/document.h
+++ b/src/mongo/db/pipeline/document.h
@@ -72,6 +72,13 @@ public:
/// Create a new Document deep-converted from the given BSONObj.
explicit Document(const BSONObj& bson);
+ /**
+ * Create a new document from key, value pairs. Enables constructing a document using this
+ * syntax:
+ * auto document = Document{{"hello", "world"}, {"number": 1}};
+ */
+ Document(std::initializer_list<std::pair<StringData, ImplicitValue>> initializerList);
+
#if defined(_MSC_VER) && _MSC_VER < 1900 // MVSC++ <= 2013 can't generate default move operations
Document(const Document& other) = default;
Document& operator=(const Document& other) = default;
diff --git a/src/mongo/db/pipeline/document_value_test.cpp b/src/mongo/db/pipeline/document_value_test.cpp
index d77c7ac0039..9a8089248c2 100644
--- a/src/mongo/db/pipeline/document_value_test.cpp
+++ b/src/mongo/db/pipeline/document_value_test.cpp
@@ -70,32 +70,36 @@ void assertRoundTrips(const Document& document1) {
ASSERT_EQUALS(document1, document2);
}
-/** Create a Document. */
-class Create {
-public:
- void run() {
- Document document;
- ASSERT_EQUALS(0U, document.size());
- assertRoundTrips(document);
- }
-};
+TEST(DocumentConstruction, Default) {
+ Document document;
+ ASSERT_EQUALS(0U, document.size());
+ assertRoundTrips(document);
+}
-/** Create a Document from a BSONObj. */
-class CreateFromBsonObj {
-public:
- void run() {
- Document document = fromBson(BSONObj());
- ASSERT_EQUALS(0U, document.size());
- document = fromBson(BSON("a" << 1 << "b"
- << "q"));
- ASSERT_EQUALS(2U, document.size());
- ASSERT_EQUALS("a", getNthField(document, 0).first.toString());
- ASSERT_EQUALS(1, getNthField(document, 0).second.getInt());
- ASSERT_EQUALS("b", getNthField(document, 1).first.toString());
- ASSERT_EQUALS("q", getNthField(document, 1).second.getString());
- assertRoundTrips(document);
- }
-};
+TEST(DocumentConstruction, FromEmptyBson) {
+ Document document = fromBson(BSONObj());
+ ASSERT_EQUALS(0U, document.size());
+ assertRoundTrips(document);
+}
+
+TEST(DocumentConstruction, FromNonEmptyBson) {
+ Document document = fromBson(BSON("a" << 1 << "b"
+ << "q"));
+ ASSERT_EQUALS(2U, document.size());
+ ASSERT_EQUALS("a", getNthField(document, 0).first.toString());
+ ASSERT_EQUALS(1, getNthField(document, 0).second.getInt());
+ ASSERT_EQUALS("b", getNthField(document, 1).first.toString());
+ ASSERT_EQUALS("q", getNthField(document, 1).second.getString());
+}
+
+TEST(DocumentConstruction, FromInitializerList) {
+ auto document = Document{{"a", 1}, {"b", "q"}};
+ ASSERT_EQUALS(2U, document.size());
+ ASSERT_EQUALS("a", getNthField(document, 0).first.toString());
+ ASSERT_EQUALS(1, getNthField(document, 0).second.getInt());
+ ASSERT_EQUALS("b", getNthField(document, 1).first.toString());
+ ASSERT_EQUALS("q", getNthField(document, 1).second.getString());
+}
/** Add Document fields. */
class AddField {
@@ -1669,8 +1673,6 @@ class All : public Suite {
public:
All() : Suite("document") {}
void setupTests() {
- add<Document::Create>();
- add<Document::CreateFromBsonObj>();
add<Document::AddField>();
add<Document::GetValue>();
add<Document::SetField>();
diff --git a/src/mongo/db/pipeline/value.h b/src/mongo/db/pipeline/value.h
index 9fc51e164b2..920b5910204 100644
--- a/src/mongo/db/pipeline/value.h
+++ b/src/mongo/db/pipeline/value.h
@@ -305,6 +305,17 @@ typedef unordered_set<Value, Value::Hash> ValueSet;
inline void swap(mongo::Value& lhs, mongo::Value& rhs) {
lhs.swap(rhs);
}
+
+/**
+ * This class is identical to Value, but supports implicit creation from any of the types explicitly
+ * supported by Value.
+ */
+class ImplicitValue : public Value {
+public:
+ template <typename T>
+ ImplicitValue(T arg)
+ : Value(std::move(arg)) {}
+};
}
/* ======================= INLINED IMPLEMENTATIONS ========================== */