OpenShot Audio Library | OpenShotAudio  0.3.0
juce_ReferenceCountedObject.h
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2017 - ROLI Ltd.
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  The code included in this file is provided under the terms of the ISC license
11  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12  To use, copy, modify, and/or distribute this software for any purpose with or
13  without fee is hereby granted provided that the above copyright notice and
14  this permission notice appear in all copies.
15 
16  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18  DISCLAIMED.
19 
20  ==============================================================================
21 */
22 
23 namespace juce
24 {
25 
26 //==============================================================================
65 class JUCE_API ReferenceCountedObject
66 {
67 public:
68  //==============================================================================
74  void incReferenceCount() noexcept
75  {
76  ++refCount;
77  }
78 
82  void decReferenceCount() noexcept
83  {
84  jassert (getReferenceCount() > 0);
85 
86  if (--refCount == 0)
87  delete this;
88  }
89 
95  {
96  jassert (getReferenceCount() > 0);
97  return --refCount == 0;
98  }
99 
101  int getReferenceCount() const noexcept { return refCount.get(); }
102 
103 
104 protected:
105  //==============================================================================
108 
114  ReferenceCountedObject& operator= (const ReferenceCountedObject&) noexcept { return *this; }
116  ReferenceCountedObject& operator= (ReferenceCountedObject&&) noexcept { return *this; }
117 
120  {
121  // it's dangerous to delete an object that's still referenced by something else!
122  jassert (getReferenceCount() == 0);
123  }
124 
128  void resetReferenceCount() noexcept
129  {
130  refCount = 0;
131  }
132 
133 private:
134  //==============================================================================
135  Atomic<int> refCount { 0 };
136  friend struct ContainerDeletePolicy<ReferenceCountedObject>;
137 };
138 
139 
140 //==============================================================================
154 {
155 public:
156  //==============================================================================
162  void incReferenceCount() noexcept
163  {
164  ++refCount;
165  }
166 
170  void decReferenceCount() noexcept
171  {
172  jassert (getReferenceCount() > 0);
173 
174  if (--refCount == 0)
175  delete this;
176  }
177 
183  {
184  jassert (getReferenceCount() > 0);
185  return --refCount == 0;
186  }
187 
189  int getReferenceCount() const noexcept { return refCount; }
190 
191 
192 protected:
193  //==============================================================================
196 
205 
208  {
209  // it's dangerous to delete an object that's still referenced by something else!
210  jassert (getReferenceCount() == 0);
211  }
212 
213 private:
214  //==============================================================================
215  int refCount = 0;
217 };
218 
219 
220 //==============================================================================
245 template <class ObjectType>
247 {
248 public:
250  using ReferencedType = ObjectType;
251 
252  //==============================================================================
255 
257  ReferenceCountedObjectPtr (decltype (nullptr)) noexcept {}
258 
262  ReferenceCountedObjectPtr (ReferencedType* refCountedObject) noexcept
263  : referencedObject (refCountedObject)
264  {
265  incIfNotNull (refCountedObject);
266  }
267 
271  ReferenceCountedObjectPtr (ReferencedType& refCountedObject) noexcept
272  : referencedObject (&refCountedObject)
273  {
274  refCountedObject.incReferenceCount();
275  }
276 
281  : referencedObject (other.referencedObject)
282  {
283  incIfNotNull (referencedObject);
284  }
285 
288  : referencedObject (other.referencedObject)
289  {
290  other.referencedObject = nullptr;
291  }
292 
296  template <typename Convertible>
298  : referencedObject (other.get())
299  {
300  incIfNotNull (referencedObject);
301  }
302 
308  {
309  return operator= (other.referencedObject);
310  }
311 
316  template <typename Convertible>
318  {
319  return operator= (other.get());
320  }
321 
328  {
329  if (newObject != nullptr)
330  return operator= (*newObject);
331 
332  reset();
333  return *this;
334  }
335 
342  {
343  if (referencedObject != &newObject)
344  {
345  newObject.incReferenceCount();
346  auto* oldObject = referencedObject;
347  referencedObject = &newObject;
348  decIfNotNull (oldObject);
349  }
350 
351  return *this;
352  }
353 
356  {
357  reset();
358  return *this;
359  }
360 
363  {
364  std::swap (referencedObject, other.referencedObject);
365  return *this;
366  }
367 
373  {
374  decIfNotNull (referencedObject);
375  }
376 
377  //==============================================================================
381  ReferencedType* get() const noexcept { return referencedObject; }
382 
384  void reset() noexcept
385  {
386  auto oldObject = referencedObject; // need to null the pointer before deleting the object
387  referencedObject = nullptr; // in case this ptr is itself deleted as a side-effect
388  decIfNotNull (oldObject); // of the destructor
389  }
390 
391  // the -> operator is called on the referenced object
392  ReferencedType* operator->() const noexcept
393  {
394  jassert (referencedObject != nullptr); // null pointer method call!
395  return referencedObject;
396  }
397 
401  ReferencedType& operator*() const noexcept { jassert (referencedObject != nullptr); return *referencedObject; }
402 
404  bool operator== (decltype (nullptr)) const noexcept { return referencedObject == nullptr; }
406  bool operator!= (decltype (nullptr)) const noexcept { return referencedObject != nullptr; }
407 
409  bool operator== (const ObjectType* other) const noexcept { return referencedObject == other; }
411  bool operator== (const ReferenceCountedObjectPtr& other) const noexcept { return referencedObject == other.get(); }
413  bool operator!= (const ObjectType* other) const noexcept { return referencedObject != other; }
415  bool operator!= (const ReferenceCountedObjectPtr& other) const noexcept { return referencedObject != other.get(); }
416 
417  #if JUCE_STRICT_REFCOUNTEDPOINTER
419  explicit operator bool() const noexcept { return referencedObject != nullptr; }
420 
421  #else
428  operator ReferencedType*() const noexcept { return referencedObject; }
429  #endif
430 
431 
432  // This old method is deprecated in favour of the shorter and more standard get() method.
433  JUCE_DEPRECATED_WITH_BODY (ReferencedType* getObject() const, { return get(); })
434 
435 private:
436  //==============================================================================
437  ReferencedType* referencedObject = nullptr;
438 
439  static void incIfNotNull (ReferencedType* o) noexcept
440  {
441  if (o != nullptr)
442  o->incReferenceCount();
443  }
444 
445  static void decIfNotNull (ReferencedType* o) noexcept
446  {
447  if (o != nullptr && o->decReferenceCountWithoutDeleting())
448  ContainerDeletePolicy<ReferencedType>::destroy (o);
449  }
450 };
451 
452 
453 //==============================================================================
455 template <typename Type>
456 bool operator== (const Type* object1, const ReferenceCountedObjectPtr<Type>& object2) noexcept
457 {
458  return object1 == object2.get();
459 }
460 
462 template <typename Type>
463 bool operator!= (const Type* object1, const ReferenceCountedObjectPtr<Type>& object2) noexcept
464 {
465  return object1 != object2.get();
466 }
467 
468 } // namespace juce
ReferencedType * get() const noexcept
bool operator!=(decltype(nullptr)) const noexcept
ReferenceCountedObjectPtr(ReferenceCountedObjectPtr &&other) noexcept
bool operator==(decltype(nullptr)) const noexcept
ReferenceCountedObjectPtr(ReferencedType *refCountedObject) noexcept
ReferenceCountedObjectPtr(ReferencedType &refCountedObject) noexcept
ReferencedType & operator*() const noexcept
ReferenceCountedObjectPtr(const ReferenceCountedObjectPtr< Convertible > &other) noexcept
ReferenceCountedObjectPtr(decltype(nullptr)) noexcept
ReferenceCountedObjectPtr & operator=(const ReferenceCountedObjectPtr &other)
ReferenceCountedObjectPtr(const ReferenceCountedObjectPtr &other) noexcept
ReferenceCountedObject(const ReferenceCountedObject &) noexcept
ReferenceCountedObject(ReferenceCountedObject &&) noexcept
SingleThreadedReferenceCountedObject(SingleThreadedReferenceCountedObject &&)
SingleThreadedReferenceCountedObject(const SingleThreadedReferenceCountedObject &)