2 ==============================================================================
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
7 JUCE is an open source library subject to commercial or open-source
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.
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
20 ==============================================================================
28 /** This is an internal helper class which converts a juce ElementComparator style
29 class (using a "compareElements" method) into a class that's compatible with
30 std::sort (i.e. using an operator() to compare the elements)
34 template <typename ElementComparator
>
35 struct SortFunctionConverter
37 SortFunctionConverter (ElementComparator
& e
) : comparator (e
) {}
38 SortFunctionConverter (const SortFunctionConverter
&) = default;
40 template <typename Type
>
41 bool operator() (Type a
, Type b
) { return comparator
.compareElements (a
, b
) < 0; }
44 ElementComparator
& comparator
;
46 SortFunctionConverter
& operator= (const SortFunctionConverter
&) = delete;
52 //==============================================================================
54 Sorts a range of elements in an array.
56 The comparator object that is passed-in must define a public method with the following
59 int compareElements (ElementType first, ElementType second);
62 ..and this method must return:
63 - a value of < 0 if the first comes before the second
64 - a value of 0 if the two objects are equivalent
65 - a value of > 0 if the second comes before the first
67 To improve performance, the compareElements() method can be declared as static or const.
69 @param comparator an object which defines a compareElements() method
70 @param array the array to sort
71 @param firstElement the index of the first element of the range to be sorted
72 @param lastElement the index of the last element in the range that needs
73 sorting (this is inclusive)
74 @param retainOrderOfEquivalentItems if true, the order of items that the
75 comparator deems the same will be maintained - this will be
76 a slower algorithm than if they are allowed to be moved around.
78 @see sortArrayRetainingOrder
80 template <class ElementType
, class ElementComparator
>
81 static void sortArray (ElementComparator
& comparator
,
82 ElementType
* const array
,
85 const bool retainOrderOfEquivalentItems
)
87 jassert (firstElement
>= 0);
89 if (lastElement
> firstElement
)
91 SortFunctionConverter
<ElementComparator
> converter (comparator
);
93 if (retainOrderOfEquivalentItems
)
94 std::stable_sort (array
+ firstElement
, array
+ lastElement
+ 1, converter
);
96 std::sort (array
+ firstElement
, array
+ lastElement
+ 1, converter
);
101 //==============================================================================
103 Searches a sorted array of elements, looking for the index at which a specified value
104 should be inserted for it to be in the correct order.
106 The comparator object that is passed-in must define a public method with the following
109 int compareElements (ElementType first, ElementType second);
112 ..and this method must return:
113 - a value of < 0 if the first comes before the second
114 - a value of 0 if the two objects are equivalent
115 - a value of > 0 if the second comes before the first
117 To improve performance, the compareElements() method can be declared as static or const.
119 @param comparator an object which defines a compareElements() method
120 @param array the array to search
121 @param newElement the value that is going to be inserted
122 @param firstElement the index of the first element to search
123 @param lastElement the index of the last element in the range (this is non-inclusive)
125 template <class ElementType
, class ElementComparator
>
126 static int findInsertIndexInSortedArray (ElementComparator
& comparator
,
127 ElementType
* const array
,
128 const ElementType newElement
,
132 jassert (firstElement
<= lastElement
);
134 ignoreUnused (comparator
); // if you pass in an object with a static compareElements() method, this
135 // avoids getting warning messages about the parameter being unused
137 while (firstElement
< lastElement
)
139 if (comparator
.compareElements (newElement
, array
[firstElement
]) == 0)
146 const int halfway
= (firstElement
+ lastElement
) >> 1;
148 if (halfway
== firstElement
)
150 if (comparator
.compareElements (newElement
, array
[halfway
]) >= 0)
155 else if (comparator
.compareElements (newElement
, array
[halfway
]) >= 0)
157 firstElement
= halfway
;
161 lastElement
= halfway
;
169 //==============================================================================
171 A simple ElementComparator class that can be used to sort an array of
172 objects that support the '<' operator.
174 This will work for primitive types and objects that implement operator<().
178 DefaultElementComparator<int> sorter;
179 myArray.sort (sorter);
182 @see ElementComparator
186 template <class ElementType
>
187 class DefaultElementComparator
190 using ParameterType
= typename
TypeHelpers::ParameterType
<ElementType
>::type
;
193 static int compareElements (ParameterType first
, ParameterType second
)
195 return (first
< second
) ? -1 : ((second
< first
) ? 1 : 0);