diff options
Diffstat (limited to 'test/support/tracked_value.h')
-rw-r--r-- | test/support/tracked_value.h | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/test/support/tracked_value.h b/test/support/tracked_value.h new file mode 100644 index 0000000000000..b0869b23bdcbb --- /dev/null +++ b/test/support/tracked_value.h @@ -0,0 +1,50 @@ +#ifndef SUPPORT_TRACKED_VALUE_H +#define SUPPORT_TRACKED_VALUE_H + +#include <cassert> + +struct TrackedValue { + enum State { CONSTRUCTED, MOVED_FROM, DESTROYED }; + State state; + + TrackedValue() : state(State::CONSTRUCTED) {} + + TrackedValue(TrackedValue const& t) : state(State::CONSTRUCTED) { + assert(t.state != State::MOVED_FROM && "copying a moved-from object"); + assert(t.state != State::DESTROYED && "copying a destroyed object"); + } + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + TrackedValue(TrackedValue&& t) : state(State::CONSTRUCTED) { + assert(t.state != State::MOVED_FROM && "double moving from an object"); + assert(t.state != State::DESTROYED && "moving from a destroyed object"); + t.state = State::MOVED_FROM; + } +#endif + + TrackedValue& operator=(TrackedValue const& t) { + assert(state != State::DESTROYED && "copy assigning into destroyed object"); + assert(t.state != State::MOVED_FROM && "copying a moved-from object"); + assert(t.state != State::DESTROYED && "copying a destroyed object"); + state = t.state; + return *this; + } + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + TrackedValue& operator=(TrackedValue&& t) { + assert(state != State::DESTROYED && "move assigning into destroyed object"); + assert(t.state != State::MOVED_FROM && "double moving from an object"); + assert(t.state != State::DESTROYED && "moving from a destroyed object"); + state = t.state; + t.state = State::MOVED_FROM; + return *this; + } +#endif + + ~TrackedValue() { + assert(state != State::DESTROYED && "double-destroying an object"); + state = State::DESTROYED; + } +}; + +#endif // SUPPORT_TRACKED_VALUE_H |