/***************************************** * UW User ID: uwuserid * Submitted for ECE 250 * Department of Electrical and Computer Engineering * University of Waterloo * Calender Term of Submission: (Winter|Spring|Fall) 20NN * * By submitting this file, I affirm that * I am the author of all modifications to * the provided code. *****************************************/ #ifndef DOUBLE_SENTINEL_LIST_H #define DOUBLE_SENTINEL_LIST_H #include #include "Exception.h" template class Double_sentinel_list { public: class Double_node { public: Double_node( Type const & = Type(), Double_node * = nullptr, Double_node * = nullptr ); Type value() const; Double_node *previous() const; Double_node *next() const; Type node_value; Double_node *previous_node; Double_node *next_node; }; Double_sentinel_list(); Double_sentinel_list( Double_sentinel_list const & ); Double_sentinel_list( Double_sentinel_list && ); ~Double_sentinel_list(); // Accessors int size() const; bool empty() const; Type front() const; Type back() const; Double_node *begin() const; Double_node *end() const; Double_node *rbegin() const; Double_node *rend() const; Double_node *find( Type const & ) const; int count( Type const & ) const; // Mutators void swap( Double_sentinel_list & ); Double_sentinel_list &operator=( Double_sentinel_list ); Double_sentinel_list &operator=( Double_sentinel_list && ); void push_front( Type const & ); void push_back( Type const & ); void pop_front(); void pop_back(); int erase( Type const & ); private: Double_node *list_head; Double_node *list_tail; int list_size; // List any additional private member functions you author here // Friends template friend std::ostream &operator<<( std::ostream &, Double_sentinel_list const & ); }; ///////////////////////////////////////////////////////////////////////// // Public member functions // ///////////////////////////////////////////////////////////////////////// template Double_sentinel_list::Double_sentinel_list(): // Updated the initialization list here list_head( nullptr ), list_tail( nullptr ), list_size( 0 ) { // Enter your implementation here } template Double_sentinel_list::Double_sentinel_list( Double_sentinel_list const &list ): // Updated the initialization list here list_head( nullptr ), list_tail( nullptr ), list_size( 0 ) { // Enter your implementation here } template Double_sentinel_list::Double_sentinel_list( Double_sentinel_list &&list ): // Updated the initialization list here list_head( nullptr ), list_tail( nullptr ), list_size( 0 ) { // Enter your implementation here } template Double_sentinel_list::~Double_sentinel_list() { // Enter your implementation here } template int Double_sentinel_list::size() const { // Enter your implementation here return 0; } template bool Double_sentinel_list::empty() const { // Enter your implementation here return true; } template Type Double_sentinel_list::front() const { // Enter your implementation here return Type(); // This returns a default value of Type } template Type Double_sentinel_list::back() const { // Enter your implementation here return Type(); // This returns a default value of Type } template typename Double_sentinel_list::Double_node *Double_sentinel_list::begin() const { // Enter your implementation here return nullptr; } template typename Double_sentinel_list::Double_node *Double_sentinel_list::end() const { // Enter your implementation here return nullptr; } template typename Double_sentinel_list::Double_node *Double_sentinel_list::rbegin() const { // Enter your implementation here return nullptr; } template typename Double_sentinel_list::Double_node *Double_sentinel_list::rend() const { // Enter your implementation here return nullptr; } template typename Double_sentinel_list::Double_node *Double_sentinel_list::find( Type const &obj ) const { // Enter your implementation here return nullptr; } template int Double_sentinel_list::count( Type const &obj ) const { // Enter your implementation here return 0; } template void Double_sentinel_list::swap( Double_sentinel_list &list ) { // This is done for you std::swap( list_head, list.list_head ); std::swap( list_tail, list.list_tail ); std::swap( list_size, list.list_size ); } // The assignment operator template Double_sentinel_list &Double_sentinel_list::operator=( Double_sentinel_list rhs ) { // This is done for you swap( rhs ); return *this; } // The move operator template Double_sentinel_list &Double_sentinel_list::operator=( Double_sentinel_list &&rhs ) { // This is done for you swap( rhs ); return *this; } template void Double_sentinel_list::push_front( Type const &obj ) { // Enter your implementation here } template void Double_sentinel_list::push_back( Type const &obj ) { // Enter your implementation here } template void Double_sentinel_list::pop_front() { // Enter your implementation here } template void Double_sentinel_list::pop_back() { // Enter your implementation here } template int Double_sentinel_list::erase( Type const &obj ) { // Enter your implementation here return 0; } template Double_sentinel_list::Double_node::Double_node( Type const &nv, typename Double_sentinel_list::Double_node *pn, typename Double_sentinel_list::Double_node *nn ): // Updated the initialization list here node_value( Type() ), // This assigns 'node_value' the default value of Type previous_node( nullptr ), next_node( nullptr ) { // Enter your implementation here } template Type Double_sentinel_list::Double_node::value() const { // Enter your implementation here return Type(); // This returns a default value of Type } template typename Double_sentinel_list::Double_node *Double_sentinel_list::Double_node::previous() const { // Enter your implementation here return nullptr; } template typename Double_sentinel_list::Double_node *Double_sentinel_list::Double_node::next() const { // Enter your implementation here return nullptr; } ///////////////////////////////////////////////////////////////////////// // Private member functions // ///////////////////////////////////////////////////////////////////////// // If you author any additional private member functions, include them here ///////////////////////////////////////////////////////////////////////// // Friends // ///////////////////////////////////////////////////////////////////////// // You can modify this function however you want: it will not be tested template std::ostream &operator<<( std::ostream &out, Double_sentinel_list const &list ) { out << "head"; for ( typename Double_sentinel_list::Double_node *ptr = list.rend(); ptr != nullptr; ptr = ptr->next() ) { if ( ptr == list.rend() || ptr == list.end() ) { out << "->S"; } else { out << "->" << ptr->value(); } } out << "->0" << std::endl << "tail"; for ( typename Double_sentinel_list::Double_node *ptr = list.end(); ptr != nullptr; ptr = ptr->previous() ) { if ( ptr == list.rend() || ptr == list.end() ) { out << "->S"; } else { out << "->" << ptr->value(); } } out << "->0"; return out; } #endif