diff options
author | Mathias Stearn <mathias@10gen.com> | 2014-12-08 12:22:05 -0500 |
---|---|---|
committer | Mathias Stearn <mathias@10gen.com> | 2015-02-13 15:29:33 -0500 |
commit | 511a2318599954ce6b58477dd7a1e8236fdb451b (patch) | |
tree | 3077332f28ddf75830ad682f11d8a0df53298c47 /src/mongo/base | |
parent | 05d73815c390e344842ac8870acfea53498279ea (diff) | |
download | mongo-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.h | 92 |
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 |