#include #include #include using namespace Upp; struct Arry { typedef T **Cursor; typedef T *SlotBuffer; Cursor GetCursor(int at) { return vector.GetCursor(); } const T& operator[Cursor c] const { return **c; } bool IsDone(Cursor c) const; void PickSlot(SlotBuffer& buffer, Cursor cursor) { buffer = *cursor; } void WriteSlot(Cursor cursor, SlotBuffer& buffer) { *cursor = buffer; } void RemovePickedSlots(Cursor cursor, int n); void SlotMove(Cursor t, Cursor s) { *t = *s; } void Swap(Cursor a, Cursor b) { Swap(*a, *b); } }; void RemoveIf(Container& c, Pred p) { Container::Cursor i; c.First(i); for(; !c.IsDone(i); i++) if(p(c[i])) break; Container::Cursor ti = i; for(; !c.IsDone(i); i++) if(!p(c[i])) c.MoveSlot(c[ti++], c[i]); c.RemovePickedSlots(ti, i - ti); } /*wep password 153ab2c29a template class C_Slice { typedef C& cont; int pos, count; int Ndx(int i) const { ASSERT(i >= 0 && i < count); return i - pos; } typedef typename C::ValueType VT; public: typename VT& operator[](int i) { return cont[Ndx(i)]; } const typename VT& operator[](int i) const { return cont[Ndx(i)]; } void Swap(int i1, int i2) { cont.Swap(Ndx(i1), Ndx(i2)); } int GetCount() const { return count; } C_Slice(C& cont, int pos, int count) : cont(cont), pos(pos), count(count) {} }; template C_Slice Slice(C& cont, int pos, int count) { return C_Slice(cont, pos, count); } */ template void C_ForwardSort0(C& cont, int begin, int end, const Less& less) { if(begin == end) return; int limit = end - 1; while(!(begin == limit)) { for(int best = limit, next = limit, ptr = limit;; best = ptr) if(!less(cont[best], cont[--ptr])) { if(ptr == begin) { begin = next; break; } } else { do { if(ptr == begin) { cont.Swap(begin, best); ++begin; goto NEXT_ITEM; } } while(less(cont[best], cont[--ptr])); if(ptr == begin) { cont.Swap(++begin, best); ++begin; break; } next = ptr; ++next; } NEXT_ITEM: ; } } template void C_ForwardSort(T& c, const Less& less) { C_ForwardSort0(c, 0, c.GetCount(), less); } template void C_ForwardSort(T& c) { typedef typename T::ValueType VT; C_ForwardSort0(c, 0, c.GetCount(), StdLess()); } template void C_Sort0(C& cont, int begin, int end, const Less& less) { int count; while((count = end - begin) > __SORT_THRESHOLD) { int expected = count >> 1, deviation = expected - (expected >> 8); int b = begin, e = end, m = b + expected; for(int pass = 1;; pass++) { for(;; ++b) { while(less(cont[m], cont[--e])) ; while(less(cont[b], cont[m])) ++b; if(!(b < e)) break; if(m == b) m = e; else if(m == e) m = b; cont.Swap(b, e); } if(pass >= __SORT_MEDIAN_PASSES) break; int pos = b - begin; if(pos <= expected - deviation) e = end; else if(pos >= expected + deviation) { e = b; b = begin; } else break; m = b + 1 + (int)((unsigned)rand() % (e - b - 2)); } if(b - begin < end - e) { C_Sort0(cont, begin, b, less); begin = b; } else { C_Sort0(cont, b, end, less); end = b; } } if(count >= 2) C_ForwardSort0(cont, begin, end, less); } template void C_Sort(T& c, const Less& less) { C_Sort0(c, 0, c.GetCount(), less); } template void C_Sort(T& c) { typedef typename T::ValueType VT; C_Sort0(c, 0, c.GetCount(), StdLess()); } struct HH : Moveable { int x; String y; bool operator<(const HH& b) const { return y < b.y; } }; CONSOLE_APP_MAIN { for(int q = 0; q < 100; q++) { Vector d1, d2, d3; std::vector d4; for(int i = 0; i < 10000; i++) { String x = AsString(rand()); d1.Add(x); d2.Add(x); d3.Add(x); d4.push_back(to_string(x)); } { RTIMING("Old"); Sort(d1); } { RTIMING("New"); C_Sort(d2); } { RTIMING("Order"); GetSortOrder(d3); } { RTIMING("Std"); std::sort(d3.Begin(), d3.End()); } { RTIMING("std"); std::sort(d4.begin(), d4.end()); } } }