ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

ptr.h

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #ifndef COMMON_PTR_H
00024 #define COMMON_PTR_H
00025 
00026 #include "common/scummsys.h"
00027 #include "common/noncopyable.h"
00028 #include "common/safe-bool.h"
00029 #include "common/types.h"
00030 
00031 namespace Common {
00032 
00033 class SharedPtrDeletionInternal {
00034 public:
00035     virtual ~SharedPtrDeletionInternal() {}
00036 };
00037 
00038 template<class T>
00039 class SharedPtrDeletionImpl : public SharedPtrDeletionInternal {
00040 public:
00041     SharedPtrDeletionImpl(T *ptr) : _ptr(ptr) {}
00042     ~SharedPtrDeletionImpl() {
00043         STATIC_ASSERT(sizeof(T) > 0, SharedPtr_cannot_delete_incomplete_type);
00044         delete _ptr;
00045     }
00046 private:
00047     T *_ptr;
00048 };
00049 
00050 template<class T, class D>
00051 class SharedPtrDeletionDeleterImpl : public SharedPtrDeletionInternal {
00052 public:
00053     SharedPtrDeletionDeleterImpl(T *ptr, D d) : _ptr(ptr), _deleter(d) {}
00054     ~SharedPtrDeletionDeleterImpl() { _deleter(_ptr); }
00055 private:
00056     T *_ptr;
00057     D _deleter;
00058 };
00059 
00101 template<class T>
00102 class SharedPtr : public SafeBool<SharedPtr<T> > {
00103 #if !defined(__GNUC__) || GCC_ATLEAST(3, 0)
00104     template<class T2> friend class SharedPtr;
00105 #endif
00106 public:
00107     typedef int RefValue;
00108     typedef T ValueType;
00109     typedef T *PointerType;
00110     typedef T &ReferenceType;
00111 
00112     SharedPtr() : _refCount(nullptr), _deletion(nullptr), _pointer(nullptr) {}
00113 
00114     template<class T2>
00115     explicit SharedPtr(T2 *p) : _refCount(new RefValue(1)), _deletion(new SharedPtrDeletionImpl<T2>(p)), _pointer(p) {}
00116 
00117     template<class T2, class D>
00118     SharedPtr(T2 *p, D d) : _refCount(new RefValue(1)), _deletion(new SharedPtrDeletionDeleterImpl<T2, D>(p, d)), _pointer(p) {}
00119 
00120     SharedPtr(const SharedPtr &r) : _refCount(r._refCount), _deletion(r._deletion), _pointer(r._pointer) { if (_refCount) ++(*_refCount); }
00121     template<class T2>
00122     SharedPtr(const SharedPtr<T2> &r) : _refCount(r._refCount), _deletion(r._deletion), _pointer(r._pointer) { if (_refCount) ++(*_refCount); }
00123 
00124     ~SharedPtr() { decRef(); }
00125 
00126     SharedPtr &operator=(const SharedPtr &r) {
00127         if (r._refCount)
00128             ++(*r._refCount);
00129         decRef();
00130 
00131         _refCount = r._refCount;
00132         _deletion = r._deletion;
00133         _pointer = r._pointer;
00134 
00135         return *this;
00136     }
00137 
00138     template<class T2>
00139     SharedPtr &operator=(const SharedPtr<T2> &r) {
00140         if (r._refCount)
00141             ++(*r._refCount);
00142         decRef();
00143 
00144         _refCount = r._refCount;
00145         _deletion = r._deletion;
00146         _pointer = r._pointer;
00147 
00148         return *this;
00149     }
00150 
00151     ReferenceType operator*() const { assert(_pointer); return *_pointer; }
00152     PointerType operator->() const { assert(_pointer); return _pointer; }
00153 
00160     PointerType get() const { return _pointer; }
00161 
00166     bool operator_bool() const { return _pointer != nullptr; }
00167 
00173     bool unique() const { return refCount() == 1; }
00174 
00178     void reset() {
00179         decRef();
00180         _deletion = nullptr;
00181         _refCount = nullptr;
00182         _pointer = nullptr;
00183     }
00184 
00185     template<class T2>
00186     bool operator==(const SharedPtr<T2> &r) const {
00187         return _pointer == r.get();
00188     }
00189 
00190     template<class T2>
00191     bool operator!=(const SharedPtr<T2> &r) const {
00192         return _pointer != r.get();
00193     }
00194 
00199     RefValue refCount() const { return _refCount ? *_refCount : 0; }
00200 #if !defined(__GNUC__) || GCC_ATLEAST(3, 0)
00201 private:
00202 #endif
00203     void decRef() {
00204         if (_refCount) {
00205             --(*_refCount);
00206             if (!*_refCount) {
00207                 delete _refCount;
00208                 delete _deletion;
00209                 _deletion = nullptr;
00210                 _refCount = nullptr;
00211                 _pointer = nullptr;
00212             }
00213         }
00214     }
00215 
00216     RefValue *_refCount;
00217     SharedPtrDeletionInternal *_deletion;
00218     PointerType _pointer;
00219 };
00220 
00221 template <typename T>
00222 struct DefaultDeleter {
00223     inline void operator()(T *object) {
00224         STATIC_ASSERT(sizeof(T) > 0, cannot_delete_incomplete_type);
00225         delete object;
00226     }
00227 };
00228 
00229 template<typename T, class D = DefaultDeleter<T> >
00230 class ScopedPtr : private NonCopyable, public SafeBool<ScopedPtr<T, D> > {
00231 public:
00232     typedef T ValueType;
00233     typedef T *PointerType;
00234     typedef T &ReferenceType;
00235 
00236     explicit ScopedPtr(PointerType o = nullptr) : _pointer(o) {}
00237 
00238     ReferenceType operator*() const { return *_pointer; }
00239     PointerType operator->() const { return _pointer; }
00240 
00245     bool operator_bool() const { return _pointer != nullptr; }
00246 
00247     ~ScopedPtr() {
00248         D()(_pointer);
00249     }
00250 
00254     void reset(PointerType o = nullptr) {
00255         D()(_pointer);
00256         _pointer = o;
00257     }
00258 
00264     PointerType get() const { return _pointer; }
00265 
00272     PointerType release() {
00273         PointerType r = _pointer;
00274         _pointer = nullptr;
00275         return r;
00276     }
00277 
00278 private:
00279     PointerType _pointer;
00280 };
00281 
00282 template<typename T, class D = DefaultDeleter<T> >
00283 class DisposablePtr : private NonCopyable, public SafeBool<DisposablePtr<T, D> > {
00284 public:
00285     typedef T  ValueType;
00286     typedef T *PointerType;
00287     typedef T &ReferenceType;
00288 
00289     explicit DisposablePtr(PointerType o, DisposeAfterUse::Flag dispose) : _pointer(o), _dispose(dispose) {}
00290 
00291     ~DisposablePtr() {
00292         if (_dispose) D()(_pointer);
00293     }
00294 
00295     ReferenceType operator*() const { return *_pointer; }
00296     PointerType operator->() const { return _pointer; }
00297 
00302     bool operator_bool() const { return _pointer != nullptr; }
00303 
00307     void reset(PointerType o, DisposeAfterUse::Flag dispose) {
00308         if (_dispose) D()(_pointer);
00309         _pointer = o;
00310         _dispose = dispose;
00311     }
00312 
00316     void reset() {
00317         reset(nullptr, DisposeAfterUse::NO);
00318     }
00319 
00325     PointerType get() const { return _pointer; }
00326 
00327 private:
00328     PointerType           _pointer;
00329     DisposeAfterUse::Flag _dispose;
00330 };
00331 
00332 } // End of namespace Common
00333 
00334 #endif


Generated on Sat May 18 2019 05:01:13 for ResidualVM by doxygen 1.7.1
curved edge   curved edge