summaryrefslogtreecommitdiff
path: root/src/mongo/base
diff options
context:
space:
mode:
authorMathias Stearn <mathias@10gen.com>2014-12-08 12:22:05 -0500
committerMathias Stearn <mathias@10gen.com>2015-02-13 15:29:33 -0500
commit511a2318599954ce6b58477dd7a1e8236fdb451b (patch)
tree3077332f28ddf75830ad682f11d8a0df53298c47 /src/mongo/base
parent05d73815c390e344842ac8870acfea53498279ea (diff)
downloadmongo-511a2318599954ce6b58477dd7a1e8236fdb451b.tar.gz
SERVER-17287 StatusWith improvements
* Implicit conversions from T and Status. * StatusWith<Status> banned at compile time. * toString() strings the value if isOK(). * Can now be streamed to an ostream. * EqualityComparable to T, Status, and ErrorCodes::Error. The last two make it possible to use StatusWith in ASSERT_OK and ASSERT_EQ.
Diffstat (limited to 'src/mongo/base')
-rw-r--r--src/mongo/base/status_with.h92
1 files changed, 88 insertions, 4 deletions
diff --git a/src/mongo/base/status_with.h b/src/mongo/base/status_with.h
index 6014e5921d2..59f3618cf6c 100644
--- a/src/mongo/base/status_with.h
+++ b/src/mongo/base/status_with.h
@@ -29,6 +29,10 @@
#pragma once
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp> // TODO replace with std::is_same in C++11
+#include <iosfwd>
+
#include "mongo/base/status.h"
namespace mongo {
@@ -53,7 +57,9 @@ namespace mongo {
*/
template<typename T>
class StatusWith {
+ BOOST_STATIC_ASSERT(!(boost::is_same<T, Status>::value)); // StatusWith<Status> is banned.
public:
+
/**
* for the error case
*/
@@ -64,7 +70,7 @@ namespace mongo {
/**
* for the error case
*/
- explicit StatusWith( const Status& status )
+ /*implicit*/ StatusWith( const Status& status )
: _status( status ) {
// verify(( !status.isOK() ); // TODO
}
@@ -72,7 +78,7 @@ namespace mongo {
/**
* for the OK case
*/
- explicit StatusWith( const T& t )
+ /*implicit*/ StatusWith( const T& t )
: _status( Status::OK() ), _t( t ) {
}
@@ -81,10 +87,88 @@ namespace mongo {
bool isOK() const { return _status.isOK(); }
- std::string toString() const { return _status.toString(); }
private:
Status _status;
T _t;
};
-}
+ template<typename T>
+ std::ostream& operator<<(std::ostream& stream, const StatusWith<T>& sw) {
+ if (sw.isOK())
+ return stream << sw.getValue();
+ return stream << sw.getStatus();
+ }
+
+ //
+ // EqualityComparable(StatusWith<T>, T). Intentionally not providing an ordering relation.
+ //
+
+ template<typename T>
+ bool operator==(const StatusWith<T>& sw, const T& val) {
+ return sw.isOK() && sw.getValue() == val;
+ }
+
+ template<typename T>
+ bool operator==(const T& val, const StatusWith<T>& sw) {
+ return sw.isOK() && val == sw.getValue();
+ }
+
+ template<typename T>
+ bool operator!=(const StatusWith<T>& sw, const T& val) {
+ return !(sw == val);
+ }
+
+ template<typename T>
+ bool operator!=(const T& val, const StatusWith<T>& sw) {
+ return !(val == sw);
+ }
+
+ //
+ // EqualityComparable(StatusWith<T>, Status)
+ //
+
+ template<typename T>
+ bool operator==(const StatusWith<T>& sw, const Status& status) {
+ return sw.getStatus() == status;
+ }
+
+ template<typename T>
+ bool operator==(const Status& status, const StatusWith<T>& sw) {
+ return status == sw.getStatus();
+ }
+
+ template<typename T>
+ bool operator!=(const StatusWith<T>& sw, const Status& status) {
+ return !(sw == status);
+ }
+
+ template<typename T>
+ bool operator!=(const Status& status, const StatusWith<T>& sw) {
+ return !(status == sw);
+ }
+
+ //
+ // EqualityComparable(StatusWith<T>, ErrorCode)
+ //
+
+ template<typename T>
+ bool operator==(const StatusWith<T>& sw, const ErrorCodes& code) {
+ return sw.getStatus() == code;
+ }
+
+ template<typename T>
+ bool operator==(const ErrorCodes::Error& code, const StatusWith<T>& sw) {
+ return code == sw.getStatus();
+ }
+
+ template<typename T>
+ bool operator!=(const StatusWith<T>& sw, const ErrorCodes::Error& code) {
+ return !(sw == code);
+ }
+
+ template<typename T>
+ bool operator!=(const ErrorCodes::Error& code, const StatusWith<T>& sw) {
+ return !(code == sw);
+ }
+
+} // namespace mongo