KDECore
ksharedptr.h
Go to the documentation of this file.00001 /* 00002 * This file is part of the KDE libraries. 00003 * 00004 * Copyright 2005 Frerich Raabe <raabe@kde.org> 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 00010 * 1. Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * 2. Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * 00016 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00017 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00018 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00019 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 00020 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00021 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00022 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00023 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00024 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00025 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 */ 00027 #ifndef KSHAREDPTR_H 00028 #define KSHAREDPTR_H 00029 00030 #include <QtCore/QExplicitlySharedDataPointer> 00031 #include <QtCore/QAtomicPointer> 00032 #include <kdemacros.h> 00033 00038 typedef QSharedData KShared; 00039 00056 template< class T > 00057 class KSharedPtr 00058 { 00059 public: 00063 inline KSharedPtr() 00064 : d(0) { } 00065 00070 inline explicit KSharedPtr( T* p ) 00071 : d(p) { if(d) d->ref.ref(); } 00072 00077 inline KSharedPtr( const KSharedPtr& o ) 00078 : d(o.d) { if(d) d->ref.ref(); } 00079 00084 inline ~KSharedPtr() { if (d && !d->ref.deref()) delete d; } 00085 00086 inline KSharedPtr<T>& operator= ( const KSharedPtr& o ) { attach(o.d); return *this; } 00087 inline bool operator== ( const KSharedPtr& o ) const { return ( d == o.d ); } 00088 inline bool operator!= ( const KSharedPtr& o ) const { return ( d != o.d ); } 00089 inline bool operator< ( const KSharedPtr& o ) const { return ( d < o.d ); } 00090 00091 inline KSharedPtr<T>& operator= ( T* p ) { attach(p); return *this; } 00092 inline bool operator== ( const T* p ) const { return ( d == p ); } 00093 inline bool operator!= ( const T* p ) const { return ( d != p ); } 00094 00100 inline operator bool() const { return ( d != 0 ); } 00101 00105 inline T* data() { return d; } 00106 00110 inline const T* data() const { return d; } 00111 00115 inline const T* constData() const { return d; } 00116 00117 inline const T& operator*() const { Q_ASSERT(d); return *d; } 00118 inline T& operator*() { Q_ASSERT(d); return *d; } 00119 inline const T* operator->() const { Q_ASSERT(d); return d; } 00120 inline T* operator->() { Q_ASSERT(d); return d; } 00121 00127 void attach(T* p); 00128 00132 void clear(); 00133 00138 inline int count() const { return d ? static_cast<int>(d->ref) : 0; } // for debugging purposes 00139 00145 inline bool isNull() const { return (d == 0); } 00146 00152 inline bool isUnique() const { return count() == 1; } 00153 00154 template <class U> friend class KSharedPtr; 00155 00166 template <class U> 00167 static KSharedPtr<T> staticCast( const KSharedPtr<U>& o ) { 00168 return KSharedPtr<T>( static_cast<T *>( o.d ) ); 00169 } 00181 template <class U> 00182 static KSharedPtr<T> dynamicCast( const KSharedPtr<U>& o ) { 00183 return KSharedPtr<T>( dynamic_cast<T *>( o.d ) ); 00184 } 00185 00186 protected: 00187 T* d; 00188 }; 00189 00190 template <class T> 00191 Q_INLINE_TEMPLATE bool operator== (const T* p, const KSharedPtr<T>& o) 00192 { 00193 return ( o == p ); 00194 } 00195 00196 template <class T> 00197 Q_INLINE_TEMPLATE bool operator!= (const T* p, const KSharedPtr<T>& o) 00198 { 00199 return ( o != p ); 00200 } 00201 00202 template <class T> 00203 Q_INLINE_TEMPLATE void KSharedPtr<T>::attach(T* p) 00204 { 00205 if (d != p) { 00206 if (p) p->ref.ref(); 00207 if (d && !d->ref.deref()) 00208 delete d; 00209 d = p; 00210 } 00211 } 00212 00213 template <class T> 00214 Q_INLINE_TEMPLATE void KSharedPtr<T>::clear() 00215 { 00216 attach(static_cast<T*>(0)); 00217 } 00218 00219 #endif 00220