X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2FSynchronized.h;h=d632a772c5e8ba140f2341d78298eaf06c57ce5b;hp=cc43071aa865deeb0ffec1b75fe95621d572c59f;hb=ca5621faf0871fa56f16754f03032cd03e03d4b1;hpb=b1463f8f7e68895866b62913997423feb338aeb1;ds=inline diff --git a/folly/Synchronized.h b/folly/Synchronized.h index cc43071a..d632a772 100644 --- a/folly/Synchronized.h +++ b/folly/Synchronized.h @@ -190,8 +190,8 @@ struct Synchronized { * constructor. */ Synchronized() = default; - /** + /** * Copy constructor copies the data (with locking the source and * all) but does NOT copy the mutex. Doing so would result in * deadlocks. @@ -220,7 +220,7 @@ struct Synchronized { * Constructor taking a datum rvalue as argument moves it. Again, * there is no need to lock the constructing object. */ - explicit Synchronized(T && rhs) : datum_(std::move(rhs)) {} + explicit Synchronized(T&& rhs) : datum_(std::move(rhs)) {} /** * The canonical assignment operator only assigns the data, NOT the @@ -228,7 +228,9 @@ struct Synchronized { * addresses. */ Synchronized& operator=(const Synchronized& rhs) { - if (this < *rhs) { + if (this == &rhs) { + // Self-assignment, pass. + } else if (this < &rhs) { auto guard1 = operator->(); auto guard2 = rhs.operator->(); datum_ = rhs.datum_; @@ -240,6 +242,26 @@ struct Synchronized { return *this; } + /** + * Move assignment operator, only assigns the data, NOT the + * mutex. It locks the two objects in ascending order of their + * addresses. + */ + Synchronized& operator=(Synchronized&& rhs) { + if (this == &rhs) { + // Self-assignment, pass. + } else if (this < &rhs) { + auto guard1 = operator->(); + auto guard2 = rhs.operator->(); + datum_ = std::move(rhs.datum_); + } else { + auto guard1 = rhs.operator->(); + auto guard2 = operator->(); + datum_ = std::move(rhs.datum_); + } + return *this; + } + /** * Lock object, assign datum. */ @@ -249,6 +271,15 @@ struct Synchronized { return *this; } + /** + * Lock object, move-assign datum. + */ + Synchronized& operator=(T&& rhs) { + auto guard = operator->(); + datum_ = std::move(rhs); + return *this; + } + /** * A LockedPtr lp keeps a modifiable (i.e. non-const) * Synchronized object locked for the duration of lp's @@ -519,7 +550,9 @@ struct Synchronized { } auto guard1 = operator->(); auto guard2 = rhs.operator->(); - datum_.swap(rhs.datum_); + + using std::swap; + swap(datum_, rhs.datum_); } /** @@ -528,7 +561,9 @@ struct Synchronized { */ void swap(T& rhs) { LockedPtr guard = operator->(); - datum_.swap(rhs); + + using std::swap; + swap(datum_, rhs); } /**