// ----------------------------------------------------------------------
 //
 // File: list_bug.cpp
 //
 // This module implements a List class for integers. (Buggy version.)
 // The module is inteded for CTA++ demonstation purposes only.
 // Copyright (c) 1998-2002 Testwell Oy
 //
 // Last edited: 12.12.2002
 //
 // ----------------------------------------------------------------------
 
 #include "list.h"
 
 // ----------------------------------------------------------------------
 // NOTE: no implementation here for the functions 'List_malloc',
 // 'List_realloc' and 'List_free' declared in header memory.h.
 // They have stub implementations in the stub function include
 // module CTA_memory.h_stb.inc
 // ----------------------------------------------------------------------
 #include "memory.h"
 
 // **********************************************************************
 //
 // The methods of the class List
 //
 // **********************************************************************
 
 // ----------------------------------------------------------------------
 // List constructor
 // ----------------------------------------------------------------------
 List::List()
 {
     last_element = 0;
     item_count = 0;
     list_size = LIST_STEP;
 
     the_list = static_cast<int*>(List_malloc(sizeof(int)*list_size));
     if (the_list == 0) {
         throw ExceptionOutOfMemory();
     }
 }
 
 // ----------------------------------------------------------------------
 // List destructor
 // ----------------------------------------------------------------------
 List::~List()
 {
     List_free(the_list);
 }
 
 // ----------------------------------------------------------------------
 // List::insert
 // ----------------------------------------------------------------------
 void List::insert(int t)
 {
     ++item_count;
     if (item_count > list_size) {
         int* reallocated_list;
         list_size *= 2;
         reallocated_list = static_cast<int*>(List_realloc(
             the_list, 
             sizeof(int)*list_size));
         if (reallocated_list == 0) {
             throw ExceptionOutOfMemory();
         } else {
             the_list = reallocated_list;
         }
         last_element = the_list + item_count - 2;
     }
     
     if (last_element == 0) {
         last_element = the_list;
         *last_element = t;
     } else {
         ++last_element;
         *last_element = t;
     }
 }
 
 // ----------------------------------------------------------------------
 // List::extract
 // ----------------------------------------------------------------------
 int List::extract()
 {
     if (last_element != 0) {
 /*correct*/ //   --item_count;
 /*buggy*/      ;
         int item = *last_element;
         if (last_element != the_list) {
             --last_element;
         } else {
             last_element = 0;
         }
         return item;
     } else {
         throw ExceptionEmptyList();
         return 0;
     }
 }
 
 // ----------------------------------------------------------------------
 // List::remove
 // ----------------------------------------------------------------------
 void List::remove(int t)
 {
     bool found = false;
     if (last_element != 0) {
         int* tmp = the_list;
         for (; tmp <= last_element; ++tmp) {
             if (*tmp == t) {
 /*buggy*/           for (int* tmp2 = tmp + 1; tmp2 < last_element; ++tmp2) {
 /*correct*/  //      for (int* tmp2 = tmp + 1; tmp2 <= last_element; ++tmp2) {
                     *(tmp2 - 1) = *tmp2;
                 }
                 if (last_element == the_list) {
                     last_element = 0;
                 } else {
                     --last_element;
                 }
                 found = true;
                 --item_count;
                 break;
             }
         }
     }
     if (!found) {
         // run-time error!
     }
 }
 
 // ----------------------------------------------------------------------
 // List::begin
 // ----------------------------------------------------------------------
 List_iterator List::begin() const
 {
     int* iter = 0;
  /*correct*/ //       if (last_element != 0) {
  /*buggy*/        if (last_element == 0) {
         iter = the_list;
     }
         
     return List_iterator(this, iter);
 }
 
 // ----------------------------------------------------------------------
 // List::last
 // ----------------------------------------------------------------------
 List_iterator List::last() const
 {
     return List_iterator(this, last_element);
 }
 
 // ----------------------------------------------------------------------
 // List::rbegin
 // ----------------------------------------------------------------------
 List_reverse_iterator List::rbegin() const
 {
     return List_reverse_iterator(this, last_element);
 }
 
 // ----------------------------------------------------------------------
 // List::empty
 // ----------------------------------------------------------------------
 bool List::empty() const
 {
     return static_cast<bool>(last_element == 0);
 }
 
 // ----------------------------------------------------------------------
 // List::itemCount
 // ----------------------------------------------------------------------
 int List::itemCount() const
 {
     return item_count;
 }
 
 
 // **********************************************************************
 //
 // The methods of the class List_iterator
 //
 // **********************************************************************
 
 // ----------------------------------------------------------------------
 // List_iterator constructor 1
 // ----------------------------------------------------------------------
 List_iterator::List_iterator(const List* l)
 {
     iter_list = 0;
     list = l;
 }
 
 // ----------------------------------------------------------------------
 // List_iterator constructor 2
 // ----------------------------------------------------------------------
 List_iterator::List_iterator(const List* l, int* iter)
 {
     iter_list = iter;
     list = l;
 }
 
 // ----------------------------------------------------------------------
 // List_iterator::end
 // ----------------------------------------------------------------------
 bool List_iterator::end() const
 { 
     return static_cast<bool>(iter_list == 0);
 }
 
 // ----------------------------------------------------------------------
 // List_iterator::operator*
 // ----------------------------------------------------------------------
 int List_iterator::operator*()
 { 
     if (iter_list != 0) {
         return *iter_list;
     } else {
         // run-time error!
         throw ExceptionIteratorOutOfBounds("operator *");
         return 0;
     }
 }
 
 // ----------------------------------------------------------------------
 // List_iterator::operator++
 // ----------------------------------------------------------------------
 List_iterator& List_iterator::operator++()
 { 
     if (iter_list == list->last_element && iter_list != 0) {
         iter_list = 0;
     } else if (iter_list != 0) {
         ++iter_list;
     } else {
         // run-time error!
         throw ExceptionIteratorOutOfBounds("operator ++");
     }
     return *this;
 }
 
 
 // **********************************************************************
 //
 // Methods of the class List_reverse_iterator
 //
 // **********************************************************************
 
 // ----------------------------------------------------------------------
 // List_reverse_iterator constructor 1
 // ----------------------------------------------------------------------
 List_reverse_iterator::List_reverse_iterator(const List* l)
 {
     list = l;
     iter_list = 0;
 }
 
 // ----------------------------------------------------------------------
 // List_reverse_iterator constructor 2
 // ----------------------------------------------------------------------
 List_reverse_iterator::List_reverse_iterator(const List* l, int* iter)
 {
     list = l;
     iter_list = iter;
 }
 
 // ----------------------------------------------------------------------
 // List_reverse_iterator::rend
 // ----------------------------------------------------------------------
 bool List_reverse_iterator::rend()
 { 
     return static_cast<bool>(iter_list == 0 || iter_list == list->the_list);
 }
 
 // ----------------------------------------------------------------------
 // List_reverse_iterator::operator*
 // ----------------------------------------------------------------------
 int List_reverse_iterator::operator*()
 {
     return *iter_list;
 }
 
 // ----------------------------------------------------------------------
 // List_reverse_iterator::operator--
 // ----------------------------------------------------------------------
 List_reverse_iterator& List_reverse_iterator::operator--()
 {
     if (iter_list != 0 && iter_list !=list->the_list) {
         --iter_list;
     } else {
         // run-time error!
         throw ExceptionIteratorOutOfBounds("operator --");
     }
     return *this;
 }
 
 // EOF