52template <
typename ElementType,
54 int minimumAllocatedSize = 0>
58 using ParameterType =
typename TypeHelpers::ParameterType<ElementType>::type;
71 values.addArray (other.values.begin(), other.values.size());
75 : values (std::move (other.values))
82 template <
typename TypeToCreateFrom>
85 while (*values != TypeToCreateFrom())
93 template <
typename TypeToCreateFrom>
96 values.addArray (
data, numValues);
100 Array (
const ElementType& singleElementToAdd)
102 add (singleElementToAdd);
106 Array (ElementType&& singleElementToAdd)
108 add (std::move (singleElementToAdd));
112 template <
typename... OtherElements>
113 Array (
const ElementType& firstNewElement, OtherElements&&... otherElements)
115 values.add (firstNewElement, std::forward<OtherElements> (otherElements)...);
119 template <
typename... OtherElements>
120 Array (ElementType&& firstNewElement, OtherElements&&... otherElements)
122 values.add (std::move (firstNewElement), std::forward<OtherElements> (otherElements)...);
125 template <
typename TypeToCreateFrom>
126 Array (
const std::initializer_list<TypeToCreateFrom>& items)
141 auto otherCopy (other);
151 values = std::move (other.values);
161 template <
class OtherArrayType>
165 const typename OtherArrayType::ScopedLockType lock2 (other.getLock());
166 return values == other;
174 template <
class OtherArrayType>
192 values.setAllocatedSize (0);
205 void fill (
const ParameterType& newValue)
noexcept
209 for (
auto& e : *
this)
215 inline int size() const noexcept
218 return values.size();
240 return values.getValueWithDefault (index);
255 return values[index];
270 return values[index];
284 return values[index];
293 return values.getFirst();
303 return values.getLast();
312 return values.begin();
321 return values.begin();
328 inline ElementType*
begin() noexcept
330 return values.begin();
336 inline const ElementType*
begin() const noexcept
338 return values.begin();
344 inline ElementType*
end() noexcept
352 inline const ElementType*
end() const noexcept
360 inline ElementType*
data() noexcept
368 inline const ElementType*
data() const noexcept
382 int indexOf (ParameterType elementToLookFor)
const
385 auto e = values.begin();
386 auto endPtr = values.end();
388 for (; e != endPtr; ++e)
389 if (exactlyEqual (elementToLookFor, *e))
390 return static_cast<int> (e - values.begin());
400 bool contains (ParameterType elementToLookFor)
const
403 auto e = values.begin();
404 auto endPtr = values.end();
406 for (; e != endPtr; ++e)
407 if (exactlyEqual (elementToLookFor, *e))
418 void add (
const ElementType& newElement)
421 values.add (newElement);
428 void add (ElementType&& newElement)
431 values.add (std::move (newElement));
435 template <
typename... OtherElements>
436 void add (
const ElementType& firstNewElement, OtherElements&&... otherElements)
439 values.add (firstNewElement, std::forward<OtherElements> (otherElements)...);
443 template <
typename... OtherElements>
444 void add (ElementType&& firstNewElement, OtherElements&&... otherElements)
447 values.add (std::move (firstNewElement), std::forward<OtherElements> (otherElements)...);
462 void insert (
int indexToInsertAt, ParameterType newElement)
465 values.insert (indexToInsertAt, newElement, 1);
481 int numberOfTimesToInsertIt)
483 if (numberOfTimesToInsertIt > 0)
486 values.insert (indexToInsertAt, newElement, numberOfTimesToInsertIt);
503 const ElementType* newElements,
504 int numberOfElements)
506 if (numberOfElements > 0)
509 values.insertArray (indexToInsertAt, newElements, numberOfElements);
542 void set (
int indexToChange, ParameterType newValue)
544 if (indexToChange >= 0)
548 if (indexToChange < values.size())
549 values[indexToChange] = newValue;
551 values.add (newValue);
571 jassert (isPositiveAndBelow (indexToChange, values.size()));
572 values[indexToChange] = newValue;
582 template <
typename Type>
583 void addArray (
const Type* elementsToAdd,
int numElementsToAdd)
587 if (numElementsToAdd > 0)
588 values.addArray (elementsToAdd, numElementsToAdd);
591 template <
typename TypeToCreateFrom>
592 void addArray (
const std::initializer_list<TypeToCreateFrom>& items)
595 values.addArray (items);
604 template <
typename Type>
609 for (
auto e = elementsToAdd; *e !=
nullptr; ++e)
620 template <
class OtherArrayType>
621 void swapWith (OtherArrayType& otherArray)
noexcept
624 const typename OtherArrayType::ScopedLockType lock2 (otherArray.getLock());
625 values.swapWith (otherArray.values);
633 template <
class OtherArrayType>
634 void addArray (
const OtherArrayType& arrayToAddFrom)
636 const typename OtherArrayType::ScopedLockType lock1 (arrayToAddFrom.getLock());
639 values.addArray (arrayToAddFrom);
651 template <
class OtherArrayType>
652 std::enable_if_t<! std::is_pointer_v<OtherArrayType>,
void>
655 int numElementsToAdd = -1)
657 const typename OtherArrayType::ScopedLockType lock1 (arrayToAddFrom.getLock());
660 values.addArray (arrayToAddFrom, startIndex, numElementsToAdd);
672 jassert (targetNumItems >= 0);
673 auto numToAdd = targetNumItems - values.size();
677 else if (numToAdd < 0)
693 template <
class ElementComparator>
694 int addSorted (ElementComparator& comparator, ParameterType newElement)
697 auto index = findInsertIndexInSortedArray (comparator, values.begin(), newElement, 0, values.size());
698 insert (index, newElement);
713 DefaultElementComparator <ElementType> comparator;
729 template <
typename ElementComparator,
typename TargetValueType>
730 int indexOfSorted (ElementComparator& comparator, TargetValueType elementToLookFor)
const;
746 if (isPositiveAndBelow (indexToRemove, values.size()))
747 removeInternal (indexToRemove);
764 if (isPositiveAndBelow (indexToRemove, values.size()))
766 ElementType removed (values[indexToRemove]);
767 removeInternal (indexToRemove);
771 return ElementType();
784 void remove (
const ElementType* elementToRemove)
786 jassert (elementToRemove !=
nullptr);
789 jassert (values.begin() !=
nullptr);
790 auto indexToRemove = (int) (elementToRemove - values.begin());
792 if (! isPositiveAndBelow (indexToRemove, values.size()))
798 removeInternal (indexToRemove);
813 auto* e = values.begin();
815 for (
int i = 0; i < values.size(); ++i)
817 if (valueToRemove == e[i])
841 for (
int i = values.size(); --i >= 0;)
843 if (valueToRemove == values[i])
864 template <
typename PredicateType>
870 for (
int i = values.size(); --i >= 0;)
872 if (predicate (values[i]))
898 auto endIndex = jlimit (0, values.size(), startIndex + numberToRemove);
899 startIndex = jlimit (0, values.size(), startIndex);
900 numberToRemove = endIndex - startIndex;
902 if (numberToRemove > 0)
904 values.removeElements (startIndex, numberToRemove);
905 minimiseStorageAfterRemoval();
916 jassert (howManyToRemove >= 0);
918 if (howManyToRemove > 0)
922 if (howManyToRemove > values.size())
923 howManyToRemove = values.size();
925 values.removeElements (values.size() - howManyToRemove, howManyToRemove);
926 minimiseStorageAfterRemoval();
935 template <
class OtherArrayType>
938 const typename OtherArrayType::ScopedLockType lock1 (otherArray.getLock());
941 if (
this == &otherArray)
947 if (otherArray.size() > 0)
949 for (
int i = values.size(); --i >= 0;)
950 if (otherArray.contains (values[i]))
963 template <
class OtherArrayType>
966 const typename OtherArrayType::ScopedLockType lock1 (otherArray.getLock());
969 if (
this != &otherArray)
971 if (otherArray.size() <= 0)
977 for (
int i = values.size(); --i >= 0;)
978 if (! otherArray.contains (values[i]))
992 void swap (
int index1,
int index2)
995 values.swap (index1, index2);
1012 void move (
int currentIndex,
int newIndex)
noexcept
1014 if (currentIndex != newIndex)
1017 values.move (currentIndex, newIndex);
1031 values.shrinkToNoMoreThan (values.size());
1043 values.ensureAllocatedSize (minNumElements);
1083 template <
class ElementComparator>
1084 void sort (ElementComparator& comparator,
bool retainOrderOfEquivalentItems =
false);
1091 inline const TypeOfCriticalSectionToUse&
getLock() const noexcept {
return values; }
1099 [[deprecated (
"This method has been replaced by a more flexible templated version and renamed "
1100 "to swapWith to be more consistent with the names used in other classes.")]]
1101 void swapWithArray (
Array& other)
noexcept {
swapWith (other); }
1108 void removeInternal (
int indexToRemove)
1110 values.removeElements (indexToRemove, 1);
1111 minimiseStorageAfterRemoval();
1114 void minimiseStorageAfterRemoval()
1116 if (values.capacity() > jmax (minimumAllocatedSize, values.size() * 2))
1117 values.shrinkToNoMoreThan (jmax (values.size(), jmax (minimumAllocatedSize, 64 / (
int)
sizeof (ElementType))));
1122template <
typename ElementType,
typename TypeOfCriticalSectionToUse,
int minimumAllocatedSize>
1123template <
typename ElementComparator,
typename TargetValueType>
1125 [[maybe_unused]] ElementComparator& comparator,
1126 TargetValueType elementToLookFor)
const
1130 for (
int s = 0, e = values.size();;)
1135 if (comparator.compareElements (elementToLookFor, values[s]) == 0)
1138 auto halfway = (s + e) / 2;
1143 if (comparator.compareElements (elementToLookFor, values[halfway]) >= 0)
1150template <
typename ElementType,
typename TypeOfCriticalSectionToUse,
int minimumAllocatedSize>
1151template <
class ElementComparator>
1153 [[maybe_unused]] ElementComparator& comparator,
1154 bool retainOrderOfEquivalentItems)
1157 sortArray (comparator, values.begin(), 0,
size() - 1, retainOrderOfEquivalentItems);
int removeIf(PredicateType &&predicate)
bool operator==(const OtherArrayType &other) const
void swapWith(OtherArrayType &otherArray) noexcept
void add(ElementType &&newElement)
void setUnchecked(int indexToChange, ParameterType newValue)
bool operator!=(const OtherArrayType &other) const
typename TypeOfCriticalSectionToUse::ScopedLockType ScopedLockType
void addNullTerminatedArray(const Type *const *elementsToAdd)
ElementType getUnchecked(int index) const
void insertArray(int indexToInsertAt, const ElementType *newElements, int numberOfElements)
bool isEmpty() const noexcept
void removeLast(int howManyToRemove=1)
Array(const ElementType &firstNewElement, OtherElements &&... otherElements)
void ensureStorageAllocated(int minNumElements)
std::enable_if_t<! std::is_pointer_v< OtherArrayType >, void > addArray(const OtherArrayType &arrayToAddFrom, int startIndex, int numElementsToAdd=-1)
void remove(const ElementType *elementToRemove)
const TypeOfCriticalSectionToUse & getLock() const noexcept
void addArray(const Type *elementsToAdd, int numElementsToAdd)
Array(const TypeToCreateFrom *data)
int removeAllInstancesOf(ParameterType valueToRemove)
Array(const TypeToCreateFrom *data, int numValues)
int size() const noexcept
int removeFirstMatchingValue(ParameterType valueToRemove)
void fill(const ParameterType &newValue) noexcept
void removeRange(int startIndex, int numberToRemove)
void removeValuesIn(const OtherArrayType &otherArray)
const ElementType * end() const noexcept
void remove(int indexToRemove)
void insert(int indexToInsertAt, ParameterType newElement)
int indexOfSorted(ElementComparator &comparator, TargetValueType elementToLookFor) const
ElementType getFirst() const noexcept
ElementType * begin() noexcept
ElementType * end() noexcept
ElementType * getRawDataPointer() noexcept
Array(ElementType &&singleElementToAdd)
void addUsingDefaultSort(ParameterType newElement)
int indexOf(ParameterType elementToLookFor) const
void add(const ElementType &newElement)
Array(ElementType &&firstNewElement, OtherElements &&... otherElements)
ElementType removeAndReturn(int indexToRemove)
ElementType operator[](int index) const
Array(const ElementType &singleElementToAdd)
void set(int indexToChange, ParameterType newValue)
int addSorted(ElementComparator &comparator, ParameterType newElement)
bool contains(ParameterType elementToLookFor) const
void insertMultiple(int indexToInsertAt, ParameterType newElement, int numberOfTimesToInsertIt)
void add(ElementType &&firstNewElement, OtherElements &&... otherElements)
const ElementType * data() const noexcept
void resize(int targetNumItems)
void move(int currentIndex, int newIndex) noexcept
void swap(int index1, int index2)
ElementType * data() noexcept
void add(const ElementType &firstNewElement, OtherElements &&... otherElements)
void removeValuesNotIn(const OtherArrayType &otherArray)
const ElementType * begin() const noexcept
const ElementType & getReference(int index) const noexcept
bool addIfNotAlreadyThere(ParameterType newElement)
Array(const Array &other)
void minimiseStorageOverheads()
void addArray(const OtherArrayType &arrayToAddFrom)
Array & operator=(const Array &other)
ElementType & getReference(int index) noexcept
ElementType getLast() const noexcept
const ElementType * getRawDataPointer() const noexcept