OpenShot Audio Library | OpenShotAudio 0.3.2

Loading...
Searching...
No Matches
juce_OwnedArray.h
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2017 - ROLI Ltd.
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23 namespace juce
24{
25
26//==============================================================================
47 template <class ObjectClass,
48 class TypeOfCriticalSectionToUse = DummyCriticalSection>
49
50 class OwnedArray
51{
52 public:
53 //==============================================================================
55 OwnedArray() = default;
56
62 ~OwnedArray()
63 {
64 deleteAllObjects();
65 }
66
68 OwnedArray (OwnedArray&& other) noexcept
69 : values (std::move (other.values))
70 {
71 }
72
74 OwnedArray (const std::initializer_list<ObjectClass*>& items)
75 {
76 addArray (items);
77 }
78
80 OwnedArray& operator= (OwnedArray&& other) noexcept
81 {
82 const ScopedLockType lock (getLock());
83 deleteAllObjects();
84 values = std::move (other.values);
85 return *this;
86 }
87
89 template <class OtherObjectClass, class OtherCriticalSection>
90 OwnedArray (OwnedArray<OtherObjectClass, OtherCriticalSection>&& other) noexcept
91 : values (std::move (other.values))
92 {
93 }
94
96 template <class OtherObjectClass, class OtherCriticalSection>
97 OwnedArray& operator= (OwnedArray<OtherObjectClass, OtherCriticalSection>&& other) noexcept
98 {
99 const ScopedLockType lock (getLock());
100 deleteAllObjects();
101 values = std::move (other.values);
102 return *this;
103 }
104
105 //==============================================================================
107 void clear (bool deleteObjects = true)
108 {
109 const ScopedLockType lock (getLock());
110 clearQuick (deleteObjects);
111 values.setAllocatedSize (0);
112 }
113
114 //==============================================================================
116 void clearQuick (bool deleteObjects)
117 {
118 const ScopedLockType lock (getLock());
119
120 if (deleteObjects)
121 deleteAllObjects();
122 else
123 values.clear();
124 }
125
126 //==============================================================================
130 inline int size() const noexcept
131 {
132 return values.size();
133 }
134
136 inline bool isEmpty() const noexcept
137 {
138 return size() == 0;
139 }
140
149 inline ObjectClass* operator[] (int index) const noexcept
150 {
151 const ScopedLockType lock (getLock());
152 return values.getValueWithDefault (index);
153 }
154
160 inline ObjectClass* getUnchecked (int index) const noexcept
161 {
162 const ScopedLockType lock (getLock());
163 return values[index];
164 }
165
171 inline ObjectClass* getFirst() const noexcept
172 {
173 const ScopedLockType lock (getLock());
174 return values.getFirst();
175 }
176
182 inline ObjectClass* getLast() const noexcept
183 {
184 const ScopedLockType lock (getLock());
185 return values.getLast();
186 }
187
192 inline ObjectClass** getRawDataPointer() noexcept
193 {
194 return values.begin();
195 }
196
197 //==============================================================================
201 inline ObjectClass** begin() noexcept
202 {
203 return values.begin();
204 }
205
209 inline ObjectClass* const* begin() const noexcept
210 {
211 return values.begin();
212 }
213
217 inline ObjectClass** end() noexcept
218 {
219 return values.end();
220 }
221
225 inline ObjectClass* const* end() const noexcept
226 {
227 return values.end();
228 }
229
233 inline ObjectClass** data() noexcept
234 {
235 return begin();
236 }
237
241 inline ObjectClass* const* data() const noexcept
242 {
243 return begin();
244 }
245
246 //==============================================================================
252 int indexOf (const ObjectClass* objectToLookFor) const noexcept
253 {
254 const ScopedLockType lock (getLock());
255 auto* e = values.begin();
256
257 for (; e != values.end(); ++e)
258 if (objectToLookFor == *e)
259 return static_cast<int> (e - values.begin());
260
261 return -1;
262 }
263
269 bool contains (const ObjectClass* objectToLookFor) const noexcept
270 {
271 const ScopedLockType lock (getLock());
272 auto* e = values.begin();
273
274 for (; e != values.end(); ++e)
275 if (objectToLookFor == *e)
276 return true;
277
278 return false;
279 }
280
281 //==============================================================================
294 ObjectClass* add (ObjectClass* newObject)
295 {
296 const ScopedLockType lock (getLock());
297 values.add (newObject);
298 return newObject;
299 }
300
313 ObjectClass* add (std::unique_ptr<ObjectClass> newObject)
314 {
315 return add (newObject.release());
316 }
317
336 ObjectClass* insert (int indexToInsertAt, ObjectClass* newObject)
337 {
338 const ScopedLockType lock (getLock());
339 values.insert (indexToInsertAt, newObject, 1);
340 return newObject;
341 }
342
361 ObjectClass* insert (int indexToInsertAt, std::unique_ptr<ObjectClass> newObject)
362 {
363 return insert (indexToInsertAt, newObject.release());
364 }
365
378 void insertArray (int indexToInsertAt,
379 ObjectClass* const* newObjects,
380 int numberOfElements)
381 {
382 if (numberOfElements > 0)
383 {
384 const ScopedLockType lock (getLock());
385 values.insertArray (indexToInsertAt, newObjects, numberOfElements);
386 }
387 }
388
402 ObjectClass* set (int indexToChange, ObjectClass* newObject, bool deleteOldElement = true)
403 {
404 if (indexToChange >= 0)
405 {
406 std::unique_ptr<ObjectClass> toDelete;
407
408 {
409 const ScopedLockType lock (getLock());
410
411 if (indexToChange < values.size())
412 {
413 if (deleteOldElement)
414 {
415 toDelete.reset (values[indexToChange]);
416
417 if (toDelete.get() == newObject)
418 toDelete.release();
419 }
420
421 values[indexToChange] = newObject;
422 }
423 else
424 {
425 values.add (newObject);
426 }
427 }
428 }
429 else
430 {
431 jassertfalse; // you're trying to set an object at a negative index, which doesn't have
432 // any effect - but since the object is not being added, it may be leaking..
433 }
434
435 return newObject;
436 }
437
451 ObjectClass* set (int indexToChange, std::unique_ptr<ObjectClass> newObject, bool deleteOldElement = true)
452 {
453 return set (indexToChange, newObject.release(), deleteOldElement);
454 }
455
465 template <class OtherArrayType>
466 void addArray (const OtherArrayType& arrayToAddFrom,
467 int startIndex = 0,
468 int numElementsToAdd = -1)
469 {
470 const typename OtherArrayType::ScopedLockType lock1 (arrayToAddFrom.getLock());
471 const ScopedLockType lock2 (getLock());
472 values.addArray (arrayToAddFrom, startIndex, numElementsToAdd);
473 }
474
476 template <typename OtherArrayType>
477 void addArray (const std::initializer_list<OtherArrayType>& items)
478 {
479 const ScopedLockType lock (getLock());
480 values.addArray (items);
481 }
482
497 template <class OtherArrayType>
498 void addCopiesOf (const OtherArrayType& arrayToAddFrom,
499 int startIndex = 0,
500 int numElementsToAdd = -1)
501 {
502 const typename OtherArrayType::ScopedLockType lock1 (arrayToAddFrom.getLock());
503 const ScopedLockType lock2 (getLock());
504
505 if (startIndex < 0)
506 {
507 jassertfalse;
508 startIndex = 0;
509 }
510
511 if (numElementsToAdd < 0 || startIndex + numElementsToAdd > arrayToAddFrom.size())
512 numElementsToAdd = arrayToAddFrom.size() - startIndex;
513
514 jassert (numElementsToAdd >= 0);
515 values.ensureAllocatedSize (values.size() + numElementsToAdd);
516
517 while (--numElementsToAdd >= 0)
518 values.add (createCopyIfNotNull (arrayToAddFrom.getUnchecked (startIndex++)));
519 }
520
533 template <class ElementComparator>
534 int addSorted (ElementComparator& comparator, ObjectClass* newObject) noexcept
535 {
536 // If you pass in an object with a static compareElements() method, this
537 // avoids getting warning messages about the parameter being unused
538 ignoreUnused (comparator);
539
540 const ScopedLockType lock (getLock());
541 auto index = findInsertIndexInSortedArray (comparator, values.begin(), newObject, 0, values.size());
542 insert (index, newObject);
543 return index;
544 }
545
558 template <typename ElementComparator>
559 int indexOfSorted (ElementComparator& comparator, const ObjectClass* objectToLookFor) const noexcept
560 {
561 // If you pass in an object with a static compareElements() method, this
562 // avoids getting warning messages about the parameter being unused
563 ignoreUnused (comparator);
564
565 const ScopedLockType lock (getLock());
566 int s = 0, e = values.size();
567
568 while (s < e)
569 {
570 if (comparator.compareElements (objectToLookFor, values[s]) == 0)
571 return s;
572
573 auto halfway = (s + e) / 2;
574
575 if (halfway == s)
576 break;
577
578 if (comparator.compareElements (objectToLookFor, values[halfway]) >= 0)
579 s = halfway;
580 else
581 e = halfway;
582 }
583
584 return -1;
585 }
586
587 //==============================================================================
598 void remove (int indexToRemove, bool deleteObject = true)
599 {
600 std::unique_ptr<ObjectClass> toDelete;
601
602 {
603 const ScopedLockType lock (getLock());
604
605 if (isPositiveAndBelow (indexToRemove, values.size()))
606 {
607 auto** e = values.begin() + indexToRemove;
608
609 if (deleteObject)
610 toDelete.reset (*e);
611
612 values.removeElements (indexToRemove, 1);
613 }
614 }
615
616 if ((values.size() << 1) < values.capacity())
617 minimiseStorageOverheads();
618 }
619
629 ObjectClass* removeAndReturn (int indexToRemove)
630 {
631 ObjectClass* removedItem = nullptr;
632 const ScopedLockType lock (getLock());
633
634 if (isPositiveAndBelow (indexToRemove, values.size()))
635 {
636 removedItem = values[indexToRemove];
637
638 values.removeElements (indexToRemove, 1);
639
640 if ((values.size() << 1) < values.capacity())
641 minimiseStorageOverheads();
642 }
643
644 return removedItem;
645 }
646
655 void removeObject (const ObjectClass* objectToRemove, bool deleteObject = true)
656 {
657 const ScopedLockType lock (getLock());
658
659 for (int i = 0; i < values.size(); ++i)
660 {
661 if (objectToRemove == values[i])
662 {
663 remove (i, deleteObject);
664 break;
665 }
666 }
667 }
668
682 void removeRange (int startIndex, int numberToRemove, bool deleteObjects = true)
683 {
684 const ScopedLockType lock (getLock());
685 auto endIndex = jlimit (0, values.size(), startIndex + numberToRemove);
686 startIndex = jlimit (0, values.size(), startIndex);
687 numberToRemove = endIndex - startIndex;
688
689 if (numberToRemove > 0)
690 {
691 Array<ObjectClass*> objectsToDelete;
692
693 if (deleteObjects)
694 objectsToDelete.addArray (values.begin() + startIndex, numberToRemove);
695
696 values.removeElements (startIndex, numberToRemove);
697
698 for (auto& o : objectsToDelete)
699 ContainerDeletePolicy<ObjectClass>::destroy (o);
700
701 if ((values.size() << 1) < values.capacity())
702 minimiseStorageOverheads();
703 }
704 }
705
712 void removeLast (int howManyToRemove = 1,
713 bool deleteObjects = true)
714 {
715 const ScopedLockType lock (getLock());
716
717 if (howManyToRemove >= values.size())
718 clear (deleteObjects);
719 else
720 removeRange (values.size() - howManyToRemove, howManyToRemove, deleteObjects);
721 }
722
728 void swap (int index1, int index2) noexcept
729 {
730 const ScopedLockType lock (getLock());
731 values.swap (index1, index2);
732 }
733
747 void move (int currentIndex, int newIndex) noexcept
748 {
749 if (currentIndex != newIndex)
750 {
751 const ScopedLockType lock (getLock());
752 values.move (currentIndex, newIndex);
753 }
754 }
755
761 template <class OtherArrayType>
762 void swapWith (OtherArrayType& otherArray) noexcept
763 {
764 const ScopedLockType lock1 (getLock());
765 const typename OtherArrayType::ScopedLockType lock2 (otherArray.getLock());
766 values.swapWith (otherArray.values);
767 }
768
769 //==============================================================================
776 void minimiseStorageOverheads() noexcept
777 {
778 const ScopedLockType lock (getLock());
779 values.shrinkToNoMoreThan (values.size());
780 }
781
788 void ensureStorageAllocated (int minNumElements) noexcept
789 {
790 const ScopedLockType lock (getLock());
791 values.ensureAllocatedSize (minNumElements);
792 }
793
794 //==============================================================================
820 template <class ElementComparator>
821 void sort (ElementComparator& comparator,
822 bool retainOrderOfEquivalentItems = false) noexcept
823 {
824 // If you pass in an object with a static compareElements() method, this
825 // avoids getting warning messages about the parameter being unused
826 ignoreUnused (comparator);
827
828 const ScopedLockType lock (getLock());
829
830 if (size() > 1)
831 sortArray (comparator, values.begin(), 0, size() - 1, retainOrderOfEquivalentItems);
832 }
833
834 //==============================================================================
839 inline const TypeOfCriticalSectionToUse& getLock() const noexcept { return values; }
840
842 using ScopedLockType = typename TypeOfCriticalSectionToUse::ScopedLockType;
843
844 //==============================================================================
845 #ifndef DOXYGEN
846 // Note that the swapWithArray method has been replaced by a more flexible templated version,
847 // and renamed "swapWith" to be more consistent with the names used in other classes.
848 JUCE_DEPRECATED_WITH_BODY (void swapWithArray (OwnedArray& other) noexcept, { swapWith (other); })
849 #endif
850
851 private:
852 //==============================================================================
853 ArrayBase <ObjectClass*, TypeOfCriticalSectionToUse> values;
854
855 void deleteAllObjects()
856 {
857 auto i = values.size();
858
859 while (--i >= 0)
860 {
861 auto* e = values[i];
862 values.removeElements (i, 1);
863 ContainerDeletePolicy<ObjectClass>::destroy (e);
864 }
865 }
866
867 template <class OtherObjectClass, class OtherCriticalSection>
868 friend class OwnedArray;
869
870 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OwnedArray)
871};
872
873} // namespace juce
juce::Array
Definition: juce_Array.h:56
juce::Array::addArray
void addArray(const Type *elementsToAdd, int numElementsToAdd)
Definition: juce_Array.h:583
juce::OwnedArray
Definition: juce_OwnedArray.h:51
juce::OwnedArray::data
ObjectClass *const * data() const noexcept
Definition: juce_OwnedArray.h:241
juce::OwnedArray::size
int size() const noexcept
Definition: juce_OwnedArray.h:130
juce::OwnedArray::getUnchecked
ObjectClass * getUnchecked(int index) const noexcept
Definition: juce_OwnedArray.h:160
juce::OwnedArray::set
ObjectClass * set(int indexToChange, ObjectClass *newObject, bool deleteOldElement=true)
Definition: juce_OwnedArray.h:402
juce::OwnedArray::removeAndReturn
ObjectClass * removeAndReturn(int indexToRemove)
Definition: juce_OwnedArray.h:629
juce::OwnedArray::add
ObjectClass * add(std::unique_ptr< ObjectClass > newObject)
Definition: juce_OwnedArray.h:313
juce::OwnedArray::set
ObjectClass * set(int indexToChange, std::unique_ptr< ObjectClass > newObject, bool deleteOldElement=true)
Definition: juce_OwnedArray.h:451
juce::OwnedArray::addCopiesOf
void addCopiesOf(const OtherArrayType &arrayToAddFrom, int startIndex=0, int numElementsToAdd=-1)
Definition: juce_OwnedArray.h:498
juce::OwnedArray::addArray
void addArray(const OtherArrayType &arrayToAddFrom, int startIndex=0, int numElementsToAdd=-1)
Definition: juce_OwnedArray.h:466
juce::OwnedArray::isEmpty
bool isEmpty() const noexcept
Definition: juce_OwnedArray.h:136
juce::OwnedArray::swapWith
void swapWith(OtherArrayType &otherArray) noexcept
Definition: juce_OwnedArray.h:762
juce::OwnedArray::remove
void remove(int indexToRemove, bool deleteObject=true)
Definition: juce_OwnedArray.h:598
juce::OwnedArray::ScopedLockType
typename TypeOfCriticalSectionToUse::ScopedLockType ScopedLockType
Definition: juce_OwnedArray.h:842
juce::OwnedArray::ensureStorageAllocated
void ensureStorageAllocated(int minNumElements) noexcept
Definition: juce_OwnedArray.h:788
juce::OwnedArray::getFirst
ObjectClass * getFirst() const noexcept
Definition: juce_OwnedArray.h:171
juce::OwnedArray::minimiseStorageOverheads
void minimiseStorageOverheads() noexcept
Definition: juce_OwnedArray.h:776
juce::OwnedArray::clear
void clear(bool deleteObjects=true)
Definition: juce_OwnedArray.h:107
juce::OwnedArray::removeLast
void removeLast(int howManyToRemove=1, bool deleteObjects=true)
Definition: juce_OwnedArray.h:712
juce::OwnedArray::indexOf
int indexOf(const ObjectClass *objectToLookFor) const noexcept
Definition: juce_OwnedArray.h:252
juce::OwnedArray::add
ObjectClass * add(ObjectClass *newObject)
Definition: juce_OwnedArray.h:294
juce::OwnedArray::begin
ObjectClass ** begin() noexcept
Definition: juce_OwnedArray.h:201
juce::OwnedArray::OwnedArray
OwnedArray(OwnedArray< OtherObjectClass, OtherCriticalSection > &&other) noexcept
Definition: juce_OwnedArray.h:90
juce::OwnedArray::~OwnedArray
~OwnedArray()
Definition: juce_OwnedArray.h:62
juce::OwnedArray::swap
void swap(int index1, int index2) noexcept
Definition: juce_OwnedArray.h:728
juce::OwnedArray::indexOfSorted
int indexOfSorted(ElementComparator &comparator, const ObjectClass *objectToLookFor) const noexcept
Definition: juce_OwnedArray.h:559
juce::OwnedArray::insert
ObjectClass * insert(int indexToInsertAt, std::unique_ptr< ObjectClass > newObject)
Definition: juce_OwnedArray.h:361
juce::OwnedArray::clearQuick
void clearQuick(bool deleteObjects)
Definition: juce_OwnedArray.h:116
juce::OwnedArray::removeObject
void removeObject(const ObjectClass *objectToRemove, bool deleteObject=true)
Definition: juce_OwnedArray.h:655
juce::OwnedArray::begin
ObjectClass *const * begin() const noexcept
Definition: juce_OwnedArray.h:209
juce::OwnedArray::end
ObjectClass *const * end() const noexcept
Definition: juce_OwnedArray.h:225
juce::OwnedArray::end
ObjectClass ** end() noexcept
Definition: juce_OwnedArray.h:217
juce::OwnedArray::OwnedArray
OwnedArray()=default
juce::OwnedArray::operator=
OwnedArray & operator=(OwnedArray &&other) noexcept
Definition: juce_OwnedArray.h:80
juce::OwnedArray::OwnedArray
OwnedArray(OwnedArray &&other) noexcept
Definition: juce_OwnedArray.h:68
juce::OwnedArray::insertArray
void insertArray(int indexToInsertAt, ObjectClass *const *newObjects, int numberOfElements)
Definition: juce_OwnedArray.h:378
juce::OwnedArray::move
void move(int currentIndex, int newIndex) noexcept
Definition: juce_OwnedArray.h:747
juce::OwnedArray::addSorted
int addSorted(ElementComparator &comparator, ObjectClass *newObject) noexcept
Definition: juce_OwnedArray.h:534
juce::OwnedArray::getLock
const TypeOfCriticalSectionToUse & getLock() const noexcept
Definition: juce_OwnedArray.h:839
juce::OwnedArray::addArray
void addArray(const std::initializer_list< OtherArrayType > &items)
Definition: juce_OwnedArray.h:477
juce::OwnedArray::sort
void sort(ElementComparator &comparator, bool retainOrderOfEquivalentItems=false) noexcept
Definition: juce_OwnedArray.h:821
juce::OwnedArray::insert
ObjectClass * insert(int indexToInsertAt, ObjectClass *newObject)
Definition: juce_OwnedArray.h:336
juce::OwnedArray::operator[]
ObjectClass * operator[](int index) const noexcept
Definition: juce_OwnedArray.h:149
juce::OwnedArray::getRawDataPointer
ObjectClass ** getRawDataPointer() noexcept
Definition: juce_OwnedArray.h:192
juce::OwnedArray::data
ObjectClass ** data() noexcept
Definition: juce_OwnedArray.h:233
juce::OwnedArray::OwnedArray
OwnedArray(const std::initializer_list< ObjectClass * > &items)
Definition: juce_OwnedArray.h:74
juce::OwnedArray::removeRange
void removeRange(int startIndex, int numberToRemove, bool deleteObjects=true)
Definition: juce_OwnedArray.h:682
juce::OwnedArray::getLast
ObjectClass * getLast() const noexcept
Definition: juce_OwnedArray.h:182
juce::OwnedArray::contains
bool contains(const ObjectClass *objectToLookFor) const noexcept
Definition: juce_OwnedArray.h:269
juce::ContainerDeletePolicy
Definition: juce_ContainerDeletePolicy.h:41