52template <
typename ElementType,
53 typename TypeOfCriticalSectionToUse = DummyCriticalSection,
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, otherElements...);
119 template <
typename... OtherElements>
120 Array (ElementType&& firstNewElement, OtherElements... otherElements)
122 values.add (std::move (firstNewElement), 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 (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 (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, otherElements...);
443 template <
typename... OtherElements>
444 void add (ElementType&& firstNewElement, OtherElements... otherElements)
447 values.add (std::move (firstNewElement), 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 typename std::enable_if<! std::is_pointer<OtherArrayType>::value,
void>::type
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
732 ignoreUnused (comparator);
737 for (
int s = 0, e = values.size();;)
742 if (comparator.compareElements (elementToLookFor, values[s]) == 0)
745 auto halfway = (s + e) / 2;
750 if (comparator.compareElements (elementToLookFor, values[halfway]) >= 0)
771 if (isPositiveAndBelow (indexToRemove, values.size()))
772 removeInternal (indexToRemove);
789 if (isPositiveAndBelow (indexToRemove, values.size()))
791 ElementType removed (values[indexToRemove]);
792 removeInternal (indexToRemove);
796 return ElementType();
809 void remove (
const ElementType* elementToRemove)
811 jassert (elementToRemove !=
nullptr);
814 jassert (values.begin() !=
nullptr);
815 auto indexToRemove = (int) (elementToRemove - values.begin());
817 if (! isPositiveAndBelow (indexToRemove, values.size()))
823 removeInternal (indexToRemove);
837 auto* e = values.begin();
839 for (
int i = 0; i < values.size(); ++i)
841 if (valueToRemove == e[i])
863 for (
int i = values.size(); --i >= 0;)
865 if (valueToRemove == values[i])
886 template <
typename PredicateType>
892 for (
int i = values.size(); --i >= 0;)
894 if (predicate (values[i]))
920 auto endIndex = jlimit (0, values.size(), startIndex + numberToRemove);
921 startIndex = jlimit (0, values.size(), startIndex);
922 numberToRemove = endIndex - startIndex;
924 if (numberToRemove > 0)
926 values.removeElements (startIndex, numberToRemove);
927 minimiseStorageAfterRemoval();
938 jassert (howManyToRemove >= 0);
940 if (howManyToRemove > 0)
944 if (howManyToRemove > values.size())
945 howManyToRemove = values.size();
947 values.removeElements (values.size() - howManyToRemove, howManyToRemove);
948 minimiseStorageAfterRemoval();
957 template <
class OtherArrayType>
960 const typename OtherArrayType::ScopedLockType lock1 (otherArray.getLock());
963 if (
this == &otherArray)
969 if (otherArray.size() > 0)
971 for (
int i = values.size(); --i >= 0;)
972 if (otherArray.contains (values[i]))
985 template <
class OtherArrayType>
988 const typename OtherArrayType::ScopedLockType lock1 (otherArray.getLock());
991 if (
this != &otherArray)
993 if (otherArray.size() <= 0)
999 for (
int i = values.size(); --i >= 0;)
1000 if (! otherArray.contains (values[i]))
1017 values.swap (index1, index2);
1034 void move (
int currentIndex,
int newIndex)
noexcept
1036 if (currentIndex != newIndex)
1039 values.move (currentIndex, newIndex);
1053 values.shrinkToNoMoreThan (values.size());
1065 values.ensureAllocatedSize (minNumElements);
1105 template <
class ElementComparator>
1106 void sort (ElementComparator& comparator,
1107 bool retainOrderOfEquivalentItems =
false)
1110 ignoreUnused (comparator);
1112 sortArray (comparator, values.begin(), 0,
size() - 1, retainOrderOfEquivalentItems);
1120 inline const TypeOfCriticalSectionToUse&
getLock() const noexcept {
return values; }
1130 JUCE_DEPRECATED_WITH_BODY (
void swapWithArray (
Array& other)
noexcept, {
swapWith (other); })
1135 ArrayBase<ElementType, TypeOfCriticalSectionToUse> values;
1137 void removeInternal (
int indexToRemove)
1139 values.removeElements (indexToRemove, 1);
1140 minimiseStorageAfterRemoval();
1143 void minimiseStorageAfterRemoval()
1145 if (values.capacity() > jmax (minimumAllocatedSize, values.size() * 2))
1146 values.shrinkToNoMoreThan (jmax (values.size(), jmax (minimumAllocatedSize, 64 / (
int)
sizeof (ElementType))));
int removeIf(PredicateType &&predicate)
Array(ElementType &&firstNewElement, OtherElements... otherElements)
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)
void ensureStorageAllocated(int minNumElements)
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
void 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 add(const ElementType &firstNewElement, OtherElements... otherElements)
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)
ElementType removeAndReturn(int indexToRemove)
Array(const ElementType &firstNewElement, OtherElements... otherElements)
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 sort(ElementComparator &comparator, bool retainOrderOfEquivalentItems=false)
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 removeValuesNotIn(const OtherArrayType &otherArray)
std::enable_if<!std::is_pointer< OtherArrayType >::value, void >::type addArray(const OtherArrayType &arrayToAddFrom, int startIndex, int numElementsToAdd=-1)
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
void add(ElementType &&firstNewElement, OtherElements... otherElements)
const ElementType * getRawDataPointer() const noexcept