Lunchbox  1.9.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
refPtr.h
1 
2 /* Copyright (c) 2005-2014, Stefan Eilemann <eile@equalizergraphics.com>
3  * 2012-2013, 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  RefPtr( T* const ptr ) : _ptr( ptr ) { _ref(); }
49 
51  RefPtr( const RefPtr& from ) : _ptr( from._ptr ) { _ref(); }
52 
57  template< class O > RefPtr( RefPtr< O > from )
58  : _ptr( from.get( )) { _ref(); }
59 
61  ~RefPtr() { _unref(); _ptr = 0; }
62 
64  RefPtr& operator = ( const RefPtr& rhs )
65  {
66  if( _ptr == rhs._ptr )
67  return *this;
68 
69  T* tmp = _ptr;
70  _ptr = rhs._ptr;
71  _ref();
72  if( tmp ) tmp->unref( this );
73  return *this;
74  }
75 
77  RefPtr& operator = ( T* ptr )
78  {
79  if( _ptr == ptr )
80  return *this;
81 
82  T* tmp = _ptr;
83  _ptr = ptr;
84  _ref();
85  if( tmp ) tmp->unref( this );
86  return *this;
87  }
88 
93  bool operator == ( const RefPtr& rhs ) const
94  { return ( _ptr == rhs._ptr ); }
95 
100  bool operator != ( const RefPtr& rhs ) const
101  { return ( _ptr != rhs._ptr ); }
102 
107  operator bool_t() const { return _ptr == 0 ? 0 : &RefPtr::_ptr; }
108 
110  bool operator ! () const { return ( _ptr==0 ); }
111 
116  bool operator < ( const RefPtr& rhs ) const { return ( _ptr < rhs._ptr ); }
117 
122  bool operator > ( const RefPtr& rhs ) const { return ( _ptr > rhs._ptr ); }
123 
128  bool operator == ( const T* ptr ) const { return ( _ptr == ptr ); }
129 
134  bool operator != ( const T* ptr ) const { return ( _ptr != ptr ); }
135 
138  { LBASSERTINFO( _ptr, className( this )); return _ptr; }
140  const T* operator->() const
141  { LBASSERTINFO( _ptr, className( this )); return _ptr; }
144  { LBASSERTINFO( _ptr, className( this )); return *_ptr; }
146  const T& operator*() const
147  { LBASSERTINFO( _ptr, className( this )); return *_ptr; }
148 
150  T* get() { return _ptr; }
152  const T* get() const { return _ptr; }
153 
155  bool isValid() const { return ( _ptr != 0 ); }
156 
157 private:
158  T* _ptr;
159 
161  void _ref() { if(_ptr) _ptr->ref( this ); }
162 
164  void _unref()
165  {
166  if(_ptr)
167  {
168 #ifdef NDEBUG
169  _ptr->unref( this );
170 #else
171  if( _ptr->unref( this ))
172  _ptr = 0;
173 #endif
174  }
175  }
176 };// LB_DEPRECATED;
177 
179 template< class T >
180 inline std::ostream& operator << ( std::ostream& os, RefPtr< T > rp )
181 {
182  const T* p = rp.get();
183  if( !p )
184  return os << "RP[ 0:NULL ]";
185 
186  os << disableFlush << "RP[" << p->getRefCount() << ":" << *p << "]";
187  p->printHolders( os );
188  return os << enableFlush;
189 }
190 
191 template< class T > inline std::string className( const RefPtr<T>& rp )
192 { return className( rp.get( )); }
193 }
194 
195 #include <boost/serialization/split_free.hpp>
196 
197 namespace boost
198 {
199 namespace serialization
200 {
201 
202 template< class Archive, class T >
203 inline void save( Archive& ar, const lunchbox::RefPtr< T >& t,
204  const unsigned int /*version*/ )
205 {
206  const T* ptr = t.get();
207  ar << ptr;
208 }
209 
210 template< class Archive, class T >
211 inline void load( Archive& ar, lunchbox::RefPtr< T >& t,
212  const unsigned int /*version*/ )
213 {
214  T* obj = 0;
215  ar >> obj;
216  t = obj;
217 }
218 
219 template< class Archive, class T >
220 inline void serialize( Archive& ar, lunchbox::RefPtr< T >& t,
221  const unsigned int version )
222 {
223  boost::serialization::split_free( ar, t, version );
224 }
225 
226 }
227 }
228 
229 #endif //LUNCHBOX_REFPTR_H
const T * operator->() const
Access the held object.
Definition: refPtr.h:140
RefPtr & operator=(const RefPtr &rhs)
Assign another RefPtr to this reference pointer.
Definition: refPtr.h:64
std::string className(const T *object)
Print the RTTI name of the given class.
Definition: debug.h:74
RefPtr()
Construct a new, empty reference pointer.
Definition: refPtr.h:45
LUNCHBOX_API std::ostream & enableFlush(std::ostream &os)
Re-enable flushing of the Log stream.
bool operator==(const RefPtr &rhs) const
Definition: refPtr.h:93
bool operator>(const RefPtr &rhs) const
Definition: refPtr.h:122
bool isValid() const
Definition: refPtr.h:155
T & operator*()
Access the held object.
Definition: refPtr.h:143
RefPtr(const RefPtr &from)
Construct a copy of a reference pointer.
Definition: refPtr.h:51
T * operator->()
Access the held object.
Definition: refPtr.h:137
~RefPtr()
Destruct this reference pointer.
Definition: refPtr.h:61
bool operator<(const RefPtr &rhs) const
Definition: refPtr.h:116
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:57
LUNCHBOX_API std::ostream & disableFlush(std::ostream &os)
Disable flushing of the Log stream.
const T & operator*() const
Access the held object.
Definition: refPtr.h:146
bool operator!=(const RefPtr &rhs) const
Definition: refPtr.h:100
RefPtr(T *const ptr)
Construct a reference pointer from a C pointer.
Definition: refPtr.h:48
bool operator!() const
Definition: refPtr.h:110