michael@0: // Copyright 2005, Google Inc. michael@0: // All rights reserved. michael@0: // michael@0: // Redistribution and use in source and binary forms, with or without michael@0: // modification, are permitted provided that the following conditions are michael@0: // met: michael@0: // michael@0: // * Redistributions of source code must retain the above copyright michael@0: // notice, this list of conditions and the following disclaimer. michael@0: // * Redistributions in binary form must reproduce the above michael@0: // copyright notice, this list of conditions and the following disclaimer michael@0: // in the documentation and/or other materials provided with the michael@0: // distribution. michael@0: // * Neither the name of Google Inc. nor the names of its michael@0: // contributors may be used to endorse or promote products derived from michael@0: // this software without specific prior written permission. michael@0: // michael@0: // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS michael@0: // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT michael@0: // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR michael@0: // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT michael@0: // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, michael@0: // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT michael@0: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, michael@0: // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY michael@0: // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT michael@0: // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE michael@0: // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. michael@0: michael@0: // A sample program demonstrating using Google C++ testing framework. michael@0: // michael@0: // Author: wan@google.com (Zhanyong Wan) michael@0: michael@0: #ifndef GTEST_SAMPLES_SAMPLE3_INL_H_ michael@0: #define GTEST_SAMPLES_SAMPLE3_INL_H_ michael@0: michael@0: #include michael@0: michael@0: michael@0: // Queue is a simple queue implemented as a singled-linked list. michael@0: // michael@0: // The element type must support copy constructor. michael@0: template // E is the element type michael@0: class Queue; michael@0: michael@0: // QueueNode is a node in a Queue, which consists of an element of michael@0: // type E and a pointer to the next node. michael@0: template // E is the element type michael@0: class QueueNode { michael@0: friend class Queue; michael@0: michael@0: public: michael@0: // Gets the element in this node. michael@0: const E& element() const { return element_; } michael@0: michael@0: // Gets the next node in the queue. michael@0: QueueNode* next() { return next_; } michael@0: const QueueNode* next() const { return next_; } michael@0: michael@0: private: michael@0: // Creates a node with a given element value. The next pointer is michael@0: // set to NULL. michael@0: explicit QueueNode(const E& an_element) : element_(an_element), next_(NULL) {} michael@0: michael@0: // We disable the default assignment operator and copy c'tor. michael@0: const QueueNode& operator = (const QueueNode&); michael@0: QueueNode(const QueueNode&); michael@0: michael@0: E element_; michael@0: QueueNode* next_; michael@0: }; michael@0: michael@0: template // E is the element type. michael@0: class Queue { michael@0: public: michael@0: // Creates an empty queue. michael@0: Queue() : head_(NULL), last_(NULL), size_(0) {} michael@0: michael@0: // D'tor. Clears the queue. michael@0: ~Queue() { Clear(); } michael@0: michael@0: // Clears the queue. michael@0: void Clear() { michael@0: if (size_ > 0) { michael@0: // 1. Deletes every node. michael@0: QueueNode* node = head_; michael@0: QueueNode* next = node->next(); michael@0: for (; ;) { michael@0: delete node; michael@0: node = next; michael@0: if (node == NULL) break; michael@0: next = node->next(); michael@0: } michael@0: michael@0: // 2. Resets the member variables. michael@0: head_ = last_ = NULL; michael@0: size_ = 0; michael@0: } michael@0: } michael@0: michael@0: // Gets the number of elements. michael@0: size_t Size() const { return size_; } michael@0: michael@0: // Gets the first element of the queue, or NULL if the queue is empty. michael@0: QueueNode* Head() { return head_; } michael@0: const QueueNode* Head() const { return head_; } michael@0: michael@0: // Gets the last element of the queue, or NULL if the queue is empty. michael@0: QueueNode* Last() { return last_; } michael@0: const QueueNode* Last() const { return last_; } michael@0: michael@0: // Adds an element to the end of the queue. A copy of the element is michael@0: // created using the copy constructor, and then stored in the queue. michael@0: // Changes made to the element in the queue doesn't affect the source michael@0: // object, and vice versa. michael@0: void Enqueue(const E& element) { michael@0: QueueNode* new_node = new QueueNode(element); michael@0: michael@0: if (size_ == 0) { michael@0: head_ = last_ = new_node; michael@0: size_ = 1; michael@0: } else { michael@0: last_->next_ = new_node; michael@0: last_ = new_node; michael@0: size_++; michael@0: } michael@0: } michael@0: michael@0: // Removes the head of the queue and returns it. Returns NULL if michael@0: // the queue is empty. michael@0: E* Dequeue() { michael@0: if (size_ == 0) { michael@0: return NULL; michael@0: } michael@0: michael@0: const QueueNode* const old_head = head_; michael@0: head_ = head_->next_; michael@0: size_--; michael@0: if (size_ == 0) { michael@0: last_ = NULL; michael@0: } michael@0: michael@0: E* element = new E(old_head->element()); michael@0: delete old_head; michael@0: michael@0: return element; michael@0: } michael@0: michael@0: // Applies a function/functor on each element of the queue, and michael@0: // returns the result in a new queue. The original queue is not michael@0: // affected. michael@0: template michael@0: Queue* Map(F function) const { michael@0: Queue* new_queue = new Queue(); michael@0: for (const QueueNode* node = head_; node != NULL; node = node->next_) { michael@0: new_queue->Enqueue(function(node->element())); michael@0: } michael@0: michael@0: return new_queue; michael@0: } michael@0: michael@0: private: michael@0: QueueNode* head_; // The first node of the queue. michael@0: QueueNode* last_; // The last node of the queue. michael@0: size_t size_; // The number of elements in the queue. michael@0: michael@0: // We disallow copying a queue. michael@0: Queue(const Queue&); michael@0: const Queue& operator = (const Queue&); michael@0: }; michael@0: michael@0: #endif // GTEST_SAMPLES_SAMPLE3_INL_H_