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 00034 typedef QSharedData KShared; 00035 00052 template< class T > 00053 class KSharedPtr 00054 { 00055 public: 00059 inline KSharedPtr() 00060 : d(0) { } 00061 00066 inline explicit KSharedPtr( T* p ) 00067 : d(p) { if(d) d->ref.ref(); } 00068 00073 inline KSharedPtr( const KSharedPtr& o ) 00074 : d(o.d) { if(d) d->ref.ref(); } 00075 00080 inline ~KSharedPtr() { if (d && !d->ref.deref()) delete d; } 00081 00082 inline KSharedPtr<T>& operator= ( const KSharedPtr& o ) { attach(o.d); return *this; } 00083 inline bool operator== ( const KSharedPtr& o ) const { return ( d == o.d ); } 00084 inline bool operator!= ( const KSharedPtr& o ) const { return ( d != o.d ); } 00085 inline bool operator< ( const KSharedPtr& o ) const { return ( d < o.d ); } 00086 00087 inline KSharedPtr<T>& operator= ( T* p ) { attach(p); return *this; } 00088 inline bool operator== ( const T* p ) const { return ( d == p ); } 00089 inline bool operator!= ( const T* p ) const { return ( d != p ); } 00090 00096 inline operator bool() const { return ( d != 0 ); } 00097 00101 inline T* data() { return d; } 00102 00106 inline const T* data() const { return d; } 00107 00111 inline const T* constData() const { return d; } 00112 00113 inline const T& operator*() const { Q_ASSERT(d); return *d; } 00114 inline T& operator*() { Q_ASSERT(d); return *d; } 00115 inline const T* operator->() const { Q_ASSERT(d); return d; } 00116 inline T* operator->() { Q_ASSERT(d); return d; } 00117 00123 void attach(T* p); 00124 00128 void clear(); 00129 00134 inline int count() const { return d ? static_cast<int>(d->ref) : 0; } // for debugging purposes 00135 00141 inline bool isNull() const { return (d == 0); } 00142 00148 inline bool isUnique() const { return count() == 1; } 00149 00150 template <class U> friend class KSharedPtr; 00151 00162 template <class U> 00163 static KSharedPtr<T> staticCast( const KSharedPtr<U>& o ) { 00164 return KSharedPtr<T>( static_cast<T *>( o.d ) ); 00165 } 00177 template <class U> 00178 static KSharedPtr<T> dynamicCast( const KSharedPtr<U>& o ) { 00179 return KSharedPtr<T>( dynamic_cast<T *>( o.d ) ); 00180 } 00181 00182 protected: 00183 T* d; 00184 }; 00185 00186 template <class T> 00187 Q_INLINE_TEMPLATE bool operator== (const T* p, const KSharedPtr<T>& o) 00188 { 00189 return ( p == o.d ); 00190 } 00191 00192 template <class T> 00193 Q_INLINE_TEMPLATE bool operator!= (const T* p, const KSharedPtr<T>& o) 00194 { 00195 return ( p != o.d ); 00196 } 00197 00198 template <class T> 00199 Q_INLINE_TEMPLATE void KSharedPtr<T>::attach(T* p) 00200 { 00201 if (d != p) { 00202 if (p) p->ref.ref(); 00203 if (d && !d->ref.deref()) 00204 delete d; 00205 d = p; 00206 } 00207 } 00208 00209 template <class T> 00210 Q_INLINE_TEMPLATE void KSharedPtr<T>::clear() 00211 { 00212 attach(static_cast<T*>(0)); 00213 } 00214 00215 #endif 00216