Pioneer
RefCounted.h
Go to the documentation of this file.
1 // Copyright © 2008-2023 Pioneer Developers. See AUTHORS.txt for details
2 // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3 
4 #ifndef _REFCOUNTED_H
5 #define _REFCOUNTED_H
6 
7 #include "SmartPtr.h"
8 #include "lua/LuaWrappable.h"
9 #include <atomic>
10 
11 class RefCounted : public LuaWrappable {
12 public:
14  m_refCount(0) {}
15  virtual ~RefCounted() {}
16 
17  inline void IncRefCount() const { ++m_refCount; }
18  inline void DecRefCount() const
19  {
20  assert(m_refCount > 0);
21  if (!--m_refCount) delete this;
22  }
23  inline int GetRefCount() const { return m_refCount; }
24 
25 private:
26  // vs2012 doesn't support the `= delete` syntax
27  RefCounted(const RefCounted &);
28  RefCounted(const RefCounted &&);
29  RefCounted &operator=(const RefCounted &);
30  RefCounted &operator=(const RefCounted &&);
31 
32  mutable std::atomic<int> m_refCount; // We model logical constness, so refcount is changeable even for const objects
33 };
34 
35 template <typename T>
36 class RefCountedPtr : public SmartPtrBase<RefCountedPtr<T>, T> {
39 
40 public:
42 
43  explicit RefCountedPtr(T *p) :
44  base_type(p)
45  {
46  if (this->m_ptr) this->m_ptr->IncRefCount();
47  }
48 
49  // Note: This is still needed, the compiler would generate a default copy constructor despite the templated version
50  RefCountedPtr(const this_type &b) :
51  base_type(b.Get())
52  {
53  if (this->m_ptr) this->m_ptr->IncRefCount();
54  }
55 
56  // Generalized copy constructor, allowing copy for compatible pointer types (e.g. RefCountedPtr<const T>)
57  template <typename U>
59  base_type(b.Get())
60  {
61  if (this->m_ptr) this->m_ptr->IncRefCount();
62  }
63 
65  {
66  T *p = this->Release();
67  if (p) p->DecRefCount();
68  }
69 
70  // Note: This is still needed, the compiler would generate a default assignment operator despite the templated version
72  {
73  this->Reset(b.Get());
74  return *this;
75  }
76 
77  // Generalized assignment operator allowing assignment for compatible pointer types (e.g. RefCountedPtr<const T>)
78  template <typename U>
80  {
81  this->Reset(b.Get());
82  return *this;
83  }
84 
85  bool Unique() const
86  {
87  assert(this->m_ptr);
88  return (this->m_ptr->GetRefCount() == 1);
89  }
90 };
91 
92 #endif
Definition: LuaWrappable.h:13
Definition: RefCounted.h:36
~RefCountedPtr()
Definition: RefCounted.h:64
RefCountedPtr(const this_type &b)
Definition: RefCounted.h:50
RefCountedPtr(const RefCountedPtr< U > &b)
Definition: RefCounted.h:58
RefCountedPtr(T *p)
Definition: RefCounted.h:43
this_type & operator=(const this_type &b)
Definition: RefCounted.h:71
bool Unique() const
Definition: RefCounted.h:85
this_type & operator=(const RefCountedPtr< U > &b)
Definition: RefCounted.h:79
RefCountedPtr()
Definition: RefCounted.h:41
Definition: RefCounted.h:11
RefCounted()
Definition: RefCounted.h:13
void DecRefCount() const
Definition: RefCounted.h:18
virtual ~RefCounted()
Definition: RefCounted.h:15
int GetRefCount() const
Definition: RefCounted.h:23
void IncRefCount() const
Definition: RefCounted.h:17
Definition: SmartPtr.h:18
m_ptr
Definition: SmartPtr.h:82
return p
Definition: SmartPtr.h:83
T * Get() const
Definition: SmartPtr.h:37
void Reset(T *p=0)
Definition: SmartPtr.h:25