//
// NAME
// plist.cpp
//
// DESCRIPTION
// This file contains the function definitions for the member
// functions of the plist class and global functions which are
// related to the plist class.
//
// For descriptions of the parameters and return values,
// see plist.h.
//
//
// Include files.
//
#include <stdlib.h>
#include "bool.h"
#include "person.h"
#include "plist.h"
//
// NAME
// plist::element
//
// DESCRIPTION
// Structure of an element used in the linked list of people.
//
// MEMBERS
// data - person.
// next - pointer to the next element in the linked list.
//
struct plistElem {
person * data;
plistElem * next;
};
//
// NAME
// plist::plist()
//
// DESCRIPTION
// This is the default constructor for the plist class.
//
plist::plist() {
head = NULL;
current = NULL;
}
//
// NAME
// plist::plist(const plist& p)
//
// DESCRIPTION
// This is the copy constructor for the plist class. It
// uses a local pointer to traverse the source list.
//
plist::plist(const plist& otherList) {
plistElem * otherCurrPos = otherList.head;
plistElem * currPos = NULL;
// Clear the list.
clearList();
// Copy the data from the other list.
while (otherCurrPos != NULL) {
addToEnd(otherCurrPos->data);
otherCurrPos = otherCurrPos->next;
}
// Set the current pointer to match that of the other list.
currPos = head;
otherCurrPos = otherList.head;
while (otherCurrPos != otherList.current) {
currPos = currPos->next;
otherCurrPos = otherCurrPos->next;
}
return;
}
//
// NAME
// plist::~plist
//
// DESCRIPTION
// This is the destructor for the plist class.
//
plist::~plist() {
clearList();
}
//
// NAME
// plist::operator=
//
// DESCRIPTION
// This is the assignment operator for the plist class. It
// uses a local pointer to traverse the source list.
//
const plist& plist::operator=(const plist& otherList) {
plistElem * currPos = NULL;
plistElem * otherCurrPos = otherList.head;
if (this != &otherList) {
// Clear the list.
clearList();
// Copy the data from the other list.
while (otherCurrPos != NULL) {
addToEnd(otherCurrPos->data);
otherCurrPos = otherCurrPos->next;
}
// Set the current pointer to match that of the other list.
currPos = head;
otherCurrPos = otherList.head;
while (otherCurrPos != otherList.current) {
currPos = currPos->next;
otherCurrPos = otherCurrPos->next;
}
}
return *this;
}
//
// NAME
// plist::addToEnd
//
// DESCRIPTION
// This functions adds the given person to the end of the list.
// It traverses the list from the head to find the end, then adds
// a new element to the end of the list.
//
void plist::addToEnd(person * p) {
plistElem * pe = newElem(p);
if (head == NULL) {
head = pe;
current = head;
return;
}
moveToEnd();
current->next = pe;
current = pe;
return;
}
//
// NAME
// plist::getFirst
//
// DESCRIPTION
// This function gets the first person from the list. The member
// variable "current" is set to point to the head of the list, and
// the person information stored in that element is returned, if such
// an element exists.
//
person * plist::getFirst() {
current = head;
if (current == NULL) {
return NULL;
}
return current->data;
}
//
// NAME
// plist::getNext
//
// DESCRIPTION
// This function gets the person information for the next person.
// The "current" pointer is moved ahead one position in the list,
// and the person information stored in that element is returned,
// if such an element exists.
//
person * plist::getNext() {
current = current->next;
if (current == NULL) {
return NULL;
}
return current->data;
}
//
// NAME
// plist::atEnd
//
// DESCRIPTION
// This function determines if the list is empty by seeing if the
// "current" member variable is NULL or not.
//
bool plist::atEnd() const {
return (current == NULL) ? true : false;
}
//
// NAME
// plist::clearList
//
// DESCRIPTION
// This function removes all elements from the list by traversing
// the list from the head and deallocating each element. The
// "current" member variable is used to traverse the list, and the
// local variable "next" points to the next element. When the
// list has been empties, the "head" and "current" member variables
// are set to NULL.
//
void plist::clearList() {
plistElem * next = NULL;
current = head;
while (current != NULL) {
next = current->next;
delete current->data;
delete current;
current = next;
}
head = NULL;
current = head;
return;
}
//
// NAME
// operator<<
//
// DESCRIPTION
// This function is the output operator for the plist class.
//
// PARAMETERS
// os (in/out) - output stream.
// pl (in) - plist to output.
//
// RETURNS
// reference to the output stream.
//
ostream& operator<<(ostream& os, const plist& pl) {
int count = 0;
plistElem * pe = pl.head;
while (pe != NULL) {
pe->data->display();
count++;
pe = pe->next;
}
cout << endl;
cout << "There are " << count << " people in the list." << endl;
return os;
}
//
// NAME
// plist::newElemment
//
// DESCRIPTION
// This function allocates a new list element and copies the given
// person information into it.
//
// PARAMETESRS
// p (in) - person information to copy into the new element.
//
// RETURNS
// pointer to the newly allocated list element
//
plistElem * plist::newElem(person * p) {
plistElem * pe = new plistElem;
pe->data = p->clone();
pe->next = NULL;
return pe;
}
//
// NAME
// plist::moveToEnd
//
// DESCRIPTION
// This function causes the "current" member variable to point to
// the last element in the list. This function assumes that the
// list is not empty.
//
// PARAMETERS
// (none)
//
// RETURNS
// (none)
void plist::moveToEnd() {
if (current == NULL) {
current = head;
}
while (current->next != NULL) {
current = current->next;
}
return;
}
//
// End of file.
//