cppyabm  1.0.17
An agent-based library to integrate C++ and Python
object.h
Go to the documentation of this file.
1 #if !defined(__OBJECT_H)
2 #define __OBJECT_H
3 
4 #include <atomic>
5 #include "constructor_stats.h"
6 
7 /// Reference counted object base class
8 class Object {
9 public:
10  /// Default constructor
12 
13  /// Copy constructor
14  Object(const Object &) : m_refCount(0) { print_copy_created(this); }
15 
16  /// Return the current reference count
17  int getRefCount() const { return m_refCount; };
18 
19  /// Increase the object's reference count by one
20  void incRef() const { ++m_refCount; }
21 
22  /** \brief Decrease the reference count of
23  * the object and possibly deallocate it.
24  *
25  * The object will automatically be deallocated once
26  * the reference count reaches zero.
27  */
28  void decRef(bool dealloc = true) const {
29  --m_refCount;
30  if (m_refCount == 0 && dealloc)
31  delete this;
32  else if (m_refCount < 0)
33  throw std::runtime_error("Internal error: reference count < 0!");
34  }
35 
36  virtual std::string toString() const = 0;
37 protected:
38  /** \brief Virtual protected deconstructor.
39  * (Will only be called by \ref ref)
40  */
41  virtual ~Object() { print_destroyed(this); }
42 private:
43  mutable std::atomic<int> m_refCount { 0 };
44 };
45 
46 // Tag class used to track constructions of ref objects. When we track constructors, below, we
47 // track and print out the actual class (e.g. ref<MyObject>), and *also* add a fake tracker for
48 // ref_tag. This lets us check that the total number of ref<Anything> constructors/destructors is
49 // correct without having to check each individual ref<Whatever> type individually.
50 class ref_tag {};
51 
52 /**
53  * \brief Reference counting helper
54  *
55  * The \a ref refeference template is a simple wrapper to store a
56  * pointer to an object. It takes care of increasing and decreasing
57  * the reference count of the object. When the last reference goes
58  * out of scope, the associated object will be deallocated.
59  *
60  * \ingroup libcore
61  */
62 template <typename T> class ref {
63 public:
64  /// Create a nullptr reference
65  ref() : m_ptr(nullptr) { print_default_created(this); track_default_created((ref_tag*) this); }
66 
67  /// Construct a reference from a pointer
68  ref(T *ptr) : m_ptr(ptr) {
69  if (m_ptr) ((Object *) m_ptr)->incRef();
70 
71  print_created(this, "from pointer", m_ptr); track_created((ref_tag*) this, "from pointer");
72 
73  }
74 
75  /// Copy constructor
76  ref(const ref &r) : m_ptr(r.m_ptr) {
77  if (m_ptr)
78  ((Object *) m_ptr)->incRef();
79 
80  print_copy_created(this, "with pointer", m_ptr); track_copy_created((ref_tag*) this);
81  }
82 
83  /// Move constructor
84  ref(ref &&r) : m_ptr(r.m_ptr) {
85  r.m_ptr = nullptr;
86 
87  print_move_created(this, "with pointer", m_ptr); track_move_created((ref_tag*) this);
88  }
89 
90  /// Destroy this reference
91  ~ref() {
92  if (m_ptr)
93  ((Object *) m_ptr)->decRef();
94 
95  print_destroyed(this); track_destroyed((ref_tag*) this);
96  }
97 
98  /// Move another reference into the current one
99  ref& operator=(ref&& r) {
100  print_move_assigned(this, "pointer", r.m_ptr); track_move_assigned((ref_tag*) this);
101 
102  if (*this == r)
103  return *this;
104  if (m_ptr)
105  ((Object *) m_ptr)->decRef();
106  m_ptr = r.m_ptr;
107  r.m_ptr = nullptr;
108  return *this;
109  }
110 
111  /// Overwrite this reference with another reference
112  ref& operator=(const ref& r) {
113  print_copy_assigned(this, "pointer", r.m_ptr); track_copy_assigned((ref_tag*) this);
114 
115  if (m_ptr == r.m_ptr)
116  return *this;
117  if (m_ptr)
118  ((Object *) m_ptr)->decRef();
119  m_ptr = r.m_ptr;
120  if (m_ptr)
121  ((Object *) m_ptr)->incRef();
122  return *this;
123  }
124 
125  /// Overwrite this reference with a pointer to another object
126  ref& operator=(T *ptr) {
127  print_values(this, "assigned pointer"); track_values((ref_tag*) this, "assigned pointer");
128 
129  if (m_ptr == ptr)
130  return *this;
131  if (m_ptr)
132  ((Object *) m_ptr)->decRef();
133  m_ptr = ptr;
134  if (m_ptr)
135  ((Object *) m_ptr)->incRef();
136  return *this;
137  }
138 
139  /// Compare this reference with another reference
140  bool operator==(const ref &r) const { return m_ptr == r.m_ptr; }
141 
142  /// Compare this reference with another reference
143  bool operator!=(const ref &r) const { return m_ptr != r.m_ptr; }
144 
145  /// Compare this reference with a pointer
146  bool operator==(const T* ptr) const { return m_ptr == ptr; }
147 
148  /// Compare this reference with a pointer
149  bool operator!=(const T* ptr) const { return m_ptr != ptr; }
150 
151  /// Access the object referenced by this reference
152  T* operator->() { return m_ptr; }
153 
154  /// Access the object referenced by this reference
155  const T* operator->() const { return m_ptr; }
156 
157  /// Return a C++ reference to the referenced object
158  T& operator*() { return *m_ptr; }
159 
160  /// Return a const C++ reference to the referenced object
161  const T& operator*() const { return *m_ptr; }
162 
163  /// Return a pointer to the referenced object
164  operator T* () { return m_ptr; }
165 
166  /// Return a const pointer to the referenced object
167  T* get_ptr() { return m_ptr; }
168 
169  /// Return a pointer to the referenced object
170  const T* get_ptr() const { return m_ptr; }
171 private:
172  T *m_ptr;
173 };
174 
175 #endif /* __OBJECT_H */
track_destroyed
void track_destroyed(T *inst)
Definition: constructor_stats.h:223
track_copy_assigned
void track_copy_assigned(T *, Values &&...values)
Definition: constructor_stats.h:203
track_values
void track_values(T *, Values &&...values)
Definition: constructor_stats.h:226
Object::~Object
virtual ~Object()
Virtual protected deconstructor. (Will only be called by ref)
Definition: object.h:41
Object::decRef
void decRef(bool dealloc=true) const
Decrease the reference count of the object and possibly deallocate it.
Definition: object.h:28
ref::get_ptr
T * get_ptr()
Return a const pointer to the referenced object.
Definition: object.h:167
ref::get_ptr
const T * get_ptr() const
Return a pointer to the referenced object.
Definition: object.h:170
Object::toString
virtual std::string toString() const =0
ref::operator==
bool operator==(const ref &r) const
Compare this reference with another reference.
Definition: object.h:140
constructor_stats.h
ref::ref
ref(T *ptr)
Construct a reference from a pointer.
Definition: object.h:68
ref::ref
ref(ref &&r)
Move constructor.
Definition: object.h:84
print_copy_created
void print_copy_created(T *inst, Values &&...values)
Definition: constructor_stats.h:244
track_move_created
void track_move_created(T *inst)
Definition: constructor_stats.h:202
print_default_created
void print_default_created(T *inst, Values &&...values)
Definition: constructor_stats.h:260
Object::incRef
void incRef() const
Increase the object's reference count by one.
Definition: object.h:20
ref::operator!=
bool operator!=(const T *ptr) const
Compare this reference with a pointer.
Definition: object.h:149
ref::ref
ref()
Create a nullptr reference.
Definition: object.h:65
ref::~ref
~ref()
Destroy this reference.
Definition: object.h:91
ref::operator*
T & operator*()
Return a C++ reference to the referenced object.
Definition: object.h:158
ref::operator!=
bool operator!=(const ref &r) const
Compare this reference with another reference.
Definition: object.h:143
print_copy_assigned
void print_copy_assigned(T *inst, Values &&...values)
Definition: constructor_stats.h:252
Object::getRefCount
int getRefCount() const
Return the current reference count.
Definition: object.h:17
Object
Reference counted object base class.
Definition: object.h:8
ref::operator->
const T * operator->() const
Access the object referenced by this reference.
Definition: object.h:155
track_copy_created
void track_copy_created(T *inst)
Definition: constructor_stats.h:201
ref_tag
Definition: object.h:50
ref::operator=
ref & operator=(const ref &r)
Overwrite this reference with another reference.
Definition: object.h:112
ref::operator*
const T & operator*() const
Return a const C++ reference to the referenced object.
Definition: object.h:161
track_default_created
void track_default_created(T *inst, Values &&...values)
Definition: constructor_stats.h:213
ref::operator=
ref & operator=(T *ptr)
Overwrite this reference with a pointer to another object.
Definition: object.h:126
Object::Object
Object(const Object &)
Copy constructor.
Definition: object.h:14
print_move_created
void print_move_created(T *inst, Values &&...values)
Definition: constructor_stats.h:248
ref::operator==
bool operator==(const T *ptr) const
Compare this reference with a pointer.
Definition: object.h:146
track_created
void track_created(T *inst, Values &&...values)
Definition: constructor_stats.h:218
print_destroyed
void print_destroyed(T *inst, Values &&...values)
Definition: constructor_stats.h:268
ref
Reference counting helper.
Definition: object.h:62
ref::operator=
ref & operator=(ref &&r)
Move another reference into the current one.
Definition: object.h:99
ref::operator->
T * operator->()
Access the object referenced by this reference.
Definition: object.h:152
print_move_assigned
void print_move_assigned(T *inst, Values &&...values)
Definition: constructor_stats.h:256
track_move_assigned
void track_move_assigned(T *, Values &&...values)
Definition: constructor_stats.h:208
Object::Object
Object()
Default constructor.
Definition: object.h:11
ref::ref
ref(const ref &r)
Copy constructor.
Definition: object.h:76
print_created
void print_created(T *inst, Values &&...values)
Definition: constructor_stats.h:264
print_values
void print_values(T *inst, Values &&...values)
Definition: constructor_stats.h:272