#include <stdio.h>
#include <stdlib.h>
#include <map>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <VectorMap.h>
#include <KernelUtilsOrder.h>
template<typename _Value> class SimpleValueStrategy {
public:
typedef _Value Value;
SimpleValueStrategy(int32 differentValues = 100000)
:
fDifferentValues(differentValues)
{
srand(0);
}
Value Generate();
private:
int32 fDifferentValues;
};
template<>
int
SimpleValueStrategy<int>::Generate()
{
return rand() % fDifferentValues;
}
template<>
string
SimpleValueStrategy<string>::Generate()
{
char buffer[10];
sprintf(buffer, "%ld", rand() % fDifferentValues);
return string(buffer);
}
template<typename _KeyStrategy, typename _ValueStrategy>
class PairEntryStrategy {
public:
typedef _KeyStrategy KeyStrategy;
typedef _ValueStrategy ValueStrategy;
typedef typename KeyStrategy::Value Key;
typedef typename ValueStrategy::Value Value;
inline Key GenerateKey() { return fKeyStrategy.Generate(); }
inline Value GenerateValue() { return fValueStrategy.Generate(); }
inline void Generate(Key& key, Value& value)
{
key = GenerateKey();
value = GenerateValue();
}
private:
KeyStrategy fKeyStrategy;
ValueStrategy fValueStrategy;
};
template<typename _KeyStrategy, typename _ValueStrategy, typename GetKey>
class ImplicitKeyStrategy {
public:
typedef _KeyStrategy KeyStrategy;
typedef _ValueStrategy ValueStrategy;
typedef typename KeyStrategy::Value Key;
typedef typename ValueStrategy::Value Value;
inline Key GenerateKey() { return fKeyStrategy.Generate(); }
inline Value GenerateValue() { return fValueStrategy.Generate(); }
inline void Generate(Key& key, Value& value)
{
value = GenerateValue();
key = fGetKey(value);
}
private:
KeyStrategy fKeyStrategy;
ValueStrategy fValueStrategy;
GetKey fGetKey;
};
struct Ascending {
template<typename Value>
class Strategy : public KernelUtilsOrder::Ascending<Value> {};
};
struct Descending {
template<typename Value>
class Strategy : public KernelUtilsOrder::Descending<Value> {};
};
template<typename Value, typename Compare>
class CompareWrapper {
public:
inline bool operator()(const Value& a, const Value& b) const
{ return fCompare(a, b) < 0; }
private:
Compare fCompare;
};
template<typename Entry, typename TestMap, typename MyIterator, typename ReferenceIterator>
class TestIterator {
private:
typedef TestIterator<Entry, TestMap, MyIterator, ReferenceIterator> Iterator;
public:
inline TestIterator(TestMap* s, MyIterator myIt, ReferenceIterator refIt)
:
fMap(s),
fMyIterator(myIt),
fReferenceIterator(refIt)
{
}
inline TestIterator(const Iterator& other)
:
fMap(other.fMap),
fMyIterator(other.fMyIterator),
fReferenceIterator(other.fReferenceIterator)
{
CPPUNIT_ASSERT(fMyIterator == other.fMyIterator);
}
inline Iterator& operator++()
{
MyIterator& myResult = ++fMyIterator;
ReferenceIterator& refResult = ++fReferenceIterator;
if (refResult == fMap->fReferenceMap.end()) {
CPPUNIT_ASSERT(myResult == fMap->fMyMap.End());
} else {
CPPUNIT_ASSERT(myResult->Key() == refResult->first);
CPPUNIT_ASSERT(myResult->Value() == refResult->second);
}
return *this;
}
inline Iterator operator++(int)
{
MyIterator oldMyResult = fMyIterator;
MyIterator myResult = fMyIterator++;
ReferenceIterator refResult = fReferenceIterator++;
CPPUNIT_ASSERT(oldMyResult == myResult);
if (refResult == fMap->fReferenceMap.end()) {
CPPUNIT_ASSERT(myResult == fMap->fMyMap.End());
} else {
CPPUNIT_ASSERT(myResult->Key() == refResult->first);
CPPUNIT_ASSERT(myResult->Value() == refResult->second);
}
return Iterator(fMap, myResult, refResult);
}
inline Iterator& operator--()
{
MyIterator& myResult = --fMyIterator;
ReferenceIterator& refResult = --fReferenceIterator;
CPPUNIT_ASSERT(myResult->Key() == refResult->first);
CPPUNIT_ASSERT(myResult->Value() == refResult->second);
return *this;
}
inline Iterator operator--(int)
{
MyIterator oldMyResult = fMyIterator;
MyIterator myResult = fMyIterator--;
ReferenceIterator refResult = fReferenceIterator--;
CPPUNIT_ASSERT(oldMyResult == myResult);
CPPUNIT_ASSERT(myResult->Key() == refResult->first);
CPPUNIT_ASSERT(myResult->Value() == refResult->second);
return Iterator(fMap, myResult, refResult);
}
inline Iterator& operator=(const Iterator& other)
{
fMap = other.fMap;
fMyIterator = other.fMyIterator;
fReferenceIterator = other.fReferenceIterator;
CPPUNIT_ASSERT(fMyIterator == other.fMyIterator);
return *this;
}
inline bool operator==(const Iterator& other) const
{
bool result = (fMyIterator == other.fMyIterator);
CPPUNIT_ASSERT((fReferenceIterator == other.fReferenceIterator) == result);
return result;
}
inline bool operator!=(const Iterator& other) const
{
bool result = (fMyIterator != other.fMyIterator);
CPPUNIT_ASSERT((fReferenceIterator != other.fReferenceIterator) == result);
return result;
}
inline Entry operator*() const
{
Entry entry = *fMyIterator;
CPPUNIT_ASSERT(entry.Key() == fReferenceIterator->first);
CPPUNIT_ASSERT(entry.Value() == fReferenceIterator->second);
return entry;
}
inline Entry operator->() const
{
Entry entry = fMyIterator.operator->();
CPPUNIT_ASSERT(entry.Key() == fReferenceIterator->first);
CPPUNIT_ASSERT(entry.Value() == fReferenceIterator->second);
return entry;
}
inline operator bool() const
{
bool result = fMyIterator;
CPPUNIT_ASSERT((fMyIterator == fMap->fMyMap.Null()) != result);
return result;
}
public:
TestMap* fMap;
MyIterator fMyIterator;
ReferenceIterator fReferenceIterator;
};
template<typename Key, typename Value, typename MyMap, typename ReferenceMap, typename Compare>
class TestMap {
public:
typedef TestMap<Key, Value, MyMap, ReferenceMap, Compare> Class;
typedef typename MyMap::Iterator MyIterator;
typedef typename ReferenceMap::iterator ReferenceIterator;
typedef typename MyMap::ConstIterator MyConstIterator;
typedef typename ReferenceMap::const_iterator ReferenceConstIterator;
typedef typename MyMap::Entry Entry;
typedef typename MyMap::ConstEntry ConstEntry;
typedef TestIterator<Entry, Class, MyIterator, ReferenceIterator> Iterator;
typedef TestIterator<ConstEntry, const Class, MyConstIterator, ReferenceConstIterator>
ConstIterator;
TestMap()
:
fMyMap(),
fReferenceMap(),
fChecking(true)
{
}
void Insert(const Key& key, const Value& value)
{
CPPUNIT_ASSERT(fMyMap.Insert(key, value) == B_OK);
fReferenceMap[key] = value;
Check();
}
void Put(const Key& key, const Value& value)
{
CPPUNIT_ASSERT(fMyMap.Put(key, value) == B_OK);
fReferenceMap[key] = value;
Check();
}
Value& Get(const Key& key)
{
Value& value = fMyMap.Get(key);
CPPUNIT_ASSERT(value == fReferenceMap[key]);
return value;
}
const Value& Get(const Key& key) const
{
const Value& value = fMyMap.Get(key);
CPPUNIT_ASSERT(value == fReferenceMap.find(key)->second);
return value;
}
void Remove(const Key& key)
{
int32 oldCount = Count();
ReferenceIterator it = fReferenceMap.find(key);
if (it != fReferenceMap.end())
fReferenceMap.erase(it);
int32 newCount = fReferenceMap.size();
CPPUNIT_ASSERT(fMyMap.Remove(key) == oldCount - newCount);
Check();
}
Iterator Erase(const Iterator& iterator)
{
bool outOfRange = (iterator.fReferenceIterator == fReferenceMap.end());
MyIterator myIt = fMyMap.Erase(iterator.fMyIterator);
if (outOfRange) {
CPPUNIT_ASSERT(myIt == fMyMap.Null());
return Iterator(this, myIt, fReferenceMap.end());
}
Key nextKey;
ReferenceIterator refIt = iterator.fReferenceIterator;
++refIt;
bool noNextEntry = (refIt == fReferenceMap.end());
if (!noNextEntry)
nextKey = refIt->first;
fReferenceMap.erase(iterator.fReferenceIterator);
if (noNextEntry)
refIt = fReferenceMap.end();
else
refIt = fReferenceMap.find(nextKey);
Check();
if (refIt == fReferenceMap.end()) {
CPPUNIT_ASSERT(myIt == fMyMap.End());
} else {
CPPUNIT_ASSERT(myIt->Key() == refIt->first);
CPPUNIT_ASSERT(myIt->Value() == refIt->second);
}
return Iterator(this, myIt, refIt);
}
inline int32 Count() const
{
int32 count = fReferenceMap.size();
CPPUNIT_ASSERT(fMyMap.Count() == count);
return count;
}
inline bool IsEmpty() const
{
bool result = fReferenceMap.empty();
CPPUNIT_ASSERT(fMyMap.IsEmpty() == result);
return result;
}
void MakeEmpty()
{
fMyMap.MakeEmpty();
fReferenceMap.clear();
Check();
}
inline Iterator Begin() { return Iterator(this, fMyMap.Begin(), fReferenceMap.begin()); }
inline ConstIterator Begin() const
{
return ConstIterator(this, fMyMap.Begin(), fReferenceMap.begin());
}
inline Iterator End() { return Iterator(this, fMyMap.End(), fReferenceMap.end()); }
inline ConstIterator End() const
{
return ConstIterator(this, fMyMap.End(), fReferenceMap.end());
}
inline Iterator Null() { return Iterator(this, fMyMap.Null(), fReferenceMap.end()); }
inline ConstIterator Null() const
{
return ConstIterator(this, fMyMap.Null(), fReferenceMap.end());
}
inline Iterator IteratorForIndex(int32 index)
{
if (index < 0 || index > Count())
return End();
MyIterator myIt = fMyMap.Begin();
ReferenceIterator refIt = fReferenceMap.begin();
for (int32 i = 0; i < index; i++) {
++myIt;
++refIt;
}
return Iterator(this, myIt, refIt);
}
inline ConstIterator IteratorForIndex(int32 index) const
{
if (index < 0 || index > Count())
return End();
MyConstIterator myIt = fMyMap.Begin();
ReferenceConstIterator refIt = fReferenceMap.begin();
for (int32 i = 0; i < index; i++) {
++myIt;
++refIt;
}
return ConstIterator(this, myIt, refIt);
}
Iterator Find(const Key& key)
{
MyIterator myIt = fMyMap.Find(key);
ReferenceIterator refIt = fReferenceMap.find(key);
if (refIt == fReferenceMap.end()) {
CPPUNIT_ASSERT(myIt = fMyMap.End());
} else {
CPPUNIT_ASSERT(myIt->Key() == refIt->first);
CPPUNIT_ASSERT(myIt->Value() == refIt->second);
}
return Iterator(this, myIt, refIt);
}
ConstIterator Find(const Key& key) const
{
MyConstIterator myIt = fMyMap.Find(key);
ReferenceConstIterator refIt = fReferenceMap.find(key);
if (refIt == fReferenceMap.end()) {
CPPUNIT_ASSERT(myIt = fMyMap.End());
} else {
CPPUNIT_ASSERT(myIt->Key() == refIt->first);
CPPUNIT_ASSERT(myIt->Value() == refIt->second);
}
return ConstIterator(this, myIt, refIt);
}
Iterator FindClose(const Key& key, bool less)
{
MyIterator myIt = fMyMap.FindClose(key, less);
if (myIt == fMyMap.End()) {
if (fMyMap.Count() > 0) {
if (less)
CPPUNIT_ASSERT(fCompare(fMyMap.Begin()->Key(), key) > 0);
else
CPPUNIT_ASSERT(fCompare((--MyIterator(myIt))->Key(), key) < 0);
}
return End();
}
if (less) {
CPPUNIT_ASSERT(fCompare(myIt->Key(), key) <= 0);
MyIterator nextMyIt(myIt);
++nextMyIt;
if (nextMyIt != fMyMap.End())
CPPUNIT_ASSERT(fCompare(nextMyIt->Key(), key) > 0);
} else {
CPPUNIT_ASSERT(fCompare(myIt->Key(), key) >= 0);
if (myIt != fMyMap.Begin()) {
MyIterator prevMyIt(myIt);
--prevMyIt;
CPPUNIT_ASSERT(fCompare(prevMyIt->Key(), key) < 0);
}
}
return Iterator(this, myIt, fReferenceMap.find(myIt->Key()));
}
ConstIterator FindClose(const Key& key, bool less) const
{
MyConstIterator myIt = fMyMap.FindClose(key, less);
if (myIt == fMyMap.End()) {
if (fMyMap.Count() > 0) {
if (less)
CPPUNIT_ASSERT(fCompare(fMyMap.Begin()->Key(), key) > 0);
else
CPPUNIT_ASSERT(fCompare((--MyConstIterator(myIt))->Key(), key) < 0);
}
return End();
}
if (less) {
CPPUNIT_ASSERT(fCompare(myIt->Key(), key) <= 0);
MyConstIterator nextMyIt(myIt);
++nextMyIt;
if (nextMyIt != fMyMap.End())
CPPUNIT_ASSERT(fCompare(nextMyIt->Key(), key) > 0);
} else {
CPPUNIT_ASSERT(fCompare(myIt->Key(), key) >= 0);
if (myIt != fMyMap.Begin()) {
MyConstIterator prevMyIt(myIt);
--prevMyIt;
CPPUNIT_ASSERT(fCompare(prevMyIt->Key(), key) < 0);
}
}
return ConstIterator(this, myIt, fReferenceMap.find(myIt->Key()));
}
void SetChecking(bool enable) { fChecking = enable; }
void Check() const
{
if (fChecking) {
int32 count = fReferenceMap.size();
CPPUNIT_ASSERT(fMyMap.Count() == count);
CPPUNIT_ASSERT(fMyMap.IsEmpty() == fReferenceMap.empty());
MyConstIterator myIt = fMyMap.Begin();
ReferenceConstIterator refIt = fReferenceMap.begin();
for (int32 i = 0; i < count; i++, ++myIt, ++refIt) {
CPPUNIT_ASSERT(myIt->Key() == refIt->first);
CPPUNIT_ASSERT(myIt->Value() == refIt->second);
CPPUNIT_ASSERT((*myIt).Key() == refIt->first);
CPPUNIT_ASSERT((*myIt).Value() == refIt->second);
}
CPPUNIT_ASSERT(myIt == fMyMap.End());
}
}
public:
MyMap fMyMap;
ReferenceMap fReferenceMap;
bool fChecking;
Compare fCompare;
};
template<template<typename> class _MyMap, typename _EntryStrategy,
class CompareStrategyWrapper>
class TestStrategy {
public:
typedef _EntryStrategy EntryStrategy;
typedef typename EntryStrategy::KeyStrategy KeyStrategy;
typedef typename EntryStrategy::ValueStrategy ValueStrategy;
typedef typename KeyStrategy::Value Key;
typedef typename ValueStrategy::Value Value;
typedef typename CompareStrategyWrapper::template Strategy<Key> Compare;
typedef CompareWrapper<Key, Compare> BoolCompare;
typedef _MyMap<Compare> MyMap;
typedef std::map<Key, Value, BoolCompare> ReferenceMap;
typedef TestMap<Key, Value, MyMap, ReferenceMap, Compare> TestClass;
};
template<class TestStrategy>
class VectorMapTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(VectorMapTest);
CPPUNIT_TEST(ConstructorTest);
CPPUNIT_TEST(Insert30ElementsTest);
CPPUNIT_TEST(Insert200ElementsTest);
CPPUNIT_TEST(Put30ElementsTest);
CPPUNIT_TEST(Put200ElementsTest);
CPPUNIT_TEST(Get30ElementsTest);
CPPUNIT_TEST(Get200ElementsTest);
CPPUNIT_TEST(Remove30ElementsTest);
CPPUNIT_TEST(Remove200ElementsTest);
CPPUNIT_TEST(Erase30ElementsTest);
CPPUNIT_TEST(Erase200ElementsTest);
CPPUNIT_TEST(MakeEmpty30ElementsTest);
CPPUNIT_TEST(MakeEmpty200ElementsTest);
CPPUNIT_TEST(Find30ElementsTest);
CPPUNIT_TEST(Find200ElementsTest);
CPPUNIT_TEST(FindClose30ElementsTest);
CPPUNIT_TEST(FindClose200ElementsTest);
CPPUNIT_TEST(Iterator30ElementsTest);
CPPUNIT_TEST(Iterator200ElementsTest);
CPPUNIT_TEST_SUITE_END();
typedef typename TestStrategy::EntryStrategy EntryStrategy;
typedef typename TestStrategy::Key Key;
typedef typename TestStrategy::Value Value;
typedef typename TestStrategy::TestClass TestClass;
typedef typename TestStrategy::MyMap MyMap;
typedef typename TestClass::Iterator Iterator;
typedef typename TestClass::ConstIterator ConstIterator;
void InsertTest(int32 maxNumber)
{
EntryStrategy entryStrategy;
TestClass v;
for (int32 i = 0; i < maxNumber; i++) {
Key key;
Value value;
entryStrategy.Generate(key, value);
v.Insert(key, value);
}
}
void PutTest(int32 maxNumber)
{
EntryStrategy entryStrategy;
TestClass v;
for (int32 i = 0; i < maxNumber; i++) {
Key key;
Value value;
entryStrategy.Generate(key, value);
v.Put(key, value);
}
}
void GetTest(int32 maxNumber)
{
EntryStrategy entryStrategy;
TestClass v;
Fill(v, entryStrategy, maxNumber);
const TestClass& cv = v;
for (int32 i = 0; i < maxNumber; i++) {
Iterator it = v.IteratorForIndex(i);
Key key = it->Key();
const Value& value = it->Value();
CPPUNIT_ASSERT(&v.Get(key) == &value);
CPPUNIT_ASSERT(&cv.Get(key) == &value);
}
}
void Fill(TestClass& v, EntryStrategy strategy, int32 maxNumber)
{
typedef typename EntryStrategy::Key Key;
typedef typename EntryStrategy::Value Value;
v.SetChecking(false);
for (int32 i = 0; v.Count() < maxNumber; i++) {
Key key;
Value value;
strategy.Generate(key, value);
v.Put(key, value);
}
v.SetChecking(true);
v.Check();
}
void RemoveTest(int32 maxNumber)
{
EntryStrategy entryStrategy;
TestClass v;
Fill(v, entryStrategy, maxNumber);
while (v.Count() > 0) {
int32 index = rand() % (v.Count());
Key key = v.IteratorForIndex(index)->Key();
v.Remove(key);
v.Remove(key);
}
}
void EraseTest(int32 maxNumber)
{
EntryStrategy entryStrategy;
TestClass v;
Fill(v, entryStrategy, maxNumber);
for (int32 i = maxNumber - 1; i >= 0; i--) {
int32 index = rand() % (i + 1);
v.Erase(v.IteratorForIndex(index));
}
}
void MakeEmptyTest(int32 maxNumber)
{
EntryStrategy entryStrategy;
TestClass v;
v.MakeEmpty();
Fill(v, entryStrategy, maxNumber);
v.MakeEmpty();
v.MakeEmpty();
}
void FindTest(int32 maxNumber)
{
EntryStrategy entryStrategy;
TestClass v;
Fill(v, entryStrategy, maxNumber);
const TestClass& cv = v;
for (int32 i = 0; i < maxNumber; i++) {
Key key = v.IteratorForIndex(i)->Key();
Iterator it = v.Find(key);
ConstIterator cit = cv.Find(key);
CPPUNIT_ASSERT(it->Key() == key);
CPPUNIT_ASSERT(it->Key() == cit->Key());
CPPUNIT_ASSERT((*it).Key() == (*it).Key());
CPPUNIT_ASSERT(&it->Value() == &cit->Value());
CPPUNIT_ASSERT(&(*it).Value() == &(*it).Value());
}
for (int32 i = 0; i < maxNumber; i++) {
Key key = v.IteratorForIndex(i)->Key();
Iterator it = v.Find(key);
ConstIterator cit = cv.Find(key);
if (it != v.End()) {
CPPUNIT_ASSERT(it->Key() == key);
CPPUNIT_ASSERT(it->Key() == cit->Key());
CPPUNIT_ASSERT((*it).Key() == (*it).Key());
CPPUNIT_ASSERT(&it->Value() == &cit->Value());
CPPUNIT_ASSERT(&(*it).Value() == &(*it).Value());
}
}
}
void FindCloseTest(int32 maxNumber)
{
EntryStrategy entryStrategy;
TestClass v;
Fill(v, entryStrategy, maxNumber);
const TestClass& cv = v;
for (int32 i = 0; i < maxNumber; i++) {
Key key = v.IteratorForIndex(i)->Key();
Iterator it = v.FindClose(key, true);
ConstIterator cit = cv.FindClose(key, true);
CPPUNIT_ASSERT(it->Key() == key);
CPPUNIT_ASSERT(it->Key() == cit->Key());
CPPUNIT_ASSERT((*it).Key() == (*it).Key());
CPPUNIT_ASSERT(&it->Value() == &cit->Value());
CPPUNIT_ASSERT(&(*it).Value() == &(*it).Value());
it = v.FindClose(key, false);
cit = cv.FindClose(key, false);
CPPUNIT_ASSERT(it->Key() == key);
CPPUNIT_ASSERT(it->Key() == cit->Key());
CPPUNIT_ASSERT((*it).Key() == (*it).Key());
CPPUNIT_ASSERT(&it->Value() == &cit->Value());
CPPUNIT_ASSERT(&(*it).Value() == &(*it).Value());
}
for (int32 i = 0; i < maxNumber; i++) {
Key key = entryStrategy.GenerateKey();
Iterator it = v.FindClose(key, true);
ConstIterator cit = cv.FindClose(key, true);
if (it != v.End()) {
CPPUNIT_ASSERT(it->Key() == cit->Key());
CPPUNIT_ASSERT((*it).Key() == (*it).Key());
CPPUNIT_ASSERT(&it->Value() == &cit->Value());
CPPUNIT_ASSERT(&(*it).Value() == &(*it).Value());
}
it = v.FindClose(key, false);
cit = cv.FindClose(key, false);
if (it != v.End()) {
CPPUNIT_ASSERT(it->Key() == cit->Key());
CPPUNIT_ASSERT((*it).Key() == (*it).Key());
CPPUNIT_ASSERT(&it->Value() == &cit->Value());
CPPUNIT_ASSERT(&(*it).Value() == &(*it).Value());
}
}
}
void IteratorTest(int32 maxNumber)
{
EntryStrategy entryStrategy;
TestClass v;
Fill(v, entryStrategy, maxNumber);
const TestClass& cv = v;
Iterator it = v.Begin();
ConstIterator cit = cv.Begin();
for (; it != v.End(); ++it, ++cit) {
CPPUNIT_ASSERT(it->Key() == cit->Key());
CPPUNIT_ASSERT(&it->Value() == &cit->Value());
CPPUNIT_ASSERT(it->Key() == (*it).Key());
CPPUNIT_ASSERT(cit->Key() == (*cit).Key());
CPPUNIT_ASSERT(&it->Value() == &(*it).Value());
CPPUNIT_ASSERT(&cit->Value() == &(*cit).Value());
CPPUNIT_ASSERT(it->Key() == it.operator->().Key());
CPPUNIT_ASSERT(&it->Value() == &it.operator->().Value());
CPPUNIT_ASSERT(cit->Key() == cit.operator->().Key());
CPPUNIT_ASSERT(&cit->Value() == &cit.operator->().Value());
CPPUNIT_ASSERT(it);
CPPUNIT_ASSERT(cit);
}
CPPUNIT_ASSERT(cit == cv.End());
while (it != v.Begin()) {
--it;
--cit;
CPPUNIT_ASSERT(it->Key() == cit->Key());
CPPUNIT_ASSERT(&it->Value() == &cit->Value());
CPPUNIT_ASSERT(it->Key() == (*it).Key());
CPPUNIT_ASSERT(cit->Key() == (*cit).Key());
CPPUNIT_ASSERT(&it->Value() == &(*it).Value());
CPPUNIT_ASSERT(&cit->Value() == &(*cit).Value());
CPPUNIT_ASSERT(it->Key() == it.operator->().Key());
CPPUNIT_ASSERT(&it->Value() == &it.operator->().Value());
CPPUNIT_ASSERT(cit->Key() == cit.operator->().Key());
CPPUNIT_ASSERT(&cit->Value() == &cit.operator->().Value());
CPPUNIT_ASSERT(it);
CPPUNIT_ASSERT(cit);
}
CPPUNIT_ASSERT(cit == cv.Begin());
CPPUNIT_ASSERT(!v.Null());
CPPUNIT_ASSERT(!cv.Null());
}
public:
void ConstructorTest()
{
MyMap v1;
CPPUNIT_ASSERT(v1.Count() == 0);
CPPUNIT_ASSERT(v1.IsEmpty());
}
void Put30ElementsTest() { PutTest(30); }
void Put200ElementsTest() { PutTest(200); }
void Get30ElementsTest() { GetTest(30); }
void Get200ElementsTest() { GetTest(200); }
void Insert30ElementsTest() { InsertTest(30); }
void Insert200ElementsTest() { InsertTest(200); }
void Remove30ElementsTest() { RemoveTest(30); }
void Remove200ElementsTest() { RemoveTest(200); }
void Erase30ElementsTest() { EraseTest(30); }
void Erase200ElementsTest() { EraseTest(200); }
void MakeEmpty30ElementsTest() { MakeEmptyTest(30); }
void MakeEmpty200ElementsTest() { MakeEmptyTest(200); }
void Find30ElementsTest() { FindTest(30); }
void Find200ElementsTest() { FindTest(200); }
void FindClose30ElementsTest() { FindCloseTest(30); }
void FindClose200ElementsTest() { FindCloseTest(200); }
void Iterator30ElementsTest() { IteratorTest(30); }
void Iterator200ElementsTest() { IteratorTest(200); }
};
template<typename Key, typename Value>
struct PairTestBase {
typedef SimpleValueStrategy<Key> KeyStrategy;
typedef SimpleValueStrategy<Value> ValueStrategy;
typedef PairEntryStrategy<KeyStrategy, ValueStrategy> EntryStrategy;
template<typename CompareStrategy>
struct MyMap
: public VectorMap<Key, Value, VectorMapEntryStrategy::Pair<Key, Value, CompareStrategy> > {
};
};
#define DECLARE_TEST_STRATEGY(Key, Value, Map, Strategy) \
template<typename CS> struct Map : PairTestBase<Key, Value>::MyMap<CS> {}; \
template<typename CS> \
struct Strategy : public TestStrategy<Map, PairTestBase<Key, Value>::EntryStrategy, CS> {};
DECLARE_TEST_STRATEGY(int, int, IntIntMap, IntIntTestStrategy)
DECLARE_TEST_STRATEGY(int, string, IntStringMap, IntStringTestStrategy)
DECLARE_TEST_STRATEGY(string, int, StringIntMap, StringIntTestStrategy)
DECLARE_TEST_STRATEGY(string, string, StringStringMap, StringStringTestStrategy)
static inline int
string_hash(const char* name)
{
uint32 h = 0;
for (; *name; name++) {
if (uint32 g = h & 0xf0000000)
h ^= g >> 24;
h = (h << 4) + *name;
}
return (int)h;
}
struct ImplicitKeyTestGetKey {
int operator()(string value) const { return string_hash(value.c_str()); }
};
template<typename CompareStrategy>
struct ImplicitKeyTestMap : public VectorMap<int, string,
VectorMapEntryStrategy::ImplicitKey<int, string,
ImplicitKeyTestGetKey, CompareStrategy> > {};
typedef ImplicitKeyStrategy<SimpleValueStrategy<int>, SimpleValueStrategy<string>,
ImplicitKeyTestGetKey>
ImplicitKeyTestEntryStrategy;
template<class CompareStrategy>
struct ImplicitKeyTestStrategy
: public TestStrategy<ImplicitKeyTestMap, ImplicitKeyTestEntryStrategy, CompareStrategy> {};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(VectorMapTest<IntIntTestStrategy<Ascending> >,
getTestSuiteName());
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(VectorMapTest<IntIntTestStrategy<Descending> >,
getTestSuiteName());
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(VectorMapTest<IntStringTestStrategy<Ascending> >,
getTestSuiteName());
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(VectorMapTest<IntStringTestStrategy<Descending> >,
getTestSuiteName());
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(VectorMapTest<StringIntTestStrategy<Ascending> >,
getTestSuiteName());
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(VectorMapTest<StringIntTestStrategy<Descending> >,
getTestSuiteName());
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(VectorMapTest<StringStringTestStrategy<Ascending> >,
getTestSuiteName());
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(VectorMapTest<StringStringTestStrategy<Descending> >,
getTestSuiteName());
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(VectorMapTest<ImplicitKeyTestStrategy<Ascending> >,
getTestSuiteName());
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(VectorMapTest<ImplicitKeyTestStrategy<Descending> >,
getTestSuiteName());