Make Status moveable

Status is a class which is frequently returned by value from functions.
  Making it movable avoids 99% of the copies automatically
  on return by value.
This commit is contained in:
Dmitri Smirnov 2015-12-22 16:06:20 -08:00
parent 2bf9b968ca
commit dbb8260f7e

View File

@ -30,7 +30,17 @@ class Status {
// Copy the specified status. // Copy the specified status.
Status(const Status& s); Status(const Status& s);
void operator=(const Status& s); Status& operator=(const Status& s);
Status(Status&& s)
#if !(defined _MSC_VER) || ((defined _MSC_VER) && (_MSC_VER >= 1900))
noexcept
#endif
;
Status& operator=(Status&& s)
#if !(defined _MSC_VER) || ((defined _MSC_VER) && (_MSC_VER >= 1900))
noexcept
#endif
;
bool operator==(const Status& rhs) const; bool operator==(const Status& rhs) const;
bool operator!=(const Status& rhs) const; bool operator!=(const Status& rhs) const;
@ -214,15 +224,41 @@ class Status {
inline Status::Status(const Status& s) : code_(s.code_), subcode_(s.subcode_) { inline Status::Status(const Status& s) : code_(s.code_), subcode_(s.subcode_) {
state_ = (s.state_ == nullptr) ? nullptr : CopyState(s.state_); state_ = (s.state_ == nullptr) ? nullptr : CopyState(s.state_);
} }
inline void Status::operator=(const Status& s) { inline Status& Status::operator=(const Status& s) {
// The following condition catches both aliasing (when this == &s), // The following condition catches both aliasing (when this == &s),
// and the common case where both s and *this are ok. // and the common case where both s and *this are ok.
code_ = s.code_; if(this != &s) {
subcode_ = s.subcode_; code_ = s.code_;
if (state_ != s.state_) { subcode_ = s.subcode_;
delete[] state_; delete[] state_;
state_ = (s.state_ == nullptr) ? nullptr : CopyState(s.state_); state_ = (s.state_ == nullptr) ? nullptr : CopyState(s.state_);
} }
return *this;
}
inline Status::Status(Status&& s)
#if !(defined _MSC_VER) || ((defined _MSC_VER) && (_MSC_VER >= 1900))
noexcept
#endif
: Status() {
*this = std::move(s);
}
inline Status& Status::operator=(Status&& s)
#if !(defined _MSC_VER) || ((defined _MSC_VER) && (_MSC_VER >= 1900))
noexcept
#endif
{
if(this != &s) {
code_ = std::move(s.code_);
s.code_ = kOk;
subcode_ = std::move(s.subcode_);
s.subcode_ = kNone;
delete [] state_;
state_ = nullptr;
std::swap(state_, s.state_);
}
return *this;
} }
inline bool Status::operator==(const Status& rhs) const { inline bool Status::operator==(const Status& rhs) const {