blocxx
COWIntrusiveReference.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
47
48#ifndef BLOCXX_COW_INTRUSIVE_REFERENCE_HPP_INCLUDE_GUARD_
49#define BLOCXX_COW_INTRUSIVE_REFERENCE_HPP_INCLUDE_GUARD_
50
51#include "blocxx/BLOCXX_config.h"
53
54namespace BLOCXX_NAMESPACE
55{
56
82
83template<class T> class COWIntrusiveReference
84{
85private:
87public:
88 typedef T element_type;
89
97
104 COWIntrusiveReference(T * p, bool addRef = true): m_pObj(p)
105 {
106 if (m_pObj != 0 && addRef) COWIntrusiveReferenceAddRef(m_pObj);
107 }
108
118 template<class U> COWIntrusiveReference(COWIntrusiveReference<U> const & rhs): m_pObj(rhs.m_pObj)
119 {
121 }
122
134
143
156 {
157 this_type(rhs).swap(*this);
158 return *this;
159 }
160
171 {
172 this_type(rhs).swap(*this);
173 return *this;
174 }
175
184 {
185 this_type(rhs).swap(*this);
186 return *this;
187 }
188
192 const T * getPtr() const
193 {
194 return m_pObj;
195 }
196
201 const T & operator*() const
202 {
203#ifdef BLOCXX_CHECK_NULL_REFERENCES
204 ReferenceHelpers::checkNull(this);
205 ReferenceHelpers::checkNull(m_pObj);
206#endif
207 return *m_pObj;
208 }
209
214 const T * operator->() const
215 {
216#ifdef BLOCXX_CHECK_NULL_REFERENCES
217 ReferenceHelpers::checkNull(this);
218 ReferenceHelpers::checkNull(m_pObj);
219#endif
220 return m_pObj;
221 }
222
228 {
229#ifdef BLOCXX_CHECK_NULL_REFERENCES
230 ReferenceHelpers::checkNull(this);
231 ReferenceHelpers::checkNull(m_pObj);
232#endif
233 getWriteLock();
234 return *m_pObj;
235 }
236
242 {
243#ifdef BLOCXX_CHECK_NULL_REFERENCES
244 ReferenceHelpers::checkNull(this);
245 ReferenceHelpers::checkNull(m_pObj);
246#endif
247 getWriteLock();
248 return m_pObj;
249 }
250
252 operator unspecified_bool_type () const
253 {
254 return m_pObj == 0? 0: &this_type::m_pObj;
255 }
256
262 bool operator! () const
263 {
264 return m_pObj == 0;
265 }
266
268 {
269 T * tmp = m_pObj;
270 m_pObj = rhs.m_pObj;
271 rhs.m_pObj = tmp;
272 }
273
274#if !defined(__GNUC__) || __GNUC__ > 2 // causes gcc 2.95 to ICE
275 /* This is so the templated constructor will work */
276 template <class U> friend class COWIntrusiveReference;
277private:
278#endif
279
286 {
288 {
290 }
291 }
292
293
295};
296template<class T, class U> inline bool operator==(COWIntrusiveReference<T> const & a, COWIntrusiveReference<U> const & b)
297{
298 return a.getPtr() == b.getPtr();
299}
300template<class T, class U> inline bool operator!=(COWIntrusiveReference<T> const & a, COWIntrusiveReference<U> const & b)
301{
302 return a.getPtr() != b.getPtr();
303}
304template<class T> inline bool operator==(COWIntrusiveReference<T> const & a, const T * b)
305{
306 return a.getPtr() == b;
307}
308template<class T> inline bool operator!=(COWIntrusiveReference<T> const & a, const T * b)
309{
310 return a.getPtr() != b;
311}
312template<class T> inline bool operator==(const T * a, COWIntrusiveReference<T> const & b)
313{
314 return a == b.getPtr();
315}
316template<class T> inline bool operator!=(const T * a, COWIntrusiveReference<T> const & b)
317{
318 return a != b.getPtr();
319}
320#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
321// Resolve the ambiguity between our op!= and the one in rel_ops
322template<class T> inline bool operator!=(COWIntrusiveReference<T> const & a, COWIntrusiveReference<T> const & b)
323{
324 return a.getPtr() != b.getPtr();
325}
326#endif
327template<class T> inline bool operator<(COWIntrusiveReference<T> const & a, COWIntrusiveReference<T> const & b)
328{
329 return a.getPtr() < b.getPtr();
330}
331template<class T> void swap(COWIntrusiveReference<T> & lhs, COWIntrusiveReference<T> & rhs)
332{
333 lhs.swap(rhs);
334}
335
336} // end namespace BLOCXX_NAMESPACE
337
338#endif
339
COWIntrusiveReference A smart pointer that uses intrusive reference counting.
COWIntrusiveReference & operator=(T *rhs)
Assignment operator.
COWIntrusiveReference & operator=(COWIntrusiveReference const &rhs)
Assignment operator.
~COWIntrusiveReference()
Destroy this COWIntrusiveReference.
COWIntrusiveReference(T *p, bool addRef=true)
Construct a COWIntrusiveReference that will contain a pointer to a COWIntrusiveCountableBase object.
COWIntrusiveReference(COWIntrusiveReference< U > const &rhs)
Copy constructor.
COWIntrusiveReference(COWIntrusiveReference const &rhs)
Copy constructor.
COWIntrusiveReference()
Default constructor The underlying object pointer will be NULL.
void getWriteLock()
Create a clone of the COWIntrusiveCountableBase object if there is more than one reference to it.
COWIntrusiveReference & operator=(COWIntrusiveReference< U > const &rhs)
Assignment operator that that takes a COWIntrusiveReference of a type derived from T.
Taken from RFC 1321.
void COWIntrusiveReferenceAddRef(COWIntrusiveCountableBase *p)
void COWIntrusiveReferenceRelease(COWIntrusiveCountableBase *p)
bool operator<(const Array< T > &x, const Array< T > &y)
bool operator==(const Array< T > &x, const Array< T > &y)
bool operator!=(const Array< T > &x, const Array< T > &y)
Determine two Arrays are not equal.
Definition Array.hpp:446
void swap(Array< T > &x, Array< T > &y)
bool COWIntrusiveReferenceUnique(COWIntrusiveCountableBase *p)