Medical Imaging Interaction Toolkit  2024.12.00
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
berrySmartPointer.h
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #ifndef BERRYSMARTPOINTER_H_
14 #define BERRYSMARTPOINTER_H_
15 
16 #include <iostream>
17 #include <stdexcept>
18 
20 
21 #include <berryConfig.h>
22 
23 #include <Poco/Bugcheck.h>
24 
25 #if defined(BLUEBERRY_DEBUG_SMARTPOINTER)
26 #include <QMutex>
27 #endif
28 
29 namespace berry
30 {
31 
32 template<class T> class WeakPointer;
33 
44 template<class TObjectType>
45 class SmartPointer
46 {
47 public:
48  typedef TObjectType ObjectType;
49  typedef SmartPointer Self;
50 
53  m_Pointer(nullptr)
54  {
55 #if defined(BLUEBERRY_DEBUG_SMARTPOINTER)
56  DebugInitSmartPointer();
57 #endif
58 
59  }
60 
62  explicit SmartPointer(ObjectType *p) :
63  m_Pointer(p)
64  {
65  if (m_Pointer)
66  this->Register();
67 
68 #if defined(BLUEBERRY_DEBUG_SMARTPOINTER)
69  DebugInitSmartPointer();
70 #endif
71  }
72 
75  m_Pointer(p.m_Pointer)
76  {
77  this->Register();
78 
79 #if defined(BLUEBERRY_DEBUG_SMARTPOINTER)
80  DebugInitSmartPointer();
81 #endif
82  }
83 
84  template<class Other>
86  m_Pointer(const_cast<Other*> (ptr.GetPointer()))
87  {
88  if (m_Pointer)
89  this->Register();
90 
91 #if defined(BLUEBERRY_DEBUG_SMARTPOINTER)
92  DebugInitSmartPointer();
93 #endif
94  }
95 
96  template<class Other>
97  explicit SmartPointer(const WeakPointer<Other>& wp);
98 
101  {
102 #if defined(BLUEBERRY_DEBUG_SMARTPOINTER)
103  if (m_Pointer) DebugRemoveSmartPointer();
104 #endif
105 
106  this->UnRegister();
107  m_Pointer = nullptr;
108  }
109 
110  template<class Other>
112  {
113  Other* pOther = dynamic_cast<Other*> (m_Pointer);
114  return SmartPointer<Other> (pOther);
115  }
116 
119  {
120  return m_Pointer;
121  }
122 
123 // /** Return pointer to object. */
124 // operator ObjectType *() const
125 // {
126 // return m_Pointer;
127 // }
128 
130  {
131  poco_assert( m_Pointer != nullptr );
132  return *m_Pointer;
133  }
134 
136  bool IsNotNull() const
137  {
138  return m_Pointer != nullptr;
139  }
140  bool IsNull() const
141  {
142  return m_Pointer == nullptr;
143  }
144 
146 
147  operator unspecified_bool_type () const
148  {
149  return m_Pointer == nullptr ? nullptr: &Self::m_Pointer;
150  }
151 
153  template<typename R>
154  bool operator ==(const R* o) const
155  {
156  return (m_Pointer == nullptr ? o == nullptr : (o && m_Pointer->operator==(o)));
157  }
158 
159  template<typename R>
160  bool operator ==(const SmartPointer<R>& r) const
161  {
162  const R* o = r.GetPointer();
163  return (m_Pointer == nullptr ? o == nullptr : (o && m_Pointer->operator==(o)));
164  }
165 
166  bool operator ==(int r) const
167  {
168  if (r == 0)
169  return m_Pointer == nullptr;
170 
171  throw std::invalid_argument("Can only compare to 0");
172  }
173 
174  template<typename R>
175  bool operator !=(const R* r) const
176  {
177  return !(this->operator==(r));
178  }
179 
180  template<typename R>
181  bool operator !=(const SmartPointer<R>& r) const
182  {
183  return !(this->operator==(r));
184  }
185 
186  bool operator !=(int r) const
187  {
188  if (r == 0)
189  return m_Pointer != nullptr;
190 
191  throw std::invalid_argument("Can only compare to 0");
192  }
193 
194 // /** Template comparison operators using operator==. */
195 // template<typename R>
196 // bool CompareTo(const SmartPointer<R>& r) const
197 // {
198 // return m_Pointer == 0 ? r == 0 : r.GetPointer() && m_Pointer->operator==(r.GetPointer());
199 // }
200 
201 // template<typename R>
202 // bool CompareTo(R r) const
203 // {
204 // //const ObjectType* o = static_cast<const ObjectType*> (r);
205 // return m_Pointer == 0 ? r == 0 : (r && m_Pointer->operator==(r));
206 // }
207 
210  {
211  return m_Pointer;
212  }
213 
215  template<typename R>
216  bool operator <(const SmartPointer<R>& r) const
217  {
218  const R* o = r.GetPointer();
219  return m_Pointer == nullptr ? o == nullptr : o && m_Pointer->operator<(o);
220  }
221 
223  template<typename R>
224  bool operator>(const SmartPointer<R>& r) const
225  {
226  const R* o = r.GetPointer();
227  return m_Pointer == 0 ? o == 0 : o && m_Pointer->operator>(o);
228  }
229 
231  template<typename R>
232  bool operator <=(const SmartPointer<R>& r) const
233  {
234  return this->operator<(r) || this->operator==(r);
235  }
236 
238  template<typename R>
239  bool operator >=(const SmartPointer<R>& r) const
240  {
241  return this->operator>(r) || this->operator==(r);
242  }
243 
246  {
247  return this->operator =(r.GetPointer());
248  }
249 
251  template<typename R>
253  {
254  return this->operator =(r.GetPointer());
255  }
256 
259  {
260  if (m_Pointer != r)
261  {
262 #if defined(BLUEBERRY_DEBUG_SMARTPOINTER)
263  DebugAssignSmartPointer(r, m_Pointer);
264 #endif
265  ObjectType* tmp = m_Pointer; //avoid recursive unregisters by retaining temporarily
266  m_Pointer = r;
267  this->Register();
268  if (tmp)
269  {
270  tmp->UnRegister();
271  }
272  }
273  return *this;
274  }
275 
277  QDebug Print(QDebug os) const;
278 
279 private:
280 
282  ObjectType* m_Pointer;
283 
284  void Register()
285  {
286  if (m_Pointer)
287  {
288  m_Pointer->Register();
289  }
290  }
291 
292  void UnRegister()
293  {
294  if (m_Pointer)
295  {
296  m_Pointer->UnRegister();
297  }
298  }
299 
300 #if defined(BLUEBERRY_DEBUG_SMARTPOINTER)
301 
302  unsigned int m_Id;
303  QMutex m_Mutex;
304 
305  void DebugInitSmartPointer();
306 
307  void DebugRemoveSmartPointer();
308 
309  void DebugAssignSmartPointer(const ObjectType* newObject, const ObjectType* oldObject);
310 
311 public:
312 
313  int GetId();
314 
315 private:
316 #endif
317 };
318 
319 template<typename T>
320 std::ostream& operator<<(std::ostream& os, const SmartPointer<T>& p)
321 {
322  os << p->ToString().toStdString();
323  return os;
324 }
325 
326 } // namespace berry
327 
328 template<class T>
330 {
331  return sp->HashCode();
332 }
333 
334 template<class T>
336 {
337  berry::SmartPointer<T> sp(wp.Lock());
338  if (sp.IsNull())
339  {
340  return 0;
341  }
342  return sp->HashCode();
343 }
344 
345 #include "berryException.h"
346 #include <QDebug>
347 
348 namespace berry {
349 
350 template<class T>
351 template<class Other>
353 {
354  if (wp.m_Pointer)
355  {
356  this->m_Pointer = wp.m_Pointer;
357  this->Register();
358 
359  #if defined(BLUEBERRY_DEBUG_SMARTPOINTER)
360  DebugInitSmartPointer();
361  #endif
362  }
363  else
364  {
365  throw BadWeakPointerException("Weak pointer is nullptr");
366  }
367 }
368 
370 template<class T>
371 QDebug SmartPointer<T>::Print(QDebug os) const
372 {
373  // This prints the object pointed to by the pointer
374  (*m_Pointer).Print(os);
375  return os;
376 }
377 
378 }
379 
380 #if defined(BLUEBERRY_DEBUG_SMARTPOINTER)
381 
382 #include "berryDebugUtil.h"
383 
384 namespace berry {
385 
386 template<class T>
387 void SmartPointer<T>::DebugInitSmartPointer()
388 {
389  {
390  QMutexLocker lock(&m_Mutex);
391  if (m_Pointer)
392  {
393  unsigned int& counter = DebugUtil::GetSmartPointerCounter();
394  m_Id = ++counter;
395  DebugUtil::RegisterSmartPointer(m_Id, m_Pointer);
396  }
397  else m_Id = 0;
398  }
399 
400  //if (DebugUtil::GetSmartPointerCounter() == Platform::GetConfiguration().getInt(Platform::DEBUG_ARG_SMARTPOINTER_ID))
401  //throw 1;
402 }
403 
404 template<class T>
405 void SmartPointer<T>::DebugRemoveSmartPointer()
406 {
407  QMutexLocker lock(&m_Mutex);
408  DebugUtil::UnregisterSmartPointer(m_Id, m_Pointer);
409 }
410 
411 template<class T>
412 void SmartPointer<T>::DebugAssignSmartPointer(const ObjectType* newObject, const ObjectType* oldObject)
413 {
414  QMutexLocker lock(&m_Mutex);
415  if (oldObject)
416  DebugUtil::UnregisterSmartPointer(m_Id, oldObject);
417 
418  if (newObject)
419  {
420  if (m_Id < 1)
421  {
422  unsigned int& counter = DebugUtil::GetSmartPointerCounter();
423  m_Id = ++counter;
424  }
425  DebugUtil::RegisterSmartPointer(m_Id, newObject);
426  }
427 }
428 
429 template<class T>
430 int SmartPointer<T>::GetId()
431 {
432  return m_Id;
433 }
434 
435 }
436 
437 #endif
438 
439 #endif /*BERRYSMARTPOINTER_H_*/
org_blueberry_core_runtime_Export.h
berry::SmartPointer::operator>=
bool operator>=(const SmartPointer< R > &r) const
Definition: berrySmartPointer.h:239
berryException.h
berry::SmartPointer::~SmartPointer
~SmartPointer()
Definition: berrySmartPointer.h:100
berry::SmartPointer::operator->
ObjectType * operator->() const
Definition: berrySmartPointer.h:118
berry::SmartPointer::SmartPointer
SmartPointer(const SmartPointer< ObjectType > &p)
Definition: berrySmartPointer.h:74
berry::SmartPointer::SmartPointer
SmartPointer(ObjectType *p)
Definition: berrySmartPointer.h:62
berry::SmartPointer::operator=
SmartPointer & operator=(const SmartPointer &r)
Definition: berrySmartPointer.h:245
berry::DebugUtil::RegisterSmartPointer
static void RegisterSmartPointer(unsigned int smartPointerId, const Object *objectPointer, bool recordStack=false)
berry::SmartPointer
Implements transparent reference counting.
Definition: berryICommandCategoryListener.h:21
berry::SmartPointer::IsNotNull
bool IsNotNull() const
Definition: berrySmartPointer.h:136
berry::WeakPointer::Lock
SmartPointer< ObjectType > Lock() const
Definition: berryWeakPointer.h:146
berry::SmartPointer::Print
QDebug Print(QDebug os) const
Definition: berrySmartPointer.h:371
berry::SmartPointer::GetPointer
ObjectType * GetPointer() const
Definition: berrySmartPointer.h:209
berry::SmartPointer::operator<
bool operator<(const SmartPointer< R > &r) const
Definition: berrySmartPointer.h:216
berry::SmartPointer::operator==
bool operator==(const R *o) const
Definition: berrySmartPointer.h:154
berry::SmartPointer::operator>
bool operator>(const SmartPointer< R > &r) const
Definition: berrySmartPointer.h:224
berry::DebugUtil::GetSmartPointerCounter
static unsigned int & GetSmartPointerCounter()
berry::DebugUtil::UnregisterSmartPointer
static void UnregisterSmartPointer(unsigned int smartPointerId, const Object *objectPointer)
berryConfig.h
berry::SmartPointer::operator<=
bool operator<=(const SmartPointer< R > &r) const
Definition: berrySmartPointer.h:232
berry::SmartPointer::operator*
ObjectType & operator*() const
Definition: berrySmartPointer.h:129
berry::SmartPointer::SmartPointer
SmartPointer()
Definition: berrySmartPointer.h:52
qHash
uint qHash(const berry::SmartPointer< T > &sp)
Definition: berrySmartPointer.h:329
berry::SmartPointer::operator!=
bool operator!=(const R *r) const
Definition: berrySmartPointer.h:175
berry::operator<<
org_blueberry_core_runtime_EXPORT QDebug operator<<(QDebug os, const berry::Indent &o)
berry::SmartPointer::ObjectType
TObjectType ObjectType
Definition: berrySmartPointer.h:48
berry::SmartPointer::Self
SmartPointer Self
Definition: berrySmartPointer.h:49
berry::SmartPointer::IsNull
bool IsNull() const
Definition: berrySmartPointer.h:140
berry::SmartPointer::SmartPointer
SmartPointer(const SmartPointer< Other > &ptr)
Definition: berrySmartPointer.h:85
berry::SmartPointer::Cast
SmartPointer< Other > Cast() const
Definition: berrySmartPointer.h:111
berry::WeakPointer
implements a WeakPointer class to deal with circular reference problems.
Definition: berrySmartPointer.h:32
berry::SmartPointer::unspecified_bool_type
ObjectType *Self::* unspecified_bool_type
Definition: berrySmartPointer.h:145
berry
Definition: QmitkPropertyItemModel.h:24
berryDebugUtil.h