Add TrackedValue to test/support. Thanks to Louis Dionne
authorEric Fiselier <eric@efcs.ca>
Mon, 9 Mar 2015 18:02:16 +0000 (18:02 +0000)
committerEric Fiselier <eric@efcs.ca>
Mon, 9 Mar 2015 18:02:16 +0000 (18:02 +0000)
llvm-svn: 231674

libcxx/test/support/tracked_value.h [new file with mode: 0644]

diff --git a/libcxx/test/support/tracked_value.h b/libcxx/test/support/tracked_value.h
new file mode 100644 (file)
index 0000000..b0869b2
--- /dev/null
@@ -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