1fa1e5db3bc5f3a1a730455c8100850248b94c1ecEric Fiselier//===----------------------------------------------------------------------===//
2fa1e5db3bc5f3a1a730455c8100850248b94c1ecEric Fiselier//
3fa1e5db3bc5f3a1a730455c8100850248b94c1ecEric Fiselier//                     The LLVM Compiler Infrastructure
4fa1e5db3bc5f3a1a730455c8100850248b94c1ecEric Fiselier//
5fa1e5db3bc5f3a1a730455c8100850248b94c1ecEric Fiselier// This file is dual licensed under the MIT and the University of Illinois Open
6fa1e5db3bc5f3a1a730455c8100850248b94c1ecEric Fiselier// Source Licenses. See LICENSE.TXT for details.
7fa1e5db3bc5f3a1a730455c8100850248b94c1ecEric Fiselier//
8fa1e5db3bc5f3a1a730455c8100850248b94c1ecEric Fiselier//===----------------------------------------------------------------------===//
93c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier#ifndef SUPPORT_TRACKED_VALUE_H
103c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier#define SUPPORT_TRACKED_VALUE_H
113c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier
123c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier#include <cassert>
133c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier
14c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert#include "test_macros.h"
15c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert
163c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselierstruct TrackedValue {
173c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier    enum State { CONSTRUCTED, MOVED_FROM, DESTROYED };
183c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier    State state;
193c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier
203c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier    TrackedValue() : state(State::CONSTRUCTED) {}
213c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier
223c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier    TrackedValue(TrackedValue const& t) : state(State::CONSTRUCTED) {
233c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier        assert(t.state != State::MOVED_FROM && "copying a moved-from object");
243c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier        assert(t.state != State::DESTROYED  && "copying a destroyed object");
253c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier    }
263c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier
27c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert#if TEST_STD_VER >= 11
283c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier    TrackedValue(TrackedValue&& t) : state(State::CONSTRUCTED) {
293c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier        assert(t.state != State::MOVED_FROM && "double moving from an object");
303c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier        assert(t.state != State::DESTROYED  && "moving from a destroyed object");
313c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier        t.state = State::MOVED_FROM;
323c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier    }
333c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier#endif
343c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier
353c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier    TrackedValue& operator=(TrackedValue const& t) {
363c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier        assert(state != State::DESTROYED && "copy assigning into destroyed object");
373c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier        assert(t.state != State::MOVED_FROM && "copying a moved-from object");
383c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier        assert(t.state != State::DESTROYED  && "copying a destroyed object");
393c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier        state = t.state;
403c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier        return *this;
413c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier    }
423c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier
43c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert#if TEST_STD_VER >= 11
443c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier    TrackedValue& operator=(TrackedValue&& t) {
453c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier        assert(state != State::DESTROYED && "move assigning into destroyed object");
463c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier        assert(t.state != State::MOVED_FROM && "double moving from an object");
473c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier        assert(t.state != State::DESTROYED  && "moving from a destroyed object");
483c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier        state = t.state;
493c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier        t.state = State::MOVED_FROM;
503c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier        return *this;
513c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier    }
523c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier#endif
533c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier
543c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier    ~TrackedValue() {
553c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier        assert(state != State::DESTROYED && "double-destroying an object");
563c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier        state = State::DESTROYED;
573c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier    }
583c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier};
593c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier
603c7b80131b4df24bbd71959a5af80961caa449cfEric Fiselier#endif // SUPPORT_TRACKED_VALUE_H
61