123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- // Copyright Louis Dionne 2013-2017
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
- #ifndef TEST_SUPPORT_TRACKED_HPP
- #define TEST_SUPPORT_TRACKED_HPP
- // Define this if you want Tracked objects to print information to stderr.
- // #define TRACKED_PRINT_STUFF
- #include <boost/hana/assert.hpp>
- #ifdef TRACKED_PRINT_STUFF
- # include <iostream>
- #endif
- #include <iosfwd>
- struct Tracked {
- enum class State { CONSTRUCTED, MOVED_FROM, DESTROYED };
- int value;
- State state;
- explicit Tracked(int k) : value{k}, state{State::CONSTRUCTED} {
- #ifdef TRACKED_PRINT_STUFF
- std::cerr << "constructing " << *this << '\n';
- #endif
- }
- Tracked(Tracked const& t) : value{t.value}, state{State::CONSTRUCTED} {
- BOOST_HANA_RUNTIME_CHECK(t.state != State::MOVED_FROM &&
- "copying a moved-from object");
- BOOST_HANA_RUNTIME_CHECK(t.state != State::DESTROYED &&
- "copying a destroyed object");
- #ifdef TRACKED_PRINT_STUFF
- std::cerr << "copying " << *this << '\n';
- #endif
- }
- Tracked(Tracked&& t) : value{t.value}, state{State::CONSTRUCTED} {
- BOOST_HANA_RUNTIME_CHECK(t.state != State::MOVED_FROM &&
- "double moving from an object");
- BOOST_HANA_RUNTIME_CHECK(t.state != State::DESTROYED &&
- "moving from a destroyed object");
- #ifdef TRACKED_PRINT_STUFF
- std::cerr << "moving " << t << '\n';
- #endif
- t.state = State::MOVED_FROM;
- }
- Tracked& operator=(Tracked const& other) {
- BOOST_HANA_RUNTIME_CHECK(this->state != State::DESTROYED &&
- "assigning to a destroyed object");
- BOOST_HANA_RUNTIME_CHECK(other.state != State::MOVED_FROM &&
- "assigning a moved-from object");
- BOOST_HANA_RUNTIME_CHECK(other.state != State::DESTROYED &&
- "assigning a destroyed object");
- #ifdef TRACKED_PRINT_STUFF
- std::cerr << "assigning " << other << " to " << *this << '\n';
- #endif
- this->value = other.value;
- return *this;
- }
- Tracked& operator=(Tracked&& other) {
- BOOST_HANA_RUNTIME_CHECK(this->state != State::DESTROYED &&
- "assigning to a destroyed object");
- BOOST_HANA_RUNTIME_CHECK(other.state != State::MOVED_FROM &&
- "double-moving from an object");
- BOOST_HANA_RUNTIME_CHECK(other.state != State::DESTROYED &&
- "assigning a destroyed object");
- #ifdef TRACKED_PRINT_STUFF
- std::cerr << "assigning " << other << " to " << *this << '\n';
- #endif
- this->value = other.value;
- other.state = State::MOVED_FROM;
- return *this;
- }
- ~Tracked() {
- BOOST_HANA_RUNTIME_CHECK(state != State::DESTROYED &&
- "double-destroying an object");
- #ifdef TRACKED_PRINT_STUFF
- std::cerr << "destructing " << *this << '\n';
- #endif
- state = State::DESTROYED;
- }
- template <typename CharT, typename Traits>
- friend std::basic_ostream<CharT, Traits>&
- operator<<(std::basic_ostream<CharT, Traits>& os, Tracked const& t) {
- os << "Tracked{" << t.value << "}";
- switch (t.state) {
- case State::CONSTRUCTED:
- os << "[ok]"; break;
- case State::MOVED_FROM:
- os << "[moved from]"; break;
- case State::DESTROYED:
- os << "[destroyed]"; break;
- default:
- BOOST_HANA_RUNTIME_CHECK(false && "never reached");
- }
- return os;
- }
- };
- #endif // !TEST_SUPPORT_TRACKED_HPP
|