56 template <
typename ElementType,
57 typename TypeOfCriticalSectionToUse = DummyCriticalSection,
58 int minimumAllocatedSize = 0>
62 using ParameterType =
typename TypeHelpers::ParameterType<ElementType>::type;
75 values.addArray (other.values.begin(), other.values.size());
79 : values (std::move (other.values))
86 template <
typename TypeToCreateFrom>
89 while (*values != TypeToCreateFrom())
97 template <
typename TypeToCreateFrom>
100 values.addArray (
data, numValues);
104 Array (
const ElementType& singleElementToAdd)
106 add (singleElementToAdd);
110 Array (ElementType&& singleElementToAdd)
112 add (std::move (singleElementToAdd));
116 template <
typename... OtherElements>
117 Array (
const ElementType& firstNewElement, OtherElements... otherElements)
119 values.add (firstNewElement, otherElements...);
123 template <
typename... OtherElements>
124 Array (ElementType&& firstNewElement, OtherElements... otherElements)
126 values.add (std::move (firstNewElement), otherElements...);
129 template <
typename TypeToCreateFrom>
130 Array (
const std::initializer_list<TypeToCreateFrom>& items)
145 auto otherCopy (other);
155 values = std::move (other.values);
165 template <
class OtherArrayType>
169 const typename OtherArrayType::ScopedLockType lock2 (other.getLock());
170 return values == other;
178 template <
class OtherArrayType>
196 values.setAllocatedSize (0);
209 void fill (
const ParameterType& newValue) noexcept
213 for (
auto& e : *
this)
219 inline int size() const noexcept
222 return values.size();
244 return values.getValueWithDefault (index);
259 return values[index];
274 return values[index];
283 return values.getFirst();
293 return values.getLast();
302 return values.begin();
309 inline ElementType*
begin() const noexcept
311 return values.begin();
317 inline ElementType*
end() const noexcept
325 inline ElementType*
data() const noexcept
339 int indexOf (ParameterType elementToLookFor)
const
342 auto e = values.begin();
343 auto endPtr = values.end();
345 for (; e != endPtr; ++e)
346 if (elementToLookFor == *e)
347 return static_cast<int> (e - values.begin());
357 bool contains (ParameterType elementToLookFor)
const
360 auto e = values.begin();
361 auto endPtr = values.end();
363 for (; e != endPtr; ++e)
364 if (elementToLookFor == *e)
375 void add (
const ElementType& newElement)
378 values.add (newElement);
385 void add (ElementType&& newElement)
388 values.add (std::move (newElement));
392 template <
typename... OtherElements>
393 void add (
const ElementType& firstNewElement, OtherElements... otherElements)
396 values.add (firstNewElement, otherElements...);
400 template <
typename... OtherElements>
401 void add (ElementType&& firstNewElement, OtherElements... otherElements)
404 values.add (std::move (firstNewElement), otherElements...);
419 void insert (
int indexToInsertAt, ParameterType newElement)
422 values.insert (indexToInsertAt, newElement, 1);
438 int numberOfTimesToInsertIt)
440 if (numberOfTimesToInsertIt > 0)
443 values.insert (indexToInsertAt, newElement, numberOfTimesToInsertIt);
460 const ElementType* newElements,
461 int numberOfElements)
463 if (numberOfElements > 0)
466 values.insertArray (indexToInsertAt, newElements, numberOfElements);
499 void set (
int indexToChange, ParameterType newValue)
501 if (indexToChange >= 0)
505 if (indexToChange < values.size())
506 values[indexToChange] = newValue;
508 values.add (newValue);
528 jassert (isPositiveAndBelow (indexToChange, values.size()));
529 values[indexToChange] = newValue;
539 template <
typename Type>
540 void addArray (
const Type* elementsToAdd,
int numElementsToAdd)
544 if (numElementsToAdd > 0)
545 values.addArray (elementsToAdd, numElementsToAdd);
548 template <
typename TypeToCreateFrom>
549 void addArray (
const std::initializer_list<TypeToCreateFrom>& items)
552 values.addArray (items);
561 template <
typename Type>
566 for (
auto e = elementsToAdd; *e !=
nullptr; ++e)
577 template <
class OtherArrayType>
578 void swapWith (OtherArrayType& otherArray) noexcept
581 const typename OtherArrayType::ScopedLockType lock2 (otherArray.getLock());
582 values.swapWith (otherArray.values);
590 template <
class OtherArrayType>
591 void addArray (
const OtherArrayType& arrayToAddFrom)
593 const typename OtherArrayType::ScopedLockType lock1 (arrayToAddFrom.getLock());
596 values.addArray (arrayToAddFrom);
608 template <
class OtherArrayType>
609 typename std::enable_if<! std::is_pointer<OtherArrayType>::value,
void>::type
612 int numElementsToAdd = -1)
614 const typename OtherArrayType::ScopedLockType lock1 (arrayToAddFrom.getLock());
617 values.addArray (arrayToAddFrom, startIndex, numElementsToAdd);
629 jassert (targetNumItems >= 0);
630 auto numToAdd = targetNumItems - values.size();
634 else if (numToAdd < 0)
650 template <
class ElementComparator>
651 int addSorted (ElementComparator& comparator, ParameterType newElement)
654 auto index = findInsertIndexInSortedArray (comparator, values.begin(), newElement, 0, values.size());
655 insert (index, newElement);
686 template <
typename ElementComparator,
typename TargetValueType>
687 int indexOfSorted (ElementComparator& comparator, TargetValueType elementToLookFor)
const
689 ignoreUnused (comparator);
694 for (
int s = 0, e = values.size();;)
699 if (comparator.compareElements (elementToLookFor, values[s]) == 0)
702 auto halfway = (s + e) / 2;
707 if (comparator.compareElements (elementToLookFor, values[halfway]) >= 0)
728 if (isPositiveAndBelow (indexToRemove, values.size()))
729 removeInternal (indexToRemove);
746 if (isPositiveAndBelow (indexToRemove, values.size()))
748 ElementType removed (values[indexToRemove]);
749 removeInternal (indexToRemove);
753 return ElementType();
766 void remove (
const ElementType* elementToRemove)
768 jassert (elementToRemove !=
nullptr);
771 jassert (values.begin() !=
nullptr);
772 auto indexToRemove = (int) (elementToRemove - values.begin());
774 if (! isPositiveAndBelow (indexToRemove, values.size()))
780 removeInternal (indexToRemove);
794 auto* e = values.begin();
796 for (
int i = 0; i < values.size(); ++i)
798 if (valueToRemove == e[i])
820 for (
int i = values.size(); --i >= 0;)
822 if (valueToRemove == values[i])
843 template <
typename PredicateType>
849 for (
int i = values.size(); --i >= 0;)
851 if (predicate (values[i]))
877 auto endIndex = jlimit (0, values.size(), startIndex + numberToRemove);
878 startIndex = jlimit (0, values.size(), startIndex);
879 numberToRemove = endIndex - startIndex;
881 if (numberToRemove > 0)
883 values.removeElements (startIndex, numberToRemove);
884 minimiseStorageAfterRemoval();
895 jassert (howManyToRemove >= 0);
897 if (howManyToRemove > 0)
901 if (howManyToRemove > values.size())
902 howManyToRemove = values.size();
904 values.removeElements (values.size() - howManyToRemove, howManyToRemove);
905 minimiseStorageAfterRemoval();
914 template <
class OtherArrayType>
917 const typename OtherArrayType::ScopedLockType lock1 (otherArray.getLock());
920 if (
this == &otherArray)
926 if (otherArray.size() > 0)
928 for (
int i = values.size(); --i >= 0;)
929 if (otherArray.contains (values[i]))
942 template <
class OtherArrayType>
945 const typename OtherArrayType::ScopedLockType lock1 (otherArray.getLock());
948 if (
this != &otherArray)
950 if (otherArray.size() <= 0)
956 for (
int i = values.size(); --i >= 0;)
957 if (! otherArray.contains (values[i]))
971 void swap (
int index1,
int index2)
974 values.swap (index1, index2);
991 void move (
int currentIndex,
int newIndex) noexcept
993 if (currentIndex != newIndex)
996 values.move (currentIndex, newIndex);
1010 values.shrinkToNoMoreThan (values.size());
1022 values.ensureAllocatedSize (minNumElements);
1062 template <
class ElementComparator>
1063 void sort (ElementComparator& comparator,
1064 bool retainOrderOfEquivalentItems =
false)
1067 ignoreUnused (comparator);
1069 sortArray (comparator, values.begin(), 0,
size() - 1, retainOrderOfEquivalentItems);
1077 inline const TypeOfCriticalSectionToUse&
getLock() const noexcept {
return values; }
1087 JUCE_DEPRECATED_WITH_BODY (
void swapWithArray (
Array& other) noexcept, {
swapWith (other); })
1094 void removeInternal (
int indexToRemove)
1096 values.removeElements (indexToRemove, 1);
1097 minimiseStorageAfterRemoval();
1100 void minimiseStorageAfterRemoval()
1102 if (values.capacity() > jmax (minimumAllocatedSize, values.size() * 2))
1103 values.shrinkToNoMoreThan (jmax (values.size(), jmax (minimumAllocatedSize, 64 / (
int)
sizeof (ElementType))));