29 #ifndef JUCE_ARRAY_H_INCLUDED
30 #define JUCE_ARRAY_H_INCLUDED
57 template <
typename ElementType,
59 int minimumAllocatedSize = 0>
63 typedef PARAMETER_TYPE (ElementType) ParameterType;
79 data.setAllocatedSize (other.
numUsed);
81 for (
int i = 0; i <
numUsed; ++i)
82 new (data.elements + i) ElementType (other.data.elements[i]);
85 #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
98 template <
typename TypeToCreateFrom>
101 while (*values != TypeToCreateFrom())
110 template <
typename TypeToCreateFrom>
111 Array (
const TypeToCreateFrom* values,
int numValues) :
numUsed (numValues)
113 data.setAllocatedSize (numValues);
115 for (
int i = 0; i < numValues; ++i)
116 new (data.elements + i) ElementType (values[i]);
119 #if JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS
120 template <
typename TypeToCreateFrom>
121 Array (
const std::initializer_list<TypeToCreateFrom>& items) :
numUsed (0)
147 #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
165 template <
class OtherArrayType>
169 const typename OtherArrayType::ScopedLockType lock2 (other.getLock());
174 for (
int i =
numUsed; --i >= 0;)
175 if (! (data.elements [i] == other.data.elements [i]))
186 template <
class OtherArrayType>
204 data.setAllocatedSize (0);
242 jassert (data.elements !=
nullptr);
243 return data.elements [index];
246 return ElementType();
262 return data.elements [index];
278 return data.elements [index];
291 jassert (data.elements !=
nullptr);
292 return data.elements[0];
295 return ElementType();
308 jassert (data.elements !=
nullptr);
309 return data.elements[
numUsed - 1];
312 return ElementType();
321 return data.elements;
330 return data.elements;
339 if (data.elements ==
nullptr ||
numUsed <= 0)
340 return data.elements;
343 return data.elements +
numUsed;
355 int indexOf (ParameterType elementToLookFor)
const
358 const ElementType* e = data.elements.getData();
359 const ElementType*
const end_ = e +
numUsed;
361 for (; e != end_; ++e)
362 if (elementToLookFor == *e)
363 return static_cast <int> (e - data.elements.getData());
373 bool contains (ParameterType elementToLookFor)
const
376 const ElementType* e = data.elements.getData();
377 const ElementType*
const end_ = e +
numUsed;
379 for (; e != end_; ++e)
380 if (elementToLookFor == *e)
392 void add (
const ElementType& newElement)
395 data.ensureAllocatedSize (
numUsed + 1);
396 new (data.elements +
numUsed++) ElementType (newElement);
399 #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
405 void add (ElementType&& newElement)
408 data.ensureAllocatedSize (
numUsed + 1);
409 new (data.elements +
numUsed++) ElementType (
static_cast<ElementType&&
> (newElement));
425 void insert (
int indexToInsertAt, ParameterType newElement)
428 data.ensureAllocatedSize (
numUsed + 1);
429 jassert (data.elements !=
nullptr);
433 ElementType*
const insertPos = data.elements + indexToInsertAt;
434 const int numberToMove =
numUsed - indexToInsertAt;
436 if (numberToMove > 0)
437 memmove (insertPos + 1, insertPos, ((
size_t) numberToMove) *
sizeof (ElementType));
439 new (insertPos) ElementType (newElement);
444 new (data.elements +
numUsed++) ElementType (newElement);
461 int numberOfTimesToInsertIt)
463 if (numberOfTimesToInsertIt > 0)
466 data.ensureAllocatedSize (
numUsed + numberOfTimesToInsertIt);
467 ElementType* insertPos;
471 insertPos = data.elements + indexToInsertAt;
472 const int numberToMove =
numUsed - indexToInsertAt;
473 memmove (insertPos + numberOfTimesToInsertIt, insertPos, ((
size_t) numberToMove) *
sizeof (ElementType));
477 insertPos = data.elements +
numUsed;
480 numUsed += numberOfTimesToInsertIt;
482 while (--numberOfTimesToInsertIt >= 0)
484 new (insertPos) ElementType (newElement);
504 const ElementType* newElements,
505 int numberOfElements)
507 if (numberOfElements > 0)
510 data.ensureAllocatedSize (
numUsed + numberOfElements);
511 ElementType* insertPos = data.elements;
515 insertPos += indexToInsertAt;
516 const int numberToMove =
numUsed - indexToInsertAt;
517 memmove (insertPos + numberOfElements, insertPos, numberToMove *
sizeof (ElementType));
526 while (--numberOfElements >= 0)
527 new (insertPos++) ElementType (*newElements++);
556 void set (
const int indexToChange, ParameterType newValue)
563 jassert (data.elements !=
nullptr);
564 data.elements [indexToChange] = newValue;
566 else if (indexToChange >= 0)
568 data.ensureAllocatedSize (
numUsed + 1);
569 new (data.elements +
numUsed++) ElementType (newValue);
586 data.elements [indexToChange] = newValue;
596 template <
typename Type>
597 void addArray (
const Type* elementsToAdd,
int numElementsToAdd)
601 if (numElementsToAdd > 0)
603 data.ensureAllocatedSize (
numUsed + numElementsToAdd);
605 while (--numElementsToAdd >= 0)
607 new (data.elements +
numUsed) ElementType (*elementsToAdd++);
613 #if JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS
614 template <
typename TypeToCreateFrom>
615 void addArray (
const std::initializer_list<TypeToCreateFrom>& items)
618 data.ensureAllocatedSize (
numUsed + (
int) items.
size());
620 for (
auto& item : items)
622 new (data.elements +
numUsed) ElementType (item);
634 template <
typename Type>
638 for (
const Type*
const* e = elementsToAdd; *e !=
nullptr; ++e)
649 template <
class OtherArrayType>
653 const typename OtherArrayType::ScopedLockType lock2 (otherArray.getLock());
654 data.swapWith (otherArray.data);
667 template <
class OtherArrayType>
668 void addArray (
const OtherArrayType& arrayToAddFrom,
670 int numElementsToAdd = -1)
672 const typename OtherArrayType::ScopedLockType lock1 (arrayToAddFrom.getLock());
683 if (numElementsToAdd < 0 || startIndex + numElementsToAdd > arrayToAddFrom.size())
684 numElementsToAdd = arrayToAddFrom.size() - startIndex;
686 while (--numElementsToAdd >= 0)
687 add (arrayToAddFrom.getUnchecked (startIndex++));
702 const int numToAdd = targetNumItems -
numUsed;
705 else if (numToAdd < 0)
721 template <
class ElementComparator>
722 int addSorted (ElementComparator& comparator, ParameterType newElement)
725 const int index = findInsertIndexInSortedArray (comparator, data.elements.getData(), newElement, 0,
numUsed);
726 insert (index, newElement);
757 template <
typename ElementComparator,
typename TargetValueType>
758 int indexOfSorted (ElementComparator& comparator, TargetValueType elementToLookFor)
const
770 if (comparator.compareElements (elementToLookFor, data.elements [s]) == 0)
773 const int halfway = (s + e) / 2;
777 if (comparator.compareElements (elementToLookFor, data.elements [halfway]) >= 0)
795 ElementType
remove (
const int indexToRemove)
801 jassert (data.elements !=
nullptr);
802 ElementType removed (data.elements[indexToRemove]);
807 return ElementType();
821 ElementType*
const e = data.elements;
823 for (
int i = 0; i <
numUsed; ++i)
825 if (valueToRemove == e[i])
845 for (
int i =
numUsed; --i >= 0;)
846 if (valueToRemove == data.elements[i])
865 const int endIndex =
jlimit (0,
numUsed, startIndex + numberToRemove);
868 if (endIndex > startIndex)
870 ElementType*
const e = data.elements + startIndex;
872 numberToRemove = endIndex - startIndex;
873 for (
int i = 0; i < numberToRemove; ++i)
876 const int numToShift =
numUsed - endIndex;
878 memmove (e, e + numberToRemove, ((
size_t) numToShift) *
sizeof (ElementType));
897 for (
int i = 1; i <= howManyToRemove; ++i)
898 data.elements [
numUsed - i].~ElementType();
909 template <
class OtherArrayType>
912 const typename OtherArrayType::ScopedLockType lock1 (otherArray.getLock());
915 if (
this == &otherArray)
921 if (otherArray.size() > 0)
923 for (
int i =
numUsed; --i >= 0;)
924 if (otherArray.contains (data.elements [i]))
937 template <
class OtherArrayType>
940 const typename OtherArrayType::ScopedLockType lock1 (otherArray.getLock());
943 if (
this != &otherArray)
945 if (otherArray.size() <= 0)
951 for (
int i =
numUsed; --i >= 0;)
952 if (! otherArray.contains (data.elements [i]))
974 std::swap (data.elements [index1],
975 data.elements [index2]);
995 if (currentIndex != newIndex)
1004 char tempCopy [
sizeof (ElementType)];
1005 memcpy (tempCopy, data.elements + currentIndex, sizeof (ElementType));
1007 if (newIndex > currentIndex)
1009 memmove (data.elements + currentIndex,
1010 data.elements + currentIndex + 1,
1011 sizeof (ElementType) * (
size_t) (newIndex - currentIndex));
1015 memmove (data.elements + newIndex + 1,
1016 data.elements + newIndex,
1017 sizeof (ElementType) * (
size_t) (currentIndex - newIndex));
1020 memcpy (data.elements + newIndex, tempCopy, sizeof (ElementType));
1035 data.shrinkToNoMoreThan (
numUsed);
1047 data.ensureAllocatedSize (minNumElements);
1077 template <
class ElementComparator>
1078 void sort (ElementComparator& comparator,
1079 const bool retainOrderOfEquivalentItems =
false)
const
1084 sortArray (comparator, data.elements.getData(), 0,
size() - 1, retainOrderOfEquivalentItems);
1113 ElementType*
const e = data.elements + indexToRemove;
1115 const int numberToShift =
numUsed - indexToRemove;
1117 if (numberToShift > 0)
1118 memmove (e, e + 1, ((
size_t) numberToShift) *
sizeof (ElementType));
1125 for (
int i = 0; i <
numUsed; ++i)
1126 data.elements[i].~ElementType();
1131 if (data.numAllocated >
jmax (minimumAllocatedSize,
numUsed * 2))
1132 data.shrinkToNoMoreThan (
jmax (
numUsed,
jmax (minimumAllocatedSize, 64 / (
int)
sizeof (ElementType))));
1137 #endif // JUCE_ARRAY_H_INCLUDED