113481Sgiacomo.travaglini@arm.com// Copyright 2005, Google Inc.
213481Sgiacomo.travaglini@arm.com// All rights reserved.
313481Sgiacomo.travaglini@arm.com//
413481Sgiacomo.travaglini@arm.com// Redistribution and use in source and binary forms, with or without
513481Sgiacomo.travaglini@arm.com// modification, are permitted provided that the following conditions are
613481Sgiacomo.travaglini@arm.com// met:
713481Sgiacomo.travaglini@arm.com//
813481Sgiacomo.travaglini@arm.com//     * Redistributions of source code must retain the above copyright
913481Sgiacomo.travaglini@arm.com// notice, this list of conditions and the following disclaimer.
1013481Sgiacomo.travaglini@arm.com//     * Redistributions in binary form must reproduce the above
1113481Sgiacomo.travaglini@arm.com// copyright notice, this list of conditions and the following disclaimer
1213481Sgiacomo.travaglini@arm.com// in the documentation and/or other materials provided with the
1313481Sgiacomo.travaglini@arm.com// distribution.
1413481Sgiacomo.travaglini@arm.com//     * Neither the name of Google Inc. nor the names of its
1513481Sgiacomo.travaglini@arm.com// contributors may be used to endorse or promote products derived from
1613481Sgiacomo.travaglini@arm.com// this software without specific prior written permission.
1713481Sgiacomo.travaglini@arm.com//
1813481Sgiacomo.travaglini@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1913481Sgiacomo.travaglini@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2013481Sgiacomo.travaglini@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2113481Sgiacomo.travaglini@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2213481Sgiacomo.travaglini@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2313481Sgiacomo.travaglini@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2413481Sgiacomo.travaglini@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2513481Sgiacomo.travaglini@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2613481Sgiacomo.travaglini@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2713481Sgiacomo.travaglini@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2813481Sgiacomo.travaglini@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2913481Sgiacomo.travaglini@arm.com
3013481Sgiacomo.travaglini@arm.com// A sample program demonstrating using Google C++ testing framework.
3113481Sgiacomo.travaglini@arm.com//
3213481Sgiacomo.travaglini@arm.com// Author: wan@google.com (Zhanyong Wan)
3313481Sgiacomo.travaglini@arm.com
3413481Sgiacomo.travaglini@arm.com#ifndef GTEST_SAMPLES_SAMPLE3_INL_H_
3513481Sgiacomo.travaglini@arm.com#define GTEST_SAMPLES_SAMPLE3_INL_H_
3613481Sgiacomo.travaglini@arm.com
3713481Sgiacomo.travaglini@arm.com#include <stddef.h>
3813481Sgiacomo.travaglini@arm.com
3913481Sgiacomo.travaglini@arm.com
4013481Sgiacomo.travaglini@arm.com// Queue is a simple queue implemented as a singled-linked list.
4113481Sgiacomo.travaglini@arm.com//
4213481Sgiacomo.travaglini@arm.com// The element type must support copy constructor.
4313481Sgiacomo.travaglini@arm.comtemplate <typename E>  // E is the element type
4413481Sgiacomo.travaglini@arm.comclass Queue;
4513481Sgiacomo.travaglini@arm.com
4613481Sgiacomo.travaglini@arm.com// QueueNode is a node in a Queue, which consists of an element of
4713481Sgiacomo.travaglini@arm.com// type E and a pointer to the next node.
4813481Sgiacomo.travaglini@arm.comtemplate <typename E>  // E is the element type
4913481Sgiacomo.travaglini@arm.comclass QueueNode {
5013481Sgiacomo.travaglini@arm.com  friend class Queue<E>;
5113481Sgiacomo.travaglini@arm.com
5213481Sgiacomo.travaglini@arm.com public:
5313481Sgiacomo.travaglini@arm.com  // Gets the element in this node.
5413481Sgiacomo.travaglini@arm.com  const E& element() const { return element_; }
5513481Sgiacomo.travaglini@arm.com
5613481Sgiacomo.travaglini@arm.com  // Gets the next node in the queue.
5713481Sgiacomo.travaglini@arm.com  QueueNode* next() { return next_; }
5813481Sgiacomo.travaglini@arm.com  const QueueNode* next() const { return next_; }
5913481Sgiacomo.travaglini@arm.com
6013481Sgiacomo.travaglini@arm.com private:
6113481Sgiacomo.travaglini@arm.com  // Creates a node with a given element value.  The next pointer is
6213481Sgiacomo.travaglini@arm.com  // set to NULL.
6313481Sgiacomo.travaglini@arm.com  explicit QueueNode(const E& an_element) : element_(an_element), next_(NULL) {}
6413481Sgiacomo.travaglini@arm.com
6513481Sgiacomo.travaglini@arm.com  // We disable the default assignment operator and copy c'tor.
6613481Sgiacomo.travaglini@arm.com  const QueueNode& operator = (const QueueNode&);
6713481Sgiacomo.travaglini@arm.com  QueueNode(const QueueNode&);
6813481Sgiacomo.travaglini@arm.com
6913481Sgiacomo.travaglini@arm.com  E element_;
7013481Sgiacomo.travaglini@arm.com  QueueNode* next_;
7113481Sgiacomo.travaglini@arm.com};
7213481Sgiacomo.travaglini@arm.com
7313481Sgiacomo.travaglini@arm.comtemplate <typename E>  // E is the element type.
7413481Sgiacomo.travaglini@arm.comclass Queue {
7513481Sgiacomo.travaglini@arm.com public:
7613481Sgiacomo.travaglini@arm.com  // Creates an empty queue.
7713481Sgiacomo.travaglini@arm.com  Queue() : head_(NULL), last_(NULL), size_(0) {}
7813481Sgiacomo.travaglini@arm.com
7913481Sgiacomo.travaglini@arm.com  // D'tor.  Clears the queue.
8013481Sgiacomo.travaglini@arm.com  ~Queue() { Clear(); }
8113481Sgiacomo.travaglini@arm.com
8213481Sgiacomo.travaglini@arm.com  // Clears the queue.
8313481Sgiacomo.travaglini@arm.com  void Clear() {
8413481Sgiacomo.travaglini@arm.com    if (size_ > 0) {
8513481Sgiacomo.travaglini@arm.com      // 1. Deletes every node.
8613481Sgiacomo.travaglini@arm.com      QueueNode<E>* node = head_;
8713481Sgiacomo.travaglini@arm.com      QueueNode<E>* next = node->next();
8813481Sgiacomo.travaglini@arm.com      for (; ;) {
8913481Sgiacomo.travaglini@arm.com        delete node;
9013481Sgiacomo.travaglini@arm.com        node = next;
9113481Sgiacomo.travaglini@arm.com        if (node == NULL) break;
9213481Sgiacomo.travaglini@arm.com        next = node->next();
9313481Sgiacomo.travaglini@arm.com      }
9413481Sgiacomo.travaglini@arm.com
9513481Sgiacomo.travaglini@arm.com      // 2. Resets the member variables.
9613481Sgiacomo.travaglini@arm.com      head_ = last_ = NULL;
9713481Sgiacomo.travaglini@arm.com      size_ = 0;
9813481Sgiacomo.travaglini@arm.com    }
9913481Sgiacomo.travaglini@arm.com  }
10013481Sgiacomo.travaglini@arm.com
10113481Sgiacomo.travaglini@arm.com  // Gets the number of elements.
10213481Sgiacomo.travaglini@arm.com  size_t Size() const { return size_; }
10313481Sgiacomo.travaglini@arm.com
10413481Sgiacomo.travaglini@arm.com  // Gets the first element of the queue, or NULL if the queue is empty.
10513481Sgiacomo.travaglini@arm.com  QueueNode<E>* Head() { return head_; }
10613481Sgiacomo.travaglini@arm.com  const QueueNode<E>* Head() const { return head_; }
10713481Sgiacomo.travaglini@arm.com
10813481Sgiacomo.travaglini@arm.com  // Gets the last element of the queue, or NULL if the queue is empty.
10913481Sgiacomo.travaglini@arm.com  QueueNode<E>* Last() { return last_; }
11013481Sgiacomo.travaglini@arm.com  const QueueNode<E>* Last() const { return last_; }
11113481Sgiacomo.travaglini@arm.com
11213481Sgiacomo.travaglini@arm.com  // Adds an element to the end of the queue.  A copy of the element is
11313481Sgiacomo.travaglini@arm.com  // created using the copy constructor, and then stored in the queue.
11413481Sgiacomo.travaglini@arm.com  // Changes made to the element in the queue doesn't affect the source
11513481Sgiacomo.travaglini@arm.com  // object, and vice versa.
11613481Sgiacomo.travaglini@arm.com  void Enqueue(const E& element) {
11713481Sgiacomo.travaglini@arm.com    QueueNode<E>* new_node = new QueueNode<E>(element);
11813481Sgiacomo.travaglini@arm.com
11913481Sgiacomo.travaglini@arm.com    if (size_ == 0) {
12013481Sgiacomo.travaglini@arm.com      head_ = last_ = new_node;
12113481Sgiacomo.travaglini@arm.com      size_ = 1;
12213481Sgiacomo.travaglini@arm.com    } else {
12313481Sgiacomo.travaglini@arm.com      last_->next_ = new_node;
12413481Sgiacomo.travaglini@arm.com      last_ = new_node;
12513481Sgiacomo.travaglini@arm.com      size_++;
12613481Sgiacomo.travaglini@arm.com    }
12713481Sgiacomo.travaglini@arm.com  }
12813481Sgiacomo.travaglini@arm.com
12913481Sgiacomo.travaglini@arm.com  // Removes the head of the queue and returns it.  Returns NULL if
13013481Sgiacomo.travaglini@arm.com  // the queue is empty.
13113481Sgiacomo.travaglini@arm.com  E* Dequeue() {
13213481Sgiacomo.travaglini@arm.com    if (size_ == 0) {
13313481Sgiacomo.travaglini@arm.com      return NULL;
13413481Sgiacomo.travaglini@arm.com    }
13513481Sgiacomo.travaglini@arm.com
13613481Sgiacomo.travaglini@arm.com    const QueueNode<E>* const old_head = head_;
13713481Sgiacomo.travaglini@arm.com    head_ = head_->next_;
13813481Sgiacomo.travaglini@arm.com    size_--;
13913481Sgiacomo.travaglini@arm.com    if (size_ == 0) {
14013481Sgiacomo.travaglini@arm.com      last_ = NULL;
14113481Sgiacomo.travaglini@arm.com    }
14213481Sgiacomo.travaglini@arm.com
14313481Sgiacomo.travaglini@arm.com    E* element = new E(old_head->element());
14413481Sgiacomo.travaglini@arm.com    delete old_head;
14513481Sgiacomo.travaglini@arm.com
14613481Sgiacomo.travaglini@arm.com    return element;
14713481Sgiacomo.travaglini@arm.com  }
14813481Sgiacomo.travaglini@arm.com
14913481Sgiacomo.travaglini@arm.com  // Applies a function/functor on each element of the queue, and
15013481Sgiacomo.travaglini@arm.com  // returns the result in a new queue.  The original queue is not
15113481Sgiacomo.travaglini@arm.com  // affected.
15213481Sgiacomo.travaglini@arm.com  template <typename F>
15313481Sgiacomo.travaglini@arm.com  Queue* Map(F function) const {
15413481Sgiacomo.travaglini@arm.com    Queue* new_queue = new Queue();
15513481Sgiacomo.travaglini@arm.com    for (const QueueNode<E>* node = head_; node != NULL; node = node->next_) {
15613481Sgiacomo.travaglini@arm.com      new_queue->Enqueue(function(node->element()));
15713481Sgiacomo.travaglini@arm.com    }
15813481Sgiacomo.travaglini@arm.com
15913481Sgiacomo.travaglini@arm.com    return new_queue;
16013481Sgiacomo.travaglini@arm.com  }
16113481Sgiacomo.travaglini@arm.com
16213481Sgiacomo.travaglini@arm.com private:
16313481Sgiacomo.travaglini@arm.com  QueueNode<E>* head_;  // The first node of the queue.
16413481Sgiacomo.travaglini@arm.com  QueueNode<E>* last_;  // The last node of the queue.
16513481Sgiacomo.travaglini@arm.com  size_t size_;  // The number of elements in the queue.
16613481Sgiacomo.travaglini@arm.com
16713481Sgiacomo.travaglini@arm.com  // We disallow copying a queue.
16813481Sgiacomo.travaglini@arm.com  Queue(const Queue&);
16913481Sgiacomo.travaglini@arm.com  const Queue& operator = (const Queue&);
17013481Sgiacomo.travaglini@arm.com};
17113481Sgiacomo.travaglini@arm.com
17213481Sgiacomo.travaglini@arm.com#endif  // GTEST_SAMPLES_SAMPLE3_INL_H_
173