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 
27 namespace 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 {
66 public:
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 
103 protected:
104  //==============================================================================
105  /** Creates the reference-counted object (with an initial ref count of zero). */
106  ReferenceCountedObject() = default;
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 
132 private:
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 {
154 public:
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 
191 protected:
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 
212 private:
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 */
244 template <class ObjectType>
246 {
247 public:
248  /** The class being referenced by this pointer. */
249  using ReferencedType = ObjectType;
250 
251  //==============================================================================
252  /** Creates a pointer to a null object. */
253  ReferenceCountedObjectPtr() = default;
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 
434 private:
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. */
454 template <typename Type>
455 bool operator== (const Type* object1, const ReferenceCountedObjectPtr<Type>& object2) noexcept
456 {
457  return object1 == object2.get();
458 }
459 
460 /** Compares two ReferenceCountedObjectPtrs. */
461 template <typename Type>
462 bool operator!= (const Type* object1, const ReferenceCountedObjectPtr<Type>& object2) noexcept
463 {
464  return object1 != object2.get();
465 }
466 
467 } // namespace juce
468 
469 /** @}*/
juce::ReferenceCountedObjectPtr::operator*
ReferencedType & operator*() const noexcept
Dereferences the object that this pointer references.
Definition: juce_ReferenceCountedObject.h:400
juce::SingleThreadedReferenceCountedObject::~SingleThreadedReferenceCountedObject
virtual ~SingleThreadedReferenceCountedObject()
Destructor.
Definition: juce_ReferenceCountedObject.h:206
juce::SingleThreadedReferenceCountedObject::SingleThreadedReferenceCountedObject
SingleThreadedReferenceCountedObject(SingleThreadedReferenceCountedObject &&)
Copying from another object does not affect this one's reference-count.
Definition: juce_ReferenceCountedObject.h:199
juce::Atomic< int >
juce::ReferenceCountedObjectPtr::ReferenceCountedObjectPtr
ReferenceCountedObjectPtr(decltype(nullptr)) noexcept
Creates a pointer to a null object.
Definition: juce_ReferenceCountedObject.h:256
juce::ReferenceCountedObject::decReferenceCountWithoutDeleting
bool decReferenceCountWithoutDeleting() noexcept
Decreases the object's reference count.
Definition: juce_ReferenceCountedObject.h:93
juce::ReferenceCountedObject::incReferenceCount
void incReferenceCount() noexcept
Increments the object's reference count.
Definition: juce_ReferenceCountedObject.h:73
juce::ReferenceCountedObject::ReferenceCountedObject
ReferenceCountedObject(ReferenceCountedObject &&) noexcept
Copying from another object does not affect this one's reference-count.
Definition: juce_ReferenceCountedObject.h:111
juce::ReferenceCountedObject
A base class which provides methods for reference-counting.
Definition: juce_ReferenceCountedObject.h:64
juce::ReferenceCountedObjectPtr::operator!=
bool operator!=(decltype(nullptr)) const noexcept
Checks whether this pointer is null.
Definition: juce_ReferenceCountedObject.h:405
juce::ReferenceCountedObjectPtr::operator=
ReferenceCountedObjectPtr & operator=(const ReferenceCountedObjectPtr &other)
Changes this pointer to point at a different object.
Definition: juce_ReferenceCountedObject.h:306
juce::ReferenceCountedObject::~ReferenceCountedObject
virtual ~ReferenceCountedObject()
Destructor.
Definition: juce_ReferenceCountedObject.h:118
juce::ReferenceCountedObjectPtr::ReferenceCountedObjectPtr
ReferenceCountedObjectPtr(ReferencedType &refCountedObject) noexcept
Creates a pointer to an object.
Definition: juce_ReferenceCountedObject.h:270
juce::SingleThreadedReferenceCountedObject
Adds reference-counting to an object.
Definition: juce_ReferenceCountedObject.h:152
juce::SingleThreadedReferenceCountedObject::incReferenceCount
void incReferenceCount() noexcept
Increments the object's reference count.
Definition: juce_ReferenceCountedObject.h:161
JUCE_API
#define JUCE_API
This macro is added to all JUCE public class declarations.
Definition: juce_StandardHeader.h:143
juce::ReferenceCountedObjectPtr::ReferencedType
ObjectType ReferencedType
The class being referenced by this pointer.
Definition: juce_ReferenceCountedObject.h:249
juce::ReferenceCountedObjectPtr::~ReferenceCountedObjectPtr
~ReferenceCountedObjectPtr()
Destructor.
Definition: juce_ReferenceCountedObject.h:371
juce::SingleThreadedReferenceCountedObject::decReferenceCountWithoutDeleting
bool decReferenceCountWithoutDeleting() noexcept
Decreases the object's reference count.
Definition: juce_ReferenceCountedObject.h:181
juce::ReferenceCountedObjectPtr::operator==
bool operator==(decltype(nullptr)) const noexcept
Checks whether this pointer is null.
Definition: juce_ReferenceCountedObject.h:403
juce::SingleThreadedReferenceCountedObject::SingleThreadedReferenceCountedObject
SingleThreadedReferenceCountedObject(const SingleThreadedReferenceCountedObject &)
Copying from another object does not affect this one's reference-count.
Definition: juce_ReferenceCountedObject.h:197
juce::ReferenceCountedObjectPtr::ReferenceCountedObjectPtr
ReferenceCountedObjectPtr(const ReferenceCountedObjectPtr< Convertible > &other) noexcept
Copies another pointer.
Definition: juce_ReferenceCountedObject.h:296
juce::ReferenceCountedObjectPtr::ReferenceCountedObjectPtr
ReferenceCountedObjectPtr()=default
Creates a pointer to a null object.
juce::ReferenceCountedObjectPtr::ReferenceCountedObjectPtr
ReferenceCountedObjectPtr(ReferencedType *refCountedObject) noexcept
Creates a pointer to an object.
Definition: juce_ReferenceCountedObject.h:261
juce::ReferenceCountedObject::decReferenceCount
void decReferenceCount() noexcept
Decreases the object's reference count.
Definition: juce_ReferenceCountedObject.h:81
juce::ReferenceCountedObjectPtr
A smart-pointer class which points to a reference-counted object.
Definition: juce_ReferenceCountedObject.h:245
juce::SingleThreadedReferenceCountedObject::getReferenceCount
int getReferenceCount() const noexcept
Returns the object's current reference count.
Definition: juce_ReferenceCountedObject.h:188
juce::ContainerDeletePolicy
Used by container classes as an indirect way to delete an object of a particular type.
Definition: juce_ContainerDeletePolicy.h:44
juce::ReferenceCountedObject::getReferenceCount
int getReferenceCount() const noexcept
Returns the object's current reference count.
Definition: juce_ReferenceCountedObject.h:100
juce::ReferenceCountedObject::resetReferenceCount
void resetReferenceCount() noexcept
Resets the reference count to zero without deleting the object.
Definition: juce_ReferenceCountedObject.h:127
juce::ReferenceCountedObjectPtr::get
ReferencedType * get() const noexcept
Returns the object that this pointer references.
Definition: juce_ReferenceCountedObject.h:380
juce::SingleThreadedReferenceCountedObject::decReferenceCount
void decReferenceCount() noexcept
Decreases the object's reference count.
Definition: juce_ReferenceCountedObject.h:169
juce::ReferenceCountedObjectPtr::ReferenceCountedObjectPtr
ReferenceCountedObjectPtr(ReferenceCountedObjectPtr &&other) noexcept
Takes-over the object from another pointer.
Definition: juce_ReferenceCountedObject.h:286
juce::ReferenceCountedObjectPtr::ReferenceCountedObjectPtr
ReferenceCountedObjectPtr(const ReferenceCountedObjectPtr &other) noexcept
Copies another pointer.
Definition: juce_ReferenceCountedObject.h:279
juce::ReferenceCountedObject::ReferenceCountedObject
ReferenceCountedObject(const ReferenceCountedObject &) noexcept
Copying from another object does not affect this one's reference-count.
Definition: juce_ReferenceCountedObject.h:109
juce::ReferenceCountedObjectPtr::reset
void reset() noexcept
Resets this object to a null pointer.
Definition: juce_ReferenceCountedObject.h:383