File indexing completed on 2024-04-21 04:47:49

0001 /*
0002  * Copyright (C) 2017  Malte Veerman <malte.veerman@gmail.com>
0003  *
0004  * This program is free software; you can redistribute it and/or modify
0005  * it under the terms of the GNU General Public License as published by
0006  * the Free Software Foundation; either version 2 of the License, or
0007  * (at your option) any later version.
0008  *
0009  * This program is distributed in the hope that it will be useful,
0010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012  * GNU General Public License for more details.
0013  *
0014  * You should have received a copy of the GNU General Public License along
0015  * with this program; if not, write to the Free Software Foundation, Inc.,
0016  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
0017  *
0018  */
0019 
0020 #ifndef AMAROKSHAREDPOINTER_H
0021 #define AMAROKSHAREDPOINTER_H
0022 
0023 #include <QObject>
0024 #include <QSharedData>
0025 
0026 template<class T>
0027 class AmarokSharedPointer
0028 {
0029 public:
0030     inline AmarokSharedPointer() : d(nullptr) {}
0031     inline explicit AmarokSharedPointer(T *t) : d(t) { if (d) d->ref.ref(); }
0032     inline AmarokSharedPointer(const AmarokSharedPointer& other) : d(other.d) { if (d) d->ref.ref(); }
0033     inline ~AmarokSharedPointer() { if (d && !d->ref.deref()) delete d; }
0034 
0035     AmarokSharedPointer& operator=(const AmarokSharedPointer& other)
0036     {
0037         if (d != other.d)
0038         {
0039             if (d && !d->ref.deref())
0040                 delete d;
0041             d = other.d;
0042             if (d)
0043                 d->ref.ref();
0044         }
0045         return *this;
0046     }
0047     AmarokSharedPointer& operator=(T *t)
0048     {
0049         if (d != t)
0050         {
0051             if (d && !d->ref.deref())
0052                 delete d;
0053             d = t;
0054             if (d)
0055                 d->ref.ref();
0056         }
0057         return *this;
0058     }
0059     inline bool operator==(const AmarokSharedPointer& other) const { return d == other.d; }
0060     inline bool operator!=(const AmarokSharedPointer& other) const { return d != other.d; }
0061     inline bool operator<(const AmarokSharedPointer& other) const { return std::less<const T*>()(d, other.d); }
0062     inline const T& operator*() const { Q_ASSERT(d); return *d; }
0063     inline T& operator*() { Q_ASSERT(d); return *d; }
0064     inline const T* operator->() const { Q_ASSERT(d); return d; }
0065     inline T* operator->() { Q_ASSERT(d); return d; }
0066     inline operator bool() const { return ( d != nullptr ); }
0067 
0068     inline bool isNull() const { return d == nullptr; }
0069     inline int count() const { return d ? d->ref.loadRelaxed() : 0; }
0070     inline T* data() const { return d; }
0071     inline void clear() { if (d && !d->ref.deref()) delete d; d = nullptr; }
0072 
0073     template <class U>
0074     static AmarokSharedPointer<T> staticCast(const AmarokSharedPointer<U>& o)
0075     {
0076         return AmarokSharedPointer<T>(static_cast<T *>(o.data()));
0077     }
0078     template <class U>
0079     static AmarokSharedPointer<T> dynamicCast(const AmarokSharedPointer<U>& o)
0080     {
0081         return AmarokSharedPointer<T>(dynamic_cast<T *>(o.data()));
0082     }
0083     template <class U>
0084     static AmarokSharedPointer<T> qobjectCast(const AmarokSharedPointer<U>& o)
0085     {
0086         return AmarokSharedPointer<T>(qobject_cast<T *>(o.data()));
0087     }
0088 
0089 private:
0090     T *d;
0091 };
0092 
0093 template<class T>
0094 inline uint qHash( const AmarokSharedPointer<T> &p, uint seed ) { return qHash( p.data(), seed ); }
0095 
0096 #endif // AMAROKSHAREDPOINTER_H