Implementing Deque<>
namespace deque { static const size_t defaultContentSize = 10; }
template <typename T>
Deque<T>::Deque() : content_(0), contentSize_(0), beg_(0), end_(0)
// Construct a deque of zero size and default contentSize_
{
content_ = new T [deque::defaultContentSize];
if (content_ == 0)
... error handling
contentSize_ = deque::defaultContentSize;
}
template <typename T>
Deque<T>::~Deque()
{
delete[] content_;
content_=0;
}
template <typename T>
Deque<T>::Deque(const Deque<T>& Q)
: contentSize_(Q.contentSize_), beg_(Q.beg_), end_(Q.end_)
// copy constructor
{
content_ = new T [contentSize_];
if (content_ == 0)
... error handling
for (size_t i = 0; i < contentSize_; ++i)
content_[i] = Q.content_[i];
}
template <typename T>
Deque<T>& Deque<T>::operator = (const Deque<T>& Q)
// assignment operator
{
if (this != &Q)
{
T* newContent = new T [Q.contentSize_];
if (newContent == 0)
... error handling
delete [] content_;
content_ = newContent;
contentSize_ = Q.contentSize_;
beg_ = Q.beg_;
end_ = Q.end_;
for (size_t i = 0; i < contentSize_; ++i)
content_[i] = Q.content_[i];
}
return *this;
}
template <typename T>
T& Deque<T>::operator [] (size_t i) const
// element operator
{
if (Size() <= i)
... error handling
i += beg_;
if (i >= contentSize_)
i -= contentSize_;
return content_[i];
}
// Container class protocol implementation
template <typename T>
bool Deque<T>::Empty() const
{
return beg_ == end_;
}
template <typename T>
size_t Deque<T>::Size() const
{
if (beg_ <= end_)
return end_ - beg_;
return contentSize_ + end_ - beg_;
}
template <typename T>
bool Deque<T>::PushFront(const T& Tval)
{
if (Size() + 1 >= contentSize_)
// deque is full -- grow by doubling content size
{
size_t newContentSize,i;
newContentSize = 2 * contentSize_;
if (contentSize_ == 0) newContentSize = 2;
T* newContent = new T [newContentSize];
if (newContent == 0)
... error handling
// copy data to new content array
if (beg_ <= end_)
{
for (i = beg_; i < end_; ++i) newContent[i] = content_[i];
}
else
{
for (i = beg_; i < contentSize_; ++i) newContent[i] = content_[i];
for (i = 0; i < end_; ++i) newContent[i + contentSize_] = content_[i];
end_ += contentSize_;
}
// switch to new content
delete [] content_;
content_ = newContent;
contentSize_ = newContentSize;
}
// now there is extra capacity
if (beg_ == 0)
beg_ = contentSize_;
--beg_;
content_[beg_] = Tval;
return 1;
}
template <typename T>
bool Deque<T>::PopFront()
{
if (beg_ == end_)
return 0;
++beg_;
if (beg_ == contentSize_)
beg_ = 0;
return 1;
}
template <typename T>
void Deque<T>::Clear()
{
beg_ = 0;
end_ = 0;
}
template <typename T>
T& Deque<T>::Front() const
{
if (beg_ == end_)
{
std::cerr << "** Deque error: Front() called on empty deque\n";
if (contentSize_ == 0)
exit (EXIT_FAILURE);
}
return content_[beg_];
}
// Iterator support
template <typename T>
DequeIterator<T> Deque<T>::Begin () const
{
Iterator I;
I.dequePtr_ = this;
I.indexBase_ = 0;
return I;
}
template <typename T>
DequeIterator<T> Deque<T>::End() const
{
Iterator I;
I.dequePtr_ = this;
I.indexBase_ = Size();
return I;
}
template <typename T>
void Deque<T>::Display(std::ostream& os, char ofc) const
{
size_t i;
if (ofc == '\0')
for (i = 0; i < Size(); ++i)
os << operator[](i);
else
for (i = 0; i < Size(); ++i)
os << operator[](i) << ofc;
} // end Display()
template <typename T>
void Deque<T>::Dump(std::ostream& os) const
{
for (size_t i = 0; i < contentSize_; ++i)
{
if (i < 10)
os << " content_[" << i << "] == " << content_[i];
else if (i < 100)
os << " content_[" << i << "] == " << content_[i];
else if (i < 1000)
os << " content_[" << i << "] == " << content_[i];
else if (i < 10000)
os << " content_[" << i << "] == " << content_[i];
else
os << "content_[" << i << "] == " << content_[i];
if (i == beg_)
os << " <- beg";
if (i == end_)
os << " <- end";
os << '\n';
}
}