| 65 | */ |
| 66 | template <typename T> |
| 67 | class ref { |
| 68 | public: |
| 69 | /// Create a nullptr reference |
| 70 | ref() : m_ptr(nullptr) { |
| 71 | print_default_created(this); |
| 72 | track_default_created((ref_tag *) this); |
| 73 | } |
| 74 | |
| 75 | /// Construct a reference from a pointer |
| 76 | explicit ref(T *ptr) : m_ptr(ptr) { |
| 77 | if (m_ptr) { |
| 78 | ((Object *) m_ptr)->incRef(); |
| 79 | } |
| 80 | |
| 81 | print_created(this, "from pointer", m_ptr); |
| 82 | track_created((ref_tag *) this, "from pointer"); |
| 83 | } |
| 84 | |
| 85 | /// Copy constructor |
| 86 | ref(const ref &r) : m_ptr(r.m_ptr) { |
| 87 | if (m_ptr) { |
| 88 | ((Object *) m_ptr)->incRef(); |
| 89 | } |
| 90 | |
| 91 | print_copy_created(this, "with pointer", m_ptr); |
| 92 | track_copy_created((ref_tag *) this); |
| 93 | } |
| 94 | |
| 95 | /// Move constructor |
| 96 | ref(ref &&r) noexcept : m_ptr(r.m_ptr) { |
| 97 | r.m_ptr = nullptr; |
| 98 | |
| 99 | print_move_created(this, "with pointer", m_ptr); |
| 100 | track_move_created((ref_tag *) this); |
| 101 | } |
| 102 | |
| 103 | /// Destroy this reference |
| 104 | ~ref() { |
| 105 | if (m_ptr) { |
| 106 | ((Object *) m_ptr)->decRef(); |
| 107 | } |
| 108 | |
| 109 | print_destroyed(this); |
| 110 | track_destroyed((ref_tag *) this); |
| 111 | } |
| 112 | |
| 113 | /// Move another reference into the current one |
| 114 | ref &operator=(ref &&r) noexcept { |
| 115 | print_move_assigned(this, "pointer", r.m_ptr); |
| 116 | track_move_assigned((ref_tag *) this); |
| 117 | |
| 118 | if (*this == r) { |
| 119 | return *this; |
| 120 | } |
| 121 | if (m_ptr) { |
| 122 | ((Object *) m_ptr)->decRef(); |
| 123 | } |
| 124 | m_ptr = r.m_ptr; |