ultimatepp/uppsrc/Core/Algo.h
mdelfede cb0ff92715 new uvs2 releases : uppsrc-2598 tutorial-38 examples-141 reference-113
git-svn-id: svn://ultimatepp.org/upp/trunk@300 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2008-06-16 23:06:34 +00:00

1567 lines
40 KiB
C++

template <class T>
inline int sgn(T a) { return a > 0 ? 1 : a < 0 ? -1 : 0; }
template <class T>
inline T tabs(T a) { return (a >= 0 ? a : -a); }
template <class T>
inline int cmp(const T& a, const T& b) { return a > b ? 1 : a < b ? -1 : 0; }
template <class I>
void Reverse(I start, I end)
{
if(start != end && --end != start)
do
IterSwap(start, end);
while(++start != end && --end != start);
}
template <class C>
void Reverse(C& container)
{
Reverse(container.Begin(), container.End());
}
template <class T, class V>
void Sum(V& sum, T ptr, T end)
{
while(ptr != end)
sum += *ptr++;
}
template <class T>
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 <class T>
typename T::ValueType Sum0(const T& c)
{
typename T::ValueType sum = 0;
Sum(sum, c.Begin(), c.End());
return sum;
}
template <class T>
T MinElement(T ptr, T end)
{
ASSERT(ptr != end);
T min = ptr;
while(++ptr != end)
if(*ptr < *min) min = ptr;
return min;
}
template <class C>
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 <class C>
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 <class T>
const typename T::ValueType& Min(const T& c)
{
return *MinElement(c.Begin(), c.End());
}
template <class T>
T MaxElement(T ptr, T end)
{
ASSERT(ptr != end);
T max = ptr;
while(++ptr != end)
if(*max < *ptr) max = ptr;
return max;
}
template <class T>
const typename T::ValueType& Max(const T& c)
{
return *MaxElement(c.Begin(), c.End());
}
template<class T>
struct StdEqual
{
bool operator () (const T& a, const T& b) const { return a == b; }
};
template<class T>
struct StdLess {
bool operator () (const T& a, const T& b) const { return a < b; }
};
template<class T>
struct StdGreater
{
bool operator () (const T& a, const T& b) const { return a > b; }
};
/*
template <class T, class C>
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 <class T, class C>
bool Compare(const T& c1, const T& c2, const C& compare)
{
return Compare(c1.Begin(), c1.End(), c2.Begin(), c2.End(), compare);
}
template <class T>
bool Compare(const T& c1, const T& c2)
{
typedef typename T::ValueType VT;
return Compare(c1, c2, StdEqual<VT>());
}
*/
template <class T, class C>
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 <class T, class C>
bool IsEqual(const T& c1, const T& c2, const C& equal)
{
return IsEqual(c1.Begin(), c1.End(), c2.Begin(), c2.End(), equal);
}
template <class T>
bool IsEqual(const T& c1, const T& c2)
{
typedef typename T::ValueType VT;
return IsEqual(c1, c2, StdEqual<VT>());
}
template <class T, class V, class C>
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 <class T, class V>
T Find(T ptr, T end, const V& value)
{
return Find(ptr, end, value, StdEqual<T>());
}
template <class T, class V, class C>
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 <class T, class V>
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 <class I, class K, class L>
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 <class C, class K, class L>
inline int BinFindIndex(const C& container, const K& key, const L& less)
{
return BinFindIndex(container.Begin(), container.End(), key, less);
}
template <class C, class K>
inline int BinFindIndex(const C& container, const K& key)
{
typedef typename C::ValueType VT;
return BinFindIndex(container, key, StdLess<VT>());
}
template <class I, class K, class L>
inline I BinFind(I begin, I end, const K& key, const L& less)
{
return begin + BinFindIndex(begin, end, key, less);
}
template <class C, class K, class L>
inline typename C::ConstIterator BinFind(const C& container, const K& key, const L& less)
{
return BinFind(container.Begin(), container.End(), key, less);
}
template <class C, class K>
inline typename C::ConstIterator BinFind(const C& container, const K& key)
{
typedef typename C::ValueType VT;
return BinFind(container, key, StdLess<VT>());
}
// -------------------------------------------------------------------
template <class I, class C>
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 <class C, class T, class L>
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 <class I, class T, class L>
I FindLowerBoundIter(I begin, I end, const T& val, const L& less)
{
return begin + FindLowerBound(begin, 0, end - begin, val, less);
}
template <class I, class T>
I FindLowerBoundIter(I begin, I end, const T& val)
{
return begin + FindLowerBound(begin, 0, end - begin, val, StdLess<T>());
}
template <class C, class T, class L>
int FindLowerBound(const C& v, const T& val, const L& less)
{
return FindLowerBound(v, 0, v.GetCount(), val, less);
}
template <class C, class T>
int FindLowerBound(const C& v, const T& val)
{
return FindLowerBound(v, val, StdLess<typename C::ValueType>());
}
template <class C, class T, class L>
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 <class I, class T, class L>
I FindUpperBoundIter(I begin, I end, const T& val, const L& less)
{
return begin + FindUpperBound(begin, 0, end - begin, val, less);
}
template <class I, class T>
I FindUpperBoundIter(I begin, I end, const T& val)
{
return begin + FindUpperBound(begin, 0, (int)(end - begin), val, StdLess<T>());
}
template <class C, class T, class L>
int FindUpperBound(const C& v, const T& val, const L& less)
{
return FindUpperBound(v, 0, v.GetCount(), val, less);
}
template <class C, class T>
int FindUpperBound(const C& v, const T& val)
{
return FindUpperBound(v, val, StdLess<typename C::ValueType>());
}
template <class C, class T, class L>
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 <class I, class T, class L>
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 <class I, class T>
I FindBinaryIter(I begin, I end, const T& val)
{
return FindBinaryIter(begin, end, val, StdLess<T>());
}
template <class C, class T, class L>
int FindBinary(const C& v, const T& val, const L& less)
{
return FindBinary(v, val, 0, v.GetCount(), less);
}
template <class C, class T>
int FindBinary(const C& v, const T& val)
{
return FindBinary(v, val, StdLess<typename C::ValueType>());
}
template <class I, class K, class X>
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 <class C, class K, class X>
inline int BinFindCompIndex(const C& container, const K& key, const X& comp)
{
return BinFindCompIndex(container.Begin(), container.End(), key, comp);
}
template <class I, class K, class X>
inline I BinFindComp(I begin, I end, const K& key, const X& comp)
{
return begin + BinFindCompIndex(begin, end, key, comp);
}
template <class C, class K, class X>
inline typename C::ConstIterator BinFindComp(const C& container, const K& key, const X& comp)
{
return BinFindComp(container.Begin(), container.End(), key, comp);
}
template <class T, class V>
void Append(T& dst, V ptr, V end)
{
for(; ptr != end; ++ptr)
dst.Add(*ptr);
}
template <class T, class V>
void Append(T& dst, V ptr, int n)
{
for(; n--; ++ptr)
dst.Add(*ptr);
}
template <class T, class V>
void Append(T& dst, const V& src)
{
Append(dst, src.Begin(), src.End());
}
template <class C, class I>
C& FindAppend(C& dest, I begin, I end)
{
for(; begin != end; ++begin)
dest.FindAdd(*begin);
return dest;
}
template <class C, class S>
inline C& FindAppend(C& dest, const S& source)
{
return FindAppend(dest, source.Begin(), source.End());
}
template <class C, class L>
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 <class C>
C& AppendSorted(C& dest, const C& src)
{
typedef typename C::ValueType VT;
return AppendSorted(dest, src, StdLess<VT>());
}
template <class C, class L>
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 <class C>
C& UnionSorted(C& dest, const C& src)
{
typedef typename C::ValueType VT;
return UnionSorted(dest, src, StdLess<VT>());
}
template <class C, class L>
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 <class C>
C& RemoveSorted(C& from, const C& what)
{
typedef typename C::ValueType VT;
return RemoveSorted(from, what, StdLess<VT>());
}
template <class D, class S, class L>
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 <class D, class S>
D& IntersectSorted(D& dest, const S& src)
{
typedef typename D::ValueType VT;
return IntersectSorted(dest, src, StdLess<VT>());
}
#ifdef UPP
template <class T>
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 <class I, class Less>
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 <class T, class Less>
void ForwardSort(T& c, const Less& less)
{
ForwardSort(c.Begin(), c.End(), less);
}
template <class T>
void ForwardSort(T& c)
{
typedef typename T::ValueType VT;
ForwardSort(c.Begin(), c.End(), StdLess<VT>());
}
enum
{
__SORT_THRESHOLD = 16,
__SORT_MEDIAN_PASSES = 2,
};
template <class I, class Less>
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 <class T, class Less>
void Sort(T& c, const Less& less)
{
Sort(c.Begin(), c.End(), less);
}
template <class T>
void Sort(T& c)
{
typedef typename T::ValueType VT;
Sort(c.Begin(), c.End(), StdLess<VT>());
}
template <class T>
struct StableSortItem {
const T& value;
int index;
StableSortItem(const T& value, int index) : value(value), index(index) {}
};
template <class II, class T>
struct StableSortIterator {
II ii;
int *vi;
typedef StableSortIterator<II, T> 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<T> operator*() const { return StableSortItem<T>(*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 <class T, class Less>
struct StableSortLess_ {
const Less& less;
bool operator()(const StableSortItem<T>& a, const StableSortItem<T>& 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 <class I, class Less, class T>
void StableSort_(I begin, I end, const Less& less, const T *)
{
int count = (int)(uintptr_t)(end - begin);
Buffer<int> h(count);
for(int i = 0; i < count; i++)
h[i] = i;
Sort(StableSortIterator<I, T>(begin, ~h),
StableSortIterator<I, T>(end, ~h + count),
StableSortLess_<T, Less>(less));
}
template <class I, class Less>
void StableSort(I begin, I end, const Less& less)
{
if(begin != end)
StableSort_(begin, end, less, &*begin);
}
template <class T, class Less>
void StableSort(T& c, const Less& less)
{
StableSort(c.Begin(), c.End(), less);
}
template <class T>
void StableSort(T& c)
{
StableSort(c.Begin(), c.End(), StdLess<typename T::ValueType>());
}
template <class T, class Cmp>
struct StableSortLessCmp_ {
const Cmp& cmp;
bool operator()(const StableSortItem<T>& a, const StableSortItem<T>& b) const {
int q = SgnCompare(a.value, b.value);
return q ? q < 0 : a.index < b.index;
}
StableSortLessCmp_(const Cmp& cmp) : cmp(cmp) {}
};
template <class I, class Cmp, class T>
void StableSortCmp_(I begin, I end, const Cmp& cmp, const T *)
{
int count = end - begin;
Buffer<int> h(count);
for(int i = 0; i < count; i++)
h[i] = i;
Sort(StableSortIterator<I, T>(begin, ~h),
StableSortIterator<I, T>(end, ~h + count),
StableSortLessCmp_<T, Cmp>(cmp));
}
template <class I, class Cmp>
void StableSortCmp(I begin, I end, const Cmp& cmp)
{
if(begin != end)
StableSortCmp_(begin, end, cmp, &*begin);
}
template <class T, class Cmp>
void StableSortCmp(T& c, const Cmp& cmp)
{
StableSortCmp(c.Begin(), c.End(), cmp);
}
template <class T>
struct StdCmp {
int operator()(const T& a, const T& b) const {
return SgnCompare(a, b);
}
};
template <class T>
void StableSortCmp(T& c)
{
StableSort(c.Begin(), c.End(), StdCmp<typename T::ValueType>());
}
template <class II, class VI, class K>
struct IndexSortIterator
{
typedef IndexSortIterator<II, VI, K> 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 <class II, class VI, class K, class Less>
inline void __IndexSort(II begin, II end, VI pair, const Less& less, const K *)
{
Sort(IndexSortIterator<II, VI, K>(begin, pair),
IndexSortIterator<II, VI, K>(end, pair + (end - begin)),
less);
}
template <class II, class VI, class Less>
inline void IndexSort(II begin, II end, VI pair, const Less& less)
{
if(begin != end)
__IndexSort(begin, end, pair, less, &*begin);
}
template <class KC, class VC, class Less>
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 <class KC, class VC>
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>(), (KT *)0);
}
template <class II, class VI, class K, class Less>
inline void __StableIndexSort(II begin, II end, VI pair, const Less& less, const K *)
{
StableSort(IndexSortIterator<II, VI, K>(begin, pair),
IndexSortIterator<II, VI, K>(end, pair + (end - begin)),
less);
}
template <class II, class VI, class Less>
inline void StableIndexSort(II begin, II end, VI pair, const Less& less)
{
if(begin != end)
__StableIndexSort(begin, end, pair, less, &*begin);
}
template <class KC, class VC, class Less>
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 <class KC, class VC>
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>(), (KT *)0);
}
template <class II, class VI, class K, class Cmp>
inline void __StableIndexSortCmp(II begin, II end, VI pair, const Cmp& cmp, const K *)
{
StableSortCmp(IndexSortIterator<II, VI, K>(begin, pair),
IndexSortIterator<II, VI, K>(end, pair + (end - begin)),
cmp);
}
template <class II, class VI, class Cmp>
inline void StableIndexSortCmp(II begin, II end, VI pair, const Cmp& cmp)
{
if(begin != end)
__StableIndexSortCmp(begin, end, pair, cmp, &*begin);
}
template <class KC, class VC, class Cmp>
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 <class KC, class VC>
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>(), (KT *)0);
}
template <class II, class VI, class WI, class K>
struct IndexSort2Iterator
{
typedef IndexSort2Iterator<II, VI, WI, K> 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 <class II, class VI, class WI, class K, class Less>
inline void __IndexSort2(II begin, II end, VI pair1, WI pair2, const Less& less, const K *)
{
int count = end - begin;
Sort(IndexSort2Iterator<II, VI, WI, K>(begin, pair1, pair2),
IndexSort2Iterator<II, VI, WI, K>(end, pair1 + count, pair2 + count),
less);
}
template <class II, class VI, class WI, class Less>
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 <class KC, class VC, class WC, class Less>
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 <class KC, class VC, class WC>
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>(), (KT *)0);
}
template <class II, class VI, class WI, class K, class Less>
inline void __StableIndexSort2(II begin, II end, VI pair1, WI pair2, const Less& less, const K *)
{
int count = end - begin;
StableSort(IndexSort2Iterator<II, VI, WI, K>(begin, pair1, pair2),
IndexSort2Iterator<II, VI, WI, K>(end, pair1 + count, pair2 + count),
less);
}
template <class II, class VI, class WI, class Less>
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 <class KC, class VC, class WC, class Less>
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 <class KC, class VC, class WC>
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>(), (KT *)0);
}
template <class II, class VI, class WI, class K, class Cmp>
inline void __StableIndexSort2Cmp(II begin, II end, VI pair1, WI pair2, const Cmp& cmp, const K *)
{
int count = end - begin;
StableSortCmp(IndexSort2Iterator<II, VI, WI, K>(begin, pair1, pair2),
IndexSort2Iterator<II, VI, WI, K>(end, pair1 + count, pair2 + count),
cmp);
}
template <class II, class VI, class WI, class Cmp>
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 <class KC, class VC, class WC, class Cmp>
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 <class KC, class VC, class WC>
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>(), (KT *)0);
}
template <class II, class VI, class WI, class XI, class K>
struct IndexSort3Iterator
{
typedef IndexSort3Iterator<II, VI, WI, XI, K> 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 <class II, class VI, class WI, class XI, class K, class Less>
inline void __IndexSort3(II begin, II end, VI pair1, WI pair2, XI pair3, const Less& less, const K *)
{
int count = end - begin;
Sort(IndexSort3Iterator<II, VI, WI, XI, K>(begin, pair1, pair2, pair3),
IndexSort3Iterator<II, VI, WI, XI, K>(end, pair1 + count, pair2 + count, pair3 + count),
less);
}
template <class II, class VI, class WI, class XI, class Less>
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 <class KC, class VC, class WC, class XC, class Less>
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 <class KC, class VC, class WC, class XC>
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>(), (KT *)0);
}
template <class II, class VI, class WI, class XI, class K, class Less>
inline void __StableIndexSort3(II begin, II end, VI pair1, WI pair2, XI pair3, const Less& less, const K *)
{
int count = end - begin;
StableSort(IndexSort3Iterator<II, VI, WI, XI, K>(begin, pair1, pair2, pair3),
IndexSort3Iterator<II, VI, WI, XI, K>(end, pair1 + count, pair2 + count, pair3 + count),
less);
}
template <class II, class VI, class WI, class XI, class Less>
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 <class KC, class VC, class WC, class XC, class Less>
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 <class KC, class VC, class WC, class XC>
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>(), (KT *)0);
}
template <class II, class VI, class WI, class XI, class K, class Cmp>
inline void __StableIndexSort3Cmp(II begin, II end, VI pair1, WI pair2, XI pair3, const Cmp& cmp, const K *)
{
int count = end - begin;
StableSortCmp(IndexSort3Iterator<II, VI, WI, XI, K>(begin, pair1, pair2, pair3),
IndexSort3Iterator<II, VI, WI, XI, K>(end, pair1 + count, pair2 + count, pair3 + count),
cmp);
}
template <class II, class VI, class WI, class XI, class Cmp>
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 <class KC, class VC, class WC, class XC, class Cmp>
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 <class KC, class VC, class WC, class XC>
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>(), (KT *)0);
}
template <class I, class V>
struct SortOrderIterator : PostfixOps< SortOrderIterator<I, V> >
{
typedef SortOrderIterator<I, V> 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 <class I, class V, class Less>
inline void __SortOrder(int *begin, int *end, I data, const Less& less, const V *)
{
Sort(SortOrderIterator<I, V>(begin, data), SortOrderIterator<I, V>(end, data), less);
}
template <class I, class Less>
inline Vector<int> GetSortOrder(I begin, I end, const Less& less)
{
Vector<int> 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 <class C, class Less>
inline Vector<int> GetSortOrder(const C& container, const Less& less)
{
return GetSortOrder(container.Begin(), container.End(), less);
}
template <class C>
inline Vector<int> GetSortOrder(const C& container)
{
typedef typename C::ValueType V;
return GetSortOrder(container.Begin(), container.End(), StdLess<V>());
}
template <class I, class T>
struct StableSortOrderIterator : PostfixOps< StableSortOrderIterator<I, T> >
{
typedef StableSortOrderIterator<I, T> 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<T> operator*() const { return StableSortItem<T>(*(vi + *ii), *ii); }
int *ii;
I vi;
};
template <class I, class T, class Less>
inline void __StableSortOrder(int *ibegin, int *iend, I data, const Less& less, const T *)
{
Sort(StableSortOrderIterator<I, T>(ibegin, data),
StableSortOrderIterator<I, T>(iend, data),
StableSortLess_<T, Less>(less));
}
template <class I, class Less>
inline Vector<int> GetStableSortOrder(I begin, I end, const Less& less)
{
Vector<int> 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 <class C, class Less>
inline Vector<int> GetStableSortOrder(const C& container, const Less& less)
{
return GetStableSortOrder(container.Begin(), container.End(), less);
}
template <class C>
inline Vector<int> GetStableSortOrder(const C& container)
{
typedef typename C::ValueType V;
return GetStableSortOrder(container.Begin(), container.End(), StdLess<V>());
}
template <class I, class T, class Cmp>
inline void __StableSortOrderCmp(int *ibegin, int *iend, I data, const Cmp& cmp, const T *)
{
Sort(StableSortOrderIterator<I, T>(ibegin, data),
StableSortOrderIterator<I, T>(iend, data),
StableSortLessCmp_<T, Cmp>(cmp));
}
template <class I, class Cmp>
inline Vector<int> GetStableSortOrderCmp(I begin, I end, const Cmp& cmp)
{
Vector<int> 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 <class C, class Cmp>
inline Vector<int> GetStableSortOrderCmp(const C& container, const Cmp& cmp)
{
return GetStableSortOrderCmp(container.Begin(), container.End(), cmp);
}
template <class C>
inline Vector<int> GetStableSortOrderCmp(const C& container)
{
typedef typename C::ValueType V;
return GetStableSortOrderCmp(container.Begin(), container.End(), StdCmp<V>());
}
template <class DC, class I, class F>
void GetFieldContainer(DC& dest, I begin, I end, F field)
{
for(; begin != end; ++begin)
dest.Add((*begin).*field);
}
template <class DC, class SC, class F>
void GetFieldContainer(DC& dest, const SC& src, F field)
{ GetFieldContainer<DC, typename SC::ConstIterator, F>(dest, src.Begin(), src.End(), field); }
template <class I, class F, class O, class E>
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 <class I, class F, class O>
I FindField(I begin, I end, F field, const O& object)
{ return FindField(begin, end, field, object, StdEqual<O>()); }
template <class C, class F, class O, class E>
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 <class C, class F, class O>
int FindFieldIndex(const C& container, F field, const O& object)
{ return FindFieldIndex(container, field, object, StdEqual<O>()); }
template <class O, class T, class R>
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 <class O, class T, class R>
inline FieldRelationCls<O, T, R> FieldRelation(O (T::*member), const R& relation)
{ return FieldRelationCls<O, T, R>(member, relation); }
template <class M, class T, class R>
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 <class O, class T, class R>
inline MethodRelationCls<O (T::*)(), T, R>
MethodRelation(O (T::*method)(), const R& relation)
{ return MethodRelationCls<O (T::*)(), T, R>(method, relation); }
template <class O, class T, class R>
inline MethodRelationCls<O (T::*)() const, T, R>
MethodRelation(O (T::*method)() const, const R& relation)
{ return MethodRelationCls<O (T::*)() const, T, R>(method, relation); }
template <class C, class T>
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);
}