Lunchbox  1.17.0
Multi-threaded C++ toolbox library for all application developers creating high-performance multi-threaded programs.
refPtr.h
1 
2 /* Copyright (c) 2005-2015, Stefan Eilemann <eile@equalizergraphics.com>
3  * Daniel Nachbaur <danielnachbaur@gmail.com>
4  *
5  * This library is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU Lesser General Public License version 2.1 as published
7  * by the Free Software Foundation.
8  *
9  * This library is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12  * details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #ifndef LUNCHBOX_REFPTR_H
20 #define LUNCHBOX_REFPTR_H
21 
22 #include <lunchbox/debug.h>
23 
24 #include <iostream>
25 #include <stdlib.h>
26 
27 namespace lunchbox
28 {
39 template <class T>
40 class RefPtr
41 {
42  typedef T* RefPtr::*bool_t;
43 
44 public:
47  : _ptr(0)
48  {
49  }
50 
52  // cppcheck-suppress noExplicitConstructor
53  RefPtr(T* const ptr)
54  : _ptr(ptr)
55  {
56  _ref();
57  }
58 
60  RefPtr(const RefPtr& from)
61  : _ptr(from._ptr)
62  {
63  _ref();
64  }
65 
70  // cppcheck-suppress noExplicitConstructor
71  template <class O>
73  : _ptr(from.get())
74  {
75  _ref();
76  }
77 
80  {
81  _unref();
82  _ptr = 0;
83  }
84 
86  RefPtr& operator=(const RefPtr& rhs)
87  {
88  if (_ptr == rhs._ptr)
89  return *this;
90 
91  T* tmp = _ptr;
92  _ptr = rhs._ptr;
93  _ref();
94  if (tmp)
95  tmp->unref(this);
96  return *this;
97  }
98 
100  RefPtr& operator=(T* ptr)
101  {
102  if (_ptr == ptr)
103  return *this;
104 
105  T* tmp = _ptr;
106  _ptr = ptr;
107  _ref();
108  if (tmp)
109  tmp->unref(this);
110  return *this;
111  }
112 
117  bool operator==(const RefPtr& rhs) const { return (_ptr == rhs._ptr); }
122  bool operator!=(const RefPtr& rhs) const { return (_ptr != rhs._ptr); }
127  operator bool_t() const { return _ptr == 0 ? 0 : &RefPtr::_ptr; }
129  bool operator!() const { return (_ptr == 0); }
134  bool operator<(const RefPtr& rhs) const { return (_ptr < rhs._ptr); }
139  bool operator>(const RefPtr& rhs) const { return (_ptr > rhs._ptr); }
144  bool operator==(const T* ptr) const { return (_ptr == ptr); }
149  bool operator!=(const T* ptr) const { return (_ptr != ptr); }
152  {
153  LBASSERTINFO(_ptr, className(this));
154  return _ptr;
155  }
157  const T* operator->() const
158  {
159  LBASSERTINFO(_ptr, className(this));
160  return _ptr;
161  }
164  {
165  LBASSERTINFO(_ptr, className(this));
166  return *_ptr;
167  }
169  const T& operator*() const
170  {
171  LBASSERTINFO(_ptr, className(this));
172  return *_ptr;
173  }
174 
176  T* get() { return _ptr; }
178  const T* get() const { return _ptr; }
180  bool isValid() const { return (_ptr != 0); }
181 private:
182  T* _ptr;
183 
185  void _ref()
186  {
187  if (_ptr)
188  _ptr->ref(this);
189  }
190 
192  void _unref()
193  {
194  if (_ptr)
195  {
196 #ifdef NDEBUG
197  _ptr->unref(this);
198 #else
199  if (_ptr->unref(this))
200  _ptr = 0;
201 #endif
202  }
203  }
204 };
205 
207 template <class T>
208 inline std::ostream& operator<<(std::ostream& os, RefPtr<T> rp)
209 {
210  const T* p = rp.get();
211  if (!p)
212  return os << "RP[ 0:NULL ]";
213 
214  os << disableFlush << "RP[" << p->getRefCount() << ":" << *p << "]";
215  p->printHolders(os);
216  return os << enableFlush;
217 }
218 
219 template <class T>
220 inline std::string className(const RefPtr<T>& rp)
221 {
222  return className(rp.get());
223 }
224 }
225 
226 #include <boost/serialization/split_free.hpp>
227 
228 namespace boost
229 {
230 namespace serialization
231 {
232 template <class Archive, class T>
233 inline void save(Archive& ar, const lunchbox::RefPtr<T>& t,
234  const unsigned int /*version*/)
235 {
236  const T* ptr = t.get();
237  ar << ptr;
238 }
239 
240 template <class Archive, class T>
241 inline void load(Archive& ar, lunchbox::RefPtr<T>& t,
242  const unsigned int /*version*/)
243 {
244  T* obj = 0;
245  ar >> obj;
246  t = obj;
247 }
248 
249 template <class Archive, class T>
250 inline void serialize(Archive& ar, lunchbox::RefPtr<T>& t,
251  const unsigned int version)
252 {
253  boost::serialization::split_free(ar, t, version);
254 }
255 }
256 }
257 
258 #endif // LUNCHBOX_REFPTR_H
std::ostream & enableFlush(std::ostream &os)
Re-enable flushing of the Log stream.
std::string className(const T &object)
Print the RTTI name of the given class.
Definition: debug.h:75
const T * operator->() const
Access the held object.
Definition: refPtr.h:157
RefPtr & operator=(const RefPtr &rhs)
Assign another RefPtr to this reference pointer.
Definition: refPtr.h:86
RefPtr()
Construct a new, empty reference pointer.
Definition: refPtr.h:46
bool operator==(const RefPtr &rhs) const
Definition: refPtr.h:117
bool operator>(const RefPtr &rhs) const
Definition: refPtr.h:139
bool isValid() const
Definition: refPtr.h:180
T & operator*()
Access the held object.
Definition: refPtr.h:163
bool operator==(const T *ptr) const
Definition: refPtr.h:144
RefPtr(const RefPtr &from)
Construct a copy of a reference pointer.
Definition: refPtr.h:60
T * operator->()
Access the held object.
Definition: refPtr.h:151
~RefPtr()
Destruct this reference pointer.
Definition: refPtr.h:79
Abstraction layer and common utilities for multi-threaded programming.
Definition: algorithm.h:29
bool operator<(const RefPtr &rhs) const
Definition: refPtr.h:134
A smart reference pointer, aka boost::intrusive_ptr.
Definition: refPtr.h:40
RefPtr(RefPtr< O > from)
Construct a copy of a reference pointer of a different type.
Definition: refPtr.h:72
bool operator!=(const T *ptr) const
Definition: refPtr.h:149
const T & operator*() const
Access the held object.
Definition: refPtr.h:169
bool operator!=(const RefPtr &rhs) const
Definition: refPtr.h:122
RefPtr & operator=(T *ptr)
Assign a C pointer to this reference pointer.
Definition: refPtr.h:100
RefPtr(T *const ptr)
Construct a reference pointer from a C pointer.
Definition: refPtr.h:53
bool operator!() const
Definition: refPtr.h:129
std::ostream & disableFlush(std::ostream &os)
Disable flushing of the Log stream.