// ----------------------------------------------------------------------
//
// 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