#ifndef AGGREGATE_H #define AGGREGATE_H /////////////////////////////////////////////////////////// // Aggregate.h - Container for Iterator Skeleton Demo // // // // Jim Fawcett, CSE776 - Design Patterns, Summer 2009 // /////////////////////////////////////////////////////////// #include "IAggregate.h" #include "Iterator.h" #include template class ConcreteAggregate : public IAggregate { public: // ConcreteIterator doesn't need friendship because // ConcreteAggregate defines index operator IIterator& CreateIterator(); ConcreteAggregate(size_t n=5); ConcreteAggregate(T* pArr, size_t size); ConcreteAggregate(const ConcreteAggregate& agg); ~ConcreteAggregate(); ConcreteAggregate& operator=(const ConcreteAggregate& agg); T& operator[](size_t n); T operator[](size_t n) const; size_t Size() const; void Append(const T& t); void Insert(IIterator& iter, const T& t); void Remove(IIterator& iter); private: size_t count; size_t capacity; T* pArray; void Copy(T* pSrc, T* pDst, size_t SrcCount); void Replace(T*& pSrc, T*& pDst); void Rotate(size_t pos); }; template IIterator& ConcreteAggregate::CreateIterator() { return *new ConcreteIterator(this); } template ConcreteAggregate::ConcreteAggregate(size_t n) : count(0), capacity(n) { if(n<0) throw std::exception("capacity must be non-negative"); pArray = new T[n]; } template ConcreteAggregate::~ConcreteAggregate() { delete [] pArray; } template void ConcreteAggregate::Copy(T* pSrc, T* pDst, size_t SrcCount) { for(size_t i=0; i void ConcreteAggregate::Replace(T*& pSrc, T*& pDst) { delete [] pSrc; pSrc = pDst; } template void ConcreteAggregate::Rotate(size_t pos) { if(pos < 0 || count <= pos) throw std::exception("index out of range in rotate"); T temp = pArray[count-1]; for(size_t i=count-1; i>pos; --i) pArray[i] = pArray[i-1]; pArray[pos] = temp; } template ConcreteAggregate::ConcreteAggregate(T* pArr, size_t size) : count(size), capacity(2*size) { pArray = new T[capacity]; Copy(pArr, pArray, size); // don't delete pArr - we don't own it! } template ConcreteAggregate::ConcreteAggregate(const ConcreteAggregate& agg) { size_t capacity = agg.capacity; Copy(agg.pArray, pArray=new T[capacity], count=agg.count); } template ConcreteAggregate& ConcreteAggregate::operator=(const ConcreteAggregate& agg) { if(this == &agg) return *this; if(agg.count <= capacity) { Copy(agg.pArray, pArray, count=agg.count); } else { size_t capacity = 2*agg.count; T* pTemp = new T[capacity]; Copy(agg.pArray, pTemp, count=agg.count); Replace(pArray, pTemp); } return *this; } template T& ConcreteAggregate::operator[](size_t n) { if(n<0 || count <= n) throw std::exception("index out of range in operator[]"); return pArray[n]; } template T ConcreteAggregate::operator[](size_t n) const { if(n<0 || count <= n) throw std::exception("index out of range in operator[]"); return pArray[n]; } template size_t ConcreteAggregate::Size() const { return count; } template void ConcreteAggregate::Append(const T& t) { if(count == capacity) { capacity *= 2; T* pTemp = new T[capacity]; Copy(pArray, pTemp, count); Replace(pArray, pTemp); } pArray[count++] = t; } template void ConcreteAggregate::Insert(IIterator& iter, const T& t) { Append(t); Rotate(iter.Offset()); } template void ConcreteAggregate::Remove(IIterator& iter) { size_t pos = iter.Offset(); for(size_t i=pos; i template void Show(const std::string& msg, const IAggregate& agg) { std::cout << "\n " << msg.c_str(); std::cout << "\n " << std::string(msg.size()+2,'-') << "\n "; for(size_t i=0; i