1 #ifndef SUPPORT_TRACKED_VALUE_H 2 #define SUPPORT_TRACKED_VALUE_H 3 4 #include <cassert> 5 6 struct TrackedValue { 7 enum State { CONSTRUCTED, MOVED_FROM, DESTROYED }; 8 State state; 9 TrackedValueTrackedValue10 TrackedValue() : state(State::CONSTRUCTED) {} 11 TrackedValueTrackedValue12 TrackedValue(TrackedValue const& t) : state(State::CONSTRUCTED) { 13 assert(t.state != State::MOVED_FROM && "copying a moved-from object"); 14 assert(t.state != State::DESTROYED && "copying a destroyed object"); 15 } 16 17 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES TrackedValueTrackedValue18 TrackedValue(TrackedValue&& t) : state(State::CONSTRUCTED) { 19 assert(t.state != State::MOVED_FROM && "double moving from an object"); 20 assert(t.state != State::DESTROYED && "moving from a destroyed object"); 21 t.state = State::MOVED_FROM; 22 } 23 #endif 24 25 TrackedValue& operator=(TrackedValue const& t) { 26 assert(state != State::DESTROYED && "copy assigning into destroyed object"); 27 assert(t.state != State::MOVED_FROM && "copying a moved-from object"); 28 assert(t.state != State::DESTROYED && "copying a destroyed object"); 29 state = t.state; 30 return *this; 31 } 32 33 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 34 TrackedValue& operator=(TrackedValue&& t) { 35 assert(state != State::DESTROYED && "move assigning into destroyed object"); 36 assert(t.state != State::MOVED_FROM && "double moving from an object"); 37 assert(t.state != State::DESTROYED && "moving from a destroyed object"); 38 state = t.state; 39 t.state = State::MOVED_FROM; 40 return *this; 41 } 42 #endif 43 ~TrackedValueTrackedValue44 ~TrackedValue() { 45 assert(state != State::DESTROYED && "double-destroying an object"); 46 state = State::DESTROYED; 47 } 48 }; 49 50 #endif // SUPPORT_TRACKED_VALUE_H 51