#ifndef QUEUE_H #define QUEUE_H #include const int null = 0; template class Queue { private: /// For each element stored in the queue, a Node is created to keep pointers to /// the next element. Note Node is for Queue class use exclusively (private) struct Node { /// A copy of the original element to be stored in the queue DataType data; /// A pointer to the next node in the queue Node* next; public: /// Conversion constructor explicit Node(const DataType& data) : data(data), next(null) { } }; private: /// A pointer to the first node in the queue. Null if queue is empty Node* head; /// A pointer to the last node in the queue. Null if queue is empty Node* tail; /// The count of elements currently stored in the queue size_t size; public: /// Default constructor Queue() : head(null), tail(null), size(0) { } /// Destructor: when the queue is destroyed, all its values are deleted also ~Queue() { clear(); } /// Returns true if queue is empty inline bool empty() const { return head == null; } /// Adds a copy of the given element into the queue /// @return true on success, false if not enough memory bool add(const DataType& data) { Node* node = new Node(data); if ( ! node ) return false; if ( empty() ) tail = head = node; else tail = tail->next = node; return ++size; } /// Remove all elements from the queue void clear() { for ( Node* node = head; head; node = head) { head = head->next; delete node; } tail = null; size = 0; } /// Prints all elements of the queue to the given output stream /// @param output File or stream to print /// @param separator Each element will be separated from another with this text std::ostream& print(std::ostream& output, const char* separator = " ") const { for ( Node* node = head; node; node = node->next) output << node->data << separator; return output; } public: /// Allows traversing the queue or pointing to a specific value in the queue class ConstIterator { private: /// An iterator mimics a pointer to this element which is stored in the queue const Node* node; public: /// Default constructor and conversion constructor explicit ConstIterator(const Node* node = null) : node(node) { } /// Returns true if this iterator points to the same element than other iterator inline bool operator!=(const ConstIterator& other) const { return node != other.node; } /// Get read-only access to the pointed element in array inline const DataType& operator*() const { return node->data; } /// Pre-increment operator: ++itr const ConstIterator& operator++() { node = node->next; return *this; } /// Post-increment operator: itr++ ConstIterator operator++(int) { ConstIterator previous(node); node = node->next; return previous; } }; /// Returns an iterator to the first element in the queue inline ConstIterator begin() const { return ConstIterator(head); } /// Returns an iterator to an invalid position in the queue inline ConstIterator end() const { return ConstIterator(); } private: Queue(const Queue& other); const Queue& operator=(const Queue& other); }; /// Allows std::cout << myqueue1 << myqueue2 << ... ; template std::ostream& operator<<(std::ostream& output, const Queue& queue) { return queue.print(output); } #endif // QUEUE_H