1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-23 01:44:22 +00:00

Fixed a cast warning, added some missing move operators to ReferenceCountedArray and URL, and tidied up some internal array code

This commit is contained in:
jules 2017-10-13 14:49:49 +01:00
parent 0093320a06
commit b0cd45329f
4 changed files with 119 additions and 143 deletions

View file

@ -42,7 +42,6 @@ public:
//==============================================================================
/** Creates an empty array. */
ArrayAllocationBase() noexcept
: numAllocated (0)
{
}
@ -51,13 +50,13 @@ public:
{
}
ArrayAllocationBase (ArrayAllocationBase<ElementType, TypeOfCriticalSectionToUse>&& other) noexcept
ArrayAllocationBase (ArrayAllocationBase&& other) noexcept
: elements (static_cast<HeapBlock<ElementType>&&> (other.elements)),
numAllocated (other.numAllocated)
{
}
ArrayAllocationBase& operator= (ArrayAllocationBase<ElementType, TypeOfCriticalSectionToUse>&& other) noexcept
ArrayAllocationBase& operator= (ArrayAllocationBase&& other) noexcept
{
elements = static_cast<HeapBlock<ElementType>&&> (other.elements);
numAllocated = other.numAllocated;
@ -72,7 +71,7 @@ public:
@param numElements the number of elements that are needed
*/
void setAllocatedSize (const int numElements)
void setAllocatedSize (int numElements)
{
if (numAllocated != numElements)
{
@ -93,7 +92,7 @@ public:
@param minNumElements the minimum number of elements that are needed
*/
void ensureAllocatedSize (const int minNumElements)
void ensureAllocatedSize (int minNumElements)
{
if (minNumElements > numAllocated)
setAllocatedSize ((minNumElements + minNumElements / 2 + 8) & ~7);
@ -104,14 +103,14 @@ public:
/** Minimises the amount of storage allocated so that it's no more than
the given number of elements.
*/
void shrinkToNoMoreThan (const int maxNumElements)
void shrinkToNoMoreThan (int maxNumElements)
{
if (maxNumElements < numAllocated)
setAllocatedSize (maxNumElements);
}
/** Swap the contents of two objects. */
void swapWith (ArrayAllocationBase <ElementType, TypeOfCriticalSectionToUse>& other) noexcept
void swapWith (ArrayAllocationBase& other) noexcept
{
elements.swapWith (other.elements);
std::swap (numAllocated, other.numAllocated);
@ -119,7 +118,7 @@ public:
//==============================================================================
HeapBlock<ElementType> elements;
int numAllocated;
int numAllocated = 0;
private:
JUCE_DECLARE_NON_COPYABLE (ArrayAllocationBase)

View file

@ -55,7 +55,6 @@ public:
@see ReferenceCountedObject, Array, OwnedArray
*/
ReferenceCountedArray() noexcept
: numUsed (0)
{
}
@ -63,26 +62,34 @@ public:
ReferenceCountedArray (const ReferenceCountedArray& other) noexcept
{
const ScopedLockType lock (other.getLock());
numUsed = other.size();
numUsed = other.numUsed;
data.setAllocatedSize (numUsed);
memcpy (data.elements, other.getRawDataPointer(), (size_t) numUsed * sizeof (ObjectClass*));
for (int i = numUsed; --i >= 0;)
if (ObjectClass* o = data.elements[i])
for (auto* o : *this)
if (o != nullptr)
o->incReferenceCount();
}
/** Moves from another array */
ReferenceCountedArray (ReferenceCountedArray&& other) noexcept
: data (static_cast<ArrayAllocationBase<ObjectClass*, TypeOfCriticalSectionToUse>&&> (other.data)),
numUsed (other.numUsed)
{
other.numUsed = 0;
}
/** Creates a copy of another array */
template <class OtherObjectClass, class OtherCriticalSection>
ReferenceCountedArray (const ReferenceCountedArray<OtherObjectClass, OtherCriticalSection>& other) noexcept
{
const typename ReferenceCountedArray<OtherObjectClass, OtherCriticalSection>::ScopedLockType lock (other.getLock());
numUsed = other.size();
numUsed = other.numUsed;
data.setAllocatedSize (numUsed);
memcpy (data.elements, other.getRawDataPointer(), numUsed * sizeof (ObjectClass*));
memcpy (data.elements, other.getRawDataPointer(), (size_t) numUsed * sizeof (ObjectClass*));
for (int i = numUsed; --i >= 0;)
if (ObjectClass* o = data.elements[i])
for (auto* o : *this)
if (o != nullptr)
o->incReferenceCount();
}
@ -91,7 +98,8 @@ public:
*/
ReferenceCountedArray& operator= (const ReferenceCountedArray& other) noexcept
{
ReferenceCountedArray otherCopy (other);
releaseAllObjects();
auto otherCopy = other;
swapWith (otherCopy);
return *this;
}
@ -100,13 +108,23 @@ public:
Any existing objects in this array will first be released.
*/
template <class OtherObjectClass>
ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& operator= (const ReferenceCountedArray<OtherObjectClass, TypeOfCriticalSectionToUse>& other) noexcept
ReferenceCountedArray& operator= (const ReferenceCountedArray<OtherObjectClass, TypeOfCriticalSectionToUse>& other) noexcept
{
ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse> otherCopy (other);
auto otherCopy = other;
swapWith (otherCopy);
return *this;
}
/** Moves from another array */
ReferenceCountedArray& operator= (ReferenceCountedArray&& other) noexcept
{
releaseAllObjects();
data = static_cast<ArrayAllocationBase<ObjectClass*, TypeOfCriticalSectionToUse>&&> (other.data);
numUsed = other.numUsed;
other.numUsed = 0;
return *this;
}
/** Destructor.
Any objects in the array will be released, and may be deleted if not referenced from elsewhere.
*/
@ -145,7 +163,7 @@ public:
/** Returns true if the array is empty, false otherwise. */
inline bool isEmpty() const noexcept
{
return size() == 0;
return numUsed == 0;
}
/** Returns a pointer to the object at this index in the array.
@ -156,7 +174,7 @@ public:
@see getUnchecked
*/
inline ObjectClassPtr operator[] (const int index) const noexcept
inline ObjectClassPtr operator[] (int index) const noexcept
{
return getObjectPointer (index);
}
@ -167,7 +185,7 @@ public:
This is a faster and less safe version of operator[] which doesn't check the index passed in, so
it can be used when you're sure the index is always going to be legal.
*/
inline ObjectClassPtr getUnchecked (const int index) const noexcept
inline ObjectClassPtr getUnchecked (int index) const noexcept
{
return getObjectPointerUnchecked (index);
}
@ -180,17 +198,17 @@ public:
@see getUnchecked
*/
inline ObjectClass* getObjectPointer (const int index) const noexcept
inline ObjectClass* getObjectPointer (int index) const noexcept
{
const ScopedLockType lock (getLock());
if (isPositiveAndBelow (index, numUsed))
{
jassert (data.elements != nullptr);
return data.elements [index];
return data.elements[index];
}
return ObjectClassPtr();
return {};
}
/** Returns a raw pointer to the object at this index in the array, without checking
@ -200,7 +218,7 @@ public:
{
const ScopedLockType lock (getLock());
jassert (isPositiveAndBelow (index, numUsed) && data.elements != nullptr);
return data.elements [index];
return data.elements[index];
}
/** Returns a pointer to the first object in the array.
@ -215,10 +233,10 @@ public:
if (numUsed > 0)
{
jassert (data.elements != nullptr);
return data.elements [0];
return data.elements[0];
}
return ObjectClassPtr();
return {};
}
/** Returns a pointer to the last object in the array.
@ -233,10 +251,10 @@ public:
if (numUsed > 0)
{
jassert (data.elements != nullptr);
return data.elements [numUsed - 1];
return data.elements[numUsed - 1];
}
return ObjectClassPtr();
return {};
}
/** Returns a pointer to the actual array data.
@ -271,11 +289,11 @@ public:
@param objectToLookFor the object to look for
@returns the index at which the object was found, or -1 if it's not found
*/
int indexOf (const ObjectClass* const objectToLookFor) const noexcept
int indexOf (const ObjectClass* objectToLookFor) const noexcept
{
const ScopedLockType lock (getLock());
ObjectClass** e = data.elements.get();
ObjectClass** const endPointer = e + numUsed;
auto** e = data.elements.get();
auto** endPointer = e + numUsed;
while (e != endPointer)
{
@ -293,11 +311,11 @@ public:
@param objectToLookFor the object to look for
@returns true if the object is in the array
*/
bool contains (const ObjectClass* const objectToLookFor) const noexcept
bool contains (const ObjectClass* objectToLookFor) const noexcept
{
const ScopedLockType lock (getLock());
ObjectClass** e = data.elements.get();
ObjectClass** const endPointer = e + numUsed;
auto** e = data.elements.get();
auto** endPointer = e + numUsed;
while (e != endPointer)
{
@ -317,12 +335,12 @@ public:
@param newObject the new object to add to the array
@see set, insert, addIfNotAlreadyThere, addSorted, addArray
*/
ObjectClass* add (ObjectClass* const newObject) noexcept
ObjectClass* add (ObjectClass* newObject) noexcept
{
const ScopedLockType lock (getLock());
data.ensureAllocatedSize (numUsed + 1);
jassert (data.elements != nullptr);
data.elements [numUsed++] = newObject;
data.elements[numUsed++] = newObject;
if (newObject != nullptr)
newObject->incReferenceCount();
@ -343,8 +361,7 @@ public:
@param newObject the new object to add to the array
@see add, addSorted, addIfNotAlreadyThere, set
*/
ObjectClass* insert (int indexToInsertAt,
ObjectClass* const newObject) noexcept
ObjectClass* insert (int indexToInsertAt, ObjectClass* newObject) noexcept
{
if (indexToInsertAt < 0)
return add (newObject);
@ -357,8 +374,8 @@ public:
data.ensureAllocatedSize (numUsed + 1);
jassert (data.elements != nullptr);
ObjectClass** const e = data.elements + indexToInsertAt;
const int numToMove = numUsed - indexToInsertAt;
auto** e = data.elements + indexToInsertAt;
auto numToMove = numUsed - indexToInsertAt;
if (numToMove > 0)
memmove (e + 1, e, sizeof (ObjectClass*) * (size_t) numToMove);
@ -369,7 +386,6 @@ public:
newObject->incReferenceCount();
++numUsed;
return newObject;
}
@ -381,7 +397,7 @@ public:
@param newObject the new object to add to the array
@returns true if the object has been added, false otherwise
*/
bool addIfNotAlreadyThere (ObjectClass* const newObject) noexcept
bool addIfNotAlreadyThere (ObjectClass* newObject) noexcept
{
const ScopedLockType lock (getLock());
@ -404,8 +420,7 @@ public:
@param newObject the new value to set for this index.
@see add, insert, remove
*/
void set (const int indexToChange,
ObjectClass* const newObject)
void set (int indexToChange, ObjectClass* newObject)
{
if (indexToChange >= 0)
{
@ -416,16 +431,14 @@ public:
if (indexToChange < numUsed)
{
if (ObjectClass* o = data.elements [indexToChange])
releaseObject (o);
data.elements [indexToChange] = newObject;
releaseObject (data.elements[indexToChange]);
data.elements[indexToChange] = newObject;
}
else
{
data.ensureAllocatedSize (numUsed + 1);
jassert (data.elements != nullptr);
data.elements [numUsed++] = newObject;
data.elements[numUsed++] = newObject;
}
}
}
@ -439,7 +452,7 @@ public:
all available elements will be copied.
@see add
*/
void addArray (const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& arrayToAddFrom,
void addArray (const ReferenceCountedArray& arrayToAddFrom,
int startIndex = 0,
int numElementsToAdd = -1) noexcept
{
@ -483,7 +496,7 @@ public:
int addSorted (ElementComparator& comparator, ObjectClass* newObject) noexcept
{
const ScopedLockType lock (getLock());
const int index = findInsertIndexInSortedArray (comparator, data.elements.get(), newObject, 0, numUsed);
auto index = findInsertIndexInSortedArray (comparator, data.elements.get(), newObject, 0, numUsed);
insert (index, newObject);
return index;
}
@ -494,13 +507,12 @@ public:
replaced by the new one, rather than the new one being added as well.
*/
template <class ElementComparator>
void addOrReplaceSorted (ElementComparator& comparator,
ObjectClass* newObject) noexcept
void addOrReplaceSorted (ElementComparator& comparator, ObjectClass* newObject) noexcept
{
const ScopedLockType lock (getLock());
const int index = findInsertIndexInSortedArray (comparator, data.elements.get(), newObject, 0, numUsed);
auto index = findInsertIndexInSortedArray (comparator, data.elements.get(), newObject, 0, numUsed);
if (index > 0 && comparator.compareElements (newObject, data.elements [index - 1]) == 0)
if (index > 0 && comparator.compareElements (newObject, data.elements[index - 1]) == 0)
set (index - 1, newObject); // replace an existing object that matches
else
insert (index, newObject); // no match, so insert the new one
@ -520,7 +532,7 @@ public:
*/
template <class ElementComparator>
int indexOfSorted (ElementComparator& comparator,
const ObjectClass* const objectToLookFor) const noexcept
const ObjectClass* objectToLookFor) const noexcept
{
ignoreUnused (comparator);
const ScopedLockType lock (getLock());
@ -528,14 +540,15 @@ public:
while (s < e)
{
if (comparator.compareElements (objectToLookFor, data.elements [s]) == 0)
if (comparator.compareElements (objectToLookFor, data.elements[s]) == 0)
return s;
const int halfway = (s + e) / 2;
auto halfway = (s + e) / 2;
if (halfway == s)
break;
if (comparator.compareElements (objectToLookFor, data.elements [halfway]) >= 0)
if (comparator.compareElements (objectToLookFor, data.elements[halfway]) >= 0)
s = halfway;
else
e = halfway;
@ -558,19 +571,16 @@ public:
@param indexToRemove the index of the element to remove
@see removeObject, removeRange
*/
void remove (const int indexToRemove)
void remove (int indexToRemove)
{
const ScopedLockType lock (getLock());
if (isPositiveAndBelow (indexToRemove, numUsed))
{
ObjectClass** const e = data.elements + indexToRemove;
if (ObjectClass* o = *e)
releaseObject (o);
auto** e = data.elements + indexToRemove;
releaseObject (*e);
--numUsed;
const int numberToShift = numUsed - indexToRemove;
auto numberToShift = numUsed - indexToRemove;
if (numberToShift > 0)
memmove (e, e + 1, sizeof (ObjectClass*) * (size_t) numberToShift);
@ -589,23 +599,18 @@ public:
@param indexToRemove the index of the element to remove
@see remove, removeObject, removeRange
*/
ObjectClassPtr removeAndReturn (const int indexToRemove)
ObjectClassPtr removeAndReturn (int indexToRemove)
{
ObjectClassPtr removedItem;
const ScopedLockType lock (getLock());
if (isPositiveAndBelow (indexToRemove, numUsed))
{
ObjectClass** const e = data.elements + indexToRemove;
if (ObjectClass* o = *e)
{
removedItem = o;
releaseObject (o);
}
auto** e = data.elements + indexToRemove;
removedItem = *e;
releaseObject (*e);
--numUsed;
const int numberToShift = numUsed - indexToRemove;
auto numberToShift = numUsed - indexToRemove;
if (numberToShift > 0)
memmove (e, e + 1, sizeof (ObjectClass*) * (size_t) numberToShift);
@ -625,7 +630,7 @@ public:
@param objectToRemove the object to try to remove
@see remove, removeRange
*/
void removeObject (ObjectClass* const objectToRemove)
void removeObject (ObjectClass* objectToRemove)
{
const ScopedLockType lock (getLock());
remove (indexOf (objectToRemove));
@ -646,34 +651,30 @@ public:
@param numberToRemove how many objects should be removed
@see remove, removeObject
*/
void removeRange (const int startIndex,
const int numberToRemove)
void removeRange (int startIndex,
int numberToRemove)
{
const ScopedLockType lock (getLock());
const int start = jlimit (0, numUsed, startIndex);
const int endIndex = jlimit (0, numUsed, startIndex + numberToRemove);
auto start = jlimit (0, numUsed, startIndex);
auto endIndex = jlimit (0, numUsed, startIndex + numberToRemove);
if (endIndex > start)
{
int i;
for (i = start; i < endIndex; ++i)
for (int i = start; i < endIndex; ++i)
{
if (ObjectClass* o = data.elements[i])
{
releaseObject (o);
data.elements[i] = nullptr; // (in case one of the destructors accesses this array and hits a dangling pointer)
}
releaseObject (data.elements[i]);
data.elements[i] = nullptr; // (in case one of the destructors accesses this array and hits a dangling pointer)
}
const int rangeSize = endIndex - start;
ObjectClass** e = data.elements + start;
i = numUsed - endIndex;
auto rangeSize = endIndex - start;
auto** e = data.elements + start;
int i = numUsed - endIndex;
numUsed -= rangeSize;
while (--i >= 0)
{
*e = e [rangeSize];
*e = e[rangeSize];
++e;
}
@ -706,16 +707,15 @@ public:
If either of the indexes passed in is out-of-range, nothing will happen,
otherwise the two objects at these positions will be exchanged.
*/
void swap (const int index1,
const int index2) noexcept
void swap (int index1, int index2) noexcept
{
const ScopedLockType lock (getLock());
if (isPositiveAndBelow (index1, numUsed)
&& isPositiveAndBelow (index2, numUsed))
{
std::swap (data.elements [index1],
data.elements [index2]);
std::swap (data.elements[index1],
data.elements[index2]);
}
}
@ -732,8 +732,7 @@ public:
@param newIndex the index at which you'd like this object to end up. If this
is less than zero, it will be moved to the end of the array
*/
void move (const int currentIndex,
int newIndex) noexcept
void move (int currentIndex, int newIndex) noexcept
{
if (currentIndex != newIndex)
{
@ -744,7 +743,7 @@ public:
if (! isPositiveAndBelow (newIndex, numUsed))
newIndex = numUsed - 1;
ObjectClass* const value = data.elements [currentIndex];
auto* value = data.elements[currentIndex];
if (newIndex > currentIndex)
{
@ -759,7 +758,7 @@ public:
sizeof (ObjectClass*) * (size_t) (currentIndex - newIndex));
}
data.elements [newIndex] = value;
data.elements[newIndex] = value;
}
}
}
@ -793,7 +792,7 @@ public:
return false;
for (int i = numUsed; --i >= 0;)
if (data.elements [i] != other.data.elements [i])
if (data.elements[i] != other.data.elements[i])
return false;
return true;
@ -837,7 +836,7 @@ public:
*/
template <class ElementComparator>
void sort (ElementComparator& comparator,
const bool retainOrderOfEquivalentItems = false) const noexcept
bool retainOrderOfEquivalentItems = false) const noexcept
{
ignoreUnused (comparator); // if you pass in an object with a static compareElements() method, this
// avoids getting warning messages about the parameter being unused
@ -891,21 +890,20 @@ public:
private:
//==============================================================================
ArrayAllocationBase <ObjectClass*, TypeOfCriticalSectionToUse> data;
int numUsed;
ArrayAllocationBase<ObjectClass*, TypeOfCriticalSectionToUse> data;
int numUsed = 0;
void releaseAllObjects()
{
while (numUsed > 0)
if (ObjectClass* o = data.elements [--numUsed])
releaseObject (o);
releaseObject (data.elements[--numUsed]);
jassert (numUsed == 0);
}
static void releaseObject (ObjectClass* o)
{
if (o->decReferenceCountWithoutDeleting())
if (o != nullptr && o->decReferenceCountWithoutDeleting())
ContainerDeletePolicy<ObjectClass>::destroy (o);
}
};

View file

@ -134,7 +134,7 @@ URL::DownloadTask::DownloadTask() {}
URL::DownloadTask::~DownloadTask() {}
//==============================================================================
URL::URL()
URL::URL() noexcept
{
}
@ -175,26 +175,6 @@ URL URL::createWithoutParsing (const String& u)
return URL (u, 0);
}
URL::URL (const URL& other)
: url (other.url),
postData (other.postData),
parameterNames (other.parameterNames),
parameterValues (other.parameterValues),
filesToUpload (other.filesToUpload)
{
}
URL& URL::operator= (const URL& other)
{
url = other.url;
postData = other.postData;
parameterNames = other.parameterNames;
parameterValues = other.parameterValues;
filesToUpload = other.filesToUpload;
return *this;
}
bool URL::operator== (const URL& other) const
{
return url == other.url
@ -301,19 +281,19 @@ bool URL::isWellFormed() const
String URL::getDomain() const
{
const int start = URLHelpers::findStartOfNetLocation (url);
const int end1 = url.indexOfChar (start, '/');
const int end2 = url.indexOfChar (start, ':');
auto start = URLHelpers::findStartOfNetLocation (url);
auto end1 = url.indexOfChar (start, '/');
auto end2 = url.indexOfChar (start, ':');
const int end = (end1 < 0 && end2 < 0) ? std::numeric_limits<int>::max()
: ((end1 < 0 || end2 < 0) ? jmax (end1, end2)
: jmin (end1, end2));
auto end = (end1 < 0 && end2 < 0) ? std::numeric_limits<int>::max()
: ((end1 < 0 || end2 < 0) ? jmax (end1, end2)
: jmin (end1, end2));
return url.substring (start, end);
}
String URL::getSubPath() const
{
const int startOfPath = URLHelpers::findStartOfPath (url);
auto startOfPath = URLHelpers::findStartOfPath (url);
return startOfPath <= 0 ? String()
: url.substring (startOfPath);

View file

@ -37,7 +37,7 @@ class JUCE_API URL
public:
//==============================================================================
/** Creates an empty URL. */
URL();
URL() noexcept;
/** Creates a URL from a string.
This will parse any embedded parameters after a '?' character and store them
@ -46,15 +46,14 @@ public:
*/
URL (const String& url);
/** Creates a copy of another URL. */
URL (const URL&);
URL (const URL&) = default;
URL (URL&&) = default;
URL& operator= (const URL&) = default;
URL& operator= (URL&&) = default;
/** Destructor. */
~URL();
/** Copies this URL from another one. */
URL& operator= (const URL&);
/** Compares two URLs.
All aspects of the URLs must be identical for them to match, including any parameters,
upload files, etc.