| | | | | |

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';
  }
}

Complete details in Narrative


| | Top of Page | 4. Generic Positional Containers and Double Ended Queues - 8 of 10