Home | History | Annotate | Download | only in support
      1 //===----------------------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 #ifndef SUPPORT_TRACKED_VALUE_H
     10 #define SUPPORT_TRACKED_VALUE_H
     11 
     12 #include <cassert>
     13 
     14 struct TrackedValue {
     15     enum State { CONSTRUCTED, MOVED_FROM, DESTROYED };
     16     State state;
     17 
     18     TrackedValue() : state(State::CONSTRUCTED) {}
     19 
     20     TrackedValue(TrackedValue const& t) : state(State::CONSTRUCTED) {
     21         assert(t.state != State::MOVED_FROM && "copying a moved-from object");
     22         assert(t.state != State::DESTROYED  && "copying a destroyed object");
     23     }
     24 
     25 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     26     TrackedValue(TrackedValue&& t) : state(State::CONSTRUCTED) {
     27         assert(t.state != State::MOVED_FROM && "double moving from an object");
     28         assert(t.state != State::DESTROYED  && "moving from a destroyed object");
     29         t.state = State::MOVED_FROM;
     30     }
     31 #endif
     32 
     33     TrackedValue& operator=(TrackedValue const& t) {
     34         assert(state != State::DESTROYED && "copy assigning into destroyed object");
     35         assert(t.state != State::MOVED_FROM && "copying a moved-from object");
     36         assert(t.state != State::DESTROYED  && "copying a destroyed object");
     37         state = t.state;
     38         return *this;
     39     }
     40 
     41 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     42     TrackedValue& operator=(TrackedValue&& t) {
     43         assert(state != State::DESTROYED && "move assigning into destroyed object");
     44         assert(t.state != State::MOVED_FROM && "double moving from an object");
     45         assert(t.state != State::DESTROYED  && "moving from a destroyed object");
     46         state = t.state;
     47         t.state = State::MOVED_FROM;
     48         return *this;
     49     }
     50 #endif
     51 
     52     ~TrackedValue() {
     53         assert(state != State::DESTROYED && "double-destroying an object");
     54         state = State::DESTROYED;
     55     }
     56 };
     57 
     58 #endif // SUPPORT_TRACKED_VALUE_H
     59