μHAL (v2.8.17)
Part of the IPbus software repository
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
object.h
Go to the documentation of this file.
1#if !defined(__OBJECT_H)
2# define __OBJECT_H
3
4# include "constructor_stats.h"
5
6# include <atomic>
7
9class Object {
10public:
13
15 Object(const Object &) : m_refCount(0) { print_copy_created(this); }
16
18 int getRefCount() const { return m_refCount; };
19
21 void incRef() const { ++m_refCount; }
22
29 void decRef(bool dealloc = true) const {
30 --m_refCount;
31 if (m_refCount == 0 && dealloc) {
32 delete this;
33 } else if (m_refCount < 0) {
34 throw std::runtime_error("Internal error: reference count < 0!");
35 }
36 }
37
38 virtual std::string toString() const = 0;
39
40protected:
44 virtual ~Object() { print_destroyed(this); }
45
46private:
47 mutable std::atomic<int> m_refCount{0};
48};
49
50// Tag class used to track constructions of ref objects. When we track constructors, below, we
51// track and print out the actual class (e.g. ref<MyObject>), and *also* add a fake tracker for
52// ref_tag. This lets us check that the total number of ref<Anything> constructors/destructors is
53// correct without having to check each individual ref<Whatever> type individually.
54class ref_tag {};
55
66template <typename T>
67class ref {
68public:
70 ref() : m_ptr(nullptr) {
73 }
74
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
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);
93 }
94
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
105 if (m_ptr) {
106 ((Object *) m_ptr)->decRef();
107 }
108
109 print_destroyed(this);
110 track_destroyed((ref_tag *) this);
111 }
112
114 ref &operator=(ref &&r) noexcept {
115 print_move_assigned(this, "pointer", r.m_ptr);
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;
125 r.m_ptr = nullptr;
126 return *this;
127 }
128
130 ref &operator=(const ref &r) {
131 if (this == &r) {
132 return *this;
133 }
134 print_copy_assigned(this, "pointer", r.m_ptr);
136
137 if (m_ptr == r.m_ptr) {
138 return *this;
139 }
140 if (m_ptr) {
141 ((Object *) m_ptr)->decRef();
142 }
143 m_ptr = r.m_ptr;
144 if (m_ptr) {
145 ((Object *) m_ptr)->incRef();
146 }
147 return *this;
148 }
149
151 ref &operator=(T *ptr) {
152 print_values(this, "assigned pointer");
153 track_values((ref_tag *) this, "assigned pointer");
154
155 if (m_ptr == ptr) {
156 return *this;
157 }
158 if (m_ptr) {
159 ((Object *) m_ptr)->decRef();
160 }
161 m_ptr = ptr;
162 if (m_ptr) {
163 ((Object *) m_ptr)->incRef();
164 }
165 return *this;
166 }
167
169 bool operator==(const ref &r) const { return m_ptr == r.m_ptr; }
170
172 bool operator!=(const ref &r) const { return m_ptr != r.m_ptr; }
173
175 bool operator==(const T *ptr) const { return m_ptr == ptr; }
176
178 bool operator!=(const T *ptr) const { return m_ptr != ptr; }
179
181 T *operator->() { return m_ptr; }
182
184 const T *operator->() const { return m_ptr; }
185
187 T &operator*() { return *m_ptr; }
188
190 const T &operator*() const { return *m_ptr; }
191
193 explicit operator T *() { return m_ptr; }
194
196 T *get_ptr() { return m_ptr; }
197
199 const T *get_ptr() const { return m_ptr; }
200
201private:
203};
204
205#endif /* __OBJECT_H */
Reference counted object base class.
Definition: object.h:9
std::atomic< int > m_refCount
Definition: object.h:47
Object()
Default constructor.
Definition: object.h:12
int getRefCount() const
Return the current reference count.
Definition: object.h:18
void incRef() const
Increase the object's reference count by one.
Definition: object.h:21
virtual std::string toString() const =0
virtual ~Object()
Virtual protected deconstructor.
Definition: object.h:44
void decRef(bool dealloc=true) const
Decrease the reference count of the object and possibly deallocate it.
Definition: object.h:29
Object(const Object &)
Copy constructor.
Definition: object.h:15
Definition: object.h:54
Reference counting helper.
Definition: object.h:67
~ref()
Destroy this reference.
Definition: object.h:104
const T * operator->() const
Access the object referenced by this reference.
Definition: object.h:184
T & operator*()
Return a C++ reference to the referenced object.
Definition: object.h:187
ref()
Create a nullptr reference.
Definition: object.h:70
T * m_ptr
Definition: object.h:202
const T & operator*() const
Return a const C++ reference to the referenced object.
Definition: object.h:190
bool operator==(const T *ptr) const
Compare this reference with a pointer.
Definition: object.h:175
T * get_ptr()
Return a const pointer to the referenced object.
Definition: object.h:196
bool operator==(const ref &r) const
Compare this reference with another reference.
Definition: object.h:169
bool operator!=(const T *ptr) const
Compare this reference with a pointer.
Definition: object.h:178
ref & operator=(const ref &r)
Overwrite this reference with another reference.
Definition: object.h:130
ref & operator=(ref &&r) noexcept
Move another reference into the current one.
Definition: object.h:114
ref(const ref &r)
Copy constructor.
Definition: object.h:86
const T * get_ptr() const
Return a pointer to the referenced object.
Definition: object.h:199
ref(T *ptr)
Construct a reference from a pointer.
Definition: object.h:76
ref(ref &&r) noexcept
Move constructor.
Definition: object.h:96
bool operator!=(const ref &r) const
Compare this reference with another reference.
Definition: object.h:172
T * operator->()
Access the object referenced by this reference.
Definition: object.h:181
ref & operator=(T *ptr)
Overwrite this reference with a pointer to another object.
Definition: object.h:151
void print_default_created(T *inst, Values &&...values)
void track_destroyed(T *inst)
void track_values(T *, Values &&...values)
void track_move_assigned(T *, Values &&...values)
void print_copy_created(T *inst, Values &&...values)
void print_copy_assigned(T *inst, Values &&...values)
void track_created(T *inst, Values &&...values)
void print_created(T *inst, Values &&...values)
void track_move_created(T *inst)
void print_values(T *inst, Values &&...values)
void track_copy_created(T *inst)
void track_copy_assigned(T *, Values &&...values)
void print_destroyed(T *inst, Values &&...values)
void print_move_assigned(T *inst, Values &&...values)
void track_default_created(T *inst, Values &&...values)
void print_move_created(T *inst, Values &&...values)