From: Christian Kamm Date: Tue, 8 Jan 2019 13:55:30 +0000 (+0100) Subject: Result: Add copy/move ctor/op= X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~12^2~21^2~468^2~337 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=7ef6e606603c09c46af5758fcf83381a3af91883;p=nextcloud-desktop.git Result: Add copy/move ctor/op= It has a destructor and these operations make sense. Particularly the move is important for code like: Result foo() { Result v; return v; } because the move-ctor will not autogenerate if x or y are not trivially destructible. --- diff --git a/src/common/result.h b/src/common/result.h index 5db087b54..61805982e 100644 --- a/src/common/result.h +++ b/src/common/result.h @@ -43,6 +43,52 @@ public: { } + Result(Result &&other) + : _isError(other._isError) + { + if (_isError) { + new (&_error) Error(std::move(other._error)); + } else { + new (&_result) T(std::move(other._result)); + } + } + + Result(const Result &other) + : _isError(other._isError) + { + if (_isError) { + new (&_error) Error(other._error); + } else { + new (&_result) T(other._result); + } + } + + Result &operator=(Result &&other) + { + if (&other != this) { + _isError = other._isError; + if (_isError) { + new (&_error) Error(std::move(other._error)); + } else { + new (&_result) T(std::move(other._result)); + } + } + return *this; + } + + Result &operator=(const Result &other) + { + if (&other != this) { + _isError = other._isError; + if (_isError) { + new (&_error) Error(other._error); + } else { + new (&_result) T(other._result); + } + } + return *this; + } + ~Result() { if (_isError) @@ -50,7 +96,9 @@ public: else _result.~T(); } + explicit operator bool() const { return !_isError; } + const T &operator*() const & { ASSERT(!_isError); @@ -61,6 +109,13 @@ public: ASSERT(!_isError); return std::move(_result); } + + const T *operator->() const + { + ASSERT(!_isError); + return &_result; + } + const Error &error() const & { ASSERT(_isError);