Warning: That file was not part of the compilation database. It may have many parsing errors.
1 | /* |
---|---|
2 | * This file is part of the KDE libraries. |
3 | * |
4 | * Copyright 2005 Frerich Raabe <raabe@kde.org> |
5 | * |
6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions |
8 | * are met: |
9 | * |
10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. |
15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
21 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ |
27 | #ifndef KSHAREDPTR_H |
28 | #define KSHAREDPTR_H |
29 | |
30 | #include <QtCore/QExplicitlySharedDataPointer> |
31 | #include <QtCore/QAtomicPointer> |
32 | #include <kdemacros.h> |
33 | |
34 | /** |
35 | * @deprecated |
36 | * Use QSharedData instead. |
37 | */ |
38 | typedef QSharedData KShared; |
39 | |
40 | /** |
41 | * \class KSharedPtr ksharedptr.h <KSharedPtr> |
42 | * |
43 | * Can be used to control the lifetime of an object that has derived |
44 | * QSharedData. As long a someone holds |
45 | * a KSharedPtr on some QSharedData object it won't become deleted but |
46 | * is deleted once its reference count is 0. |
47 | * This struct emulates C++ pointers virtually perfectly. |
48 | * So just use it like a simple C++ pointer. |
49 | * |
50 | * The difference with QSharedPointer is that QSharedPointer does the refcounting |
51 | * in the pointer, while KSharedPtr does the refcounting in the object. |
52 | * This allows to convert to a raw pointer temporarily and back to a KSharedPtr |
53 | * without deleting the object, if another reference exists. But it imposes a |
54 | * requirement on the object, which must inherit QSharedData. |
55 | * |
56 | * The difference with using QSharedDataPointer is that QSharedDataPointer is |
57 | * a building block for implementing a value class with implicit sharing (like QString), |
58 | * whereas KSharedPtr provides refcounting to code that uses pointers. |
59 | * |
60 | * @author Waldo Bastian <bastian@kde.org> |
61 | */ |
62 | template< class T > |
63 | class KSharedPtr |
64 | { |
65 | public: |
66 | /** |
67 | * Creates a null pointer. |
68 | */ |
69 | inline KSharedPtr() |
70 | : d(0) { } |
71 | |
72 | /** |
73 | * Creates a new pointer. |
74 | * @param p the pointer |
75 | */ |
76 | inline explicit KSharedPtr( T* p ) |
77 | : d(p) { if(d) d->ref.ref(); } |
78 | |
79 | /** |
80 | * Copies a pointer. |
81 | * @param o the pointer to copy |
82 | */ |
83 | inline KSharedPtr( const KSharedPtr& o ) |
84 | : d(o.d) { if(d) d->ref.ref(); } |
85 | |
86 | /** |
87 | * Unreferences the object that this pointer points to. If it was |
88 | * the last reference, the object will be deleted. |
89 | */ |
90 | inline ~KSharedPtr() { if (d && !d->ref.deref()) delete d; } |
91 | |
92 | inline KSharedPtr<T>& operator= ( const KSharedPtr& o ) { attach(o.d); return *this; } |
93 | inline bool operator== ( const KSharedPtr& o ) const { return ( d == o.d ); } |
94 | inline bool operator!= ( const KSharedPtr& o ) const { return ( d != o.d ); } |
95 | inline bool operator< ( const KSharedPtr& o ) const { return ( d < o.d ); } |
96 | |
97 | inline KSharedPtr<T>& operator= ( T* p ) { attach(p); return *this; } |
98 | inline bool operator== ( const T* p ) const { return ( d == p ); } |
99 | inline bool operator!= ( const T* p ) const { return ( d != p ); } |
100 | |
101 | /** |
102 | * Test if the shared pointer is NOT null. |
103 | * @return true if the shared pointer is NOT null, false otherwise. |
104 | * @see isNull |
105 | */ |
106 | inline operator bool() const { return ( d != 0 ); } |
107 | |
108 | /** |
109 | * @return the pointer |
110 | */ |
111 | inline T* data() { return d; } |
112 | |
113 | /** |
114 | * @return the pointer |
115 | */ |
116 | inline const T* data() const { return d; } |
117 | |
118 | /** |
119 | * @return a const pointer to the shared object. |
120 | */ |
121 | inline const T* constData() const { return d; } |
122 | |
123 | inline const T& operator*() const { Q_ASSERT(d); return *d; } |
124 | inline T& operator*() { Q_ASSERT(d); return *d; } |
125 | inline const T* operator->() const { Q_ASSERT(d); return d; } |
126 | inline T* operator->() { Q_ASSERT(d); return d; } |
127 | |
128 | /** |
129 | * Attach the given pointer to the current KSharedPtr. |
130 | * If the previous shared pointer is not owned by any KSharedPtr, |
131 | * it is deleted. |
132 | */ |
133 | void attach(T* p); |
134 | |
135 | /** |
136 | * Clear the pointer, i.e. make it a null pointer. |
137 | */ |
138 | void clear(); |
139 | |
140 | /** |
141 | * Returns the number of references. |
142 | * @return the number of references |
143 | */ |
144 | inline int count() const { return d ? static_cast<int>(d->ref) : 0; } // for debugging purposes |
145 | |
146 | /** |
147 | * Test if the shared pointer is null. |
148 | * @return true if the pointer is null, false otherwise. |
149 | * @see opertor (bool) |
150 | */ |
151 | inline bool isNull() const { return (d == 0); } |
152 | |
153 | /** |
154 | * @return Whether this is the only shared pointer pointing to |
155 | * to the pointee, or whether it's shared among multiple |
156 | * shared pointers. |
157 | */ |
158 | inline bool isUnique() const { return count() == 1; } |
159 | |
160 | template <class U> friend class KSharedPtr; |
161 | |
162 | /** |
163 | * Convert KSharedPtr<U> to KSharedPtr<T>, using a static_cast. |
164 | * This will compile whenever T* and U* are compatible, i.e. |
165 | * T is a subclass of U or vice-versa. |
166 | * Example syntax: |
167 | * <code> |
168 | * KSharedPtr<T> tPtr; |
169 | * KSharedPtr<U> uPtr = KSharedPtr<U>::staticCast( tPtr ); |
170 | * </code> |
171 | */ |
172 | template <class U> |
173 | static KSharedPtr<T> staticCast( const KSharedPtr<U>& o ) { |
174 | return KSharedPtr<T>( static_cast<T *>( o.d ) ); |
175 | } |
176 | /** |
177 | * Convert KSharedPtr<U> to KSharedPtr<T>, using a dynamic_cast. |
178 | * This will compile whenever T* and U* are compatible, i.e. |
179 | * T is a subclass of U or vice-versa. |
180 | * Example syntax: |
181 | * <code> |
182 | * KSharedPtr<T> tPtr; |
183 | * KSharedPtr<U> uPtr = KSharedPtr<U>::dynamicCast( tPtr ); |
184 | * </code> |
185 | * Since a dynamic_cast is used, if U derives from T, and tPtr isn't an instance of U, uPtr will be 0. |
186 | */ |
187 | template <class U> |
188 | static KSharedPtr<T> dynamicCast( const KSharedPtr<U>& o ) { |
189 | return KSharedPtr<T>( dynamic_cast<T *>( o.d ) ); |
190 | } |
191 | |
192 | protected: |
193 | T* d; |
194 | }; |
195 | |
196 | template <class T> |
197 | Q_INLINE_TEMPLATE bool operator== (const T* p, const KSharedPtr<T>& o) |
198 | { |
199 | return ( o == p ); |
200 | } |
201 | |
202 | template <class T> |
203 | Q_INLINE_TEMPLATE bool operator!= (const T* p, const KSharedPtr<T>& o) |
204 | { |
205 | return ( o != p ); |
206 | } |
207 | |
208 | template <class T> |
209 | Q_INLINE_TEMPLATE void KSharedPtr<T>::attach(T* p) |
210 | { |
211 | if (d != p) { |
212 | if (p) p->ref.ref(); |
213 | if (d && !d->ref.deref()) |
214 | delete d; |
215 | d = p; |
216 | } |
217 | } |
218 | |
219 | template <class T> |
220 | Q_INLINE_TEMPLATE void KSharedPtr<T>::clear() |
221 | { |
222 | attach(static_cast<T*>(0)); |
223 | } |
224 | |
225 | #endif |
226 | |
227 |
Warning: That file was not part of the compilation database. It may have many parsing errors.