00001 // Copyright 2005, Google Inc. 00002 // All rights reserved. 00003 // 00004 // Redistribution and use in source and binary forms, with or without 00005 // modification, are permitted provided that the following conditions are 00006 // met: 00007 // 00008 // * Redistributions of source code must retain the above copyright 00009 // notice, this list of conditions and the following disclaimer. 00010 // * Redistributions in binary form must reproduce the above 00011 // copyright notice, this list of conditions and the following disclaimer 00012 // in the documentation and/or other materials provided with the 00013 // distribution. 00014 // * Neither the name of Google Inc. nor the names of its 00015 // contributors may be used to endorse or promote products derived from 00016 // this software without specific prior written permission. 00017 // 00018 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00019 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00020 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00021 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00022 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00023 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00024 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00025 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00026 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00027 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00028 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 00030 // A sample program demonstrating using Google C++ testing framework. 00031 // 00032 // Author: wan@google.com (Zhanyong Wan) 00033 00034 #ifndef GTEST_SAMPLES_SAMPLE3_INL_H_ 00035 #define GTEST_SAMPLES_SAMPLE3_INL_H_ 00036 00037 #include <stddef.h> 00038 00039 00040 // Queue is a simple queue implemented as a singled-linked list. 00041 // 00042 // The element type must support copy constructor. 00043 template <typename E> // E is the element type 00044 class Queue; 00045 00046 // QueueNode is a node in a Queue, which consists of an element of 00047 // type E and a pointer to the next node. 00048 template <typename E> // E is the element type 00049 class QueueNode { 00050 friend class Queue<E>; 00051 00052 public: 00053 // Gets the element in this node. 00054 const E& element() const { return element_; } 00055 00056 // Gets the next node in the queue. 00057 QueueNode* next() { return next_; } 00058 const QueueNode* next() const { return next_; } 00059 00060 private: 00061 // Creates a node with a given element value. The next pointer is 00062 // set to NULL. 00063 explicit QueueNode(const E& an_element) : element_(an_element), next_(NULL) {} 00064 00065 // We disable the default assignment operator and copy c'tor. 00066 const QueueNode& operator = (const QueueNode&); 00067 QueueNode(const QueueNode&); 00068 00069 E element_; 00070 QueueNode* next_; 00071 }; 00072 00073 template <typename E> // E is the element type. 00074 class Queue { 00075 public: 00076 // Creates an empty queue. 00077 Queue() : head_(NULL), last_(NULL), size_(0) {} 00078 00079 // D'tor. Clears the queue. 00080 ~Queue() { Clear(); } 00081 00082 // Clears the queue. 00083 void Clear() { 00084 if (size_ > 0) { 00085 // 1. Deletes every node. 00086 QueueNode<E>* node = head_; 00087 QueueNode<E>* next = node->next(); 00088 for (; ;) { 00089 delete node; 00090 node = next; 00091 if (node == NULL) break; 00092 next = node->next(); 00093 } 00094 00095 // 2. Resets the member variables. 00096 head_ = last_ = NULL; 00097 size_ = 0; 00098 } 00099 } 00100 00101 // Gets the number of elements. 00102 size_t Size() const { return size_; } 00103 00104 // Gets the first element of the queue, or NULL if the queue is empty. 00105 QueueNode<E>* Head() { return head_; } 00106 const QueueNode<E>* Head() const { return head_; } 00107 00108 // Gets the last element of the queue, or NULL if the queue is empty. 00109 QueueNode<E>* Last() { return last_; } 00110 const QueueNode<E>* Last() const { return last_; } 00111 00112 // Adds an element to the end of the queue. A copy of the element is 00113 // created using the copy constructor, and then stored in the queue. 00114 // Changes made to the element in the queue doesn't affect the source 00115 // object, and vice versa. 00116 void Enqueue(const E& element) { 00117 QueueNode<E>* new_node = new QueueNode<E>(element); 00118 00119 if (size_ == 0) { 00120 head_ = last_ = new_node; 00121 size_ = 1; 00122 } else { 00123 last_->next_ = new_node; 00124 last_ = new_node; 00125 size_++; 00126 } 00127 } 00128 00129 // Removes the head of the queue and returns it. Returns NULL if 00130 // the queue is empty. 00131 E* Dequeue() { 00132 if (size_ == 0) { 00133 return NULL; 00134 } 00135 00136 const QueueNode<E>* const old_head = head_; 00137 head_ = head_->next_; 00138 size_--; 00139 if (size_ == 0) { 00140 last_ = NULL; 00141 } 00142 00143 E* element = new E(old_head->element()); 00144 delete old_head; 00145 00146 return element; 00147 } 00148 00149 // Applies a function/functor on each element of the queue, and 00150 // returns the result in a new queue. The original queue is not 00151 // affected. 00152 template <typename F> 00153 Queue* Map(F function) const { 00154 Queue* new_queue = new Queue(); 00155 for (const QueueNode<E>* node = head_; node != NULL; node = node->next_) { 00156 new_queue->Enqueue(function(node->element())); 00157 } 00158 00159 return new_queue; 00160 } 00161 00162 private: 00163 QueueNode<E>* head_; // The first node of the queue. 00164 QueueNode<E>* last_; // The last node of the queue. 00165 size_t size_; // The number of elements in the queue. 00166 00167 // We disallow copying a queue. 00168 Queue(const Queue&); 00169 const Queue& operator = (const Queue&); 00170 }; 00171 00172 #endif // GTEST_SAMPLES_SAMPLE3_INL_H_