LMMS
Loading...
Searching...
No Matches
juce_ReferenceCountedArray.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//==============================================================================
49template <class ObjectClass, class TypeOfCriticalSectionToUse = DummyCriticalSection>
51{
52public:
54
55 //==============================================================================
60
63 {
64 const ScopedLockType lock (other.getLock());
65 values.addArray (other.begin(), other.size());
66
67 for (auto* o : *this)
68 if (o != nullptr)
69 o->incReferenceCount();
70 }
71
74 : values (std::move (other.values))
75 {
76 }
77
79 template <class OtherObjectClass, class OtherCriticalSection>
81 {
83 values.addArray (other.begin(), other.size());
84
85 for (auto* o : *this)
86 if (o != nullptr)
87 o->incReferenceCount();
88 }
89
93 ReferenceCountedArray& operator= (const ReferenceCountedArray& other) noexcept
94 {
96 auto otherCopy = other;
97 swapWith (otherCopy);
98 return *this;
99 }
100
104 template <class OtherObjectClass>
106 {
107 auto otherCopy = other;
108 swapWith (otherCopy);
109 return *this;
110 }
111
113 ReferenceCountedArray& operator= (ReferenceCountedArray&& other) noexcept
114 {
116 values = std::move (other.values);
117 return *this;
118 }
119
127
128 //==============================================================================
132 void clear()
133 {
134 const ScopedLockType lock (getLock());
135 clearQuick();
136 values.setAllocatedSize (0);
137 }
138
144 {
145 const ScopedLockType lock (getLock());
147 }
148
150 inline int size() const noexcept
151 {
152 return values.size();
153 }
154
156 inline bool isEmpty() const noexcept
157 {
158 return size() == 0;
159 }
160
169 inline ObjectClassPtr operator[] (int index) const noexcept
170 {
171 return ObjectClassPtr (getObjectPointer (index));
172 }
173
180 inline ObjectClassPtr getUnchecked (int index) const noexcept
181 {
183 }
184
193 inline ObjectClass* getObjectPointer (int index) const noexcept
194 {
195 const ScopedLockType lock (getLock());
196 return values.getValueWithDefault (index);
197 }
198
202 inline ObjectClass* getObjectPointerUnchecked (int index) const noexcept
203 {
204 const ScopedLockType lock (getLock());
205 return values[index];
206 }
207
214 {
215 const ScopedLockType lock (getLock());
216 return values.getFirst();
217 }
218
225 {
226 const ScopedLockType lock (getLock());
227 return values.getLast();
228 }
229
234 inline ObjectClass** getRawDataPointer() const noexcept
235 {
236 return values.begin();
237 }
238
239 //==============================================================================
243 inline ObjectClass** begin() noexcept
244 {
245 return values.begin();
246 }
247
251 inline ObjectClass* const* begin() const noexcept
252 {
253 return values.begin();
254 }
255
259 inline ObjectClass** end() noexcept
260 {
261 return values.end();
262 }
263
267 inline ObjectClass* const* end() const noexcept
268 {
269 return values.end();
270 }
271
275 inline ObjectClass** data() noexcept
276 {
277 return begin();
278 }
279
283 inline ObjectClass* const* data() const noexcept
284 {
285 return begin();
286 }
287
288 //==============================================================================
294 int indexOf (const ObjectClass* objectToLookFor) const noexcept
295 {
296 const ScopedLockType lock (getLock());
297 auto* e = values.begin();
298 auto* endPointer = values.end();
299
300 while (e != endPointer)
301 {
302 if (objectToLookFor == *e)
303 return static_cast<int> (e - values.begin());
304
305 ++e;
306 }
307
308 return -1;
309 }
310
316 int indexOf (const ObjectClassPtr& objectToLookFor) const noexcept { return indexOf (objectToLookFor.get()); }
317
323 bool contains (const ObjectClass* objectToLookFor) const noexcept
324 {
325 const ScopedLockType lock (getLock());
326 auto* e = values.begin();
327 auto* endPointer = values.end();
328
329 while (e != endPointer)
330 {
331 if (objectToLookFor == *e)
332 return true;
333
334 ++e;
335 }
336
337 return false;
338 }
339
345 bool contains (const ObjectClassPtr& objectToLookFor) const noexcept { return contains (objectToLookFor.get()); }
346
354 ObjectClass* add (ObjectClass* newObject)
355 {
356 const ScopedLockType lock (getLock());
357 values.add (newObject);
358
359 if (newObject != nullptr)
360 newObject->incReferenceCount();
361
362 return newObject;
363 }
364
372 ObjectClass* add (const ObjectClassPtr& newObject) { return add (newObject.get()); }
373
387 ObjectClass* insert (int indexToInsertAt, ObjectClass* newObject)
388 {
389 values.insert (indexToInsertAt, newObject, 1);
390
391 if (newObject != nullptr)
392 newObject->incReferenceCount();
393
394 return newObject;
395 }
396
410 ObjectClass* insert (int indexToInsertAt, const ObjectClassPtr& newObject) { return insert (indexToInsertAt, newObject.get()); }
411
420 bool addIfNotAlreadyThere (ObjectClass* newObject)
421 {
422 const ScopedLockType lock (getLock());
423
424 if (contains (newObject))
425 return false;
426
427 add (newObject);
428 return true;
429 }
430
439 bool addIfNotAlreadyThere (const ObjectClassPtr& newObject) { return addIfNotAlreadyThere (newObject.get()); }
440
453 void set (int indexToChange, ObjectClass* newObject)
454 {
455 if (indexToChange >= 0)
456 {
457 const ScopedLockType lock (getLock());
458
459 if (newObject != nullptr)
460 newObject->incReferenceCount();
461
462 if (indexToChange < values.size())
463 {
464 auto* e = values[indexToChange];
465 values[indexToChange] = newObject;
467 }
468 else
469 {
470 values.add (newObject);
471 }
472 }
473 }
474
487 void set (int indexToChange, const ObjectClassPtr& newObject) { set (indexToChange, newObject.get()); }
488
498 void addArray (const ReferenceCountedArray& arrayToAddFrom,
499 int startIndex = 0,
500 int numElementsToAdd = -1) noexcept
501 {
502 const ScopedLockType lock1 (arrayToAddFrom.getLock());
503
504 {
505 const ScopedLockType lock2 (getLock());
506
507 auto numElementsAdded = values.addArray (arrayToAddFrom.values, startIndex, numElementsToAdd);
508 auto** e = values.end();
509
510 for (int i = 0; i < numElementsAdded; ++i)
511 (*(--e))->incReferenceCount();
512 }
513 }
514
527 template <class ElementComparator>
528 int addSorted (ElementComparator& comparator, ObjectClass* newObject) noexcept
529 {
530 const ScopedLockType lock (getLock());
531 auto index = findInsertIndexInSortedArray (comparator, values.begin(), newObject, 0, values.size());
532 insert (index, newObject);
533 return index;
534 }
535
541 template <class ElementComparator>
542 void addOrReplaceSorted (ElementComparator& comparator, ObjectClass* newObject) noexcept
543 {
544 const ScopedLockType lock (getLock());
545 auto index = findInsertIndexInSortedArray (comparator, values.begin(), newObject, 0, values.size());
546
547 if (index > 0 && comparator.compareElements (newObject, values[index - 1]) == 0)
548 set (index - 1, newObject); // replace an existing object that matches
549 else
550 insert (index, newObject); // no match, so insert the new one
551 }
552
565 template <class ElementComparator>
566 int indexOfSorted (ElementComparator& comparator,
567 const ObjectClass* objectToLookFor) const noexcept
568 {
569 ignoreUnused (comparator);
570 const ScopedLockType lock (getLock());
571 int s = 0, e = values.size();
572
573 while (s < e)
574 {
575 if (comparator.compareElements (objectToLookFor, values[s]) == 0)
576 return s;
577
578 auto halfway = (s + e) / 2;
579
580 if (halfway == s)
581 break;
582
583 if (comparator.compareElements (objectToLookFor, values[halfway]) >= 0)
584 s = halfway;
585 else
586 e = halfway;
587 }
588
589 return -1;
590 }
591
592 //==============================================================================
606 void remove (int indexToRemove)
607 {
608 const ScopedLockType lock (getLock());
609
610 if (isPositiveAndBelow (indexToRemove, values.size()))
611 {
612 auto* e = *(values.begin() + indexToRemove);
613 values.removeElements (indexToRemove, 1);
615
616 if ((values.size() << 1) < values.capacity())
618 }
619 }
620
630 ObjectClassPtr removeAndReturn (int indexToRemove)
631 {
632 ObjectClassPtr removedItem;
633 const ScopedLockType lock (getLock());
634
635 if (isPositiveAndBelow (indexToRemove, values.size()))
636 {
637 auto* e = *(values.begin() + indexToRemove);
638 removedItem = e;
639 values.removeElements (indexToRemove, 1);
641
642 if ((values.size() << 1) < values.capacity())
644 }
645
646 return removedItem;
647 }
648
657 void removeObject (ObjectClass* objectToRemove)
658 {
659 const ScopedLockType lock (getLock());
660 remove (indexOf (objectToRemove));
661 }
662
671 void removeObject (const ObjectClassPtr& objectToRemove) { removeObject (objectToRemove.get()); }
672
688 void removeRange (int startIndex,
689 int numberToRemove)
690 {
691 const ScopedLockType lock (getLock());
692 startIndex = jlimit (0, values.size(), startIndex);
693 auto endIndex = jlimit (0, values.size(), startIndex + numberToRemove);
694 numberToRemove = endIndex - startIndex;
695
696 if (numberToRemove > 0)
697 {
698 Array<ObjectClass*> objectsToRemove;
699 objectsToRemove.addArray (values.begin() + startIndex, numberToRemove);
700
701 values.removeElements (startIndex, numberToRemove);
702
703 for (auto& o : objectsToRemove)
704 releaseObject (o);
705
706 if ((values.size() << 1) < values.capacity())
708 }
709 }
710
719 void removeLast (int howManyToRemove = 1)
720 {
721 const ScopedLockType lock (getLock());
722
723 if (howManyToRemove > values.size())
724 howManyToRemove = values.size();
725
726 while (--howManyToRemove >= 0)
727 remove (values.size() - 1);
728 }
729
735 void swap (int index1, int index2) noexcept
736 {
737 const ScopedLockType lock (getLock());
738
739 if (isPositiveAndBelow (index1, values.size())
740 && isPositiveAndBelow (index2, values.size()))
741 {
742 std::swap (values[index1], values[index2]);
743 }
744 }
745
759 void move (int currentIndex, int newIndex) noexcept
760 {
761 if (currentIndex != newIndex)
762 {
763 const ScopedLockType lock (getLock());
764 values.move (currentIndex, newIndex);
765 }
766 }
767
768 //==============================================================================
774 template <class OtherArrayType>
775 void swapWith (OtherArrayType& otherArray) noexcept
776 {
777 const ScopedLockType lock1 (getLock());
778 const typename OtherArrayType::ScopedLockType lock2 (otherArray.getLock());
779 values.swapWith (otherArray.values);
780 }
781
782 //==============================================================================
787 bool operator== (const ReferenceCountedArray& other) const noexcept
788 {
789 const ScopedLockType lock2 (other.getLock());
790 const ScopedLockType lock1 (getLock());
791 return values == other.values;
792 }
793
798 bool operator!= (const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& other) const noexcept
799 {
800 return ! operator== (other);
801 }
802
803 //==============================================================================
830 template <class ElementComparator>
831 void sort (ElementComparator& comparator,
832 bool retainOrderOfEquivalentItems = false) noexcept
833 {
834 // If you pass in an object with a static compareElements() method, this
835 // avoids getting warning messages about the parameter being unused
836 ignoreUnused (comparator);
837
838 const ScopedLockType lock (getLock());
839 sortArray (comparator, values.begin(), 0, values.size() - 1, retainOrderOfEquivalentItems);
840 }
841
842 //==============================================================================
850 {
851 const ScopedLockType lock (getLock());
852 values.shrinkToNoMoreThan (values.size());
853 }
854
861 void ensureStorageAllocated (const int minNumElements)
862 {
863 const ScopedLockType lock (getLock());
864 values.ensureAllocatedSize (minNumElements);
865 }
866
867 //==============================================================================
872 inline const TypeOfCriticalSectionToUse& getLock() const noexcept { return values; }
873
875 using ScopedLockType = typename TypeOfCriticalSectionToUse::ScopedLockType;
876
877 //==============================================================================
878 #ifndef DOXYGEN
879 [[deprecated ("This method has been replaced by a more flexible templated version and renamed "
880 "to swapWith to be more consistent with the names used in other classes.")]]
881 void swapWithArray (ReferenceCountedArray& other) noexcept { swapWith (other); }
882 #endif
883
884private:
885 //==============================================================================
887
889 {
890 auto i = values.size();
891
892 while (--i >= 0)
893 {
894 auto* e = values[i];
895 values.removeElements (i, 1);
897 }
898 }
899
900 static void releaseObject (ObjectClass* o)
901 {
902 if (o != nullptr && o->decReferenceCountWithoutDeleting())
904 }
905};
906
907} // namespace juce
#define noexcept
Definition DistrhoDefines.h:72
Definition juce_ArrayBase.h:41
Definition juce_Array.h:56
void addArray(const Type *elementsToAdd, int numElementsToAdd)
Definition juce_Array.h:583
ReferenceCountedArray(ReferenceCountedArray &&other) noexcept
Definition juce_ReferenceCountedArray.h:73
ObjectClass * add(const ObjectClassPtr &newObject)
Definition juce_ReferenceCountedArray.h:372
bool isEmpty() const noexcept
Definition juce_ReferenceCountedArray.h:156
int indexOf(const ObjectClass *objectToLookFor) const noexcept
Definition juce_ReferenceCountedArray.h:294
ReferenceCountedArray(const ReferenceCountedArray &other) noexcept
Definition juce_ReferenceCountedArray.h:62
int size() const noexcept
Definition juce_ReferenceCountedArray.h:150
void removeLast(int howManyToRemove=1)
Definition juce_ReferenceCountedArray.h:719
ObjectClass *const * end() const noexcept
Definition juce_ReferenceCountedArray.h:267
void minimiseStorageOverheads() noexcept
Definition juce_ReferenceCountedArray.h:849
void set(int indexToChange, ObjectClass *newObject)
Definition juce_ReferenceCountedArray.h:453
ObjectClass *const * begin() const noexcept
Definition juce_ReferenceCountedArray.h:251
ObjectClass * insert(int indexToInsertAt, const ObjectClassPtr &newObject)
Definition juce_ReferenceCountedArray.h:410
int indexOfSorted(ElementComparator &comparator, const ObjectClass *objectToLookFor) const noexcept
Definition juce_ReferenceCountedArray.h:566
typename TypeOfCriticalSectionToUse::ScopedLockType ScopedLockType
Definition juce_ReferenceCountedArray.h:875
bool addIfNotAlreadyThere(ObjectClass *newObject)
Definition juce_ReferenceCountedArray.h:420
void remove(int indexToRemove)
Definition juce_ReferenceCountedArray.h:606
void sort(ElementComparator &comparator, bool retainOrderOfEquivalentItems=false) noexcept
Definition juce_ReferenceCountedArray.h:831
ReferenceCountedArray(const ReferenceCountedArray< OtherObjectClass, OtherCriticalSection > &other) noexcept
Definition juce_ReferenceCountedArray.h:80
void removeObject(ObjectClass *objectToRemove)
Definition juce_ReferenceCountedArray.h:657
ObjectClass * getObjectPointer(int index) const noexcept
Definition juce_ReferenceCountedArray.h:193
void swap(int index1, int index2) noexcept
Definition juce_ReferenceCountedArray.h:735
ObjectClassPtr getFirst() const noexcept
Definition juce_ReferenceCountedArray.h:213
void ensureStorageAllocated(const int minNumElements)
Definition juce_ReferenceCountedArray.h:861
~ReferenceCountedArray()
Definition juce_ReferenceCountedArray.h:123
void clearQuick()
Definition juce_ReferenceCountedArray.h:143
void set(int indexToChange, const ObjectClassPtr &newObject)
Definition juce_ReferenceCountedArray.h:487
ObjectClass *const * data() const noexcept
Definition juce_ReferenceCountedArray.h:283
ReferenceCountedObjectPtr< ObjectClass > ObjectClassPtr
Definition juce_ReferenceCountedArray.h:53
const TypeOfCriticalSectionToUse & getLock() const noexcept
Definition juce_ReferenceCountedArray.h:872
ObjectClassPtr getUnchecked(int index) const noexcept
Definition juce_ReferenceCountedArray.h:180
static void releaseObject(ObjectClass *o)
Definition juce_ReferenceCountedArray.h:900
void releaseAllObjects()
Definition juce_ReferenceCountedArray.h:888
ObjectClass ** begin() noexcept
Definition juce_ReferenceCountedArray.h:243
void addOrReplaceSorted(ElementComparator &comparator, ObjectClass *newObject) noexcept
Definition juce_ReferenceCountedArray.h:542
bool contains(const ObjectClass *objectToLookFor) const noexcept
Definition juce_ReferenceCountedArray.h:323
void removeRange(int startIndex, int numberToRemove)
Definition juce_ReferenceCountedArray.h:688
ObjectClass * getObjectPointerUnchecked(int index) const noexcept
Definition juce_ReferenceCountedArray.h:202
void move(int currentIndex, int newIndex) noexcept
Definition juce_ReferenceCountedArray.h:759
ObjectClassPtr removeAndReturn(int indexToRemove)
Definition juce_ReferenceCountedArray.h:630
ObjectClass ** end() noexcept
Definition juce_ReferenceCountedArray.h:259
void clear()
Definition juce_ReferenceCountedArray.h:132
ObjectClass ** getRawDataPointer() const noexcept
Definition juce_ReferenceCountedArray.h:234
bool contains(const ObjectClassPtr &objectToLookFor) const noexcept
Definition juce_ReferenceCountedArray.h:345
void swapWithArray(ReferenceCountedArray &other) noexcept
Definition juce_ReferenceCountedArray.h:881
ObjectClass ** data() noexcept
Definition juce_ReferenceCountedArray.h:275
void swapWith(OtherArrayType &otherArray) noexcept
Definition juce_ReferenceCountedArray.h:775
bool addIfNotAlreadyThere(const ObjectClassPtr &newObject)
Definition juce_ReferenceCountedArray.h:439
int addSorted(ElementComparator &comparator, ObjectClass *newObject) noexcept
Definition juce_ReferenceCountedArray.h:528
int indexOf(const ObjectClassPtr &objectToLookFor) const noexcept
Definition juce_ReferenceCountedArray.h:316
ObjectClassPtr getLast() const noexcept
Definition juce_ReferenceCountedArray.h:224
void addArray(const ReferenceCountedArray &arrayToAddFrom, int startIndex=0, int numElementsToAdd=-1) noexcept
Definition juce_ReferenceCountedArray.h:498
ObjectClass * insert(int indexToInsertAt, ObjectClass *newObject)
Definition juce_ReferenceCountedArray.h:387
ArrayBase< ObjectClass *, TypeOfCriticalSectionToUse > values
Definition juce_ReferenceCountedArray.h:886
ObjectClass * add(ObjectClass *newObject)
Definition juce_ReferenceCountedArray.h:354
void removeObject(const ObjectClassPtr &objectToRemove)
Definition juce_ReferenceCountedArray.h:671
Definition juce_ReferenceCountedObject.h:247
ReferencedType * get() const noexcept
Definition juce_ReferenceCountedObject.h:381
* e
Definition inflate.c:1404
register unsigned i
Definition inflate.c:1575
unsigned s
Definition inflate.c:1555
Definition carla_juce.cpp:31
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