LMMS
Loading...
Searching...
No Matches
juce_OwnedArray.h
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
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
23namespace juce
24{
25
26//==============================================================================
47template <class ObjectClass,
48 class TypeOfCriticalSectionToUse = DummyCriticalSection>
49
51{
52public:
53 //==============================================================================
55 OwnedArray() = default;
56
63 {
65 }
66
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());
84 values = std::move (other.values);
85 return *this;
86 }
87
89 template <class OtherObjectClass, class OtherCriticalSection>
91 : values (std::move (other.values))
92 {
93 }
94
96 template <class OtherObjectClass, class OtherCriticalSection>
98 {
99 const ScopedLockType lock (getLock());
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)
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 {
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())
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())
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)
700
701 if ((values.size() << 1) < values.capacity())
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 //==============================================================================
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 [[deprecated ("This method has been replaced by a more flexible templated version and renamed "
847 "to swapWith to be more consistent with the names used in other classes.")]]
848 void swapWithArray (OwnedArray& other) noexcept { swapWith (other); }
849 #endif
850
851private:
852 //==============================================================================
853 ArrayBase <ObjectClass*, TypeOfCriticalSectionToUse> values;
854
856 {
857 auto i = values.size();
858
859 while (--i >= 0)
860 {
861 auto* e = values[i];
862 values.removeElements (i, 1);
864 }
865 }
866
867 template <class OtherObjectClass, class OtherCriticalSection>
868 friend class OwnedArray;
869
871};
872
873} // namespace juce
#define noexcept
Definition DistrhoDefines.h:72
Definition juce_Array.h:56
void addArray(const Type *elementsToAdd, int numElementsToAdd)
Definition juce_Array.h:583
ObjectClass *const * data() const noexcept
Definition juce_OwnedArray.h:241
int size() const noexcept
Definition juce_OwnedArray.h:130
ObjectClass * getUnchecked(int index) const noexcept
Definition juce_OwnedArray.h:160
ObjectClass * set(int indexToChange, ObjectClass *newObject, bool deleteOldElement=true)
Definition juce_OwnedArray.h:402
ObjectClass * removeAndReturn(int indexToRemove)
Definition juce_OwnedArray.h:629
ArrayBase< ObjectClass *, TypeOfCriticalSectionToUse > values
Definition juce_OwnedArray.h:853
ObjectClass * add(std::unique_ptr< ObjectClass > newObject)
Definition juce_OwnedArray.h:313
ObjectClass * set(int indexToChange, std::unique_ptr< ObjectClass > newObject, bool deleteOldElement=true)
Definition juce_OwnedArray.h:451
void addCopiesOf(const OtherArrayType &arrayToAddFrom, int startIndex=0, int numElementsToAdd=-1)
Definition juce_OwnedArray.h:498
void addArray(const OtherArrayType &arrayToAddFrom, int startIndex=0, int numElementsToAdd=-1)
Definition juce_OwnedArray.h:466
bool isEmpty() const noexcept
Definition juce_OwnedArray.h:136
void swapWith(OtherArrayType &otherArray) noexcept
Definition juce_OwnedArray.h:762
void remove(int indexToRemove, bool deleteObject=true)
Definition juce_OwnedArray.h:598
typename TypeOfCriticalSectionToUse::ScopedLockType ScopedLockType
Definition juce_OwnedArray.h:842
void ensureStorageAllocated(int minNumElements) noexcept
Definition juce_OwnedArray.h:788
ObjectClass * getFirst() const noexcept
Definition juce_OwnedArray.h:171
void minimiseStorageOverheads() noexcept
Definition juce_OwnedArray.h:776
void clear(bool deleteObjects=true)
Definition juce_OwnedArray.h:107
void removeLast(int howManyToRemove=1, bool deleteObjects=true)
Definition juce_OwnedArray.h:712
int indexOf(const ObjectClass *objectToLookFor) const noexcept
Definition juce_OwnedArray.h:252
ObjectClass * add(ObjectClass *newObject)
Definition juce_OwnedArray.h:294
ObjectClass ** begin() noexcept
Definition juce_OwnedArray.h:201
OwnedArray(OwnedArray< OtherObjectClass, OtherCriticalSection > &&other) noexcept
Definition juce_OwnedArray.h:90
~OwnedArray()
Definition juce_OwnedArray.h:62
void swap(int index1, int index2) noexcept
Definition juce_OwnedArray.h:728
int indexOfSorted(ElementComparator &comparator, const ObjectClass *objectToLookFor) const noexcept
Definition juce_OwnedArray.h:559
ObjectClass * insert(int indexToInsertAt, std::unique_ptr< ObjectClass > newObject)
Definition juce_OwnedArray.h:361
void clearQuick(bool deleteObjects)
Definition juce_OwnedArray.h:116
void removeObject(const ObjectClass *objectToRemove, bool deleteObject=true)
Definition juce_OwnedArray.h:655
ObjectClass *const * begin() const noexcept
Definition juce_OwnedArray.h:209
ObjectClass *const * end() const noexcept
Definition juce_OwnedArray.h:225
ObjectClass ** end() noexcept
Definition juce_OwnedArray.h:217
void swapWithArray(OwnedArray &other) noexcept
Definition juce_OwnedArray.h:848
OwnedArray()=default
OwnedArray(OwnedArray &&other) noexcept
Definition juce_OwnedArray.h:68
void insertArray(int indexToInsertAt, ObjectClass *const *newObjects, int numberOfElements)
Definition juce_OwnedArray.h:378
void move(int currentIndex, int newIndex) noexcept
Definition juce_OwnedArray.h:747
int addSorted(ElementComparator &comparator, ObjectClass *newObject) noexcept
Definition juce_OwnedArray.h:534
const TypeOfCriticalSectionToUse & getLock() const noexcept
Definition juce_OwnedArray.h:839
void addArray(const std::initializer_list< OtherArrayType > &items)
Definition juce_OwnedArray.h:477
void sort(ElementComparator &comparator, bool retainOrderOfEquivalentItems=false) noexcept
Definition juce_OwnedArray.h:821
ObjectClass * insert(int indexToInsertAt, ObjectClass *newObject)
Definition juce_OwnedArray.h:336
void deleteAllObjects()
Definition juce_OwnedArray.h:855
ObjectClass ** getRawDataPointer() noexcept
Definition juce_OwnedArray.h:192
friend class OwnedArray
Definition juce_OwnedArray.h:868
ObjectClass ** data() noexcept
Definition juce_OwnedArray.h:233
OwnedArray(const std::initializer_list< ObjectClass * > &items)
Definition juce_OwnedArray.h:74
void removeRange(int startIndex, int numberToRemove, bool deleteObjects=true)
Definition juce_OwnedArray.h:682
ObjectClass * getLast() const noexcept
Definition juce_OwnedArray.h:182
bool contains(const ObjectClass *objectToLookFor) const noexcept
Definition juce_OwnedArray.h:269
* e
Definition inflate.c:1404
register unsigned i
Definition inflate.c:1575
unsigned s
Definition inflate.c:1555
#define jassert(expression)
#define JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(className)
#define jassertfalse
Definition carla_juce.cpp:31
Type * createCopyIfNotNull(const Type *objectToCopy)
Definition juce_Memory.h:60
static int findInsertIndexInSortedArray(ElementComparator &comparator, ElementType *const array, const ElementType newElement, int firstElement, int lastElement)
Definition juce_ElementComparator.h:126
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Definition juce_MathsFunctions.h:262
static void sortArray(ElementComparator &comparator, ElementType *const array, int firstElement, int lastElement, const bool retainOrderOfEquivalentItems)
Definition juce_ElementComparator.h:81
void ignoreUnused(Types &&...) noexcept
Definition juce_MathsFunctions.h:333
bool isPositiveAndBelow(Type1 valueToTest, Type2 upperLimit) noexcept
Definition juce_MathsFunctions.h:279
static void destroy(ObjectType *object)
Definition juce_ContainerDeletePolicy.h:42
ulg size
Definition extract.c:2350
#define const
Definition zconf.h:137