/*************************************** Class: CS251 Assignment Number: 3 Honor Pledge: I pledge that I have not recieved nor given help on this assignment. ***************************************/ /* -*- C++ -*- */ #ifndef _LQUEUE_H #define _LQUEUE_H // This header defines "size_t" #include #include // Solve circular include problem via forward decls. template class LQueue_Iterator; template class Const_LQueue_Iterator; template class LQueue_Node // = TITLE // Defines an element in the . { public: // = Initialization methods LQueue_Node (LQueue_Node *next, LQueue_Node *prev); LQueue_Node (void); // Default constructor that doesn't initialize . ~LQueue_Node (void); T item_; // Item in this node. LQueue_Node *next_; // Pointer to the next node. LQueue_Node *prev_; // Pointer to the prev node. }; /** * @class LQueue * @brief Defines a generic "first-in/first-out" (FIFO) Abstract Data * Type (ADT) using a "circular list" with a dummy node. * * This queue is a circular linked list. The pointer points * to a dummy node which makes implementation much easier * (particularly iterator traversal). When enqueuing an item, the * dummy node contains the new item and points to a new dummy node. * Therefore the head of the list is always next_>. * Dequeuing an object gets rid of the head node and makes the dummy * node point to the new head. */ template > class LQueue { friend class LQueue_Iterator; friend class Const_LQueue_Iterator; public: // = Exceptions thrown by methods in this class. class Underflow {}; class Overflow {}; // = Initialization, assignment, and termination methods. // Constructor. LQueue (size_t = 0); // Copy constructor. LQueue (const LQueue &rhs); // Assignment operator. LQueue &operator = (const LQueue &rhs); // Perform actions needed when queue goes out of scope. ~LQueue (void); // = Classic Queue operations. // Place a at the tail of the queue. Throws the // exception if the queue is full, e.g., if memory is // exhausted. void enqueue (const T &new_item); // Remove the front item on the queue. Throws the // exception if the queue is empty. void dequeue (void); // Returns the front queue item without removing it. // Throws the exception if the queue is empty. T front (void) const; // = Check boundary conditions for Queue operations. // Returns 1 if the queue is empty, otherwise returns 0. bool is_empty (void) const; // Returns 1 if the queue is full, otherwise returns 0. bool is_full (void) const; // Returns the current number of elements in the queue. size_t size (void) const; // Compare this queue with for equality. Returns true if the // size()'s of the two queues are equal and all the elements from 0 // .. size() are equal, else false. bool operator== (const LQueue &rhs) const; // Compare this queue with for inequality such that <*this> != // is always the complement of the boolean return value of // <*this> == . bool operator!= (const LQueue &s) const; // Efficiently swap the contents of this with . // Does not throw an exception. void swap (LQueue &new_queue); // = Traits for the class. typedef T value_type; typedef LQueue_Iterator iterator; typedef Const_LQueue_Iterator const_iterator; // = Factory methods that create iterators. // Get an iterator that points to the beginning of the queue. iterator begin (void); // Get a const iterator that points to the beginning of the queue. const_iterator begin (void) const; // Get an iterator that points to the end of the queue. iterator end (void); // Get a const iterator that points to the end of the queue. const_iterator end (void) const; protected: // Remove the front item on the queue without checking if the queue is empty. void dequeue_i (void); private: LQUEUE_NODE *tail_; // We only need to keep a single pointer for the circular linked // list. This points to the tail of the queue. Since the list is // circular, the head of the queue is always this->tail_->next_; size_t count_; // Number of items that are currently in the queue. }; /** * @class LQueue_Iterator * @brief Implements a bidirectional iterator for LQueue type classes. * * Note: Having a const Iterator does not guarantee that the current * *position* that it points to will not change, it only guarantees that * you cannot change the underlying queue! */ template class LQueue_Iterator { public: friend class LQueue; /// Dereference operator returns a reference to the item contained /// at the current position T& operator* (void); /// Returns a const reference to the item contained at the current position const T& operator* (void) const; /// Preincrement operator LQueue_Iterator &operator++ (void); /// Postincrement operator LQueue_Iterator operator++ (int); /// Equality operator bool operator== (const LQueue_Iterator &rhs) const; /// Nonequality operator bool operator!= (const LQueue_Iterator &lhs) const; // = Necessary traits typedef std::forward_iterator_tag iterator_category; typedef T value_type; typedef T *pointer; typedef T &reference; typedef int difference_type; protected: /// Construct an LQueue_Iterator at node pos. LQueue_Iterator (LQUEUE_NODE *pos); private: // the position in the linked list mutable LQUEUE_NODE *pos_; }; /** * @class Const_LQueue_Iterator * @brief Implements a bidirectional iterator for LQueue type classes. * * Note: Having a const Iterator does not guarantee that the current * *position* that it points to will not change, it only guarantees that * you cannot change the underlying queue! */ template class Const_LQueue_Iterator { public: friend class LQueue; /// Dereference operator returns a const reference to the item /// contained at the current position. const T& operator* (void) const; /// Preincrement operator const Const_LQueue_Iterator &operator++ (void) const; /// Postincrement operator Const_LQueue_Iterator operator++ (int) const; /// Equality operator bool operator== (const Const_LQueue_Iterator &rhs) const; /// Nonequality operator bool operator!= (const Const_LQueue_Iterator &lhs) const; // = Necessary traits typedef std::bidirectional_iterator_tag iterator_category; typedef T value_type; typedef T *pointer; typedef T &reference; typedef int difference_type; protected: /// Construct a Const_LQueue_Iterator at node pos. Const_LQueue_Iterator (LQUEUE_NODE *pos); private: // the position in the linked list mutable LQUEUE_NODE *pos_; }; #include "LQueue.cpp" #endif /* _LQUEUE_H */