OpenShot Library | libopenshot-audio 0.2.0
juce_ReferenceCountedObject.h
1
2/** @weakgroup juce_core-memory
3 * @{
4 */
5/*
6 ==============================================================================
7
8 This file is part of the JUCE library.
9 Copyright (c) 2017 - ROLI Ltd.
10
11 JUCE is an open source library subject to commercial or open-source
12 licensing.
13
14 The code included in this file is provided under the terms of the ISC license
15 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
16 To use, copy, modify, and/or distribute this software for any purpose with or
17 without fee is hereby granted provided that the above copyright notice and
18 this permission notice appear in all copies.
19
20 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22 DISCLAIMED.
23
24 ==============================================================================
25*/
26
27namespace juce
28{
29
30//==============================================================================
31/**
32 A base class which provides methods for reference-counting.
33
34 To add reference-counting to a class, derive it from this class, and
35 use the ReferenceCountedObjectPtr class to point to it.
36
37 e.g. @code
38 class MyClass : public ReferenceCountedObject
39 {
40 void foo();
41
42 // This is a neat way of declaring a typedef for a pointer class,
43 // rather than typing out the full templated name each time..
44 using Ptr = ReferenceCountedObjectPtr<MyClass>;
45 };
46
47 MyClass::Ptr p = new MyClass();
48 MyClass::Ptr p2 = p;
49 p = nullptr;
50 p2->foo();
51 @endcode
52
53 Once a new ReferenceCountedObject has been assigned to a pointer, be
54 careful not to delete the object manually.
55
56 This class uses an Atomic<int> value to hold the reference count, so that
57 the pointers can be passed between threads safely. For a faster but non-thread-safe
58 version, use SingleThreadedReferenceCountedObject instead.
59
60 @see ReferenceCountedObjectPtr, ReferenceCountedArray, SingleThreadedReferenceCountedObject
61
62 @tags{Core}
63*/
65{
66public:
67 //==============================================================================
68 /** Increments the object's reference count.
69
70 This is done automatically by the smart pointer, but is public just
71 in case it's needed for nefarious purposes.
72 */
73 void incReferenceCount() noexcept
74 {
75 ++refCount;
76 }
77
78 /** Decreases the object's reference count.
79 If the count gets to zero, the object will be deleted.
80 */
81 void decReferenceCount() noexcept
82 {
83 jassert (getReferenceCount() > 0);
84
85 if (--refCount == 0)
86 delete this;
87 }
88
89 /** Decreases the object's reference count.
90 If the count gets to zero, the object will not be deleted, but this method
91 will return true, allowing the caller to take care of deletion.
92 */
94 {
95 jassert (getReferenceCount() > 0);
96 return --refCount == 0;
97 }
98
99 /** Returns the object's current reference count. */
100 int getReferenceCount() const noexcept { return refCount.get(); }
101
102
103protected:
104 //==============================================================================
105 /** Creates the reference-counted object (with an initial ref count of zero). */
107
108 /** Copying from another object does not affect this one's reference-count. */
110 /** Copying from another object does not affect this one's reference-count. */
112 /** Copying from another object does not affect this one's reference-count. */
113 ReferenceCountedObject& operator= (const ReferenceCountedObject&) noexcept { return *this; }
114 /** Copying from another object does not affect this one's reference-count. */
115 ReferenceCountedObject& operator= (ReferenceCountedObject&&) noexcept { return *this; }
116
117 /** Destructor. */
119 {
120 // it's dangerous to delete an object that's still referenced by something else!
121 jassert (getReferenceCount() == 0);
122 }
123
124 /** Resets the reference count to zero without deleting the object.
125 You should probably never need to use this!
126 */
127 void resetReferenceCount() noexcept
128 {
129 refCount = 0;
130 }
131
132private:
133 //==============================================================================
134 Atomic<int> refCount { 0 };
135 friend struct ContainerDeletePolicy<ReferenceCountedObject>;
136};
137
138
139//==============================================================================
140/**
141 Adds reference-counting to an object.
142
143 This is effectively a version of the ReferenceCountedObject class, but which
144 uses a non-atomic counter, and so is not thread-safe (but which will be more
145 efficient).
146 For more details on how to use it, see the ReferenceCountedObject class notes.
147
148 @see ReferenceCountedObject, ReferenceCountedObjectPtr, ReferenceCountedArray
149
150 @tags{Core}
151*/
153{
154public:
155 //==============================================================================
156 /** Increments the object's reference count.
157
158 This is done automatically by the smart pointer, but is public just
159 in case it's needed for nefarious purposes.
160 */
161 void incReferenceCount() noexcept
162 {
163 ++refCount;
164 }
165
166 /** Decreases the object's reference count.
167 If the count gets to zero, the object will be deleted.
168 */
169 void decReferenceCount() noexcept
170 {
171 jassert (getReferenceCount() > 0);
172
173 if (--refCount == 0)
174 delete this;
175 }
176
177 /** Decreases the object's reference count.
178 If the count gets to zero, the object will not be deleted, but this method
179 will return true, allowing the caller to take care of deletion.
180 */
182 {
183 jassert (getReferenceCount() > 0);
184 return --refCount == 0;
185 }
186
187 /** Returns the object's current reference count. */
188 int getReferenceCount() const noexcept { return refCount; }
189
190
191protected:
192 //==============================================================================
193 /** Creates the reference-counted object (with an initial ref count of zero). */
195
196 /** Copying from another object does not affect this one's reference-count. */
198 /** Copying from another object does not affect this one's reference-count. */
200 /** Copying from another object does not affect this one's reference-count. */
202 /** Copying from another object does not affect this one's reference-count. */
204
205 /** Destructor. */
207 {
208 // it's dangerous to delete an object that's still referenced by something else!
209 jassert (getReferenceCount() == 0);
210 }
211
212private:
213 //==============================================================================
214 int refCount = 0;
216};
217
218
219//==============================================================================
220/**
221 A smart-pointer class which points to a reference-counted object.
222
223 The template parameter specifies the class of the object you want to point to - the easiest
224 way to make a class reference-countable is to simply make it inherit from ReferenceCountedObject
225 or SingleThreadedReferenceCountedObject, but if you need to, you can roll your own reference-countable
226 class by implementing a set of methods called incReferenceCount(), decReferenceCount(), and
227 decReferenceCountWithoutDeleting(). See ReferenceCountedObject for examples of how these methods
228 should behave.
229
230 When using this class, you'll probably want to create a typedef to abbreviate the full
231 templated name - e.g.
232 @code
233 struct MyClass : public ReferenceCountedObject
234 {
235 using Ptr = ReferenceCountedObjectPtr<MyClass>;
236 ...
237 }
238 @endcode
239
240 @see ReferenceCountedObject, ReferenceCountedObjectArray
241
242 @tags{Core}
243*/
244template <class ObjectType>
246{
247public:
248 /** The class being referenced by this pointer. */
249 using ReferencedType = ObjectType;
250
251 //==============================================================================
252 /** Creates a pointer to a null object. */
254
255 /** Creates a pointer to a null object. */
256 ReferenceCountedObjectPtr (decltype (nullptr)) noexcept {}
257
258 /** Creates a pointer to an object.
259 This will increment the object's reference-count.
260 */
261 ReferenceCountedObjectPtr (ReferencedType* refCountedObject) noexcept
262 : referencedObject (refCountedObject)
263 {
264 incIfNotNull (refCountedObject);
265 }
266
267 /** Creates a pointer to an object.
268 This will increment the object's reference-count.
269 */
270 ReferenceCountedObjectPtr (ReferencedType& refCountedObject) noexcept
271 : referencedObject (&refCountedObject)
272 {
273 refCountedObject.incReferenceCount();
274 }
275
276 /** Copies another pointer.
277 This will increment the object's reference-count.
278 */
280 : referencedObject (other.referencedObject)
281 {
282 incIfNotNull (referencedObject);
283 }
284
285 /** Takes-over the object from another pointer. */
287 : referencedObject (other.referencedObject)
288 {
289 other.referencedObject = nullptr;
290 }
291
292 /** Copies another pointer.
293 This will increment the object's reference-count (if it is non-null).
294 */
295 template <typename Convertible>
297 : referencedObject (other.get())
298 {
299 incIfNotNull (referencedObject);
300 }
301
302 /** Changes this pointer to point at a different object.
303 The reference count of the old object is decremented, and it might be
304 deleted if it hits zero. The new object's count is incremented.
305 */
307 {
308 return operator= (other.referencedObject);
309 }
310
311 /** Changes this pointer to point at a different object.
312 The reference count of the old object is decremented, and it might be
313 deleted if it hits zero. The new object's count is incremented.
314 */
315 template <typename Convertible>
317 {
318 return operator= (other.get());
319 }
320
321 /** Changes this pointer to point at a different object.
322
323 The reference count of the old object is decremented, and it might be
324 deleted if it hits zero. The new object's count is incremented.
325 */
327 {
328 if (newObject != nullptr)
329 return operator= (*newObject);
330
331 reset();
332 return *this;
333 }
334
335 /** Changes this pointer to point at a different object.
336
337 The reference count of the old object is decremented, and it might be
338 deleted if it hits zero. The new object's count is incremented.
339 */
341 {
342 if (referencedObject != &newObject)
343 {
344 newObject.incReferenceCount();
345 auto* oldObject = referencedObject;
346 referencedObject = &newObject;
347 decIfNotNull (oldObject);
348 }
349
350 return *this;
351 }
352
353 /** Resets this pointer to a null pointer. */
355 {
356 reset();
357 return *this;
358 }
359
360 /** Takes-over the object from another pointer. */
362 {
363 std::swap (referencedObject, other.referencedObject);
364 return *this;
365 }
366
367 /** Destructor.
368 This will decrement the object's reference-count, which will cause the
369 object to be deleted when the ref-count hits zero.
370 */
372 {
373 decIfNotNull (referencedObject);
374 }
375
376 //==============================================================================
377 /** Returns the object that this pointer references.
378 The pointer returned may be null, of course.
379 */
380 ReferencedType* get() const noexcept { return referencedObject; }
381
382 /** Resets this object to a null pointer. */
383 void reset() noexcept
384 {
385 auto oldObject = referencedObject; // need to null the pointer before deleting the object
386 referencedObject = nullptr; // in case this ptr is itself deleted as a side-effect
387 decIfNotNull (oldObject); // of the destructor
388 }
389
390 // the -> operator is called on the referenced object
391 ReferencedType* operator->() const noexcept
392 {
393 jassert (referencedObject != nullptr); // null pointer method call!
394 return referencedObject;
395 }
396
397 /** Dereferences the object that this pointer references.
398 The pointer returned may be null, of course.
399 */
400 ReferencedType& operator*() const noexcept { jassert (referencedObject != nullptr); return *referencedObject; }
401
402 /** Checks whether this pointer is null */
403 bool operator== (decltype (nullptr)) const noexcept { return referencedObject == nullptr; }
404 /** Checks whether this pointer is null */
405 bool operator!= (decltype (nullptr)) const noexcept { return referencedObject != nullptr; }
406
407 /** Compares two ReferenceCountedObjectPtrs. */
408 bool operator== (const ObjectType* other) const noexcept { return referencedObject == other; }
409 /** Compares two ReferenceCountedObjectPtrs. */
410 bool operator== (const ReferenceCountedObjectPtr& other) const noexcept { return referencedObject == other.get(); }
411 /** Compares two ReferenceCountedObjectPtrs. */
412 bool operator!= (const ObjectType* other) const noexcept { return referencedObject != other; }
413 /** Compares two ReferenceCountedObjectPtrs. */
414 bool operator!= (const ReferenceCountedObjectPtr& other) const noexcept { return referencedObject != other.get(); }
415
416 #if JUCE_STRICT_REFCOUNTEDPOINTER
417 /** Checks whether this pointer is null */
418 explicit operator bool() const noexcept { return referencedObject != nullptr; }
419
420 #else
421 /** Returns the object that this pointer references.
422 The pointer returned may be null, of course.
423 Note that this methods allows the compiler to be very lenient with what it allows you to do
424 with the pointer, it's safer to disable this by setting JUCE_STRICT_REFCOUNTEDPOINTER=1, which
425 increased type safety and can prevent some common slip-ups.
426 */
427 operator ReferencedType*() const noexcept { return referencedObject; }
428 #endif
429
430
431 // This old method is deprecated in favour of the shorter and more standard get() method.
432 JUCE_DEPRECATED_WITH_BODY (ReferencedType* getObject() const, { return get(); })
433
434private:
435 //==============================================================================
436 ReferencedType* referencedObject = nullptr;
437
438 static void incIfNotNull (ReferencedType* o) noexcept
439 {
440 if (o != nullptr)
441 o->incReferenceCount();
442 }
443
444 static void decIfNotNull (ReferencedType* o) noexcept
445 {
446 if (o != nullptr && o->decReferenceCountWithoutDeleting())
447 ContainerDeletePolicy<ReferencedType>::destroy (o);
448 }
449};
450
451
452//==============================================================================
453/** Compares two ReferenceCountedObjectPtrs. */
454template <typename Type>
455bool operator== (const Type* object1, const ReferenceCountedObjectPtr<Type>& object2) noexcept
456{
457 return object1 == object2.get();
458}
459
460/** Compares two ReferenceCountedObjectPtrs. */
461template <typename Type>
462bool operator!= (const Type* object1, const ReferenceCountedObjectPtr<Type>& object2) noexcept
463{
464 return object1 != object2.get();
465}
466
467} // namespace juce
468
469/** @}*/
A smart-pointer class which points to a reference-counted object.
ReferenceCountedObjectPtr & operator=(const ReferenceCountedObjectPtr &other)
Changes this pointer to point at a different object.
ObjectType ReferencedType
The class being referenced by this pointer.
bool operator!=(decltype(nullptr)) const noexcept
Checks whether this pointer is null.
ReferenceCountedObjectPtr(ReferenceCountedObjectPtr &&other) noexcept
Takes-over the object from another pointer.
bool operator==(decltype(nullptr)) const noexcept
Checks whether this pointer is null.
ReferenceCountedObjectPtr(ReferencedType *refCountedObject) noexcept
Creates a pointer to an object.
ReferenceCountedObjectPtr(ReferencedType &refCountedObject) noexcept
Creates a pointer to an object.
ReferenceCountedObjectPtr()=default
Creates a pointer to a null object.
ReferenceCountedObjectPtr(const ReferenceCountedObjectPtr< Convertible > &other) noexcept
Copies another pointer.
void reset() noexcept
Resets this object to a null pointer.
ReferenceCountedObjectPtr(decltype(nullptr)) noexcept
Creates a pointer to a null object.
ReferencedType & operator*() const noexcept
Dereferences the object that this pointer references.
ReferenceCountedObjectPtr(const ReferenceCountedObjectPtr &other) noexcept
Copies another pointer.
ReferencedType * get() const noexcept
Returns the object that this pointer references.
A base class which provides methods for reference-counting.
ReferenceCountedObject(const ReferenceCountedObject &) noexcept
Copying from another object does not affect this one's reference-count.
ReferenceCountedObject(ReferenceCountedObject &&) noexcept
Copying from another object does not affect this one's reference-count.
void resetReferenceCount() noexcept
Resets the reference count to zero without deleting the object.
bool decReferenceCountWithoutDeleting() noexcept
Decreases the object's reference count.
ReferenceCountedObject()=default
Creates the reference-counted object (with an initial ref count of zero).
void incReferenceCount() noexcept
Increments the object's reference count.
int getReferenceCount() const noexcept
Returns the object's current reference count.
void decReferenceCount() noexcept
Decreases the object's reference count.
SingleThreadedReferenceCountedObject(SingleThreadedReferenceCountedObject &&)
Copying from another object does not affect this one's reference-count.
SingleThreadedReferenceCountedObject(const SingleThreadedReferenceCountedObject &)
Copying from another object does not affect this one's reference-count.
SingleThreadedReferenceCountedObject()=default
Creates the reference-counted object (with an initial ref count of zero).
void decReferenceCount() noexcept
Decreases the object's reference count.
void incReferenceCount() noexcept
Increments the object's reference count.
int getReferenceCount() const noexcept
Returns the object's current reference count.
bool decReferenceCountWithoutDeleting() noexcept
Decreases the object's reference count.
#define JUCE_API
This macro is added to all JUCE public class declarations.
A simple wrapper around std::atomic.
Definition juce_Atomic.h:46
Used by container classes as an indirect way to delete an object of a particular type.