summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Stearn <mathias@10gen.com>2018-03-26 12:31:11 -0400
committerMathias Stearn <mathias@10gen.com>2018-03-26 15:40:35 -0400
commit2676a176759359c8614c0e37b267198259b6789f (patch)
tree3ba394a2fca60aabde3cd85a5808e129b10ee0bd
parentb3c9e24d7434c929c097d85f65a3586687031116 (diff)
downloadmongo-2676a176759359c8614c0e37b267198259b6789f.tar.gz
SERVER-33568 Support StringBuilder << streaming for Status and StatusWith<T>
-rw-r--r--src/mongo/base/status.cpp25
-rw-r--r--src/mongo/base/status.h8
-rw-r--r--src/mongo/base/status_with.h17
-rw-r--r--src/mongo/client/dbclient.cpp2
4 files changed, 41 insertions, 11 deletions
diff --git a/src/mongo/base/status.cpp b/src/mongo/base/status.cpp
index 30cc3558497..b6776bd7bf5 100644
--- a/src/mongo/base/status.cpp
+++ b/src/mongo/base/status.cpp
@@ -110,28 +110,35 @@ std::ostream& operator<<(std::ostream& os, const Status& status) {
return os << status.codeString() << " " << status.reason();
}
-std::string Status::toString() const {
- StringBuilder ss;
- ss << codeString();
- if (!isOK()) {
+template <typename Allocator>
+StringBuilderImpl<Allocator>& operator<<(StringBuilderImpl<Allocator>& sb, const Status& status) {
+ sb << status.codeString();
+ if (!status.isOK()) {
try {
- if (auto extra = extraInfo()) {
+ if (auto extra = status.extraInfo()) {
BSONObjBuilder bob;
extra->serialize(&bob);
- ss << bob.obj();
+ sb << bob.obj();
}
} catch (const DBException&) {
// This really shouldn't happen but it would be really annoying if it broke error
// logging in production.
if (kDebugBuild) {
- severe() << "Error serializing extra info for " << code()
+ severe() << "Error serializing extra info for " << status.code()
<< " in Status::toString()";
std::terminate();
}
}
- ss << ": " << reason();
+ sb << ": " << status.reason();
}
- return ss.str();
+ return sb;
+}
+template StringBuilder& operator<<(StringBuilder& sb, const Status& status);
+
+std::string Status::toString() const {
+ StringBuilder sb;
+ sb << *this;
+ return sb.str();
}
} // namespace mongo
diff --git a/src/mongo/base/status.h b/src/mongo/base/status.h
index 11c14bc57ad..2bb524ee413 100644
--- a/src/mongo/base/status.h
+++ b/src/mongo/base/status.h
@@ -43,6 +43,10 @@ class stream;
namespace mongo {
+// Including builder.h here would cause a cycle.
+template <typename Allocator>
+class StringBuilderImpl;
+
/**
* Status represents an error state or the absence thereof.
*
@@ -259,6 +263,10 @@ inline bool operator!=(const ErrorCodes::Error lhs, const Status& rhs);
std::ostream& operator<<(std::ostream& os, const Status& status);
+// This is only implemented for StringBuilder, not StackStringBuilder.
+template <typename Allocator>
+StringBuilderImpl<Allocator>& operator<<(StringBuilderImpl<Allocator>& os, const Status& status);
+
} // namespace mongo
#include "mongo/base/status-inl.h"
diff --git a/src/mongo/base/status_with.h b/src/mongo/base/status_with.h
index 1092f9bdc87..c4d60d2fb81 100644
--- a/src/mongo/base/status_with.h
+++ b/src/mongo/base/status_with.h
@@ -43,6 +43,10 @@
namespace mongo {
+// Including builder.h here would cause a cycle.
+template <typename Allocator>
+class StringBuilderImpl;
+
template <typename T>
class StatusWith;
@@ -155,7 +159,18 @@ StatusWith<T> makeStatusWith(Args&&... args) {
}
template <typename T>
-std::ostream& operator<<(std::ostream& stream, const StatusWith<T>& sw) {
+auto operator<<(std::ostream& stream, const StatusWith<T>& sw)
+ -> decltype(stream << sw.getValue()) // SFINAE on T streamability.
+{
+ if (sw.isOK())
+ return stream << sw.getValue();
+ return stream << sw.getStatus();
+}
+
+template <typename Allocator, typename T>
+auto operator<<(StringBuilderImpl<Allocator>& stream, const StatusWith<T>& sw)
+ -> decltype(stream << sw.getValue()) // SFINAE on T streamability.
+{
if (sw.isOK())
return stream << sw.getValue();
return stream << sw.getStatus();
diff --git a/src/mongo/client/dbclient.cpp b/src/mongo/client/dbclient.cpp
index 90dc9388cf8..7ca8bd55540 100644
--- a/src/mongo/client/dbclient.cpp
+++ b/src/mongo/client/dbclient.cpp
@@ -970,7 +970,7 @@ Status DBClientConnection::connectSocketOnly(const HostAndPort& serverAddress) {
return Status(ErrorCodes::HostUnreachable,
str::stream() << "couldn't connect to server " << _serverAddress.toString()
<< ", connection attempt failed: "
- << sws.getStatus().toString());
+ << sws.getStatus());
}
_session = std::move(sws.getValue());