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
56namespace 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
75template<class T> class IntrusiveReference
76{
77private:
79public:
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 }
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
157private:
159};
160template<class T, class U> inline bool operator==(IntrusiveReference<T> const & a, IntrusiveReference<U> const & b)
161{
162 return a.getPtr() == b.getPtr();
163}
164template<class T, class U> inline bool operator!=(IntrusiveReference<T> const & a, IntrusiveReference<U> const & b)
165{
166 return a.getPtr() != b.getPtr();
167}
168template<class T> inline bool operator==(IntrusiveReference<T> const & a, T * b)
169{
170 return a.getPtr() == b;
171}
172template<class T> inline bool operator!=(IntrusiveReference<T> const & a, T * b)
173{
174 return a.getPtr() != b;
175}
176template<class T> inline bool operator==(T * a, IntrusiveReference<T> const & b)
177{
178 return a == b.getPtr();
179}
180template<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
186template<class T> inline bool operator!=(IntrusiveReference<T> const & a, IntrusiveReference<T> const & b)
187{
188 return a.getPtr() != b.getPtr();
189}
190#endif
191template<class T> inline bool operator<(IntrusiveReference<T> const & a, IntrusiveReference<T> const & b)
192{
193 return a.getPtr() < b.getPtr();
194}
195template<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
#define BLOCXX_SAFE_BOOL_IMPL(classname, type, variable, test)
Definition SafeBool.hpp:58
IntrusiveReference & operator=(IntrusiveReference const &rhs)
IntrusiveReference(IntrusiveReference const &rhs)
IntrusiveReference< U > cast_to() const
IntrusiveReference & operator=(T *rhs)
IntrusiveReference(T *p, bool add_ref=true)
IntrusiveReference(IntrusiveReference< U > const &rhs)
IntrusiveReference & operator=(IntrusiveReference< U > const &rhs)
BLOCXX_DEPRECATED bool isNull() const
Taken from RFC 1321.
void IntrusiveReferenceRelease(IntrusiveCountableBase *p)
IntrusiveReference< T > dynamic_pointer_cast(IntrusiveReference< U > const &p)
void IntrusiveReferenceAddRef(IntrusiveCountableBase *p)
IntrusiveReference< T > static_pointer_cast(IntrusiveReference< U > const &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)
IntrusiveReference< T > const_pointer_cast(IntrusiveReference< U > const &p)