upgrade to JUCE 5.4.3. Remove (probably) unused JUCE modules. Remove VST2 target (it's been end-of-life'd by Steinberg and by JUCE)
This commit is contained in:
@ -40,10 +40,10 @@ namespace juce
|
||||
template <typename Type>
|
||||
struct Atomic final
|
||||
{
|
||||
typedef typename AtomicHelpers::DiffTypeHelper<Type>::Type DiffType;
|
||||
using DiffType = typename AtomicHelpers::DiffTypeHelper<Type>::Type;
|
||||
|
||||
/** Creates a new value, initialised to zero. */
|
||||
Atomic() noexcept : value (0) {}
|
||||
Atomic() noexcept : value (Type()) {}
|
||||
|
||||
/** Creates a new value, with a given initial value. */
|
||||
Atomic (Type initialValue) noexcept : value (initialValue) {}
|
||||
|
@ -85,6 +85,11 @@ namespace HeapBlockHelper
|
||||
template <class ElementType, bool throwOnFailure = false>
|
||||
class HeapBlock
|
||||
{
|
||||
private:
|
||||
template <class OtherElementType>
|
||||
using AllowConversion = typename std::enable_if<std::is_base_of<typename std::remove_pointer<ElementType>::type,
|
||||
typename std::remove_pointer<OtherElementType>::type>::value>::type;
|
||||
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a HeapBlock which is initially just a null pointer.
|
||||
@ -92,9 +97,7 @@ public:
|
||||
After creation, you can resize the array using the malloc(), calloc(),
|
||||
or realloc() methods.
|
||||
*/
|
||||
HeapBlock() noexcept
|
||||
{
|
||||
}
|
||||
HeapBlock() = default;
|
||||
|
||||
/** Creates a HeapBlock containing a number of elements.
|
||||
|
||||
@ -147,6 +150,30 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Converting move constructor.
|
||||
Only enabled if this is a HeapBlock<Base*> and the other object is a HeapBlock<Derived*>,
|
||||
where std::is_base_of<Base, Derived>::value == true.
|
||||
*/
|
||||
template <class OtherElementType, bool otherThrowOnFailure, typename = AllowConversion<OtherElementType>>
|
||||
HeapBlock (HeapBlock<OtherElementType, otherThrowOnFailure>&& other) noexcept
|
||||
: data (reinterpret_cast<ElementType*> (other.data))
|
||||
{
|
||||
other.data = nullptr;
|
||||
}
|
||||
|
||||
/** Converting move assignment operator.
|
||||
Only enabled if this is a HeapBlock<Base*> and the other object is a HeapBlock<Derived*>,
|
||||
where std::is_base_of<Base, Derived>::value == true.
|
||||
*/
|
||||
template <class OtherElementType, bool otherThrowOnFailure, typename = AllowConversion<OtherElementType>>
|
||||
HeapBlock& operator= (HeapBlock<OtherElementType, otherThrowOnFailure>&& other) noexcept
|
||||
{
|
||||
free();
|
||||
data = reinterpret_cast<ElementType*> (other.data);
|
||||
other.data = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a raw pointer to the allocated data.
|
||||
This may be a null pointer if the data hasn't yet been allocated, or if it has been
|
||||
@ -296,7 +323,7 @@ public:
|
||||
}
|
||||
|
||||
/** This typedef can be used to get the type of the heapblock's elements. */
|
||||
typedef ElementType Type;
|
||||
using Type = ElementType;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
@ -311,6 +338,9 @@ private:
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class OtherElementType, bool otherThrowOnFailure>
|
||||
friend class HeapBlock;
|
||||
|
||||
#if ! (defined (JUCE_DLL) || defined (JUCE_DLL_BUILD))
|
||||
JUCE_DECLARE_NON_COPYABLE (HeapBlock)
|
||||
JUCE_PREVENT_HEAP_ALLOCATION // Creating a 'new HeapBlock' would be missing the point!
|
||||
|
144
modules/juce_core/memory/juce_HeavyweightLeakedObjectDetector.h
Normal file
144
modules/juce_core/memory/juce_HeavyweightLeakedObjectDetector.h
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
This class is a useful way of tracking down hard to find memory leaks when the
|
||||
regular LeakedObjectDetector isn't enough.
|
||||
|
||||
As well as firing when any instances of the OwnerClass type are leaked, it will
|
||||
print out a stack trace showing where the leaked object was created. This is obviously
|
||||
quite a heavyweight task so, unlike the LeakedObjectDetector which should be always
|
||||
be added to your classes, you should only use this object temporarily when you are
|
||||
debugging and remove it when finished.
|
||||
|
||||
To use it, use the JUCE_HEAVYWEIGHT_LEAK_DETECTOR macro as a simple way to put
|
||||
one in your class declaration.
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
template <class OwnerClass>
|
||||
class HeavyweightLeakedObjectDetector
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
HeavyweightLeakedObjectDetector() noexcept { getBacktraceMap().set (this, SystemStats::getStackBacktrace()); }
|
||||
HeavyweightLeakedObjectDetector (const HeavyweightLeakedObjectDetector&) noexcept { getBacktraceMap().set (this, SystemStats::getStackBacktrace()); }
|
||||
|
||||
~HeavyweightLeakedObjectDetector() { getBacktraceMap().remove (this); }
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
typedef HashMap<HeavyweightLeakedObjectDetector<OwnerClass>*, String> BacktraceMap;
|
||||
|
||||
//==============================================================================
|
||||
struct BacktraceMapHolder
|
||||
{
|
||||
BacktraceMapHolder() = default;
|
||||
|
||||
~BacktraceMapHolder()
|
||||
{
|
||||
if (map.size() > 0)
|
||||
{
|
||||
DBG ("*** Leaked objects detected: " << map.size() << " instance(s) of class " << getLeakedObjectClassName());
|
||||
DBG (getFormattedBacktracesString());
|
||||
|
||||
/** If you hit this, then you've leaked one or more objects of the type specified by
|
||||
the 'OwnerClass' template parameter - the name and stack trace of its creation should
|
||||
have been printed by the lines above.
|
||||
|
||||
If you're leaking, it's probably because you're using old-fashioned, non-RAII techniques for
|
||||
your object management. Tut, tut. Always, always use std::unique_ptrs, OwnedArrays,
|
||||
ReferenceCountedObjects, etc, and avoid the 'delete' operator at all costs!
|
||||
*/
|
||||
jassertfalse;
|
||||
}
|
||||
}
|
||||
|
||||
String getFormattedBacktracesString() const
|
||||
{
|
||||
String str;
|
||||
|
||||
int counter = 1;
|
||||
for (typename BacktraceMap::Iterator i (map); i.next();)
|
||||
{
|
||||
str << "\nBacktrace " << String (counter++) << "\n"
|
||||
<< "-----------------------------------------------------------------" << "\n"
|
||||
<< i.getValue();
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
BacktraceMap map;
|
||||
};
|
||||
|
||||
static BacktraceMap& getBacktraceMap()
|
||||
{
|
||||
static BacktraceMapHolder holder;
|
||||
return holder.map;
|
||||
}
|
||||
|
||||
static const char* getLeakedObjectClassName()
|
||||
{
|
||||
return OwnerClass::getLeakedObjectClassName();
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
#if DOXYGEN || ! defined (JUCE_HEAVYWEIGHT_LEAK_DETECTOR)
|
||||
#if (DOXYGEN || JUCE_CHECK_MEMORY_LEAKS)
|
||||
/** This macro lets you embed a heavyweight leak-detecting object inside a class.
|
||||
|
||||
To use it, simply declare a JUCE_HEAVYWEIGHT_LEAK_DETECTOR (YourClassName) inside a private section
|
||||
of the class declaration. E.g.
|
||||
|
||||
@code
|
||||
class MyClass
|
||||
{
|
||||
public:
|
||||
MyClass();
|
||||
void blahBlah();
|
||||
|
||||
private:
|
||||
JUCE_HEAVYWEIGHT_LEAK_DETECTOR (MyClass)
|
||||
};
|
||||
@endcode
|
||||
|
||||
NB: you should only use this when you really need to track down a tricky memory leak, and
|
||||
should never leave one of these inside a class!
|
||||
|
||||
@see HeavyweightLeakedObjectDetector, JUCE_LEAK_DETECTOR, LeakedObjectDetector
|
||||
*/
|
||||
#define JUCE_HEAVYWEIGHT_LEAK_DETECTOR(OwnerClass) \
|
||||
friend class juce::HeavyweightLeakedObjectDetector<OwnerClass>; \
|
||||
static const char* getLeakedObjectClassName() noexcept { return #OwnerClass; } \
|
||||
juce::HeavyweightLeakedObjectDetector<OwnerClass> JUCE_JOIN_MACRO (leakDetector, __LINE__);
|
||||
#else
|
||||
#define JUCE_HEAVYWEIGHT_LEAK_DETECTOR(OwnerClass)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
@ -72,7 +72,7 @@ private:
|
||||
class LeakCounter
|
||||
{
|
||||
public:
|
||||
LeakCounter() noexcept {}
|
||||
LeakCounter() = default;
|
||||
|
||||
~LeakCounter()
|
||||
{
|
||||
|
@ -29,7 +29,7 @@ inline void zeromem (void* memory, size_t numBytes) noexcept { memset (me
|
||||
|
||||
/** Overwrites a structure or object with zeros. */
|
||||
template <typename Type>
|
||||
inline void zerostruct (Type& structure) noexcept { memset (&structure, 0, sizeof (structure)); }
|
||||
inline void zerostruct (Type& structure) noexcept { memset ((void*) &structure, 0, sizeof (structure)); }
|
||||
|
||||
/** Delete an object pointer, and sets the pointer to null.
|
||||
|
||||
@ -44,7 +44,7 @@ inline void deleteAndZero (Type& pointer) { delete poi
|
||||
a specific number of bytes,
|
||||
*/
|
||||
template <typename Type, typename IntegerType>
|
||||
inline Type* addBytesToPointer (Type* basePointer, IntegerType bytes) noexcept { return (Type*) (((char*) basePointer) + bytes); }
|
||||
inline Type* addBytesToPointer (Type* basePointer, IntegerType bytes) noexcept { return (Type*) (const_cast<char*> (reinterpret_cast<const char*> (basePointer)) + bytes); }
|
||||
|
||||
/** A handy function to round up a pointer to the nearest multiple of a given number of bytes.
|
||||
alignmentBytes must be a power of two. */
|
||||
|
@ -81,14 +81,14 @@ MemoryBlock& MemoryBlock::operator= (const MemoryBlock& other)
|
||||
}
|
||||
|
||||
MemoryBlock::MemoryBlock (MemoryBlock&& other) noexcept
|
||||
: data (static_cast<HeapBlockType&&> (other.data)),
|
||||
: data (std::move (other.data)),
|
||||
size (other.size)
|
||||
{
|
||||
}
|
||||
|
||||
MemoryBlock& MemoryBlock::operator= (MemoryBlock&& other) noexcept
|
||||
{
|
||||
data = static_cast<HeapBlockType&&> (other.data);
|
||||
data = std::move (other.data);
|
||||
size = other.size;
|
||||
return *this;
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ namespace juce
|
||||
/**
|
||||
A class to hold a resizable block of raw data.
|
||||
|
||||
|
||||
@tags{Core}
|
||||
*/
|
||||
class JUCE_API MemoryBlock
|
||||
@ -252,7 +251,7 @@ public:
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
typedef HeapBlock<char, true> HeapBlockType;
|
||||
using HeapBlockType = HeapBlock<char, true>;
|
||||
HeapBlockType data;
|
||||
size_t size = 0;
|
||||
|
||||
|
@ -41,7 +41,7 @@ class OptionalScopedPointer
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty OptionalScopedPointer. */
|
||||
OptionalScopedPointer() : shouldDelete (false) {}
|
||||
OptionalScopedPointer() = default;
|
||||
|
||||
/** Creates an OptionalScopedPointer to point to a given object, and specifying whether
|
||||
the OptionalScopedPointer will delete it.
|
||||
@ -177,7 +177,7 @@ public:
|
||||
private:
|
||||
//==============================================================================
|
||||
ScopedPointer<ObjectType> object;
|
||||
bool shouldDelete;
|
||||
bool shouldDelete = false;
|
||||
|
||||
// This is here to avoid people accidentally taking a second owned copy of
|
||||
// a scoped pointer, which is almost certainly not what you intended to do!
|
||||
|
@ -49,7 +49,7 @@ namespace juce
|
||||
Once a new ReferenceCountedObject has been assigned to a pointer, be
|
||||
careful not to delete the object manually.
|
||||
|
||||
This class uses an Atomic<int> value to hold the reference count, so that it
|
||||
This class uses an Atomic<int> value to hold the reference count, so that
|
||||
the pointers can be passed between threads safely. For a faster but non-thread-safe
|
||||
version, use SingleThreadedReferenceCountedObject instead.
|
||||
|
||||
@ -99,7 +99,7 @@ public:
|
||||
protected:
|
||||
//==============================================================================
|
||||
/** Creates the reference-counted object (with an initial ref count of zero). */
|
||||
ReferenceCountedObject() {}
|
||||
ReferenceCountedObject() = default;
|
||||
|
||||
/** Copying from another object does not affect this one's reference-count. */
|
||||
ReferenceCountedObject (const ReferenceCountedObject&) noexcept {}
|
||||
@ -187,7 +187,7 @@ public:
|
||||
protected:
|
||||
//==============================================================================
|
||||
/** Creates the reference-counted object (with an initial ref count of zero). */
|
||||
SingleThreadedReferenceCountedObject() {}
|
||||
SingleThreadedReferenceCountedObject() = default;
|
||||
|
||||
/** Copying from another object does not affect this one's reference-count. */
|
||||
SingleThreadedReferenceCountedObject (const SingleThreadedReferenceCountedObject&) {}
|
||||
@ -246,7 +246,7 @@ public:
|
||||
|
||||
//==============================================================================
|
||||
/** Creates a pointer to a null object. */
|
||||
ReferenceCountedObjectPtr() noexcept {}
|
||||
ReferenceCountedObjectPtr() = default;
|
||||
|
||||
/** Creates a pointer to a null object. */
|
||||
ReferenceCountedObjectPtr (decltype (nullptr)) noexcept {}
|
||||
@ -260,6 +260,15 @@ public:
|
||||
incIfNotNull (refCountedObject);
|
||||
}
|
||||
|
||||
/** Creates a pointer to an object.
|
||||
This will increment the object's reference-count.
|
||||
*/
|
||||
ReferenceCountedObjectPtr (ReferencedType& refCountedObject) noexcept
|
||||
: referencedObject (&refCountedObject)
|
||||
{
|
||||
refCountedObject.incReferenceCount();
|
||||
}
|
||||
|
||||
/** Copies another pointer.
|
||||
This will increment the object's reference-count.
|
||||
*/
|
||||
@ -269,6 +278,13 @@ public:
|
||||
incIfNotNull (referencedObject);
|
||||
}
|
||||
|
||||
/** Takes-over the object from another pointer. */
|
||||
ReferenceCountedObjectPtr (ReferenceCountedObjectPtr&& other) noexcept
|
||||
: referencedObject (other.referencedObject)
|
||||
{
|
||||
other.referencedObject = nullptr;
|
||||
}
|
||||
|
||||
/** Copies another pointer.
|
||||
This will increment the object's reference-count (if it is non-null).
|
||||
*/
|
||||
@ -305,26 +321,40 @@ public:
|
||||
*/
|
||||
ReferenceCountedObjectPtr& operator= (ReferencedType* newObject)
|
||||
{
|
||||
if (referencedObject != newObject)
|
||||
if (newObject != nullptr)
|
||||
return operator= (*newObject);
|
||||
|
||||
reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Changes this pointer to point at a different object.
|
||||
|
||||
The reference count of the old object is decremented, and it might be
|
||||
deleted if it hits zero. The new object's count is incremented.
|
||||
*/
|
||||
ReferenceCountedObjectPtr& operator= (ReferencedType& newObject)
|
||||
{
|
||||
if (referencedObject != &newObject)
|
||||
{
|
||||
incIfNotNull (newObject);
|
||||
newObject.incReferenceCount();
|
||||
auto* oldObject = referencedObject;
|
||||
referencedObject = newObject;
|
||||
referencedObject = &newObject;
|
||||
decIfNotNull (oldObject);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Takes-over the object from another pointer. */
|
||||
ReferenceCountedObjectPtr (ReferenceCountedObjectPtr&& other) noexcept
|
||||
: referencedObject (other.referencedObject)
|
||||
/** Resets this pointer to a null pointer. */
|
||||
ReferenceCountedObjectPtr& operator= (decltype (nullptr))
|
||||
{
|
||||
other.referencedObject = nullptr;
|
||||
reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Takes-over the object from another pointer. */
|
||||
ReferenceCountedObjectPtr& operator= (ReferenceCountedObjectPtr&& other)
|
||||
ReferenceCountedObjectPtr& operator= (ReferenceCountedObjectPtr&& other) noexcept
|
||||
{
|
||||
std::swap (referencedObject, other.referencedObject);
|
||||
return *this;
|
||||
@ -343,17 +373,15 @@ public:
|
||||
/** Returns the object that this pointer references.
|
||||
The pointer returned may be null, of course.
|
||||
*/
|
||||
operator ReferencedType*() const noexcept { return referencedObject; }
|
||||
ReferencedType* get() const noexcept { return referencedObject; }
|
||||
|
||||
/** Returns the object that this pointer references.
|
||||
The pointer returned may be null, of course.
|
||||
*/
|
||||
ReferencedType* get() const noexcept { return referencedObject; }
|
||||
|
||||
/** Returns the object that this pointer references.
|
||||
The pointer returned may be null, of course.
|
||||
*/
|
||||
ReferencedType* getObject() const noexcept { return referencedObject; }
|
||||
/** Resets this object to a null pointer. */
|
||||
void reset() noexcept
|
||||
{
|
||||
auto oldObject = referencedObject; // need to null the pointer before deleting the object
|
||||
referencedObject = nullptr; // in case this ptr is itself deleted as a side-effect
|
||||
decIfNotNull (oldObject); // of the destructor
|
||||
}
|
||||
|
||||
// the -> operator is called on the referenced object
|
||||
ReferencedType* operator->() const noexcept
|
||||
@ -362,6 +390,43 @@ public:
|
||||
return referencedObject;
|
||||
}
|
||||
|
||||
/** Dereferences the object that this pointer references.
|
||||
The pointer returned may be null, of course.
|
||||
*/
|
||||
ReferencedType& operator*() const noexcept { jassert (referencedObject != nullptr); return *referencedObject; }
|
||||
|
||||
/** Checks whether this pointer is null */
|
||||
bool operator== (decltype (nullptr)) const noexcept { return referencedObject == nullptr; }
|
||||
/** Checks whether this pointer is null */
|
||||
bool operator!= (decltype (nullptr)) const noexcept { return referencedObject != nullptr; }
|
||||
|
||||
/** Compares two ReferenceCountedObjectPtrs. */
|
||||
bool operator== (const ObjectType* other) const noexcept { return referencedObject == other; }
|
||||
/** Compares two ReferenceCountedObjectPtrs. */
|
||||
bool operator== (const ReferenceCountedObjectPtr& other) const noexcept { return referencedObject == other.get(); }
|
||||
/** Compares two ReferenceCountedObjectPtrs. */
|
||||
bool operator!= (const ObjectType* other) const noexcept { return referencedObject != other; }
|
||||
/** Compares two ReferenceCountedObjectPtrs. */
|
||||
bool operator!= (const ReferenceCountedObjectPtr& other) const noexcept { return referencedObject != other.get(); }
|
||||
|
||||
#if JUCE_STRICT_REFCOUNTEDPOINTER
|
||||
/** Checks whether this pointer is null */
|
||||
explicit operator bool() const noexcept { return referencedObject != nullptr; }
|
||||
|
||||
#else
|
||||
/** Returns the object that this pointer references.
|
||||
The pointer returned may be null, of course.
|
||||
Note that this methods allows the compiler to be very lenient with what it allows you to do
|
||||
with the pointer, it's safer to disable this by setting JUCE_STRICT_REFCOUNTEDPOINTER=1, which
|
||||
increased type safety and can prevent some common slip-ups.
|
||||
*/
|
||||
operator ReferencedType*() const noexcept { return referencedObject; }
|
||||
#endif
|
||||
|
||||
|
||||
// This old method is deprecated in favour of the shorter and more standard get() method.
|
||||
JUCE_DEPRECATED_WITH_BODY (ReferencedType* getObject() const, { return get(); })
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
ReferencedType* referencedObject = nullptr;
|
||||
@ -382,43 +447,15 @@ private:
|
||||
|
||||
//==============================================================================
|
||||
/** Compares two ReferenceCountedObjectPtrs. */
|
||||
template <typename ObjectType>
|
||||
bool operator== (const ReferenceCountedObjectPtr<ObjectType>& object1, ObjectType* const object2) noexcept
|
||||
{
|
||||
return object1.get() == object2;
|
||||
}
|
||||
|
||||
/** Compares two ReferenceCountedObjectPtrs. */
|
||||
template <typename ObjectType>
|
||||
bool operator== (const ReferenceCountedObjectPtr<ObjectType>& object1, const ReferenceCountedObjectPtr<ObjectType>& object2) noexcept
|
||||
{
|
||||
return object1.get() == object2.get();
|
||||
}
|
||||
|
||||
/** Compares two ReferenceCountedObjectPtrs. */
|
||||
template <typename ObjectType>
|
||||
bool operator== (ObjectType* object1, const ReferenceCountedObjectPtr<ObjectType>& object2) noexcept
|
||||
template <typename Type>
|
||||
bool operator== (const Type* object1, const ReferenceCountedObjectPtr<Type>& object2) noexcept
|
||||
{
|
||||
return object1 == object2.get();
|
||||
}
|
||||
|
||||
/** Compares two ReferenceCountedObjectPtrs. */
|
||||
template <typename ObjectType>
|
||||
bool operator!= (const ReferenceCountedObjectPtr<ObjectType>& object1, const ObjectType* object2) noexcept
|
||||
{
|
||||
return object1.get() != object2;
|
||||
}
|
||||
|
||||
/** Compares two ReferenceCountedObjectPtrs. */
|
||||
template <typename ObjectType>
|
||||
bool operator!= (const ReferenceCountedObjectPtr<ObjectType>& object1, const ReferenceCountedObjectPtr<ObjectType>& object2) noexcept
|
||||
{
|
||||
return object1.get() != object2.get();
|
||||
}
|
||||
|
||||
/** Compares two ReferenceCountedObjectPtrs. */
|
||||
template <typename ObjectType>
|
||||
bool operator!= (ObjectType* object1, const ReferenceCountedObjectPtr<ObjectType>& object2) noexcept
|
||||
template <typename Type>
|
||||
bool operator!= (const Type* object1, const ReferenceCountedObjectPtr<Type>& object2) noexcept
|
||||
{
|
||||
return object1 != object2.get();
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ class ScopedPointer
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a ScopedPointer containing a null pointer. */
|
||||
inline ScopedPointer() noexcept {}
|
||||
inline ScopedPointer() = default;
|
||||
|
||||
/** Creates a ScopedPointer containing a null pointer. */
|
||||
inline ScopedPointer (decltype (nullptr)) noexcept {}
|
||||
@ -149,8 +149,9 @@ public:
|
||||
/** Clears this pointer, deleting the object it points to if there is one. */
|
||||
void reset()
|
||||
{
|
||||
ContainerDeletePolicy<ObjectType>::destroy (object);
|
||||
auto* oldObject = object;
|
||||
object = {};
|
||||
ContainerDeletePolicy<ObjectType>::destroy (oldObject);
|
||||
}
|
||||
|
||||
/** Sets this pointer to a new object, deleting the old object that it was previously pointing to if there was one. */
|
||||
@ -162,6 +163,12 @@ public:
|
||||
object = newObject;
|
||||
ContainerDeletePolicy<ObjectType>::destroy (oldObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
// You're trying to reset this ScopedPointer to itself! This will work here as ScopedPointer does an equality check
|
||||
// but be aware that std::unique_ptr won't do this and you could end up with some nasty, subtle bugs!
|
||||
jassert (newObject == nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets this pointer to a new object, deleting the old object that it was previously pointing to if there was one. */
|
||||
|
@ -39,7 +39,7 @@ namespace juce
|
||||
the underlying object is also immediately destroyed. This allows you to use scoping
|
||||
to manage the lifetime of a shared resource.
|
||||
|
||||
Note: the construction/deletion of the shared object must not involve any
|
||||
Note: The construction/deletion of the shared object must not involve any
|
||||
code that makes recursive calls to a SharedResourcePointer, or you'll cause
|
||||
a deadlock.
|
||||
|
||||
@ -137,7 +137,7 @@ private:
|
||||
|
||||
static SharedObjectHolder& getSharedObjectHolder() noexcept
|
||||
{
|
||||
static void* holder [(sizeof (SharedObjectHolder) + sizeof(void*) - 1) / sizeof(void*)] = { 0 };
|
||||
static void* holder [(sizeof (SharedObjectHolder) + sizeof(void*) - 1) / sizeof(void*)] = { nullptr };
|
||||
return *reinterpret_cast<SharedObjectHolder*> (holder);
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ namespace juce
|
||||
template <typename Type, typename MutexType, bool onlyCreateOncePerRun>
|
||||
struct SingletonHolder : private MutexType // (inherited so we can use the empty-base-class optimisation)
|
||||
{
|
||||
SingletonHolder() noexcept {}
|
||||
SingletonHolder() = default;
|
||||
|
||||
~SingletonHolder()
|
||||
{
|
||||
|
@ -32,18 +32,16 @@ namespace juce
|
||||
It must embed a WeakReference::Master object, which stores a shared pointer object, and must clear
|
||||
this master pointer in its destructor.
|
||||
|
||||
Note that WeakReference is not designed to be thread-safe, so if you're accessing it from
|
||||
different threads, you'll need to do your own locking around all uses of the pointer and
|
||||
the object it refers to.
|
||||
|
||||
E.g.
|
||||
@code
|
||||
class MyObject
|
||||
{
|
||||
public:
|
||||
MyObject()
|
||||
{
|
||||
// If you're planning on using your WeakReferences in a multi-threaded situation, you may choose
|
||||
// to create a WeakReference to the object here in the constructor, which will pre-initialise the
|
||||
// embedded object, avoiding an (extremely unlikely) race condition that could occur if multiple
|
||||
// threads overlap while creating the first WeakReference to it.
|
||||
}
|
||||
MyObject() {}
|
||||
|
||||
~MyObject()
|
||||
{
|
||||
@ -63,12 +61,12 @@ namespace juce
|
||||
|
||||
// Here's an example of using a pointer..
|
||||
|
||||
MyObject* n = new MyObject();
|
||||
auto* n = new MyObject();
|
||||
WeakReference<MyObject> myObjectRef = n;
|
||||
|
||||
MyObject* pointer1 = myObjectRef; // returns a valid pointer to 'n'
|
||||
auto pointer1 = myObjectRef.get(); // returns a valid pointer to 'n'
|
||||
delete n;
|
||||
MyObject* pointer2 = myObjectRef; // returns a null pointer
|
||||
auto pointer2 = myObjectRef.get(); // now returns nullptr
|
||||
@endcode
|
||||
|
||||
@see WeakReference::Master
|
||||
@ -80,7 +78,7 @@ class WeakReference
|
||||
{
|
||||
public:
|
||||
/** Creates a null WeakReference. */
|
||||
inline WeakReference() noexcept {}
|
||||
inline WeakReference() = default;
|
||||
|
||||
/** Creates a WeakReference that points at the given object. */
|
||||
WeakReference (ObjectType* object) : holder (getRef (object)) {}
|
||||
@ -89,7 +87,7 @@ public:
|
||||
WeakReference (const WeakReference& other) noexcept : holder (other.holder) {}
|
||||
|
||||
/** Move constructor */
|
||||
WeakReference (WeakReference&& other) noexcept : holder (static_cast<SharedRef&&> (other.holder)) {}
|
||||
WeakReference (WeakReference&& other) noexcept : holder (std::move (other.holder)) {}
|
||||
|
||||
/** Copies another pointer to this one. */
|
||||
WeakReference& operator= (const WeakReference& other) { holder = other.holder; return *this; }
|
||||
@ -98,7 +96,7 @@ public:
|
||||
WeakReference& operator= (ObjectType* newObject) { holder = getRef (newObject); return *this; }
|
||||
|
||||
/** Move assignment operator */
|
||||
WeakReference& operator= (WeakReference&& other) noexcept { holder = static_cast<SharedRef&&> (other.holder); return *this; }
|
||||
WeakReference& operator= (WeakReference&& other) noexcept { holder = std::move (other.holder); return *this; }
|
||||
|
||||
/** Returns the object that this pointer refers to, or null if the object no longer exists. */
|
||||
ObjectType* get() const noexcept { return holder != nullptr ? holder->get() : nullptr; }
|
||||
@ -143,7 +141,7 @@ public:
|
||||
JUCE_DECLARE_NON_COPYABLE (SharedPointer)
|
||||
};
|
||||
|
||||
typedef ReferenceCountedObjectPtr<SharedPointer> SharedRef;
|
||||
using SharedRef = ReferenceCountedObjectPtr<SharedPointer>;
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
@ -154,7 +152,7 @@ public:
|
||||
class Master
|
||||
{
|
||||
public:
|
||||
Master() noexcept {}
|
||||
Master() = default;
|
||||
|
||||
~Master() noexcept
|
||||
{
|
||||
@ -166,11 +164,11 @@ public:
|
||||
/** The first call to this method will create an internal object that is shared by all weak
|
||||
references to the object.
|
||||
*/
|
||||
SharedPointer* getSharedPointer (ObjectType* object)
|
||||
SharedRef getSharedPointer (ObjectType* object)
|
||||
{
|
||||
if (sharedPointer == nullptr)
|
||||
{
|
||||
sharedPointer = new SharedPointer (object);
|
||||
sharedPointer = *new SharedPointer (object);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -206,9 +204,12 @@ public:
|
||||
private:
|
||||
SharedRef holder;
|
||||
|
||||
static inline SharedPointer* getRef (ObjectType* o)
|
||||
static inline SharedRef getRef (ObjectType* o)
|
||||
{
|
||||
return (o != nullptr) ? o->masterReference.getSharedPointer (o) : nullptr;
|
||||
if (o != nullptr)
|
||||
return o->masterReference.getSharedPointer (o);
|
||||
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
@ -234,9 +235,9 @@ private:
|
||||
@see WeakReference, WeakReference::Master
|
||||
*/
|
||||
#define JUCE_DECLARE_WEAK_REFERENCEABLE(Class) \
|
||||
struct WeakRefMaster : public WeakReference<Class>::Master { ~WeakRefMaster() { this->clear(); } }; \
|
||||
struct WeakRefMaster : public juce::WeakReference<Class>::Master { ~WeakRefMaster() { this->clear(); } }; \
|
||||
WeakRefMaster masterReference; \
|
||||
friend class WeakReference<Class>; \
|
||||
friend class juce::WeakReference<Class>; \
|
||||
|
||||
|
||||
} // namespace juce
|
||||
|
Reference in New Issue
Block a user