#include "Col.ph" #ifdef __GNUG__ #pragma implementation #endif #include "Set.h" #include "Class.h" #include "IterIter.h" #include "Error.h" #include "RobustHashTable.h" //---- Set --------------------------------------------------------------------- NewMetaImpl(Set,Collection, (TP(ht))); Set::Set(int initCapacity) { Init(initCapacity); } Set::~Set() { SafeDelete(ht); } void Set::InitNew() { Collection::InitNew(); Init(cContainerInitCap); } void Set::Empty(int newCapacity) { if (HasIterators()) ForEachIterDo(SetIter, SavePosition(ht->cInvalidIndex)); ht->Empty(newCapacity); if (HasIterators()) ForEachIterDo(SetIter, ResetPosition()); } void Set::FreeAll() { Object *op; if (HasIterators()) ForEachIterDo(SetIter, SavePosition(ht->cInvalidIndex)); int i= ht->GetInitialIndex(); while (op= (Object*) ht->AtNextIndex(i)) { op->FreeAll(); delete op; } ht->Empty(cContainerInitCap); if (HasIterators()) ForEachIterDo(SetIter, ResetPosition()) } int Set::Capacity() { return ht->Capacity(); } Object *Set::Add(Object *op) { if (IsArgNull("Add", op)) return 0; Object *result= (Object*) ht->Add(op); if (! result) Changed(); return result; } Object *Set::Remove(Object *op) { if (IsArgNull("Remove", op)) return 0; Object *result= (Object*) ht->Remove(op, eEqValue); if (result) Changed(); return result; } Object *Set::RemovePtr(Object *op) { if (IsArgNull("RemovePtr", op)) return 0; Object *result= (Object*) ht->Remove(op, eEqPointer); if (result) Changed(); return result; } Iterator *Set::MakeIterator(bool, void *placement) { return new(placement) SetIter(this); } Object *Set::Find(Object *op) { if (IsArgNull("Find", op)) return 0; return (Object*) ht->Find(op, eEqValue); } Object *Set::FindPtr(Object *op) { if (IsArgNull("FindPtr", op)) return 0; return (Object*) ht->Find(op, eEqPointer); } int Set::OccurrencesOf(Object *op) { return Find(op) ? 1 : 0; } int Set::OccurrencesOfPtr(Object *op) { return FindPtr(op) ? 1 : 0; } //---- statistics ---- double Set::AverageCollisions() { return ht->AverageCollisions(); } //---- initialization ---- Set::Set(Set*) { ht= 0; } void Set::Init(int initCapacity) { ht= new RobustHashTable( this, initCapacity, &ContainerTypes::pEqual, &ContainerTypes::pHash, &size); } //---- robust iterators ---- void Set::SaveItersPosition(int pix) { ForEachIterDo(SetIter, SavePosition(pix)); } void Set::ResetItersPosition() { ForEachIterDo(SetIter, ResetPosition()); } //---- SetIter ---------------------------------------------------------------- SetIter::SetIter(Set *aSet) { set= aSet; ht= 0; pix= 0; saved= 0; } SetIter::~SetIter() { Terminate(); } Object *SetIter::operator()() { Object *op; if (! Activated()) { if (Activate()) { ht= set->ht; pix= ht->GetInitialIndex(); } } if (! Terminated()) { op= (Object*) ht->AtNextIndex(pix); if (! op) Terminate(); return op; } return 0; } void SetIter::Reset() { Iterator::Reset(); pix= 0; saved= 0; } Container *SetIter::GetContainer() { return set; } void SetIter::SavePosition(int forPix) { if (IsActive()) { if (forPix == pix) saved= (Object*) ht->AtPrevIndex(pix); else saved= (Object*) ht->AtIndex(pix); } else Error("SetIter::SavePosition", "this is not active"); } void SetIter::ResetPosition() { if (IsActive()) { if (saved) pix= ht->IndexOf(saved, eEqPointer); else pix= ht->GetInitialIndex(); } else Error("SetIter::SavePosition", "this is not active"); saved= 0; } //---- IdSet ------------------------------------------------------------------- NewMetaImpl0(IdSet, Set); IdSet::IdSet(int aCapacity) : Set(this) { Init(aCapacity); } void IdSet::InitNew() { Collection::InitNew(); Init(cContainerInitCap); } void IdSet::Init(int aCapacity) { ht= new RobustHashTable( this, aCapacity, &ContainerTypes::pIdentical, &ContainerTypes::pHashPtr, &size); }