@@ -102,55 +102,20 @@ inline void timsort(RandomAccessIterator const first, RandomAccessIterator const
102102/* *
103103 * Same as std::stable_sort(first, last, c).
104104 */
105- template <typename RandomAccessIterator, typename LessFunction >
106- inline void timsort (RandomAccessIterator const first, RandomAccessIterator const last, LessFunction compare);
105+ template <typename RandomAccessIterator, typename Compare >
106+ inline void timsort (RandomAccessIterator const first, RandomAccessIterator const last, Compare compare);
107107
108108// ---------------------------------------
109109// Implementation
110110// ---------------------------------------
111111
112- template <typename Value, typename LessFunction> class Compare {
113- public:
114- typedef Value value_type;
115- typedef LessFunction func_type;
116-
117- Compare (LessFunction f) : less_(f) {
118- }
119- Compare (const Compare<value_type, func_type> &other) : less_(other.less_) {
120- }
121-
122- bool lt (value_type x, value_type y) {
123- return less_ (x, y);
124- }
125- bool le (value_type x, value_type y) {
126- return less_ (x, y) || !less_ (y, x);
127- }
128- bool gt (value_type x, value_type y) {
129- return !less_ (x, y) && less_ (y, x);
130- }
131- bool ge (value_type x, value_type y) {
132- return !less_ (x, y);
133- }
134-
135- func_type &less_function () {
136- return less_;
137- }
138-
139- private:
140- func_type less_;
141- };
142-
143- template <typename RandomAccessIterator, typename LessFunction> class TimSort {
112+ template <typename RandomAccessIterator, typename Compare> class TimSort {
144113 typedef RandomAccessIterator iter_t ;
145114 typedef typename std::iterator_traits<iter_t >::value_type value_t ;
146115 typedef typename std::iterator_traits<iter_t >::reference ref_t ;
147116 typedef typename std::iterator_traits<iter_t >::difference_type diff_t ;
148- typedef Compare<const value_t &, LessFunction> compare_t ;
149117
150118 static const int MIN_MERGE = 32 ;
151-
152- compare_t comp_;
153-
154119 static const int MIN_GALLOP = 7 ;
155120
156121 int minGallop_; // default to MIN_GALLOP
@@ -167,7 +132,7 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
167132 };
168133 std::vector<run> pending_;
169134
170- static void sort (iter_t const lo, iter_t const hi, compare_t c ) {
135+ static void sort (iter_t const lo, iter_t const hi, Compare compare ) {
171136 GFX_TIMSORT_ASSERT (lo <= hi);
172137
173138 diff_t nRemaining = (hi - lo);
@@ -176,40 +141,40 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
176141 }
177142
178143 if (nRemaining < MIN_MERGE) {
179- diff_t const initRunLen = countRunAndMakeAscending (lo, hi, c );
144+ diff_t const initRunLen = countRunAndMakeAscending (lo, hi, compare );
180145 GFX_TIMSORT_LOG (" initRunLen: " << initRunLen);
181- binarySort (lo, hi, lo + initRunLen, c );
146+ binarySort (lo, hi, lo + initRunLen, compare );
182147 return ;
183148 }
184149
185- TimSort ts (c) ;
150+ TimSort ts;
186151 diff_t const minRun = minRunLength (nRemaining);
187152 iter_t cur = lo;
188153 do {
189- diff_t runLen = countRunAndMakeAscending (cur, hi, c );
154+ diff_t runLen = countRunAndMakeAscending (cur, hi, compare );
190155
191156 if (runLen < minRun) {
192157 diff_t const force = std::min (nRemaining, minRun);
193- binarySort (cur, cur + force, cur + runLen, c );
158+ binarySort (cur, cur + force, cur + runLen, compare );
194159 runLen = force;
195160 }
196161
197162 ts.pushRun (cur, runLen);
198- ts.mergeCollapse ();
163+ ts.mergeCollapse (compare );
199164
200165 cur += runLen;
201166 nRemaining -= runLen;
202167 } while (nRemaining != 0 );
203168
204169 GFX_TIMSORT_ASSERT (cur == hi);
205- ts.mergeForceCollapse ();
170+ ts.mergeForceCollapse (compare );
206171 GFX_TIMSORT_ASSERT (ts.pending_ .size () == 1 );
207172
208173 GFX_TIMSORT_LOG (" size: " << (hi - lo) << " tmp_.size(): " << ts.tmp_ .size ()
209174 << " pending_.size(): " << ts.pending_ .size ());
210175 } // sort()
211176
212- static void binarySort (iter_t const lo, iter_t const hi, iter_t start, compare_t compare) {
177+ static void binarySort (iter_t const lo, iter_t const hi, iter_t start, Compare compare) {
213178 GFX_TIMSORT_ASSERT (lo <= start && start <= hi);
214179 if (start == lo) {
215180 ++start;
@@ -218,29 +183,29 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
218183 GFX_TIMSORT_ASSERT (lo <= start);
219184 /* const*/ value_t pivot = GFX_TIMSORT_MOVE (*start);
220185
221- iter_t const pos = std::upper_bound (lo, start, pivot, compare. less_function () );
186+ iter_t const pos = std::upper_bound (lo, start, pivot, compare);
222187 for (iter_t p = start; p > pos; --p) {
223188 *p = GFX_TIMSORT_MOVE (*(p - 1 ));
224189 }
225190 *pos = GFX_TIMSORT_MOVE (pivot);
226191 }
227192 }
228193
229- static diff_t countRunAndMakeAscending (iter_t const lo, iter_t const hi, compare_t compare) {
194+ static diff_t countRunAndMakeAscending (iter_t const lo, iter_t const hi, Compare compare) {
230195 GFX_TIMSORT_ASSERT (lo < hi);
231196
232197 iter_t runHi = lo + 1 ;
233198 if (runHi == hi) {
234199 return 1 ;
235200 }
236201
237- if (compare. lt (*(runHi++), *lo)) { // descending
238- while (runHi < hi && compare. lt (*runHi, *(runHi - 1 ))) {
202+ if (compare (*(runHi++), *lo)) { // descending
203+ while (runHi < hi && compare (*runHi, *(runHi - 1 ))) {
239204 ++runHi;
240205 }
241206 std::reverse (lo, runHi);
242207 } else { // ascending
243- while (runHi < hi && compare. ge (*runHi, *(runHi - 1 ))) {
208+ while (runHi < hi && ! compare (*runHi, *(runHi - 1 ))) {
244209 ++runHi;
245210 }
246211 }
@@ -259,14 +224,14 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
259224 return n + r;
260225 }
261226
262- TimSort (compare_t c ) : comp_(c), minGallop_(MIN_GALLOP) {
227+ TimSort () : minGallop_(MIN_GALLOP) {
263228 }
264229
265230 void pushRun (iter_t const runBase, diff_t const runLen) {
266231 pending_.push_back (run (runBase, runLen));
267232 }
268233
269- void mergeCollapse () {
234+ void mergeCollapse (Compare compare ) {
270235 while (pending_.size () > 1 ) {
271236 diff_t n = pending_.size () - 2 ;
272237
@@ -275,27 +240,27 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
275240 if (pending_[n - 1 ].len < pending_[n + 1 ].len ) {
276241 --n;
277242 }
278- mergeAt (n);
243+ mergeAt (n, compare );
279244 } else if (pending_[n].len <= pending_[n + 1 ].len ) {
280- mergeAt (n);
245+ mergeAt (n, compare );
281246 } else {
282247 break ;
283248 }
284249 }
285250 }
286251
287- void mergeForceCollapse () {
252+ void mergeForceCollapse (Compare compare ) {
288253 while (pending_.size () > 1 ) {
289254 diff_t n = pending_.size () - 2 ;
290255
291256 if (n > 0 && pending_[n - 1 ].len < pending_[n + 1 ].len ) {
292257 --n;
293258 }
294- mergeAt (n);
259+ mergeAt (n, compare );
295260 }
296261 }
297262
298- void mergeAt (diff_t const i) {
263+ void mergeAt (diff_t const i, Compare compare ) {
299264 diff_t const stackSize = pending_.size ();
300265 GFX_TIMSORT_ASSERT (stackSize >= 2 );
301266 GFX_TIMSORT_ASSERT (i >= 0 );
@@ -317,7 +282,7 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
317282
318283 pending_.pop_back ();
319284
320- diff_t const k = gallopRight (*base2, base1, len1, 0 );
285+ diff_t const k = gallopRight (*base2, base1, len1, 0 , compare );
321286 GFX_TIMSORT_ASSERT (k >= 0 );
322287
323288 base1 += k;
@@ -327,28 +292,29 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
327292 return ;
328293 }
329294
330- len2 = gallopLeft (*(base1 + (len1 - 1 )), base2, len2, len2 - 1 );
295+ len2 = gallopLeft (*(base1 + (len1 - 1 )), base2, len2, len2 - 1 , compare );
331296 GFX_TIMSORT_ASSERT (len2 >= 0 );
332297 if (len2 == 0 ) {
333298 return ;
334299 }
335300
336301 if (len1 <= len2) {
337- mergeLo (base1, len1, base2, len2);
302+ mergeLo (base1, len1, base2, len2, compare );
338303 } else {
339- mergeHi (base1, len1, base2, len2);
304+ mergeHi (base1, len1, base2, len2, compare );
340305 }
341306 }
342307
343- template <typename Iter> diff_t gallopLeft (ref_t key, Iter const base, diff_t const len, diff_t const hint) {
308+ template <typename Iter>
309+ diff_t gallopLeft (ref_t key, Iter const base, diff_t const len, diff_t const hint, Compare compare) {
344310 GFX_TIMSORT_ASSERT (len > 0 && hint >= 0 && hint < len);
345311
346312 diff_t lastOfs = 0 ;
347313 diff_t ofs = 1 ;
348314
349- if (comp_. gt (key, *(base + hint))) {
315+ if (compare ( *(base + hint), key )) {
350316 diff_t const maxOfs = len - hint;
351- while (ofs < maxOfs && comp_. gt (key, *(base + (hint + ofs)))) {
317+ while (ofs < maxOfs && compare ( *(base + (hint + ofs)), key )) {
352318 lastOfs = ofs;
353319 ofs = (ofs << 1 ) + 1 ;
354320
@@ -364,7 +330,7 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
364330 ofs += hint;
365331 } else {
366332 diff_t const maxOfs = hint + 1 ;
367- while (ofs < maxOfs && comp_. le (key, *(base + (hint - ofs)))) {
333+ while (ofs < maxOfs && ! compare ( *(base + (hint - ofs)), key )) {
368334 lastOfs = ofs;
369335 ofs = (ofs << 1 ) + 1 ;
370336
@@ -382,18 +348,19 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
382348 }
383349 GFX_TIMSORT_ASSERT (-1 <= lastOfs && lastOfs < ofs && ofs <= len);
384350
385- return std::lower_bound (base + (lastOfs + 1 ), base + ofs, key, comp_. less_function () ) - base;
351+ return std::lower_bound (base + (lastOfs + 1 ), base + ofs, key, compare ) - base;
386352 }
387353
388- template <typename Iter> diff_t gallopRight (ref_t key, Iter const base, diff_t const len, diff_t const hint) {
354+ template <typename Iter>
355+ diff_t gallopRight (ref_t key, Iter const base, diff_t const len, diff_t const hint, Compare compare) {
389356 GFX_TIMSORT_ASSERT (len > 0 && hint >= 0 && hint < len);
390357
391358 diff_t ofs = 1 ;
392359 diff_t lastOfs = 0 ;
393360
394- if (comp_. lt (key, *(base + hint))) {
361+ if (compare (key, *(base + hint))) {
395362 diff_t const maxOfs = hint + 1 ;
396- while (ofs < maxOfs && comp_. lt (key, *(base + (hint - ofs)))) {
363+ while (ofs < maxOfs && compare (key, *(base + (hint - ofs)))) {
397364 lastOfs = ofs;
398365 ofs = (ofs << 1 ) + 1 ;
399366
@@ -410,7 +377,7 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
410377 ofs = hint - tmp;
411378 } else {
412379 diff_t const maxOfs = len - hint;
413- while (ofs < maxOfs && comp_. ge (key, *(base + (hint + ofs)))) {
380+ while (ofs < maxOfs && ! compare (key, *(base + (hint + ofs)))) {
414381 lastOfs = ofs;
415382 ofs = (ofs << 1 ) + 1 ;
416383
@@ -427,10 +394,10 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
427394 }
428395 GFX_TIMSORT_ASSERT (-1 <= lastOfs && lastOfs < ofs && ofs <= len);
429396
430- return std::upper_bound (base + (lastOfs + 1 ), base + ofs, key, comp_. less_function () ) - base;
397+ return std::upper_bound (base + (lastOfs + 1 ), base + ofs, key, compare ) - base;
431398 }
432399
433- void mergeLo (iter_t const base1, diff_t len1, iter_t const base2, diff_t len2) {
400+ void mergeLo (iter_t const base1, diff_t len1, iter_t const base2, diff_t len2, Compare compare ) {
434401 GFX_TIMSORT_ASSERT (len1 > 0 && len2 > 0 && base1 + len1 == base2);
435402
436403 copy_to_tmp (base1, len1);
@@ -460,7 +427,7 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
460427 do {
461428 GFX_TIMSORT_ASSERT (len1 > 1 && len2 > 0 );
462429
463- if (comp_. lt (*cursor2, *cursor1)) {
430+ if (compare (*cursor2, *cursor1)) {
464431 *(dest++) = GFX_TIMSORT_MOVE (*(cursor2++));
465432 ++count2;
466433 count1 = 0 ;
@@ -480,7 +447,7 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
480447 do {
481448 GFX_TIMSORT_ASSERT (len1 > 1 && len2 > 0 );
482449
483- count1 = gallopRight (*cursor2, cursor1, len1, 0 );
450+ count1 = gallopRight (*cursor2, cursor1, len1, 0 , compare );
484451 if (count1 != 0 ) {
485452 GFX_TIMSORT_MOVE_BACKWARD (cursor1, cursor1 + count1, dest + count1);
486453 dest += count1;
@@ -496,7 +463,7 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
496463 goto epilogue;
497464 }
498465
499- count2 = gallopLeft (*cursor1, cursor2, len2, 0 );
466+ count2 = gallopLeft (*cursor1, cursor2, len2, 0 , compare );
500467 if (count2 != 0 ) {
501468 GFX_TIMSORT_MOVE_RANGE (cursor2, cursor2 + count2, dest);
502469 dest += count2;
@@ -536,7 +503,7 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
536503 }
537504 }
538505
539- void mergeHi (iter_t const base1, diff_t len1, iter_t const base2, diff_t len2) {
506+ void mergeHi (iter_t const base1, diff_t len1, iter_t const base2, diff_t len2, Compare compare ) {
540507 GFX_TIMSORT_ASSERT (len1 > 0 && len2 > 0 && base1 + len1 == base2);
541508
542509 copy_to_tmp (base2, len2);
@@ -574,7 +541,7 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
574541 do {
575542 GFX_TIMSORT_ASSERT (len1 > 0 && len2 > 1 );
576543
577- if (comp_. lt (*cursor2, *cursor1)) {
544+ if (compare (*cursor2, *cursor1)) {
578545 *(dest--) = GFX_TIMSORT_MOVE (*cursor1);
579546 ++count1;
580547 count2 = 0 ;
@@ -597,7 +564,7 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
597564 do {
598565 GFX_TIMSORT_ASSERT (len1 > 0 && len2 > 1 );
599566
600- count1 = len1 - gallopRight (*cursor2, base1, len1, len1 - 1 );
567+ count1 = len1 - gallopRight (*cursor2, base1, len1, len1 - 1 , compare );
601568 if (count1 != 0 ) {
602569 dest -= count1;
603570 cursor1 -= count1;
@@ -613,7 +580,7 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
613580 goto epilogue;
614581 }
615582
616- count2 = len2 - gallopLeft (*(cursor1 - 1 ), tmp_.begin (), len2, len2 - 1 );
583+ count2 = len2 - gallopLeft (*(cursor1 - 1 ), tmp_.begin (), len2, len2 - 1 , compare );
617584 if (count2 != 0 ) {
618585 dest -= count2;
619586 cursor2 -= count2;
@@ -661,7 +628,8 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
661628 }
662629
663630 // the only interface is the friend timsort() function
664- template <typename IterT, typename LessT> friend void timsort (IterT first, IterT last, LessT c);
631+ template <typename IterT, typename LessT>
632+ friend void timsort (IterT first, IterT last, LessT c);
665633};
666634
667635template <typename RandomAccessIterator>
@@ -670,9 +638,9 @@ inline void timsort(RandomAccessIterator const first, RandomAccessIterator const
670638 timsort (first, last, std::less<value_type>());
671639}
672640
673- template <typename RandomAccessIterator, typename LessFunction >
674- inline void timsort (RandomAccessIterator const first, RandomAccessIterator const last, LessFunction compare) {
675- TimSort<RandomAccessIterator, LessFunction >::sort (first, last, compare);
641+ template <typename RandomAccessIterator, typename Compare >
642+ inline void timsort (RandomAccessIterator const first, RandomAccessIterator const last, Compare compare) {
643+ TimSort<RandomAccessIterator, Compare >::sort (first, last, compare);
676644}
677645
678646} // namespace gfx
0 commit comments