#ifndef CA_UWATERLOO_ALUMNI_DWHARDER_SINGLE_LIST #define CA_UWATERLOO_ALUMNI_DWHARDER_SINGLE_LIST #include "Single_node.h" #include "Exception.h" #include // Author: Douglas Wilhelm Harder // Copyright (c) 2011 by Douglas Wilhelm Harder. All rights reserved. namespace Data_structures { template class Single_list { private: Single_node *list_head; Single_node *list_tail; Single_node *head() const; Single_node *tail() const; public: class iterator; Single_list(); ~Single_list(); // Mutators void push_front( const Type & ); void push_back( const Type & ); void pop_front(); class iterator { private: iterator( Single_node * ); Single_node *current; public: Type &operator*(); iterator operator++(); iterator operator++( int ); bool operator==( iterator const & ) const; bool operator!=( iterator const & ) const; friend class Single_list; }; iterator find( Type const & ) const; iterator begin() const; iterator end() const; // Friends template friend std::ostream &operator<<( std::ostream &, const Single_list & ); }; template Single_list::Single_list(): list_head(0), list_tail(0) { // Empty constructor } template Single_list::~Single_list() { while ( head() != 0 ) { pop_front(); } } template Single_node *Single_list::head() const { return list_head; } template typename Single_list::iterator Single_list::begin() const { return iterator( head() ); } template typename Single_list::iterator Single_list::end() const { return iterator( 0 ); } template Single_node *Single_list::tail() const { return list_tail; } template typename Single_list::iterator Single_list::find( const Type &obj ) const { for ( Single_node *ptr = list_head; ptr != 0; ptr = ptr->next() ) { if ( ptr->retrieve() == obj ) { return iterator( ptr ); } } return iterator( 0 ); } template void Single_list::push_front( const Type &obj ) { if ( head() == 0 ) { list_head = new Single_node( obj ); list_tail = list_head; } else { list_head = new Single_node( obj, list_head ); } } template void Single_list::push_back( const Type &obj ) { if ( head() == 0 ) { list_head = new Single_node( obj ); list_tail = list_head; } else { list_tail->next_node = new Single_node( obj, 0 ); list_tail = list_tail->next(); } } template void Single_list::pop_front() { if ( head() == 0 ) { throw underflow(); } if ( head()->next() == 0 ) { delete list_head; list_head = 0; list_tail = 0; } else { Single_node *tmp = list_head; list_head = list_head->next(); delete tmp; } } template Single_list::iterator::iterator( Single_node *ptr ): current( ptr ) { // empty constructor } template Type &Single_list::iterator::operator*() { return current->element; } template typename Single_list::iterator Single_list::iterator::operator++() { if ( current != 0 ) { current = current->next(); } return iterator( current ); } template typename Single_list::iterator Single_list::iterator::operator++( int ) { Single_node *previous = current; if ( current != 0 ) { current = current->next(); } return iterator( previous ); } template bool Single_list::iterator::operator==( Single_list::iterator const &itr ) const { return current == itr.current; } template bool Single_list::iterator::operator!=( Single_list::iterator const &itr ) const { return current != itr.current; } template std::ostream &operator<<( std::ostream &out, const Single_list &list ) { for ( Single_node *ptr = list.head(); ptr != 0; ptr = ptr->next() ) { out << " -> " << ptr->retrieve(); } out << " -> 0"; return out; } } #endif