@@ -27,9 +27,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
27
27
* It should only be used for user-managed objects, i.e. those created with
28
28
* the @c new operator or @c create* functions, like:
29
29
* `irr_ptr<scene::IMeshBuffer> buf{new scene::SMeshBuffer()};`
30
+ * The reference counting is *not* balanced as new objects have reference
31
+ * count set to one, and the @c irr_ptr constructor (and @c reset) assumes
32
+ * ownership of that reference.
30
33
*
31
- * It should *never* be used for engine-managed objects, including
32
- * those created with @c addTexture and similar methods.
34
+ * It shouldn’t be used for engine-managed objects, including those created
35
+ * with @c addTexture and similar methods. Constructing @c irr_ptr directly
36
+ * from such object is a bug and may lead to a crash. Indirect construction
37
+ * is possible though; see the @c grab free function for details and use cases.
33
38
*/
34
39
template <class ReferenceCounted ,
35
40
class = typename std::enable_if<std::is_base_of<IReferenceCounted,
@@ -38,16 +43,6 @@ class irr_ptr
38
43
{
39
44
ReferenceCounted *value = nullptr ;
40
45
41
- /* * Drops stored pointer replacing it with the given one.
42
- * @note Copy semantics: reference counter *is* increased.
43
- */
44
- void grab (ReferenceCounted *object)
45
- {
46
- if (object)
47
- object->grab ();
48
- reset (object);
49
- }
50
-
51
46
public:
52
47
irr_ptr () {}
53
48
@@ -71,8 +66,10 @@ class irr_ptr
71
66
reset (b.release ());
72
67
}
73
68
74
- /* * Constructs a shared pointer out of a plain one
69
+ /* * Constructs a shared pointer out of a plain one to control object lifetime.
70
+ * @param object The object, usually returned by some @c create* function.
75
71
* @note Move semantics: reference counter is *not* increased.
72
+ * @warning Never wrap any @c add* function with this!
76
73
*/
77
74
explicit irr_ptr (ReferenceCounted *object) noexcept { reset (object); }
78
75
@@ -134,4 +131,70 @@ class irr_ptr
134
131
value->drop ();
135
132
value = object;
136
133
}
134
+
135
+ /* * Drops stored pointer replacing it with the given one.
136
+ * @note Copy semantics: reference counter *is* increased.
137
+ */
138
+ void grab (ReferenceCounted *object) noexcept
139
+ {
140
+ if (object)
141
+ object->grab ();
142
+ reset (object);
143
+ }
137
144
};
145
+
146
+ // clang-format off
147
+ // ^ dislikes long lines
148
+
149
+ /* * Constructs a shared pointer as a *secondary* reference to an object
150
+ *
151
+ * This function is intended to make a temporary reference to an object which
152
+ * is owned elsewhere so that it is not destroyed too early. To acheive that
153
+ * it does balanced reference counting, i.e. reference count is increased
154
+ * in this function and decreased when the returned pointer is destroyed.
155
+ */
156
+ template <class ReferenceCounted >
157
+ irr_ptr<ReferenceCounted> grab (ReferenceCounted *object) noexcept
158
+ {
159
+ irr_ptr<ReferenceCounted> ptr;
160
+ ptr.grab (object);
161
+ return ptr;
162
+ }
163
+
164
+ template <typename ReferenceCounted>
165
+ bool operator ==(const irr_ptr<ReferenceCounted> &a, const irr_ptr<ReferenceCounted> &b) noexcept
166
+ {
167
+ return a.get () == b.get ();
168
+ }
169
+
170
+ template <typename ReferenceCounted>
171
+ bool operator ==(const irr_ptr<ReferenceCounted> &a, const ReferenceCounted *b) noexcept
172
+ {
173
+ return a.get () == b;
174
+ }
175
+
176
+ template <typename ReferenceCounted>
177
+ bool operator ==(const ReferenceCounted *a, const irr_ptr<ReferenceCounted> &b) noexcept
178
+ {
179
+ return a == b.get ();
180
+ }
181
+
182
+ template <typename ReferenceCounted>
183
+ bool operator !=(const irr_ptr<ReferenceCounted> &a, const irr_ptr<ReferenceCounted> &b) noexcept
184
+ {
185
+ return a.get () != b.get ();
186
+ }
187
+
188
+ template <typename ReferenceCounted>
189
+ bool operator !=(const irr_ptr<ReferenceCounted> &a, const ReferenceCounted *b) noexcept
190
+ {
191
+ return a.get () != b;
192
+ }
193
+
194
+ template <typename ReferenceCounted>
195
+ bool operator !=(const ReferenceCounted *a, const irr_ptr<ReferenceCounted> &b) noexcept
196
+ {
197
+ return a != b.get ();
198
+ }
199
+
200
+ // clang-format on
0 commit comments