blocxx
IntrusiveReference.hpp
Go to the documentation of this file.
1 /*******************************************************************************
2 * Copyright (C) 2005, Vintela, Inc. All rights reserved.
3 * Copyright (C) 2006, Novell, Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of
14 * Vintela, Inc.,
15 * nor Novell, Inc.,
16 * nor the names of its contributors or employees may be used to
17 * endorse or promote products derived from this software without
18 * specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 *******************************************************************************/
32 
33 
34 //
35 // Copyright (c) 2001, 2002 Peter Dimov
36 //
37 // Permission to copy, use, modify, sell and distribute this software
38 // is granted provided this copyright notice appears in all copies.
39 // This software is provided "as is" without express or implied
40 // warranty, and with no claim as to its suitability for any purpose.
41 //
42 
49 #ifndef BLOCXX_INTRUSIVE_REFERENCE_HPP_INCLUDE_GUARD_
50 #define BLOCXX_INTRUSIVE_REFERENCE_HPP_INCLUDE_GUARD_
51 
52 #include "blocxx/BLOCXX_config.h"
54 #include "blocxx/SafeBool.hpp"
55 
56 namespace BLOCXX_NAMESPACE
57 {
58 
59 //
60 // IntrusiveReference
61 //
62 // A smart pointer that uses intrusive reference counting.
63 //
64 // Relies on unqualified calls to
65 //
66 // void IntrusiveReferenceAddRef(T * p);
67 // void IntrusiveReferenceRelease(T * p);
68 //
69 // (p != 0)
70 //
71 // The object is responsible for destroying itself.
72 //
73 
74 
75 template<class T> class IntrusiveReference
76 {
77 private:
79 public:
80  typedef T element_type;
81 
83  {
84  }
85  IntrusiveReference(T * p, bool add_ref = true): m_pObj(p)
86  {
87  if (m_pObj != 0 && add_ref) IntrusiveReferenceAddRef(m_pObj);
88  }
89  template<class U> IntrusiveReference(IntrusiveReference<U> const & rhs): m_pObj(rhs.getPtr())
90  {
92  }
94  {
96  }
98  {
100  }
101  template<class U> IntrusiveReference & operator=(IntrusiveReference<U> const & rhs)
102  {
103  this_type(rhs).swap(*this);
104  return *this;
105  }
107  {
108  this_type(rhs).swap(*this);
109  return *this;
110  }
112  {
113  this_type(rhs).swap(*this);
114  return *this;
115  }
116  T * getPtr() const
117  {
118  return m_pObj;
119  }
120  T & operator*() const
121  {
122 #ifdef BLOCXX_CHECK_NULL_REFERENCES
123  ReferenceHelpers::checkNull(this);
124  ReferenceHelpers::checkNull(m_pObj);
125 #endif
126  return *m_pObj;
127  }
128  T * operator->() const
129  {
130 #ifdef BLOCXX_CHECK_NULL_REFERENCES
131  ReferenceHelpers::checkNull(this);
132  ReferenceHelpers::checkNull(m_pObj);
133 #endif
134  return m_pObj;
135  }
136 
138 
139  BLOCXX_DEPRECATED bool isNull() const // in 3.1.0
140  {
141  return m_pObj == 0;
142  }
143 
145  {
146  T * tmp = m_pObj;
147  m_pObj = rhs.m_pObj;
148  rhs.m_pObj = tmp;
149  }
150 
151  template <class U>
153  {
154  return IntrusiveReference<U>(dynamic_cast<U*>(m_pObj));
155  }
156 
157 private:
158  T * m_pObj;
159 };
160 template<class T, class U> inline bool operator==(IntrusiveReference<T> const & a, IntrusiveReference<U> const & b)
161 {
162  return a.getPtr() == b.getPtr();
163 }
164 template<class T, class U> inline bool operator!=(IntrusiveReference<T> const & a, IntrusiveReference<U> const & b)
165 {
166  return a.getPtr() != b.getPtr();
167 }
168 template<class T> inline bool operator==(IntrusiveReference<T> const & a, T * b)
169 {
170  return a.getPtr() == b;
171 }
172 template<class T> inline bool operator!=(IntrusiveReference<T> const & a, T * b)
173 {
174  return a.getPtr() != b;
175 }
176 template<class T> inline bool operator==(T * a, IntrusiveReference<T> const & b)
177 {
178  return a == b.getPtr();
179 }
180 template<class T> inline bool operator!=(T * a, IntrusiveReference<T> const & b)
181 {
182  return a != b.getPtr();
183 }
184 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
185 // Resolve the ambiguity between our op!= and the one in rel_ops
186 template<class T> inline bool operator!=(IntrusiveReference<T> const & a, IntrusiveReference<T> const & b)
187 {
188  return a.getPtr() != b.getPtr();
189 }
190 #endif
191 template<class T> inline bool operator<(IntrusiveReference<T> const & a, IntrusiveReference<T> const & b)
192 {
193  return a.getPtr() < b.getPtr();
194 }
195 template<class T> void swap(IntrusiveReference<T> & lhs, IntrusiveReference<T> & rhs)
196 {
197  lhs.swap(rhs);
198 }
200 {
201  return static_cast<T *>(p.getPtr());
202 }
204 {
205  return const_cast<T *>(p.getPtr());
206 }
208 {
209  return dynamic_cast<T *>(p.getPtr());
210 }
211 
212 } // end namespace BLOCXX_NAMESPACE
213 
214 #endif