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 00062 template< class T > 00063 class KSharedPtr 00064 { 00065 public: 00069 inline KSharedPtr() 00070 : d(0) { } 00071 00076 inline explicit KSharedPtr( T* p ) 00077 : d(p) { if(d) d->ref.ref(); } 00078 00083 inline KSharedPtr( const KSharedPtr& o ) 00084 : d(o.d) { if(d) d->ref.ref(); } 00085 00090 inline ~KSharedPtr() { if (d && !d->ref.deref()) delete d; } 00091 00092 inline KSharedPtr<T>& operator= ( const KSharedPtr& o ) { attach(o.d); return *this; } 00093 inline bool operator== ( const KSharedPtr& o ) const { return ( d == o.d ); } 00094 inline bool operator!= ( const KSharedPtr& o ) const { return ( d != o.d ); } 00095 inline bool operator< ( const KSharedPtr& o ) const { return ( d < o.d ); } 00096 00097 inline KSharedPtr<T>& operator= ( T* p ) { attach(p); return *this; } 00098 inline bool operator== ( const T* p ) const { return ( d == p ); } 00099 inline bool operator!= ( const T* p ) const { return ( d != p ); } 00100 00106 inline operator bool() const { return ( d != 0 ); } 00107 00111 inline T* data() { return d; } 00112 00116 inline const T* data() const { return d; } 00117 00121 inline const T* constData() const { return d; } 00122 00123 inline const T& operator*() const { Q_ASSERT(d); return *d; } 00124 inline T& operator*() { Q_ASSERT(d); return *d; } 00125 inline const T* operator->() const { Q_ASSERT(d); return d; } 00126 inline T* operator->() { Q_ASSERT(d); return d; } 00127 00133 void attach(T* p); 00134 00138 void clear(); 00139 00144 inline int count() const { return d ? static_cast<int>(d->ref) : 0; } // for debugging purposes 00145 00151 inline bool isNull() const { return (d == 0); } 00152 00158 inline bool isUnique() const { return count() == 1; } 00159 00160 template <class U> friend class KSharedPtr; 00161 00172 template <class U> 00173 static KSharedPtr<T> staticCast( const KSharedPtr<U>& o ) { 00174 return KSharedPtr<T>( static_cast<T *>( o.d ) ); 00175 } 00187 template <class U> 00188 static KSharedPtr<T> dynamicCast( const KSharedPtr<U>& o ) { 00189 return KSharedPtr<T>( dynamic_cast<T *>( o.d ) ); 00190 } 00191 00192 protected: 00193 T* d; 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 bool operator!= (const T* p, const KSharedPtr<T>& o) 00204 { 00205 return ( o != p ); 00206 } 00207 00208 template <class T> 00209 Q_INLINE_TEMPLATE void KSharedPtr<T>::attach(T* p) 00210 { 00211 if (d != p) { 00212 if (p) p->ref.ref(); 00213 if (d && !d->ref.deref()) 00214 delete d; 00215 d = p; 00216 } 00217 } 00218 00219 template <class T> 00220 Q_INLINE_TEMPLATE void KSharedPtr<T>::clear() 00221 { 00222 attach(static_cast<T*>(0)); 00223 } 00224 00225 #endif 00226