ScummVM API documentation
te_intrusive_ptr.h
1/* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
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.
11 *
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.
16 *
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/>.
19 *
20 */
21
22#ifndef TETRAEDGE_TE_TE_INTRUSIVE_PTR_H
23#define TETRAEDGE_TE_TE_INTRUSIVE_PTR_H
24
25namespace Tetraedge {
26
31template<class T> class TeIntrusivePtr {
32public:
33 // NOTE: The original uses a member function for this, which is cleaner, but
34 // MSVC compiles member functions for different class types (forward
35 // declaration, multi-inheritance, etc) as different sizes which causes all
36 // sorts of issues. Only accept a static function to avoid such problems.
37 typedef void(*Tdestructor)(T *obj);
38
39 TeIntrusivePtr() : _p(nullptr), _deleteFn(nullptr) {}
40
41 TeIntrusivePtr(const TeIntrusivePtr<T> &other) : _deleteFn(nullptr) {
42 _p = other._p;
43 if (_p)
44 _p->incrementCounter();
45 }
46
47 TeIntrusivePtr(T *obj) : _deleteFn(nullptr) {
48 _p = obj;
49 if (_p)
50 _p->incrementCounter();
51 }
52
53 virtual ~TeIntrusivePtr() {
54 release();
55 }
56
57 TeIntrusivePtr<T> &operator=(T *obj) {
58 if (_p != obj) {
59 release();
60 _p = obj;
61 if (_p)
62 _p->incrementCounter();
63 }
64 return *this;
65 }
66
67 TeIntrusivePtr<T> &operator=(const TeIntrusivePtr<T> &other) {
68 if (this != &other) {
69 release();
70 _p = other._p;
71 _deleteFn = other._deleteFn;
72 if (_p)
73 _p->incrementCounter();
74 }
75 return *this;
76 }
77
78 void release() {
79 if (_p) {
80 if (_p->decrementCounter()) {
81 if (_deleteFn)
82 (_deleteFn)(_p);
83 else
84 delete _p;
85 }
86 }
87 _p = nullptr;
88 }
89
90 bool operator==(const TeIntrusivePtr<T> &other) const {
91 return (this == &other || _p == other._p);
92 }
93
94 T *get() {
95 return _p;
96 }
97
98 const T *get() const {
99 return _p;
100 }
101
102 T &operator*() {
103 return *_p;
104 }
105
106 const T &operator*() const {
107 return *_p;
108 }
109
110 operator bool() const {
111 return _p != nullptr;
112 }
113
114 T *operator->() {
115 return _p;
116 }
117
118 const T *operator->() const {
119 return _p;
120 }
121
122 void setDeleteFn(Tdestructor destructor) {
123 _deleteFn = destructor;
124 }
125
126private:
127 T *_p;
128 Tdestructor _deleteFn;
129};
130
131} // end namespace Tetraedge
132
133#endif // TETRAEDGE_TE_TE_INTRUSIVE_PTR_H
Definition: te_intrusive_ptr.h:31