Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / QtCollider / safeptr.hpp
blob0f609ae7cd2e5b7e1d3f79c73ba4275782995a6c
1 /************************************************************************
3 * Copyright 2011 Jakob Leben (jakob.leben@gmail.com)
5 * This file is part of SuperCollider Qt GUI.
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ************************************************************************/
22 #ifndef QC_SAFE_PTR_H
23 #define QC_SAFE_PTR_H
25 #include "Common.h"
27 #include <QApplication>
28 #include <QAtomicPointer>
29 #include <QAtomicInt>
30 #include <QMutex>
32 namespace QtCollider {
34 template<typename T> class SafePtr
36 public:
37 SafePtr() : d(0) {}
39 SafePtr( const SafePtr & other )
40 : d ( other.d )
42 ref();
45 SafePtr( T* ptr )
46 : d ( new Data( ptr ) )
49 SafePtr & operator= ( const SafePtr & other ) {
50 deref();
51 d = other.d;
52 ref();
53 return *this;
56 ~SafePtr() {
57 deref();
60 T * operator-> () const { return d->ptr; }
62 T & operator* () const { return *d->ptr; }
64 operator T* () const { return (d ? d->ptr : 0); }
66 T *ptr() const { return (d ? d->ptr : 0); }
68 void *id() const { return (void*) d; } // useful for checking internal pointer identity
70 void invalidate() { qcDebugMsg(2,"SafePtr: invalidating"); if(d) d->ptr = 0; }
72 private:
73 struct Data {
74 Data ( T * ptr_ ) : ptr(ptr_), refCount(1) {}
75 QAtomicPointer<T> ptr;
76 QAtomicInt refCount;
79 void ref() {
80 if( d ) {
81 d->refCount.ref();
82 qcDebugMsg(2,QString("SafePtr: +refcount = %1").arg(d->refCount));
85 void deref() {
86 if( d ) {
87 bool ref = d->refCount.deref();
88 qcDebugMsg(2,QString("SafePtr: -refcount = %1").arg(d->refCount));
89 if( !ref ) {
90 qcDebugMsg(2,"SafePtr: unreferenced!");
91 delete d;
96 Data *d;
99 } // namespace QtCollider
101 #endif