libvisual  0.5.0
lv_intrusive_ptr.hpp
1 #ifndef _LV_INTRUSIVE_HPP
2 #define _LV_INTRUSIVE_HPP
3 
4 namespace LV
5 {
6 
18  template <typename T>
20  {
21  public:
22 
23  typedef T element_type;
24 
25  IntrusivePtr ()
26  : m_ptr (nullptr)
27  {}
28 
29  IntrusivePtr (T* ptr, bool add_ref = true)
30  : m_ptr (ptr)
31  {
32  if (ptr && add_ref)
33  intrusive_ptr_add_ref (m_ptr);
34  }
35 
36  template <typename U>
37  IntrusivePtr (IntrusivePtr<U> const& rhs)
38  : m_ptr (rhs.get ())
39  {
40  if (m_ptr)
41  intrusive_ptr_add_ref (m_ptr);
42  }
43 
46  : m_ptr (rhs.m_ptr)
47  {
48  if (m_ptr)
49  intrusive_ptr_add_ref (m_ptr);
50  }
51 
54  : m_ptr (rhs.m_ptr)
55  {
56  rhs.m_ptr = nullptr;
57  }
58 
61  {
62  if (m_ptr)
63  intrusive_ptr_release (m_ptr);
64  }
65 
67  template <class U>
69  {
70  IntrusivePtr (rhs).swap (*this);
71  return *this;
72  }
73 
76  {
77  IntrusivePtr (rhs).swap (*this);
78  return *this;
79  }
80 
83  {
84  IntrusivePtr (rhs).swap (*this);
85  return *this;
86  }
87 
90  {
91  IntrusivePtr (rhs).swap (*this);
92  return *this;
93  }
94 
96  void reset ()
97  {
98  IntrusivePtr ().swap (*this);
99  }
100 
101  void reset (T* rhs)
102  {
103  IntrusivePtr (rhs).swap (*this);
104  }
105 
107  T* get () const
108  {
109  return m_ptr;
110  }
111 
113  T& operator* () const
114  {
115  return *m_ptr;
116  }
117 
119  T* operator-> () const
120  {
121  return m_ptr;
122  }
123 
125  explicit operator bool () const
126  {
127  return m_ptr != nullptr;
128  }
129 
131  void swap (IntrusivePtr& rhs)
132  {
133  T* tmp = m_ptr;
134  m_ptr = rhs.m_ptr;
135  rhs.m_ptr = tmp;
136  }
137 
138  private:
139 
140  T* m_ptr;
141  };
142 
143 } // LV namespace
144 
145 namespace std {
146 
147  // std::swap() overload for efficiently swapping IntrusivePtrs
148  template <class T>
149  void swap (LV::IntrusivePtr<T>& lhs, LV::IntrusivePtr<T>& rhs)
150  {
151  lhs.swap (rhs);
152  }
153 
154 } // std namespace
155 
156 #endif // _LV_INTRUSIVE_HPP