@@ -10,12 +10,19 @@ in the source distribution for its full text.
1010#include "Vector.h"
1111
1212#include <assert.h>
13+ #include <stdint.h>
1314#include <stdlib.h>
1415#include <string.h>
1516
1617#include "XUtils.h"
18+ #include "generic/sort.h"
1719
1820
21+ typedef struct VectorSortContext_ {
22+ Object_Compare compare ;
23+ void * compareContext ;
24+ } VectorSortContext ;
25+
1926Vector * Vector_new (const ObjectClass * type , bool owner , int size ) {
2027 Vector * this ;
2128
@@ -93,97 +100,24 @@ void Vector_prune(Vector* this) {
93100 memset (this -> array , '\0' , this -> arraySize * sizeof (Object * ));
94101}
95102
96- //static int comparisons = 0;
97-
98- static void swap (Object * * array , int indexA , int indexB ) {
99- assert (indexA >= 0 );
100- assert (indexB >= 0 );
101- Object * tmp = array [indexA ];
102- array [indexA ] = array [indexB ];
103- array [indexB ] = tmp ;
104- }
105-
106- static int partition (Object * * array , int left , int right , int pivotIndex , Object_Compare compare , void * context ) {
107- const Object * pivotValue = array [pivotIndex ];
108- swap (array , pivotIndex , right );
109- int storeIndex = left ;
110- for (int i = left ; i < right ; i ++ ) {
111- //comparisons++;
112- if (compare (array [i ], pivotValue , context ) <= 0 ) {
113- swap (array , i , storeIndex );
114- storeIndex ++ ;
115- }
116- }
117- swap (array , storeIndex , right );
118- return storeIndex ;
119- }
120-
121- static void quickSort (Object * * array , int left , int right , Object_Compare compare , void * context ) {
122- if (left >= right )
123- return ;
124-
125- int pivotIndex = left + (right - left ) / 2 ;
126- int pivotNewIndex = partition (array , left , right , pivotIndex , compare , context );
127- quickSort (array , left , pivotNewIndex - 1 , compare , context );
128- quickSort (array , pivotNewIndex + 1 , right , compare , context );
129- }
130-
131- // If I were to use only one sorting algorithm for both cases, it would probably be this one:
132- /*
133-
134- static void combSort(Object** array, int left, int right, Object_Compare compare, void* context) {
135- int gap = right - left;
136- bool swapped = true;
137- while ((gap > 1) || swapped) {
138- if (gap > 1) {
139- gap = (int)((double)gap / 1.247330950103979);
140- }
141- swapped = false;
142- for (int i = left; gap + i <= right; i++) {
143- comparisons++;
144- if (compare(array[i], array[i+gap], context) > 0) {
145- swap(array, i, i+gap);
146- swapped = true;
147- }
148- }
149- }
150- }
151-
152- */
103+ ATTR_NONNULL
104+ static int Vector_sortCompare (const void * p1 , const void * p2 , void * context ) {
105+ VectorSortContext * vc = (VectorSortContext * ) context ;
153106
154- static void insertionSort (Object * * array , int left , int right , Object_Compare compare , void * context ) {
155- for (int i = left + 1 ; i <= right ; i ++ ) {
156- Object * t = array [i ];
157- int j = i - 1 ;
158- while (j >= left ) {
159- //comparisons++;
160- if (compare (array [j ], t , context ) <= 0 )
161- break ;
162-
163- array [j + 1 ] = array [j ];
164- j -- ;
165- }
166- array [j + 1 ] = t ;
167- }
107+ return vc -> compare (* (const void * const * )p1 , * (const void * const * )p2 , vc -> compareContext );
168108}
169109
170- void Vector_quickSort ( Vector * this , Object_Compare compare , void * context ) {
171- if (! compare ) {
172- assert ( this -> type -> compare );
173- compare = this -> type -> compare ;
174- }
175- assert ( Vector_isConsistent ( this )) ;
176- quickSort ( this -> array , 0 , this -> items - 1 , compare , context );
110+ ATTR_NONNULL_N ( 1 )
111+ void Vector_sort ( Vector * this , Object_Compare compare , void * context ) {
112+ VectorSortContext vc = {
113+ . compare = compare ? compare : this -> type -> compare ,
114+ . compareContext = context ? context : this ,
115+ } ;
116+ assert ( vc . compare );
177117 assert (Vector_isConsistent (this ));
178- }
179118
180- void Vector_insertionSort (Vector * this , Object_Compare compare , void * context ) {
181- if (!compare ) {
182- assert (this -> type -> compare );
183- compare = this -> type -> compare ;
184- }
185- assert (Vector_isConsistent (this ));
186- insertionSort (this -> array , 0 , this -> items - 1 , compare , context );
119+ Generic_sort (this -> array , this -> items , sizeof (* this -> array ), Vector_sortCompare , & vc );
120+
187121 assert (Vector_isConsistent (this ));
188122}
189123
0 commit comments