// This does not work! template inline bool I2less(I a, I b, int *ia, int *ib, const Comp& cmp) { int q = cmp(*a, *b); return q == 0 ? *ia < *ib : q < 0; } template void I2ForwardSort(I begin, I end, int *ibegin, int *iend, const Comp& cmp) { if(begin == end) return; I limit = end; int *ilimit = iend; --limit, --ilimit; while(!(begin == limit)) { I best = limit, next = limit, ptr = limit; int *ibest = limit, *inext = limit, *iptr = limit; for(;;) { if(!I2less(best, --ptr, ibest, --iptr, cmp)) { if(ptr == begin) { begin = next, ibegin = inext; break; } } else { do { if(ptr == begin) { IterSwap(begin, best), IterSwap(ibegin, ibest); ++begin, ++ibegin; goto NEXT_ITEM; } } while(I2less(best, --ptr, ibest, --iptr, cmp)); if(ptr == begin) { IterSwap(++begin, best), IterSwap(++ibegin, ibest); ++begin, ++ibegin; break; } next = ptr, inext = iptr; ++next, ++inext; } best = ptr, ibest = iptr; } NEXT_ITEM: ; } } template void QStableSort_(I begin, I end, int *ibegin, int *iend, const Comp& cmp) { int count; while((count = (int)(end - begin)) > __SORT_THRESHOLD) { int expected = count >> 1, deviation = expected - (expected >> 8); I b = begin, e = end, m = b + expected; int *ib = ibegin, *ie = iend, *im = ib + expected; for(int pass = 1;; pass++) { for(;; ++b) { while(I2less(m, --e, im, --ie, cmp)) ; while(I2less(b, m, ib, im, cmp)) ++b, ++ib; if(!(b < e)) break; if(m == b) m = e, im = ie; else if(m == e) m = b, im = ib; IterSwap(b, e); IterSwap(ib, ie); } if(pass >= __SORT_MEDIAN_PASSES) break; int pos = (int)(b - begin); if(pos <= expected - deviation) { e = end; ie = iend; } else if(pos >= expected + deviation) { e = b; b = begin; ie = ib; ib = ibegin; } else break; pos = 1 + (int)((unsigned)rand() % (e - b - 2)); m = b + pos; im = ib + pos; } if(b - begin < end - e) { QStableSort_(begin, b, ibegin, ib, cmp); begin = b; ibegin = ib; } else { QStableSort_(b, end, ibegin, iend, cmp); end = b; iend = ib; } } if(count >= 2) I2ForwardSort(begin, end, ibegin, iend, cmp); } template struct StdCompare { int operator()(const T& a, const T& b) const { return SgnCompare(a, b); } }; template void QStableSort(C& c) { Buffer temp(c.GetCount()); for(int i = 0; i < c.GetCount(); i++) temp[i] = i; QStableSort_(c.Begin(), c.End(), ~temp, ~temp + c.GetCount(), StdCompare()); }