#ifndef Container_First #define Container_First #ifdef __GNUG__ #pragma interface #endif #include "Iterator.h" #include "Object.h" extern const char *cWarningActiveIterator, *cWarningNullArgument; const int cContainerInitCap= 16; const bool cIterForward= TRUE, cIterBackward= !cIterForward; //---- Container --------------------------------------------------------------- class Container : public Object { friend Iterator; friend IterIter; protected: Container(); public: MetaDef(Container); ~Container(); void InitNew(); virtual int Capacity(); bool assertclass(Class*); void InspectorId(char*, int); //---- comparison bool IsEqual(Object*); u_long Hash(); //---- access int Size(); bool IsEmpty(); bool Contains(Object*); bool ContainsPtr(Object*); virtual Iterator *MakeIterator(bool dir= cIterForward, void *placement= 0); Iterator *MakeReversedIterator(void *placement= 0); virtual Object *AnyElement(); // return any element virtual Object *Find(Object*); // returns 0 if not found, uses IsEqual virtual Object *FindPtr(Object*); // returns 0 if not found, uses identity virtual int OccurrencesOf(Object*); // uses IsEqual virtual int OccurrencesOfPtr(Object*); // uses identity //---- object i/o OStream& PrintOn(OStream&); IStream& ReadFrom(IStream&); protected: bool IsArgNull(char *where, Object *arg); bool CheckForIterator(char *where); //---- iterators bool HasIterators(); void IteratorActivates(Iterator *which); void IteratorTerminates(Iterator *which); void DetachIterators(); //---- robust iterators - place holder approach (old style) virtual void RemoveDeleted(); void AnnounceRemove(); bool HasDeletedObjects(); protected: int size; int nDeleted; // for robust iterators (place holder approach) int iterCount; // active iterators private: Iterator iterHead; public: void setCurrentContainer(); // for ForEach macro static Container *currentContainer; // for ForEach macro }; //---- Iter -------------------------------------------------------------------- class Iter { Iterator *seq; char space[64]; public: Iter(Container *coll, bool dir= cIterForward); Iter(Iterator *it); ~Iter(); Object *operator()(); void Reset(Container *coll, bool dir= cIterForward); void Reset(); }; inline Iter::Iter(Container *coll, bool dir) { seq= coll->MakeIterator(dir, space); } inline Iter::Iter(Iterator *it) { seq= it; } inline Object *Iter::operator()() { return (*seq)(); } inline void Iter::Reset() { seq->Reset(); } //---- macros ------------------------------------------------------------------ #define ForEach(type,proc) \ setCurrentContainer(); \ Iter _NAME3_(type,proc,_next0)(Container::currentContainer); \ register type *_NAME3_(type,proc,_op0); \ while (_NAME3_(type,proc,_op0)= (type*) _NAME3_(type,proc,_next0)()) \ _NAME3_(type,proc,_op0)->proc #define _ForEach(type,proc,p) \ setCurrentContainer(); \ { Iter _next(Container::currentContainer); \ register type *_op; \ while (_op= (type*) _next()) \ if (p _op->IsKindOf(type)) \ _op->proc; } #define ForEachOfClass(type,proc) \ _ForEach(type,proc,) #define ForEachNotOfClass(type,proc) \ _ForEach(type,proc,!) //---- Container inlines ------------------------------------------------------- inline int Container::Size() { return size - nDeleted; } inline bool Container::IsEmpty() { return (bool) (Size() <= 0); } inline bool Container::Contains(Object *op) { return Find(op) != 0; } inline bool Container::ContainsPtr(Object *op) { return FindPtr(op) != 0; } inline Iterator *Container::MakeReversedIterator(void *placement) { return MakeIterator(FALSE, placement); } //---- inlines (protected and private) ---- inline void Container::setCurrentContainer() { currentContainer= this; } inline bool Container::IsArgNull(char *where, Object *arg) { return arg ? FALSE : (Warning(where, cWarningNullArgument), TRUE); } inline bool Container::HasIterators() { return iterCount > 0; } inline bool Container::CheckForIterator(char *where) { return HasIterators() ? (Warning(where, cWarningActiveIterator), TRUE) : FALSE; } inline void Container::AnnounceRemove() { nDeleted++; } inline bool Container::HasDeletedObjects() { return (bool) (nDeleted > 0); } #endif