#ifndef DL_LIST_H #define DL_LIST_H #include #include namespace cop4530 { template class List { private: // nested Node class struct Node { T data; Node *prev; Node *next; Node(const T & d = T{}, Node *p = nullptr, Node *n = nullptr) : data{d}, prev{p}, next{n} {} Node(T && d, Node *p = nullptr, Node *n = nullptr) : data{std::move(d)}, prev{p}, next{n} {} }; public: //nested const_iterator class class const_iterator { public: const_iterator(); // default zero parameter constructor const T & operator*() const; // operator*() to return element // increment/decrement operators const_iterator & operator++(); const_iterator operator++(int); const_iterator & operator--(); const_iterator operator--(int); // comparison operators bool operator==(const const_iterator &rhs) const; bool operator!=(const const_iterator &rhs) const; protected: Node *current; // pointer to node in List T & retrieve() const; // retrieve the element refers to const_iterator(Node *p); // protected constructor friend class List; }; // nested iterator class class iterator : public const_iterator { public: iterator(); T & operator*(); const T & operator*() const; // increment/decrement operators iterator & operator++(); iterator operator++(int); iterator & operator--(); iterator operator--(int); protected: iterator(Node *p); friend class List; }; public: // constructor, desctructor, copy constructor List(); // default zero parameter constructor List(const List &rhs); // copy constructor List(List && rhs); // move constructor // num elements with value of val explicit List(int num, const T& val = T{}); // constructs with elements [start, end) List(const_iterator start, const_iterator end); // constructs with a copy of each of the elements in the initalizer_list List (std::initializer_list iList); ~List(); // destructor // copy assignment operator const List& operator=(const List &rhs); // move assignment operator List & operator=(List && rhs); // sets list to the elements of the initializer_list List& operator= (std::initializer_list iList); // member functions int size() const; // number of elements bool empty() const; // check if list is empty void clear(); // delete all elements void reverse(); // reverse the order of the elements T& front(); // reference to the first element const T& front() const; T& back(); // reference to the last element const T& back() const; void push_front(const T & val); // insert to the beginning void push_front(T && val); // move version of insert void push_back(const T & val); // insert to the end void push_back(T && val); // move version of insert void pop_front(); // delete first element void pop_back(); // delete last element void remove(const T &val); // remove all elements with value = val template void remove_if(PREDICATE pred); // remove all elements for which Predicate pred // returns true. pred can take in a function object // print out all elements. ofc is deliminitor void print(std::ostream& os, char ofc = ' ') const; iterator begin(); // iterator to first element const_iterator begin() const; iterator end(); // end marker iterator const_iterator end() const; iterator insert(iterator itr, const T& val); // insert val ahead of itr iterator insert(iterator itr, T && val); // move version of insert iterator erase(iterator itr); // erase one element iterator erase(iterator start, iterator end); // erase [start, end) private: int theSize; // number of elements Node *head; // head node Node *tail; // tail node void init(); // initialization }; // overloading comparison operators template bool operator==(const List & lhs, const List &rhs); template bool operator!=(const List & lhs, const List &rhs); // overloading output operator template std::ostream & operator<<(std::ostream &os, const List &l); // include the implementation file here #include "List.hpp" } // end of namespace 4530 #endif