• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  // Copyright Louis Dionne 2013-2017
2  // Distributed under the Boost Software License, Version 1.0.
3  // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
4  
5  #ifndef TEST_SUPPORT_TRACKED_HPP
6  #define TEST_SUPPORT_TRACKED_HPP
7  
8  // Define this if you want Tracked objects to print information to stderr.
9  // #define TRACKED_PRINT_STUFF
10  
11  #include <boost/hana/assert.hpp>
12  
13  #ifdef TRACKED_PRINT_STUFF
14  #   include <iostream>
15  #endif
16  
17  #include <iosfwd>
18  
19  
20  struct Tracked {
21      enum class State { CONSTRUCTED, MOVED_FROM, DESTROYED };
22  
23      int value;
24      State state;
25  
TrackedTracked26      explicit Tracked(int k) : value{k}, state{State::CONSTRUCTED} {
27  #ifdef TRACKED_PRINT_STUFF
28          std::cerr << "constructing " << *this << '\n';
29  #endif
30      }
31  
TrackedTracked32      Tracked(Tracked const& t) : value{t.value}, state{State::CONSTRUCTED} {
33          BOOST_HANA_RUNTIME_CHECK(t.state != State::MOVED_FROM &&
34              "copying a moved-from object");
35  
36          BOOST_HANA_RUNTIME_CHECK(t.state != State::DESTROYED &&
37              "copying a destroyed object");
38  
39  #ifdef TRACKED_PRINT_STUFF
40          std::cerr << "copying " << *this << '\n';
41  #endif
42      }
43  
TrackedTracked44      Tracked(Tracked&& t) : value{t.value}, state{State::CONSTRUCTED} {
45          BOOST_HANA_RUNTIME_CHECK(t.state != State::MOVED_FROM &&
46              "double moving from an object");
47  
48          BOOST_HANA_RUNTIME_CHECK(t.state != State::DESTROYED &&
49              "moving from a destroyed object");
50  
51  #ifdef TRACKED_PRINT_STUFF
52          std::cerr << "moving " << t << '\n';
53  #endif
54          t.state = State::MOVED_FROM;
55      }
56  
operator =Tracked57      Tracked& operator=(Tracked const& other) {
58          BOOST_HANA_RUNTIME_CHECK(this->state != State::DESTROYED &&
59              "assigning to a destroyed object");
60  
61          BOOST_HANA_RUNTIME_CHECK(other.state != State::MOVED_FROM &&
62              "assigning a moved-from object");
63  
64          BOOST_HANA_RUNTIME_CHECK(other.state != State::DESTROYED &&
65              "assigning a destroyed object");
66  
67  #ifdef TRACKED_PRINT_STUFF
68          std::cerr << "assigning " << other << " to " << *this << '\n';
69  #endif
70          this->value = other.value;
71          return *this;
72      }
73  
operator =Tracked74      Tracked& operator=(Tracked&& other) {
75          BOOST_HANA_RUNTIME_CHECK(this->state != State::DESTROYED &&
76              "assigning to a destroyed object");
77  
78          BOOST_HANA_RUNTIME_CHECK(other.state != State::MOVED_FROM &&
79              "double-moving from an object");
80  
81          BOOST_HANA_RUNTIME_CHECK(other.state != State::DESTROYED &&
82              "assigning a destroyed object");
83  
84  #ifdef TRACKED_PRINT_STUFF
85          std::cerr << "assigning " << other << " to " << *this << '\n';
86  #endif
87          this->value = other.value;
88          other.state = State::MOVED_FROM;
89          return *this;
90      }
91  
~TrackedTracked92      ~Tracked() {
93          BOOST_HANA_RUNTIME_CHECK(state != State::DESTROYED &&
94              "double-destroying an object");
95  
96  #ifdef TRACKED_PRINT_STUFF
97          std::cerr << "destructing " << *this << '\n';
98  #endif
99          state = State::DESTROYED;
100      }
101  
102      template <typename CharT, typename Traits>
103      friend std::basic_ostream<CharT, Traits>&
operator <<(std::basic_ostream<CharT,Traits> & os,Tracked const & t)104      operator<<(std::basic_ostream<CharT, Traits>& os, Tracked const& t) {
105          os << "Tracked{" << t.value << "}";
106          switch (t.state) {
107          case State::CONSTRUCTED:
108              os << "[ok]"; break;
109          case State::MOVED_FROM:
110              os << "[moved from]"; break;
111          case State::DESTROYED:
112              os << "[destroyed]"; break;
113          default:
114              BOOST_HANA_RUNTIME_CHECK(false && "never reached");
115          }
116          return os;
117      }
118  };
119  
120  #endif // !TEST_SUPPORT_TRACKED_HPP
121