Lunchbox  1.15.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 > class RefPtr
40 {
41  typedef T* RefPtr::*bool_t;
42 
43 public:
45  RefPtr() : _ptr( 0 ) {}
46 
48  // cppcheck-suppress noExplicitConstructor
49  RefPtr( T* const ptr ) : _ptr( ptr ) { _ref(); }
50 
52  RefPtr( const RefPtr& from ) : _ptr( from._ptr ) { _ref(); }
53 
58  // cppcheck-suppress noExplicitConstructor
59  template< class O > RefPtr( RefPtr< O > from )
60  : _ptr( from.get( )) { _ref(); }
61 
63  ~RefPtr() { _unref(); _ptr = 0; }
64 
66  RefPtr& operator = ( const RefPtr& rhs )
67  {
68  if( _ptr == rhs._ptr )
69  return *this;
70 
71  T* tmp = _ptr;
72  _ptr = rhs._ptr;
73  _ref();
74  if( tmp ) tmp->unref( this );
75  return *this;
76  }
77 
79  RefPtr& operator = ( T* ptr )
80  {
81  if( _ptr == ptr )
82  return *this;
83 
84  T* tmp = _ptr;
85  _ptr = ptr;
86  _ref();
87  if( tmp ) tmp->unref( this );
88  return *this;
89  }
90 
95  bool operator == ( const RefPtr& rhs ) const
96  { return ( _ptr == rhs._ptr ); }
97 
102  bool operator != ( const RefPtr& rhs ) const
103  { return ( _ptr != rhs._ptr ); }
104 
109  operator bool_t() const { return _ptr == 0 ? 0 : &RefPtr::_ptr; }
110 
112  bool operator ! () const { return ( _ptr==0 ); }
113 
118  bool operator < ( const RefPtr& rhs ) const { return ( _ptr < rhs._ptr ); }
119 
124  bool operator > ( const RefPtr& rhs ) const { return ( _ptr > rhs._ptr ); }
125 
130  bool operator == ( const T* ptr ) const { return ( _ptr == ptr ); }
131 
136  bool operator != ( const T* ptr ) const { return ( _ptr != ptr ); }
137 
140  { LBASSERTINFO( _ptr, className( this )); return _ptr; }
142  const T* operator->() const
143  { LBASSERTINFO( _ptr, className( this )); return _ptr; }
146  { LBASSERTINFO( _ptr, className( this )); return *_ptr; }
148  const T& operator*() const
149  { LBASSERTINFO( _ptr, className( this )); return *_ptr; }
150 
152  T* get() { return _ptr; }
154  const T* get() const { return _ptr; }
155 
157  bool isValid() const { return ( _ptr != 0 ); }
158 
159 private:
160  T* _ptr;
161 
163  void _ref() { if(_ptr) _ptr->ref( this ); }
164 
166  void _unref()
167  {
168  if(_ptr)
169  {
170 #ifdef NDEBUG
171  _ptr->unref( this );
172 #else
173  if( _ptr->unref( this ))
174  _ptr = 0;
175 #endif
176  }
177  }
178 };
179 
181 template< class T >
182 inline std::ostream& operator << ( std::ostream& os, RefPtr< T > rp )
183 {
184  const T* p = rp.get();
185  if( !p )
186  return os << "RP[ 0:NULL ]";
187 
188  os << disableFlush << "RP[" << p->getRefCount() << ":" << *p << "]";
189  p->printHolders( os );
190  return os << enableFlush;
191 }
192 
193 template< class T > inline std::string className( const RefPtr<T>& rp )
194 { return className( rp.get( )); }
195 }
196 
197 #include <boost/serialization/split_free.hpp>
198 
199 namespace boost
200 {
201 namespace serialization
202 {
203 
204 template< class Archive, class T >
205 inline void save( Archive& ar, const lunchbox::RefPtr< T >& t,
206  const unsigned int /*version*/ )
207 {
208  const T* ptr = t.get();
209  ar << ptr;
210 }
211 
212 template< class Archive, class T >
213 inline void load( Archive& ar, lunchbox::RefPtr< T >& t,
214  const unsigned int /*version*/ )
215 {
216  T* obj = 0;
217  ar >> obj;
218  t = obj;
219 }
220 
221 template< class Archive, class T >
222 inline void serialize( Archive& ar, lunchbox::RefPtr< T >& t,
223  const unsigned int version )
224 {
225  boost::serialization::split_free( ar, t, version );
226 }
227 
228 }
229 }
230 
231 #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:74
const T * operator->() const
Access the held object.
Definition: refPtr.h:142
RefPtr & operator=(const RefPtr &rhs)
Assign another RefPtr to this reference pointer.
Definition: refPtr.h:66
RefPtr()
Construct a new, empty reference pointer.
Definition: refPtr.h:45
bool operator==(const RefPtr &rhs) const
Definition: refPtr.h:95
bool operator>(const RefPtr &rhs) const
Definition: refPtr.h:124
bool isValid() const
Definition: refPtr.h:157
T & operator*()
Access the held object.
Definition: refPtr.h:145
RefPtr(const RefPtr &from)
Construct a copy of a reference pointer.
Definition: refPtr.h:52
T * operator->()
Access the held object.
Definition: refPtr.h:139
~RefPtr()
Destruct this reference pointer.
Definition: refPtr.h:63
Abstraction layer and common utilities for multi-threaded programming.
Definition: algorithm.h:32
bool operator<(const RefPtr &rhs) const
Definition: refPtr.h:118
A smart reference pointer, aka boost::intrusive_ptr.
Definition: refPtr.h:39
RefPtr(RefPtr< O > from)
Construct a copy of a reference pointer of a different type.
Definition: refPtr.h:59
const T & operator*() const
Access the held object.
Definition: refPtr.h:148
bool operator!=(const RefPtr &rhs) const
Definition: refPtr.h:102
RefPtr(T *const ptr)
Construct a reference pointer from a C pointer.
Definition: refPtr.h:49
bool operator!() const
Definition: refPtr.h:112
std::ostream & disableFlush(std::ostream &os)
Disable flushing of the Log stream.