TSmartPtr.h
Go to the documentation of this file.
1 #ifndef istd_TSmartPtr_included
2 #define istd_TSmartPtr_included
3 
4 
5 // Qt includes
6 #include <QtCore/QMutex>
7 
8 // ACF includes
9 #include <istd/TTransPtr.h>
10 
11 
12 namespace istd
13 {
14 
15 
23 template <class Type, class Accessor = DefaultAccessor<Type> >
24 class TSmartPtr: public TTransPtr<Type>
25 {
26 public:
28  typedef typename BaseClass::RefCountBase RefCountBase;
29 
30  TSmartPtr();
31  explicit TSmartPtr(Type* pointer);
32  TSmartPtr(const TTransPtr<Type>& pointer);
33  TSmartPtr(const TSmartPtr& pointer);
34 
38  void SetPtr(Type* pointer);
39 
44  template <class SourceType>
45  bool SetCastedOrRemove(SourceType* pointer)
46  {
47  Type* castedPtr = dynamic_cast<Type*>(pointer);
48 
49  SetPtr(castedPtr);
50 
51  if (castedPtr != NULL){
52  return true;
53  }
54  else{
55  if (pointer != NULL){
56  delete pointer;
57  }
58 
59  return false;
60  }
61  }
62 
63  // operators
64  TSmartPtr& operator=(const TTransPtr<Type>& pointer);
65  TSmartPtr& operator=(const TSmartPtr& pointer);
66 
67 protected:
68  class RefCounter: public RefCountBase
69  {
70  public:
72 
73  explicit RefCounter(Type* pointer)
74  : BaseClass(pointer),
75  m_count(1),
76  m_lock(QMutex::Recursive)
77  {
78  }
79 
80  // reimplemented (RefCountBase)
81  virtual void OnAttached()
82  {
83  m_lock.lock();
84 
85  Q_ASSERT(BaseClass::IsValid());
86  Q_ASSERT(m_count > 0);
87 
88  ++m_count;
89 
90  m_lock.unlock();
91  }
92 
93  virtual void OnDetached()
94  {
95  m_lock.lock();
96 
97  Q_ASSERT(BaseClass::IsValid());
98  Q_ASSERT(m_count > 0);
99 
100  if (--m_count <= 0){
101  Accessor::Delete(BaseClass::GetPtr());
102 
103  m_lock.unlock();
104 
105  delete this;
106 
107  return;
108  }
109 
110  m_lock.unlock();
111  }
112 
113  private:
114  int m_count;
115  QMutex m_lock;
116  };
117 };
118 
119 
120 template <class Type, class Accessor>
122  :BaseClass()
123 {
125 }
126 
127 
128 template <class Type, class Accessor>
130  :BaseClass()
131 {
132  if (pointer != NULL){
133  BaseClass::m_counterPtr = new RefCounter(pointer);
134  }
135  else{
137  }
138 }
139 
140 
141 template <class Type, class Accessor>
143  :BaseClass()
144 {
146 
149  }
150 }
151 
152 
153 template <class Type, class Accessor>
155  :BaseClass()
156 {
158 
161  }
162 }
163 
164 
165 template <class Type, class Accessor>
166 inline void TSmartPtr<Type, Accessor>::SetPtr(Type* pointer)
167 {
168  BaseClass::Detach();
169 
170  if (pointer != NULL){
171  BaseClass::m_counterPtr = new RefCounter(pointer);
172  }
173  else{
174  BaseClass::m_counterPtr = NULL;
175  }
176 }
177 
178 
179 template <class Type, class Accessor>
181 {
182  RefCountBase* pointerInternalCounter = BaseClass::GetInternalCounter(pointer);
183 
184  if (pointerInternalCounter != BaseClass::m_counterPtr){
185  Q_ASSERT((pointerInternalCounter == NULL) || (BaseClass::m_counterPtr == NULL) || (*pointerInternalCounter != *BaseClass::m_counterPtr)); // two different reference counters cannot shown at the same destination object
186 
187  BaseClass::Detach();
188 
189  BaseClass::m_counterPtr = pointerInternalCounter;
190 
191  if (BaseClass::m_counterPtr != NULL){
192  BaseClass::m_counterPtr->OnAttached();
193  }
194  }
195 
196  return *this;
197 }
198 
199 
200 template <class Type, class Accessor>
202 {
203  RefCountBase* pointerInternalCounter = BaseClass::GetInternalCounter(pointer);
204 
205  if (pointerInternalCounter != BaseClass::m_counterPtr){
206  Q_ASSERT((pointerInternalCounter == NULL) || (BaseClass::m_counterPtr == NULL) || (*pointerInternalCounter != *BaseClass::m_counterPtr)); // two different reference counters cannot shown at the same destination object
207 
208  BaseClass::Detach();
209 
210  BaseClass::m_counterPtr = pointerInternalCounter;
211 
212  if (BaseClass::m_counterPtr != NULL){
213  BaseClass::m_counterPtr->OnAttached();
214  }
215  }
216 
217  return *this;
218 }
219 
220 
221 } // namespace istd
222 
223 
224 #endif // !istd_TSmartPtr_included
225 
226 
virtual void OnAttached()=0
Called if new pointer is attached to this internal handler.
bool IsValid() const
Check if internal pointer not NULL.
Definition: TPointerBase.h:136
Implementation of data transfer smart pointer.
Definition: TTransPtr.h:24
TSmartPtr & operator=(const TTransPtr< Type > &pointer)
Definition: TSmartPtr.h:180
BaseClass::RefCountBase RefCountBase
Definition: TSmartPtr.h:28
RefCountBase * m_counterPtr
Definition: TTransPtr.h:109
bool SetCastedOrRemove(SourceType *pointer)
Set this pointer using casted pointer of other type.
Definition: TSmartPtr.h:45
virtual void OnDetached()
Called if pointer is detached from this internal handler.
Definition: TSmartPtr.h:93
Implementation of a smart pointer.
Definition: TSmartPtr.h:24
RefCounter(Type *pointer)
Definition: TSmartPtr.h:73
void SetPtr(Type *pointer)
Set pointed object.
Definition: TSmartPtr.h:166
Type * GetPtr() const
Return access to internal stored pointer.
Definition: TPointerBase.h:129
RefCountBase * GetInternalCounter(const TTransPtr &pointer) const
Get internal counter.
Definition: TTransPtr.h:231
#define NULL
Definition: istd.h:64
virtual void OnAttached()
Called if new pointer is attached to this internal handler.
Definition: TSmartPtr.h:81
TTransPtr< Type > BaseClass
Definition: TSmartPtr.h:27

© 2007-2017 Witold Gantzke and Kirill Lepskiy