#include using namespace Upp; #ifdef flagLONG #define N 100 #else #define N 8 #endif template void Compare(C1& a, C2& b) { ASSERT(a.GetCount() == b.GetCount()); for(int i = 0; i < a.GetCount(); i++) ASSERT(a[i] == b[i]); typename C1::Iterator ia = a.Begin(); typename C2::Iterator ib = b.Begin(); while(ib != b.End()) { ASSERT(*ia == *ib); ia++; ib++; } } template void Check(const InVector& iv) { ASSERT(iv.GetCount() == 0 || iv.FindUpperBound(iv.Top()) == iv.GetCount()); } template T ToType(int); template <> String ToType(int i) { return Format("%010d", i); } template <> int ToType(int i) { return i; } template void InVectorTest() { SeedRandom(); Vector q; InVector iv; Compare(q, iv); iv.Insert(0) = 0; q.Insert(0) = 0; iv.Insert(1) = ToType(-1); q.Insert(1) = ToType(-1); for(int j = 0; j < 100 * N; j++) { if(j % 1000 == 0) LOG(j); int i = Random(iv.GetCount()); iv.Insert(i) = ToType(i); q.Insert(i) = ToType(i); Compare(q, iv); } for(int i = 0; i < N; i++) { int n = Random(100) + 20; typename InVector::Iterator it2, it = iv.Begin(); it += n; ASSERT(it - iv.Begin() == n); it2 = it; for(int j = 0; j < 10; j++) { ASSERT(it2 - iv.Begin() == n + j); ++it2; } it2 = it; for(int j = 0; j < 10; j++) { ASSERT(it2 - iv.Begin() == n - j); --it2; } } StableSort(q); StableSort(iv); Compare(q, iv); } template void TestUpperBound() { { InVector v; for(int i = 0; i < 30 * N; i++) { if(i % 1000 == 0) LOG(i); v.Insert(i) = ToType(i); ASSERT(v.FindUpperBound(ToType(i)) == i + 1); for(int j = 0; j < i; j++) ASSERT(v.FindUpperBound(ToType(j)) == j + 1); Check(v); } } { InVector v; for(int i = 0; i < 30 * N; i++) { if(i % 1000 == 0) LOG(i); for(int j = 0; j < 7; j++) v.Insert(7 * i) = ToType(i); ASSERT(v.FindUpperBound(ToType(i)) == 7 * i + 7); for(int j = 0; j < i; j++) ASSERT(v.FindUpperBound(ToType(j)) == 7 * j + 7); Check(v); } } } template void TestLowerBound() { { InVector v; for(int i = 0; i < 30 * N; i++) { if(i % 1000 == 0) LOG(i); v.Insert(i) = ToType(i); ASSERT(v.FindLowerBound(ToType(i)) == i); for(int j = 0; j < i; j++) ASSERT(v.FindLowerBound(ToType(j)) == j); Check(v); } } { InVector v; for(int i = 0; i < 30 * N; i++) { if(i % 1000 == 0) LOG(i); for(int j = 0; j < 7; j++) v.Insert(7 * i) = ToType(i); ASSERT(v.FindLowerBound(ToType(i)) == 7 * i); for(int j = 0; j < i; j++) ASSERT(v.FindLowerBound(ToType(j)) == 7 * j); Check(v); } } } template void SetTest() { for(int j = 0; j < 100; j++) { LOG(j); Vector va; InVector ia; for(int i = 0; i < 10 * N; i++) { int q = Random(100); int ii = FindUpperBound(va, ToType(q)); T val = ToType(q); va.Insert(ii) = val; ia.InsertUpperBound(val); Compare(va, ia); Check(ia); ii = ia.Find(val); ASSERT(ia[ii] == val); ASSERT(ia.Find(ToType(20000)) < 0); } } } template void RemoveTest() { SeedRandom(); Vector q; InVector iv; Compare(q, iv); iv.Insert(0) = 0; q.Insert(0) = 0; iv.Insert(1) = ToType(-1); q.Insert(1) = ToType(-1); for(int j = 0; j < 100000 * N; j++) { if(j % 1000 == 0) LOG(j); if(iv.GetCount() > 200 && Random(4) == 1) { int i = Random(iv.GetCount() - 21); int n = Random(20); iv.Remove(i, n); q.Remove(i, n); } else { int i = Random(iv.GetCount()); iv.Insert(i) = ToType(i); q.Insert(i) = ToType(i); } Compare(q, iv); ASSERT(iv.End() - iv.Begin() == iv.GetCount()); } } template void InsertNTest() { SeedRandom(); Vector av; InVector iv; for(int i = 0; i < 1000 * N; i++) { if(i % 1000 == 0) LOG(i); if(av.GetCount() > 2000) { av.Clear(); iv.Clear(); } int pos = av.GetCount() ? Random(av.GetCount()) : 0; int n = Random(30); av.InsertN(pos, n); iv.InsertN(pos, n); for(int j = 0; j < n; j++) { int r = Random(); av[pos + j] = ToType(r); iv[pos + j] = ToType(r); } Compare(av, iv); } } struct TestType : Moveable { int x; String y; bool operator<(const TestType& b) const { return CombineCompare(x, b.x)(y, b.y) < 0; } bool operator==(const TestType& b) const { return x == b.x && y == b.y; } TestType(int i) { x = i; y = AsString(i ^ 7); } TestType() {} }; template <> TestType ToType(int i) { return TestType(i); } CONSOLE_APP_MAIN { StdLogSetup(LOG_FILE|LOG_COUT); TimeStop tm; int time0 = msecs(); SeedRandom(); SetTest(); TestLowerBound(); TestUpperBound(); RemoveTest(); InsertNTest(); InVectorTest(); SetTest(); TestLowerBound(); TestUpperBound(); RemoveTest(); InsertNTest(); InVectorTest(); SetTest(); TestLowerBound(); TestUpperBound(); RemoveTest(); InsertNTest(); InVectorTest(); LOG("========= OK " << tm); }