1dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// Copyright 2005, Google Inc.
2dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// All rights reserved.
3dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
4dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// Redistribution and use in source and binary forms, with or without
5dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// modification, are permitted provided that the following conditions are
6dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// met:
7dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
8dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//     * Redistributions of source code must retain the above copyright
9dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// notice, this list of conditions and the following disclaimer.
10dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//     * Redistributions in binary form must reproduce the above
11dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// copyright notice, this list of conditions and the following disclaimer
12dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// in the documentation and/or other materials provided with the
13dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// distribution.
14dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//     * Neither the name of Google Inc. nor the names of its
15dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// contributors may be used to endorse or promote products derived from
16dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// this software without specific prior written permission.
17dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
18dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
30dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// A sample program demonstrating using Google C++ testing framework.
31dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
32dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// Author: wan@google.com (Zhanyong Wan)
33dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
34dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#ifndef GTEST_SAMPLES_SAMPLE3_INL_H_
35dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#define GTEST_SAMPLES_SAMPLE3_INL_H_
36dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
37dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#include <stddef.h>
38dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
39dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
40dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// Queue is a simple queue implemented as a singled-linked list.
41dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
42dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// The element type must support copy constructor.
43dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixtertemplate <typename E>  // E is the element type
44dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixterclass Queue;
45dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
46dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// QueueNode is a node in a Queue, which consists of an element of
47dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// type E and a pointer to the next node.
48dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixtertemplate <typename E>  // E is the element type
49dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixterclass QueueNode {
50dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  friend class Queue<E>;
51dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
52dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter public:
53dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Gets the element in this node.
5446108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  const E& element() const { return element_; }
55dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
56dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Gets the next node in the queue.
5746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  QueueNode* next() { return next_; }
5846108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  const QueueNode* next() const { return next_; }
59dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
60dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter private:
61dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Creates a node with a given element value.  The next pointer is
62dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // set to NULL.
6346108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  explicit QueueNode(const E& an_element) : element_(an_element), next_(NULL) {}
64dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
65dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // We disable the default assignment operator and copy c'tor.
6646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  const QueueNode& operator = (const QueueNode&);
6746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  QueueNode(const QueueNode&);
68dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
69dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  E element_;
7046108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  QueueNode* next_;
71dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter};
72dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
73dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixtertemplate <typename E>  // E is the element type.
74dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixterclass Queue {
7546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan public:
76dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Creates an empty queue.
77dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  Queue() : head_(NULL), last_(NULL), size_(0) {}
78dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
79dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // D'tor.  Clears the queue.
80dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  ~Queue() { Clear(); }
81dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
82dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Clears the queue.
83dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  void Clear() {
84dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    if (size_ > 0) {
85dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      // 1. Deletes every node.
8646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan      QueueNode<E>* node = head_;
8746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan      QueueNode<E>* next = node->next();
88dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      for (; ;) {
89dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter        delete node;
90dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter        node = next;
91dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter        if (node == NULL) break;
92dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter        next = node->next();
93dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      }
94dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
95dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      // 2. Resets the member variables.
96dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      head_ = last_ = NULL;
97dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      size_ = 0;
98dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    }
99dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
100dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
101dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Gets the number of elements.
102dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  size_t Size() const { return size_; }
103dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
104dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Gets the first element of the queue, or NULL if the queue is empty.
10546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  QueueNode<E>* Head() { return head_; }
10646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  const QueueNode<E>* Head() const { return head_; }
107dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
108dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Gets the last element of the queue, or NULL if the queue is empty.
10946108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  QueueNode<E>* Last() { return last_; }
11046108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  const QueueNode<E>* Last() const { return last_; }
111dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
112dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Adds an element to the end of the queue.  A copy of the element is
113dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // created using the copy constructor, and then stored in the queue.
114dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Changes made to the element in the queue doesn't affect the source
115dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // object, and vice versa.
11646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  void Enqueue(const E& element) {
11746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    QueueNode<E>* new_node = new QueueNode<E>(element);
118dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
119dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    if (size_ == 0) {
120dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      head_ = last_ = new_node;
121dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      size_ = 1;
122dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    } else {
123dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      last_->next_ = new_node;
124dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      last_ = new_node;
125dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      size_++;
126dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    }
127dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
128dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
129dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Removes the head of the queue and returns it.  Returns NULL if
130dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // the queue is empty.
13146108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  E* Dequeue() {
132dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    if (size_ == 0) {
133dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      return NULL;
134dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    }
135dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
13646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    const QueueNode<E>* const old_head = head_;
137dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    head_ = head_->next_;
138dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    size_--;
139dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    if (size_ == 0) {
140dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      last_ = NULL;
141dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    }
142dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
14346108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    E* element = new E(old_head->element());
144dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    delete old_head;
145dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
146dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    return element;
147dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
148dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
149dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Applies a function/functor on each element of the queue, and
150dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // returns the result in a new queue.  The original queue is not
151dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // affected.
152dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  template <typename F>
15346108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  Queue* Map(F function) const {
15446108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    Queue* new_queue = new Queue();
15546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    for (const QueueNode<E>* node = head_; node != NULL; node = node->next_) {
156dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      new_queue->Enqueue(function(node->element()));
157dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    }
158dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
159dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    return new_queue;
160dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
161dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
162dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter private:
16346108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  QueueNode<E>* head_;  // The first node of the queue.
16446108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  QueueNode<E>* last_;  // The last node of the queue.
165dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  size_t size_;  // The number of elements in the queue.
166dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
167dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // We disallow copying a queue.
16846108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  Queue(const Queue&);
16946108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  const Queue& operator = (const Queue&);
17046108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan};
171dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
172dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#endif  // GTEST_SAMPLES_SAMPLE3_INL_H_
173