template inline int sgn(T a) { return a > 0 ? 1 : a < 0 ? -1 : 0; } template inline T tabs(T a) { return (a >= 0 ? a : -a); } template inline int cmp(const T& a, const T& b) { return a > b ? 1 : a < b ? -1 : 0; } template void Reverse(I start, I end) { if(start != end && --end != start) do IterSwap(start, end); while(++start != end && --end != start); } template void Reverse(C& container) { Reverse(container.Begin(), container.End()); } template void Sum(V& sum, T ptr, T end) { while(ptr != end) sum += *ptr++; } template typename T::ValueType Sum(const T& c, const typename T::ValueType& init = typename T::ValueType()) { typename T::ValueType sum = init; Sum(sum, c.Begin(), c.End()); return sum; } template typename T::ValueType Sum0(const T& c) { typename T::ValueType sum = 0; Sum(sum, c.Begin(), c.End()); return sum; } template T MinElement(T ptr, T end) { ASSERT(ptr != end); T min = ptr; while(++ptr != end) if(*ptr < *min) min = ptr; return min; } template int MinIndex(const C& c) { if(c.GetCount() == 0) return -1; typename C::ValueType m = c[0]; int mi = 0; for(int i = 1; i < c.GetCount(); i++) if(c[i] < m) { m = c[i]; mi = i; } return mi; } template int MaxIndex(const C& c) { if(c.GetCount() == 0) return -1; typename C::ValueType m = c[0]; int mi = 0; for(int i = 1; i < c.GetCount(); i++) if(c[i] > m) { m = c[i]; mi = i; } return mi; } template const typename T::ValueType& Min(const T& c) { return *MinElement(c.Begin(), c.End()); } template T MaxElement(T ptr, T end) { ASSERT(ptr != end); T max = ptr; while(++ptr != end) if(*max < *ptr) max = ptr; return max; } template const typename T::ValueType& Max(const T& c) { return *MaxElement(c.Begin(), c.End()); } template struct StdEqual { bool operator () (const T& a, const T& b) const { return a == b; } }; template struct StdLess { bool operator () (const T& a, const T& b) const { return a < b; } }; template struct StdGreater { bool operator () (const T& a, const T& b) const { return a > b; } }; /* template bool Compare(T ptr1, T end1, T ptr2, T end2, const C& compare) { for(; ptr1 != end1 && ptr2 != end2; ++ptr1, ++ptr2) if(!compare(*ptr1, *ptr2)) return false; return ptr1 == end1 && ptr2 == end2; } template bool Compare(const T& c1, const T& c2, const C& compare) { return Compare(c1.Begin(), c1.End(), c2.Begin(), c2.End(), compare); } template bool Compare(const T& c1, const T& c2) { typedef typename T::ValueType VT; return Compare(c1, c2, StdEqual()); } */ template bool IsEqual(T ptr1, T end1, T ptr2, T end2, const C& equal) { for(; ptr1 != end1 && ptr2 != end2; ++ptr1, ++ptr2) if(!equal(*ptr1, *ptr2)) return false; return ptr1 == end1 && ptr2 == end2; } template bool IsEqual(const T& c1, const T& c2, const C& equal) { return IsEqual(c1.Begin(), c1.End(), c2.Begin(), c2.End(), equal); } template bool IsEqual(const T& c1, const T& c2) { typedef typename T::ValueType VT; return IsEqual(c1, c2, StdEqual()); } template T Find(T ptr, T end, const V& value, const C& equal) { while(ptr != end) { if(equal(*ptr, value)) return ptr; ptr++; } return NULL; } template T Find(T ptr, T end, const V& value) { return Find(ptr, end, value, StdEqual()); } template int FindIndex(const T& cont, const V& value, const C& equal) { for(int i = 0; i < cont.GetCount(); i++) if(equal(cont[i], value)) return i; return -1; } template int FindIndex(const T& cont, const V& value) { for(int i = 0; i < cont.GetCount(); i++) if(cont[i] == value) return i; return -1; } template int BinFindIndex(I begin, I end, const K& key, const L& less) { if(begin == end) return 0; int min = 0; int max = end - begin; while(min < max) { int mid = (max + min) >> 1; if(less(*(begin + mid), key)) min = mid + 1; else max = mid; } return min; } template inline int BinFindIndex(const C& container, const K& key, const L& less) { return BinFindIndex(container.Begin(), container.End(), key, less); } template inline int BinFindIndex(const C& container, const K& key) { typedef typename C::ValueType VT; return BinFindIndex(container, key, StdLess()); } template inline I BinFind(I begin, I end, const K& key, const L& less) { return begin + BinFindIndex(begin, end, key, less); } template inline typename C::ConstIterator BinFind(const C& container, const K& key, const L& less) { return BinFind(container.Begin(), container.End(), key, less); } template inline typename C::ConstIterator BinFind(const C& container, const K& key) { typedef typename C::ValueType VT; return BinFind(container, key, StdLess()); } // ------------------------------------------------------------------- template int IterCompare(I a, I a_end, I b, I b_end, const C& compare) { for(;;) { if(a >= a_end) return b < b_end ? -1 : 0; if(b >= b_end) return a < a_end ? 1 : 0; int q = compare(*a++, *b++); if(q) return q; } } template int FindLowerBound(const C& v, int pos, int count, const T& val, const L& less) { while(count > 0) { int half = count >> 1; int m = pos + half; if(less(v[m], val)) { pos = m + 1; count = count - half - 1; } else count = half; } return pos; } template I FindLowerBoundIter(I begin, I end, const T& val, const L& less) { return begin + FindLowerBound(begin, 0, end - begin, val, less); } template I FindLowerBoundIter(I begin, I end, const T& val) { return begin + FindLowerBound(begin, 0, end - begin, val, StdLess()); } template int FindLowerBound(const C& v, const T& val, const L& less) { return FindLowerBound(v, 0, v.GetCount(), val, less); } template int FindLowerBound(const C& v, const T& val) { return FindLowerBound(v, val, StdLess()); } template int FindUpperBound(const C& v, int pos, int count, const T& val, const L& less) { while(count > 0) { int half = count >> 1; int m = pos + half; if(less(val, v[m])) count = half; else { pos = m + 1; count = count - half - 1; } } return pos; } template I FindUpperBoundIter(I begin, I end, const T& val, const L& less) { return begin + FindUpperBound(begin, 0, end - begin, val, less); } template I FindUpperBoundIter(I begin, I end, const T& val) { return begin + FindUpperBound(begin, 0, (int)(end - begin), val, StdLess()); } template int FindUpperBound(const C& v, const T& val, const L& less) { return FindUpperBound(v, 0, v.GetCount(), val, less); } template int FindUpperBound(const C& v, const T& val) { return FindUpperBound(v, val, StdLess()); } template int FindBinary(const C& v, const T& val, int pos, int count, const L& less) { int i = FindLowerBound(v, pos, count, val, less); return i < count && !less(val, v[i]) ? i : -1; } template I FindBinaryIter(I begin, I end, const T& val, const L& less) { int q = FindUpperBound(begin, begin, end, val, less); return q < 0 ? NULL : begin + q; } template I FindBinaryIter(I begin, I end, const T& val) { return FindBinaryIter(begin, end, val, StdLess()); } template int FindBinary(const C& v, const T& val, const L& less) { return FindBinary(v, val, 0, v.GetCount(), less); } template int FindBinary(const C& v, const T& val) { return FindBinary(v, val, StdLess()); } template int BinFindCompIndex(I begin, I end, const K& key, const X& comp) { if(begin == end) // empty array return 0; int min = 0; int max = end - begin; while(min < max) { int mid = (max + min) >> 1; if(comp.Compare(key, *(begin + mid)) > 0) min = mid + 1; else max = mid; } return min; } template inline int BinFindCompIndex(const C& container, const K& key, const X& comp) { return BinFindCompIndex(container.Begin(), container.End(), key, comp); } template inline I BinFindComp(I begin, I end, const K& key, const X& comp) { return begin + BinFindCompIndex(begin, end, key, comp); } template inline typename C::ConstIterator BinFindComp(const C& container, const K& key, const X& comp) { return BinFindComp(container.Begin(), container.End(), key, comp); } template void Append(T& dst, V ptr, V end) { for(; ptr != end; ++ptr) dst.Add(*ptr); } template void Append(T& dst, V ptr, int n) { for(; n--; ++ptr) dst.Add(*ptr); } template void Append(T& dst, const V& src) { Append(dst, src.Begin(), src.End()); } template C& FindAppend(C& dest, I begin, I end) { for(; begin != end; ++begin) dest.FindAdd(*begin); return dest; } template inline C& FindAppend(C& dest, const S& source) { return FindAppend(dest, source.Begin(), source.End()); } template C& AppendSorted(C& dest, const C& src, const L& less) { if(src.IsEmpty()) return dest; if(dest.IsEmpty()) { dest <<= src; return dest; } if(!less(*src, dest.Top())) { dest.Append(src); return dest; } if(!less(*dest, src.Top())) { dest.Insert(0, src); return dest; } int dc = dest.GetCount(); int sc = src.GetCount(); dest.SetCount(dc + sc); typename C::Iterator de = dest.End(); typename C::ConstIterator se = src.End(), pe = dest.GetIter(dc); --se; --pe; for(;;) { if(less(*se, *pe)) { *--de = *pe; if(pe == dest.Begin()) { // dest items are finished *--de = *se; while(se != src.Begin()) *--de = *--se; return dest; } --pe; } else { *--de = *se; if(se == src.Begin()) return dest; // src items are finished, dest items are in place --se; } } return dest; } template C& AppendSorted(C& dest, const C& src) { typedef typename C::ValueType VT; return AppendSorted(dest, src, StdLess()); } template C& UnionSorted(C& dest, const C& src, const L& less) { if(src.IsEmpty()) return dest; if(dest.IsEmpty()) { dest <<= src; return dest; } if(less(dest.Top(), *src)) { dest.Append(src); return dest; } if(less(src.Top(), *dest)) { dest.Insert(0, src); return dest; } int dc = dest.GetCount(); int sc = src.GetCount(); dest.SetCount(dc + sc); typename C::Iterator de = dest.End(); typename C::ConstIterator se = src.End(), pe = dest.GetIter(dc); --se; --pe; for(;;) { if(less(*se, *pe)) { *--de = *pe; if(pe == dest.Begin()) { // dest items are finished *--de = *se; while(se != src.Begin()) *--de = *--se; dest.Remove(0, dest.GetIndex(*de)); return dest; } --pe; } else { *--de = *se; if(!less(*pe, *se)) { if(pe == dest.Begin()) { while(se != src.Begin()) *--de = *--se; dest.Remove(0, dest.GetIndex(*de)); return dest; } --pe; } if(se == src.Begin()) { int pi = (pe - dest.Begin()) + 1; dest.Remove(pi, (de - dest.Begin()) - pi); return dest; // src items are finished, dest items are in place } --se; } } return dest; } template C& UnionSorted(C& dest, const C& src) { typedef typename C::ValueType VT; return UnionSorted(dest, src, StdLess()); } template C& RemoveSorted(C& from, const C& what, const L& less) { if(from.IsEmpty() || what.IsEmpty() || less(from.Top(), *what.Begin()) || less(what.Top(), *from.Begin())) return from; typename C::ConstIterator we = what.End(), wp = BinFind(what, from[0], less); if(wp == we) return from; typename C::Iterator fp = from.Begin() + BinFindIndex(from, *wp), fe = from.End(), fd = fp; if(fp == fe) { from.Clear(); return from; } for(;;) { while(less(*fp, *wp)) { *fd = *fp; ++fd; if(++fp == fe) { from.SetCount(fd - from.Begin()); return from; } } if(less(*wp, *fp)) { do if(++wp == we) { Copy(fd, fp, fe); fd += (fe - fp); from.SetCount(fd - from.Begin()); return from; } while(less(*wp, *fp)); } else { const typename C::ValueType& value = *fp; while(!less(value, *fp)) if(++fp == fe) { from.SetCount(fd - from.Begin()); return from; } do if(++wp == we) { Copy(fd, fp, fe); fd += (fe - fp); from.SetCount(fd - from.Begin()); return from; } while(!less(value, *wp)); } } } template C& RemoveSorted(C& from, const C& what) { typedef typename C::ValueType VT; return RemoveSorted(from, what, StdLess()); } template D& IntersectSorted(D& dest, const S& src, const L& less) { if(dest.IsEmpty()) return dest; if(src.IsEmpty() || less(dest.Top(), src[0]) || less(src.Top(), dest[0])) { // empty source set or disjunct intervals dest.Clear(); return dest; } typename S::ConstIterator ss = BinFind(src, dest[0], less), se = src.End(); if(ss == se) { dest.Clear(); return dest; } typename D::ConstIterator ds = BinFind(dest, src[0], less), de = dest.End(); if(ds == de) { dest.Clear(); return dest; } typename D::Iterator d = dest.Begin(); int count = 0; for(;;) { if(less(*ss, *ds)) { if(++ss == se) break; } else { if(!less(*ds, *ss)) { *d = *ds; ++d; count++; } if(++ds == de) break; } } dest.SetCount(count); return dest; } template D& IntersectSorted(D& dest, const S& src) { typedef typename D::ValueType VT; return IntersectSorted(dest, src, StdLess()); } #ifdef UPP template void StreamContainer(Stream& s, T& cont) { int n = cont.GetCount(); s / n; if(n < 0) { s.LoadError(); return; } if(s.IsLoading()) { cont.Clear(); while(n--) s % cont.Add(); } else { for(typename T::Iterator ptr = cont.Begin(); n--; ++ptr) s % *ptr; } } #endif template void ForwardSort(I begin, I end, const Less& less) { if(begin == end) return; I limit = end; --limit; while(!(begin == limit)) { for(I best = limit, next = limit, ptr = limit;; best = ptr) if(!less(*best, *--ptr)) { if(ptr == begin) { begin = next; break; } } else { do { if(ptr == begin) { IterSwap(begin, best); ++begin; goto NEXT_ITEM; } } while(less(*best, *--ptr)); if(ptr == begin) { IterSwap(++begin, best); ++begin; break; } next = ptr; ++next; } NEXT_ITEM: ; } } template void ForwardSort(T& c, const Less& less) { ForwardSort(c.Begin(), c.End(), less); } template void ForwardSort(T& c) { typedef typename T::ValueType VT; ForwardSort(c.Begin(), c.End(), StdLess()); } enum { __SORT_THRESHOLD = 16, __SORT_MEDIAN_PASSES = 2, }; template void Sort(I begin, I end, const Less& less) { 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; for(int pass = 1;; pass++) { for(;; ++b) { while(less(*m, *--e)) ; while(less(*b, *m)) ++b; if(!(b < e)) break; if(m == b) m = e; else if(m == e) m = b; IterSwap(b, e); } if(pass >= __SORT_MEDIAN_PASSES) break; int pos = (int)(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) { Sort(begin, b, less); begin = b; } else { Sort(b, end, less); end = b; } } if(count >= 2) ForwardSort(begin, end, less); } template void Sort(T& c, const Less& less) { Sort(c.Begin(), c.End(), less); } template void Sort(T& c) { typedef typename T::ValueType VT; Sort(c.Begin(), c.End(), StdLess()); } template struct StableSortItem { const T& value; int index; StableSortItem(const T& value, int index) : value(value), index(index) {} }; template struct StableSortIterator { II ii; int *vi; typedef StableSortIterator Iter; Iter& operator ++ () { ++ii; ++vi; return *this; } Iter& operator -- () { --ii; --vi; return *this; } Iter operator + (int i) const { return Iter(ii + i, vi + i); } Iter operator - (int i) const { return Iter(ii - i, vi - i); } int operator - (Iter b) const { return (int)(ii - b.ii); } bool operator == (Iter b) const { return ii == b.ii; } bool operator != (Iter b) const { return ii != b.ii; } bool operator < (Iter b) const { return ii < b.ii; } StableSortItem operator*() const { return StableSortItem(*ii, *vi); } friend void IterSwap(Iter a, Iter b) { IterSwap(a.ii, b.ii); IterSwap(a.vi, b.vi); } StableSortIterator(II ii, int *vi) : ii(ii), vi(vi) {} }; template struct StableSortLess_ { const Less& less; bool operator()(const StableSortItem& a, const StableSortItem& b) const { if(less(a.value, b.value)) return true; return less(b.value, a.value) ? false : a.index < b.index; } StableSortLess_(const Less& less) : less(less) {} }; template void StableSort_(I begin, I end, const Less& less, const T *) { int count = (int)(uintptr_t)(end - begin); Buffer h(count); for(int i = 0; i < count; i++) h[i] = i; Sort(StableSortIterator(begin, ~h), StableSortIterator(end, ~h + count), StableSortLess_(less)); } template void StableSort(I begin, I end, const Less& less) { if(begin != end) StableSort_(begin, end, less, &*begin); } template void StableSort(T& c, const Less& less) { StableSort(c.Begin(), c.End(), less); } template void StableSort(T& c) { StableSort(c.Begin(), c.End(), StdLess()); } template struct StableSortLessCmp_ { const Cmp& cmp; bool operator()(const StableSortItem& a, const StableSortItem& b) const { int q = SgnCompare(a.value, b.value); return q ? q < 0 : a.index < b.index; } StableSortLessCmp_(const Cmp& cmp) : cmp(cmp) {} }; template void StableSortCmp_(I begin, I end, const Cmp& cmp, const T *) { int count = end - begin; Buffer h(count); for(int i = 0; i < count; i++) h[i] = i; Sort(StableSortIterator(begin, ~h), StableSortIterator(end, ~h + count), StableSortLessCmp_(cmp)); } template void StableSortCmp(I begin, I end, const Cmp& cmp) { if(begin != end) StableSortCmp_(begin, end, cmp, &*begin); } template void StableSortCmp(T& c, const Cmp& cmp) { StableSortCmp(c.Begin(), c.End(), cmp); } template struct StdCmp { int operator()(const T& a, const T& b) const { return SgnCompare(a, b); } }; template void StableSortCmp(T& c) { StableSort(c.Begin(), c.End(), StdCmp()); } template struct IndexSortIterator { typedef IndexSortIterator Iter; IndexSortIterator(II ii, VI vi) : ii(ii), vi(vi) {} Iter& operator ++ () { ++ii; ++vi; return *this; } Iter& operator -- () { --ii; --vi; return *this; } const K& operator * () const { return *ii; } Iter operator + (int i) const { return Iter(ii + i, vi + i); } Iter operator - (int i) const { return Iter(ii - i, vi - i); } int operator - (Iter b) const { return (int)(ii - b.ii); } bool operator == (Iter b) const { return ii == b.ii; } bool operator != (Iter b) const { return ii != b.ii; } bool operator < (Iter b) const { return ii < b.ii; } friend void IterSwap (Iter a, Iter b) { IterSwap(a.ii, b.ii); IterSwap(a.vi, b.vi); } II ii; VI vi; }; template inline void __IndexSort(II begin, II end, VI pair, const Less& less, const K *) { Sort(IndexSortIterator(begin, pair), IndexSortIterator(end, pair + (end - begin)), less); } template inline void IndexSort(II begin, II end, VI pair, const Less& less) { if(begin != end) __IndexSort(begin, end, pair, less, &*begin); } template inline void IndexSort(KC& keys, VC& values, const Less& less) { typedef typename KC::ValueType KT; ASSERT(keys.GetCount() == values.GetCount()); if(keys.GetCount() >= 2) __IndexSort(keys.Begin(), keys.End(), values.Begin(), less, (KT *)0); } template inline void IndexSort(KC& keys, VC& values) { typedef typename KC::ValueType KT; if(keys.GetCount() >= 2) __IndexSort(keys.Begin(), keys.End(), values.Begin(), StdLess(), (KT *)0); } template inline void __StableIndexSort(II begin, II end, VI pair, const Less& less, const K *) { StableSort(IndexSortIterator(begin, pair), IndexSortIterator(end, pair + (end - begin)), less); } template inline void StableIndexSort(II begin, II end, VI pair, const Less& less) { if(begin != end) __StableIndexSort(begin, end, pair, less, &*begin); } template inline void StableIndexSort(KC& keys, VC& values, const Less& less) { typedef typename KC::ValueType KT; ASSERT(keys.GetCount() == values.GetCount()); if(keys.GetCount() >= 2) __StableIndexSort(keys.Begin(), keys.End(), values.Begin(), less, (KT *)0); } template inline void StableIndexSort(KC& keys, VC& values) { typedef typename KC::ValueType KT; if(keys.GetCount() >= 2) __StableIndexSort(keys.Begin(), keys.End(), values.Begin(), StdLess(), (KT *)0); } template inline void __StableIndexSortCmp(II begin, II end, VI pair, const Cmp& cmp, const K *) { StableSortCmp(IndexSortIterator(begin, pair), IndexSortIterator(end, pair + (end - begin)), cmp); } template inline void StableIndexSortCmp(II begin, II end, VI pair, const Cmp& cmp) { if(begin != end) __StableIndexSortCmp(begin, end, pair, cmp, &*begin); } template inline void StableIndexSortCmp(KC& keys, VC& values, const Cmp& cmp) { typedef typename KC::ValueType KT; ASSERT(keys.GetCount() == values.GetCount()); if(keys.GetCount() >= 2) __StableIndexSortCmp(keys.Begin(), keys.End(), values.Begin(), cmp, (KT *)0); } template inline void StableIndexSortCmp(KC& keys, VC& values) { typedef typename KC::ValueType KT; if(keys.GetCount() >= 2) __StableIndexSortCmp(keys.Begin(), keys.End(), values.Begin(), StdCmp(), (KT *)0); } template struct IndexSort2Iterator { typedef IndexSort2Iterator Iter; IndexSort2Iterator(II ii, VI vi, WI wi) : ii(ii), vi(vi), wi(wi) {} Iter& operator ++ () { ++ii; ++vi; ++wi; return *this; } Iter& operator -- () { --ii; --vi; --wi; return *this; } const K& operator * () const { return *ii; } Iter operator + (int i) const { return Iter(ii + i, vi + i, wi + i); } Iter operator - (int i) const { return Iter(ii - i, vi - i, wi - i); } int operator - (Iter b) const { return (int)(ii - b.ii); } bool operator == (Iter b) const { return ii == b.ii; } bool operator != (Iter b) const { return ii != b.ii; } bool operator < (Iter b) const { return ii < b.ii; } friend void IterSwap (Iter a, Iter b) { IterSwap(a.ii, b.ii); IterSwap(a.vi, b.vi); IterSwap(a.wi, b.wi); } II ii; VI vi; WI wi; }; template inline void __IndexSort2(II begin, II end, VI pair1, WI pair2, const Less& less, const K *) { int count = end - begin; Sort(IndexSort2Iterator(begin, pair1, pair2), IndexSort2Iterator(end, pair1 + count, pair2 + count), less); } template inline void IndexSort2(II begin, II end, VI pair1, WI pair2, const Less& less) { if(begin != end) __IndexSort2(begin, end, pair1, pair2, less, &*begin); } template inline void IndexSort2(KC& keys, VC& values1, WC& values2, const Less& less) { typedef typename KC::ValueType KT; ASSERT(keys.GetCount() == values1.GetCount() && keys.GetCount() == values2.GetCount()); if(keys.GetCount() >= 2) __IndexSort2(keys.Begin(), keys.End(), values1.Begin(), values2.Begin(), less, (KT *)0); } template inline void IndexSort2(KC& keys, VC& values1, WC& values2) { typedef typename KC::ValueType KT; if(keys.GetCount() >= 2) __IndexSort2(keys.Begin(), keys.End(), values1.Begin(), values2.Begin(), StdLess(), (KT *)0); } template inline void __StableIndexSort2(II begin, II end, VI pair1, WI pair2, const Less& less, const K *) { int count = end - begin; StableSort(IndexSort2Iterator(begin, pair1, pair2), IndexSort2Iterator(end, pair1 + count, pair2 + count), less); } template inline void StableIndexSort2(II begin, II end, VI pair1, WI pair2, const Less& less) { if(begin != end) __StableIndexSort2(begin, end, pair1, pair2, less, &*begin); } template inline void StableIndexSort2(KC& keys, VC& values1, WC& values2, const Less& less) { typedef typename KC::ValueType KT; ASSERT(keys.GetCount() == values1.GetCount() && keys.GetCount() == values2.GetCount()); if(keys.GetCount() >= 2) __StableIndexSort2(keys.Begin(), keys.End(), values1.Begin(), values2.Begin(), less, (KT *)0); } template inline void StableIndexSort2(KC& keys, VC& values1, WC& values2) { typedef typename KC::ValueType KT; if(keys.GetCount() >= 2) __StableIndexSort2(keys.Begin(), keys.End(), values1.Begin(), values2.Begin(), StdLess(), (KT *)0); } template inline void __StableIndexSort2Cmp(II begin, II end, VI pair1, WI pair2, const Cmp& cmp, const K *) { int count = end - begin; StableSortCmp(IndexSort2Iterator(begin, pair1, pair2), IndexSort2Iterator(end, pair1 + count, pair2 + count), cmp); } template inline void StableIndexSort2Cmp(II begin, II end, VI pair1, WI pair2, const Cmp& cmp) { if(begin != end) __StableIndexSort2Cmp(begin, end, pair1, pair2, cmp, &*begin); } template inline void StableIndexSort2Cmp(KC& keys, VC& values1, WC& values2, const Cmp& cmp) { typedef typename KC::ValueType KT; ASSERT(keys.GetCount() == values1.GetCount() && keys.GetCount() == values2.GetCount()); if(keys.GetCount() >= 2) __StableIndexSort2Cmp(keys.Begin(), keys.End(), values1.Begin(), values2.Begin(), cmp, (KT *)0); } template inline void StableIndexSort2Cmp(KC& keys, VC& values1, WC& values2) { typedef typename KC::ValueType KT; if(keys.GetCount() >= 2) __StableIndexSort2Cmp(keys.Begin(), keys.End(), values1.Begin(), values2.Begin(), StdCmp(), (KT *)0); } template struct IndexSort3Iterator { typedef IndexSort3Iterator Iter; IndexSort3Iterator(II ii, VI vi, WI wi, XI xi) : ii(ii), vi(vi), wi(wi), xi(xi) {} Iter& operator ++ () { ++ii; ++vi; ++wi; ++xi; return *this; } Iter& operator -- () { --ii; --vi; --wi; --xi; return *this; } const K& operator * () const { return *ii; } Iter operator + (int i) const { return Iter(ii + i, vi + i, wi + i, xi + i); } Iter operator - (int i) const { return Iter(ii - i, vi - i, wi - i, xi - i); } int operator - (Iter b) const { return (int)(ii - b.ii); } bool operator == (Iter b) const { return ii == b.ii; } bool operator != (Iter b) const { return ii != b.ii; } bool operator < (Iter b) const { return ii < b.ii; } friend void IterSwap (Iter a, Iter b) { IterSwap(a.ii, b.ii); IterSwap(a.vi, b.vi); IterSwap(a.wi, b.wi); IterSwap(a.xi, b.xi); } II ii; VI vi; WI wi; XI xi; }; template inline void __IndexSort3(II begin, II end, VI pair1, WI pair2, XI pair3, const Less& less, const K *) { int count = end - begin; Sort(IndexSort3Iterator(begin, pair1, pair2, pair3), IndexSort3Iterator(end, pair1 + count, pair2 + count, pair3 + count), less); } template inline void IndexSort3(II begin, II end, VI pair1, WI pair2, XI pair3, const Less& less) { if(begin != end) __IndexSort3(begin, end, pair1, pair2, pair3, less, &*begin); } template inline void IndexSort3(KC& keys, VC& values1, WC& values2, XC& values3, const Less& less) { typedef typename KC::ValueType KT; ASSERT(keys.GetCount() == values1.GetCount() && keys.GetCount() == values2.GetCount() && keys.GetCount() == values3.GetCount()); if(keys.GetCount() >= 2) __IndexSort3(keys.Begin(), keys.End(), values1.Begin(), values2.Begin(), values3.Begin(), less, (KT *)0); } template inline void IndexSort3(KC& keys, VC& values1, WC& values2, XC& values3) { typedef typename KC::ValueType KT; if(keys.GetCount() >= 2) __IndexSort3(keys.Begin(), keys.End(), values1.Begin(), values2.Begin(), values3.Begin(), StdLess(), (KT *)0); } template inline void __StableIndexSort3(II begin, II end, VI pair1, WI pair2, XI pair3, const Less& less, const K *) { int count = end - begin; StableSort(IndexSort3Iterator(begin, pair1, pair2, pair3), IndexSort3Iterator(end, pair1 + count, pair2 + count, pair3 + count), less); } template inline void StableIndexSort3(II begin, II end, VI pair1, WI pair2, XI pair3, const Less& less) { if(begin != end) __StableIndexSort3(begin, end, pair1, pair2, pair3, less, &*begin); } template inline void StableIndexSort3(KC& keys, VC& values1, WC& values2, XC& values3, const Less& less) { typedef typename KC::ValueType KT; ASSERT(keys.GetCount() == values1.GetCount() && keys.GetCount() == values2.GetCount() && keys.GetCount() == values3.GetCount()); if(keys.GetCount() >= 2) __StableIndexSort3(keys.Begin(), keys.End(), values1.Begin(), values2.Begin(), values3.Begin(), less, (KT *)0); } template inline void StableIndexSort3(KC& keys, VC& values1, WC& values2, XC& values3) { typedef typename KC::ValueType KT; if(keys.GetCount() >= 2) __StableIndexSort3(keys.Begin(), keys.End(), values1.Begin(), values2.Begin(), values3.Begin(), StdLess(), (KT *)0); } template inline void __StableIndexSort3Cmp(II begin, II end, VI pair1, WI pair2, XI pair3, const Cmp& cmp, const K *) { int count = end - begin; StableSortCmp(IndexSort3Iterator(begin, pair1, pair2, pair3), IndexSort3Iterator(end, pair1 + count, pair2 + count, pair3 + count), cmp); } template inline void StableIndexSort3Cmp(II begin, II end, VI pair1, WI pair2, XI pair3, const Cmp& cmp) { if(begin != end) __StableIndexSort3Cmp(begin, end, pair1, pair2, pair3, cmp, &*begin); } template inline void StableIndexSort3Cmp(KC& keys, VC& values1, WC& values2, XC& values3, const Cmp& cmp) { typedef typename KC::ValueType KT; ASSERT(keys.GetCount() == values1.GetCount() && keys.GetCount() == values2.GetCount() && keys.GetCount() == values3.GetCount()); if(keys.GetCount() >= 2) __StableIndexSort3Cmp(keys.Begin(), keys.End(), values1.Begin(), values2.Begin(), values3.Begin(), cmp, (KT *)0); } template inline void StableIndexSort3Cmp(KC& keys, VC& values1, WC& values2, XC& values3) { typedef typename KC::ValueType KT; if(keys.GetCount() >= 2) __StableIndexSort3Cmp(keys.Begin(), keys.End(), values1.Begin(), values2.Begin(), values3.Begin(), StdCmp(), (KT *)0); } template struct SortOrderIterator : PostfixOps< SortOrderIterator > { typedef SortOrderIterator Iter; SortOrderIterator(int *ii, I vi) : ii(ii), vi(vi) {} Iter& operator ++ () { ++ii; return *this; } Iter& operator -- () { --ii; return *this; } const V& operator * () const { return *(vi + *ii); } Iter operator + (int i) const { return Iter(ii + i, vi); } Iter operator - (int i) const { return Iter(ii - i, vi); } int operator - (Iter b) const { return int(ii - b.ii); } bool operator == (Iter b) const { return ii == b.ii; } bool operator != (Iter b) const { return ii != b.ii; } bool operator < (Iter b) const { return ii < b.ii; } friend void IterSwap (Iter a, Iter b) { IterSwap(a.ii, b.ii); } int *ii; I vi; }; template inline void __SortOrder(int *begin, int *end, I data, const Less& less, const V *) { Sort(SortOrderIterator(begin, data), SortOrderIterator(end, data), less); } template inline Vector GetSortOrder(I begin, I end, const Less& less) { Vector index; index.SetCount((int)(end - begin)); for(int i = index.GetCount(); --i >= 0; index[i] = i) ; if(begin != end) __SortOrder(index.Begin(), index.End(), begin, less, &*begin); return index; } template inline Vector GetSortOrder(const C& container, const Less& less) { return GetSortOrder(container.Begin(), container.End(), less); } template inline Vector GetSortOrder(const C& container) { typedef typename C::ValueType V; return GetSortOrder(container.Begin(), container.End(), StdLess()); } template struct StableSortOrderIterator : PostfixOps< StableSortOrderIterator > { typedef StableSortOrderIterator Iter; StableSortOrderIterator(int *ii, I vi) : ii(ii), vi(vi) {} Iter& operator ++ () { ++ii; return *this; } Iter& operator -- () { --ii; return *this; } Iter operator + (int i) const { return Iter(ii + i, vi); } Iter operator - (int i) const { return Iter(ii - i, vi); } int operator - (Iter b) const { return int(ii - b.ii); } bool operator == (Iter b) const { return ii == b.ii; } bool operator != (Iter b) const { return ii != b.ii; } bool operator < (Iter b) const { return ii < b.ii; } friend void IterSwap (Iter a, Iter b) { IterSwap(a.ii, b.ii); } StableSortItem operator*() const { return StableSortItem(*(vi + *ii), *ii); } int *ii; I vi; }; template inline void __StableSortOrder(int *ibegin, int *iend, I data, const Less& less, const T *) { Sort(StableSortOrderIterator(ibegin, data), StableSortOrderIterator(iend, data), StableSortLess_(less)); } template inline Vector GetStableSortOrder(I begin, I end, const Less& less) { Vector index; index.SetCount((int)(end - begin)); for(int i = index.GetCount(); --i >= 0; index[i] = i) ; if(begin != end) __StableSortOrder(index.Begin(), index.End(), begin, less, &*begin); return index; } template inline Vector GetStableSortOrder(const C& container, const Less& less) { return GetStableSortOrder(container.Begin(), container.End(), less); } template inline Vector GetStableSortOrder(const C& container) { typedef typename C::ValueType V; return GetStableSortOrder(container.Begin(), container.End(), StdLess()); } template inline void __StableSortOrderCmp(int *ibegin, int *iend, I data, const Cmp& cmp, const T *) { Sort(StableSortOrderIterator(ibegin, data), StableSortOrderIterator(iend, data), StableSortLessCmp_(cmp)); } template inline Vector GetStableSortOrderCmp(I begin, I end, const Cmp& cmp) { Vector index; index.SetCount((int)(end - begin)); for(int i = index.GetCount(); --i >= 0; index[i] = i) ; if(begin != end) __StableSortOrderCmp(index.Begin(), index.End(), begin, cmp, &*begin); return index; } template inline Vector GetStableSortOrderCmp(const C& container, const Cmp& cmp) { return GetStableSortOrderCmp(container.Begin(), container.End(), cmp); } template inline Vector GetStableSortOrderCmp(const C& container) { typedef typename C::ValueType V; return GetStableSortOrderCmp(container.Begin(), container.End(), StdCmp()); } template void GetFieldContainer(DC& dest, I begin, I end, F field) { for(; begin != end; ++begin) dest.Add((*begin).*field); } template void GetFieldContainer(DC& dest, const SC& src, F field) { GetFieldContainer(dest, src.Begin(), src.End(), field); } template I FindField(I begin, I end, F field, const O& object, const E& equal) { for(; begin != end && !equal((*begin).*field, object); ++begin) ; return begin; } template I FindField(I begin, I end, F field, const O& object) { return FindField(begin, end, field, object, StdEqual()); } template int FindFieldIndex(const C& container, F field, const O& object, const E& equal) { int i = 0; for(typename C::ConstIterator b = container.Begin(), e = container.End(); b != e; ++b, ++i) if(equal((*b).*field, object)) return i; return -1; } template int FindFieldIndex(const C& container, F field, const O& object) { return FindFieldIndex(container, field, object, StdEqual()); } template class FieldRelationCls { O T::*member; const R& relation; public: FieldRelationCls(O (T::*member), const R& relation) : member(member), relation(relation) {} bool operator () (const T& t1, const T& t2) const { return relation(t1.*member, t2.*member); } }; template inline FieldRelationCls FieldRelation(O (T::*member), const R& relation) { return FieldRelationCls(member, relation); } template class MethodRelationCls { M method; const R& relation; public: MethodRelationCls(M method, const R& relation) : method(method), relation(relation) {} bool operator () (const T& t1, const T& t2) const { return relation((t1.*method)(), (t2.*method)()); } }; template inline MethodRelationCls MethodRelation(O (T::*method)(), const R& relation) { return MethodRelationCls(method, relation); } template inline MethodRelationCls MethodRelation(O (T::*method)() const, const R& relation) { return MethodRelationCls(method, relation); } template void LruAdd(C& lru, T value, int limit = 10) { int q = FindIndex(lru, value); if(q >= 0) lru.Remove(q); lru.Insert(0, value); if(lru.GetCount() > limit) lru.SetCount(limit); }