// L-12 MCS 360 Mon 10 Feb 2020 : mcs360_list_iterator.h

/* In this file we give a definition of an iterator for double linked list,
   for inclusion in the file "mcs360_double_list.h". 

Observe the definitions of the begin() and end() methods listed
after the definition of the class.  We could have inserted these
definitions just as well in mcs360_double_list.h, but it is cleaner
to define these methods here. */

#ifndef __MCS360_LIST_ITERATOR_H__
#define __MCS360_LIST_ITERATOR_H__

class Iterator
{
   friend class List<T>;

   private:
    
      List<T> *parent; /* refers to the list */

      typename List<T>::Node *current;
      /* pointer to the current node in parent */

      Iterator( List<T> *L, Node *n ) :
         parent(L), current(n) {}

   public:

      T& operator*() const // dereferencing operator
      {
         if(current == NULL)
            throw std::invalid_argument("cannot dereference past end()");
         return current->data;
      }

      Iterator& operator++() // prefix increment operator
      {
         if(current == NULL)
            throw std::invalid_argument("cannot go past end()");
         current = current->next;
      }

      Iterator operator++(int) // postfix increment operator
      {
         Iterator return_value = *this;
         ++(*this);
         return return_value;
      }

      bool operator!=(const Iterator &other)
      {
         return current != other.current;
      }

};

Iterator begin()
{
   Iterator r(this,this->first);
   return r;
}

Iterator end()
{
   Iterator r(this,NULL);
   return r;
}

#endif
