Cafu Engine
Pointer.hpp
1 /*
2 Cafu Engine, http://www.cafu.de/
3 Copyright (c) Carsten Fuchs and other contributors.
4 This project is licensed under the terms of the MIT license.
5 */
6 
7 #ifndef CAFU_SMART_POINTER_HPP_INCLUDED
8 #define CAFU_SMART_POINTER_HPP_INCLUDED
9 
10 
11 /// A base class for objects that are reference-counted with IntrusivePtrTs.
12 /// See http://www.drdobbs.com/article/print?articleId=229218807 for details.
14 {
15  public:
16 
17  unsigned int GetRefCount() const { return m_RefCount; }
18 
19 
20  protected:
21 
22  RefCountedT() : m_RefCount(0) { }
23  RefCountedT(const RefCountedT&) : m_RefCount(0) { }
24  RefCountedT& operator = (const RefCountedT&) { return *this; }
25 
26 
27  private:
28 
29  template<class T> friend class IntrusivePtrT;
30 
31  /// m_RefCount is mutable, so that an IntrusivePtrT<const T> can still modify it.
32  mutable unsigned int m_RefCount;
33 };
34 
35 
36 /// This class implements smart (reference-counted) pointers.
37 ///
38 /// The implementation is intrusive: It requires from the class \c T that it is used with
39 /// that it keeps a member \c m_RefCount that it can access either publicly or as a friend.
40 ///
41 /// This class might be replaced by <code>boost::intrusive_ptr<></code> at a later time.
42 template<class T>
44 {
45  public:
46 
47  /// The constructor.
48  IntrusivePtrT(T* Ptr = 0)
49  : m_Ptr(Ptr)
50  {
51  if (m_Ptr) m_Ptr->m_RefCount++;
52  }
53 
54  /// The copy constructor.
56  : m_Ptr(IP.m_Ptr)
57  {
58  if (m_Ptr) m_Ptr->m_RefCount++;
59  }
60 
61  /// The copy constructor (for Y classes that are derived from T).
62  template<class Y> IntrusivePtrT(const IntrusivePtrT<Y>& IP)
63  : m_Ptr(IP.get())
64  {
65  if (m_Ptr) m_Ptr->m_RefCount++;
66  }
67 
68  /// The destructor.
70  {
71  if (m_Ptr)
72  {
73  m_Ptr->m_RefCount--;
74  if (m_Ptr->m_RefCount == 0) delete m_Ptr;
75  }
76  }
77 
78  /// The assignment operator.
80  {
81  // Do not change the order of these statements!
82  // This order properly handles self-assignment as well as recursion,
83  // e.g. when an T contains IntrusivePtrT's.
84  T* const Old=m_Ptr;
85 
86  m_Ptr = IP.m_Ptr;
87  if (m_Ptr) m_Ptr->m_RefCount++;
88 
89  if (Old)
90  {
91  Old->m_RefCount--;
92  if (Old->m_RefCount == 0) delete Old;
93  }
94 
95  return *this;
96  }
97 
98  /// Returns the stored pointer.
99  T* get() const { return m_Ptr; }
100 
101  /// The structure dereference operator.
102  T* operator -> () const { return m_Ptr; }
103 
104  /// The dereference operator.
105  T& operator * () { return *m_Ptr; }
106 
107  /// The dereference operator (const).
108  const T& operator * () const { return *m_Ptr; }
109 
110  /// The equality operator.
111  bool operator == (const IntrusivePtrT& IP) const { return m_Ptr == IP.m_Ptr; }
112  template<class U> bool operator == (U* b) const { return m_Ptr == b; }
113 
114  /// The inequality operator.
115  bool operator != (const IntrusivePtrT& IP) const { return m_Ptr != IP.m_Ptr; }
116  template<class U> bool operator != (U* b) const { return m_Ptr != b; }
117 
118  /// A safe alternative for the bool conversion operator.
119  /// For details, see:
120  /// - http://stackoverflow.com/questions/7226801/how-does-shared-ptr-work-in-if-condition
121  /// - http://stackoverflow.com/questions/6967448/does-msvc10-visual-studio-2010-support-c-explicit-conversion-operators
122  bool IsNull() const { return m_Ptr == 0; }
123 
124 
125  private:
126 
127  T* m_Ptr; ///< The pointer to the reference-counted object.
128 };
129 
130 
131 template<class T, class U> IntrusivePtrT<T> static_pointer_cast(IntrusivePtrT<U> const& IP)
132 {
133  return static_cast<T*>(IP.get());
134 }
135 
136 
137 template<class T, class U> IntrusivePtrT<T> dynamic_pointer_cast(IntrusivePtrT<U> const& IP)
138 {
139  return dynamic_cast<T*>(IP.get());
140 }
141 
142 #endif
T * operator->() const
The structure dereference operator.
Definition: Pointer.hpp:102
This class implements smart (reference-counted) pointers.
Definition: Pointer.hpp:43
IntrusivePtrT(const IntrusivePtrT< Y > &IP)
The copy constructor (for Y classes that are derived from T).
Definition: Pointer.hpp:62
bool operator==(const IntrusivePtrT &IP) const
The equality operator.
Definition: Pointer.hpp:111
IntrusivePtrT(T *Ptr=0)
The constructor.
Definition: Pointer.hpp:48
~IntrusivePtrT()
The destructor.
Definition: Pointer.hpp:69
T & operator*()
The dereference operator.
Definition: Pointer.hpp:105
bool IsNull() const
A safe alternative for the bool conversion operator.
Definition: Pointer.hpp:122
IntrusivePtrT(const IntrusivePtrT &IP)
The copy constructor.
Definition: Pointer.hpp:55
bool operator!=(const IntrusivePtrT &IP) const
The inequality operator.
Definition: Pointer.hpp:115
T * get() const
Returns the stored pointer.
Definition: Pointer.hpp:99
IntrusivePtrT & operator=(const IntrusivePtrT &IP)
The assignment operator.
Definition: Pointer.hpp:79
A base class for objects that are reference-counted with IntrusivePtrTs.
Definition: Pointer.hpp:13