1f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Copyright 2008 Google Inc.
2f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// All Rights Reserved.
3f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
4f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Redistribution and use in source and binary forms, with or without
5f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// modification, are permitted provided that the following conditions are
6f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// met:
7f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
8f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//     * Redistributions of source code must retain the above copyright
9f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// notice, this list of conditions and the following disclaimer.
10f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//     * Redistributions in binary form must reproduce the above
11f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// copyright notice, this list of conditions and the following disclaimer
12f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// in the documentation and/or other materials provided with the
13f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// distribution.
14f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//     * Neither the name of Google Inc. nor the names of its
15f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// contributors may be used to endorse or promote products derived from
16f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// this software without specific prior written permission.
17f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
18f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
30f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Author: vladl@google.com (Vlad Losev)
31f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
32f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Type and function utilities for implementing parameterized tests.
33f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
34f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
35f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
36f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
37f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include <ctype.h>
38f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
39f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include <iterator>
40f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include <set>
41f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include <utility>
42f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include <vector>
43f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
44f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// scripts/fuse_gtest.py depends on gtest's own header being #included
45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// *unconditionally*.  Therefore these #includes cannot be moved
46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// inside #if GTEST_HAS_PARAM_TEST.
47f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "gtest/internal/gtest-internal.h"
48f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "gtest/internal/gtest-linked_ptr.h"
49f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "gtest/internal/gtest-port.h"
50f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "gtest/gtest-printers.h"
51f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
52f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#if GTEST_HAS_PARAM_TEST
53f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
54f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace testing {
55f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
56f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Input to a parameterized test name generator, describing a test parameter.
57f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Consists of the parameter value and the integer parameter index.
58f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <class ParamType>
59f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct TestParamInfo {
60f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  TestParamInfo(const ParamType& a_param, size_t an_index) :
61f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    param(a_param),
62f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    index(an_index) {}
63f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ParamType param;
64f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  size_t index;
65f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
66f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
67f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// A builtin parameterized test name generator which returns the result of
68f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// testing::PrintToString.
69f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct PrintToStringParamName {
70f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  template <class ParamType>
71f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  std::string operator()(const TestParamInfo<ParamType>& info) const {
72f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return PrintToString(info.param);
73f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
74f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
75f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
76f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace internal {
77f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
78f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
79f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
80f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Outputs a message explaining invalid registration of different
81f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// fixture class for the same test case. This may happen when
82f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// TEST_P macro is used to define two tests with the same name
83f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// but in different namespaces.
84f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochGTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name,
85f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                          CodeLocation code_location);
86f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
87f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename> class ParamGeneratorInterface;
88f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename> class ParamGenerator;
89f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
90f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Interface for iterating over elements provided by an implementation
91f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// of ParamGeneratorInterface<T>.
92f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename T>
93f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass ParamIteratorInterface {
94f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
95f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual ~ParamIteratorInterface() {}
96f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // A pointer to the base generator instance.
97f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Used only for the purposes of iterator comparison
98f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // to make sure that two iterators belong to the same generator.
99f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;
100f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Advances iterator to point to the next element
101f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // provided by the generator. The caller is responsible
102f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // for not calling Advance() on an iterator equal to
103f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // BaseGenerator()->End().
104f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual void Advance() = 0;
105f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Clones the iterator object. Used for implementing copy semantics
106f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // of ParamIterator<T>.
107f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual ParamIteratorInterface* Clone() const = 0;
108f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Dereferences the current iterator and provides (read-only) access
109f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // to the pointed value. It is the caller's responsibility not to call
110f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Current() on an iterator equal to BaseGenerator()->End().
111f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Used for implementing ParamGenerator<T>::operator*().
112f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual const T* Current() const = 0;
113f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Determines whether the given iterator and other point to the same
114f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // element in the sequence generated by the generator.
115f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Used for implementing ParamGenerator<T>::operator==().
116f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual bool Equals(const ParamIteratorInterface& other) const = 0;
117f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
118f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
119f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Class iterating over elements provided by an implementation of
120f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
121f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// and implements the const forward iterator concept.
122f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename T>
123f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass ParamIterator {
124f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
125f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  typedef T value_type;
126f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  typedef const T& reference;
127f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  typedef ptrdiff_t difference_type;
128f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
129f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // ParamIterator assumes ownership of the impl_ pointer.
130f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
131f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ParamIterator& operator=(const ParamIterator& other) {
132f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (this != &other)
133f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      impl_.reset(other.impl_->Clone());
134f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return *this;
135f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
136f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
137f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const T& operator*() const { return *impl_->Current(); }
138f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const T* operator->() const { return impl_->Current(); }
139f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Prefix version of operator++.
140f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ParamIterator& operator++() {
141f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    impl_->Advance();
142f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return *this;
143f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
144f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Postfix version of operator++.
145f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ParamIterator operator++(int /*unused*/) {
146f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ParamIteratorInterface<T>* clone = impl_->Clone();
147f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    impl_->Advance();
148f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return ParamIterator(clone);
149f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
150f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool operator==(const ParamIterator& other) const {
151f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
152f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
153f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool operator!=(const ParamIterator& other) const {
154f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return !(*this == other);
155f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
156f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
157f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
158f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class ParamGenerator<T>;
159f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
160f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  scoped_ptr<ParamIteratorInterface<T> > impl_;
161f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
162f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ParamGeneratorInterface<T> is the binary interface to access generators
164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// defined in other translation units.
165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename T>
166f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass ParamGeneratorInterface {
167f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  typedef T ParamType;
169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual ~ParamGeneratorInterface() {}
171f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
172f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Generator interface definition
173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual ParamIteratorInterface<T>* Begin() const = 0;
174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual ParamIteratorInterface<T>* End() const = 0;
175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Wraps ParamGeneratorInterface<T> and provides general generator syntax
178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// compatible with the STL Container concept.
179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// This class implements copy initialization semantics and the contained
180f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ParamGeneratorInterface<T> instance is shared among all copies
181f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// of the original object. This is possible because that instance is immutable.
182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate<typename T>
183f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass ParamGenerator {
184f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  typedef ParamIterator<T> iterator;
186f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
187f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}
188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}
189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ParamGenerator& operator=(const ParamGenerator& other) {
191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    impl_ = other.impl_;
192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return *this;
193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  iterator begin() const { return iterator(impl_->Begin()); }
196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  iterator end() const { return iterator(impl_->End()); }
197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  linked_ptr<const ParamGeneratorInterface<T> > impl_;
200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Generates values from a range of two comparable values. Can be used to
203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// generate sequences of user-defined types that implement operator+() and
204f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// operator<().
205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// This class is used in the Range() function.
206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename T, typename IncrementT>
207f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass RangeGenerator : public ParamGeneratorInterface<T> {
208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
209f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  RangeGenerator(T begin, T end, IncrementT step)
210f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : begin_(begin), end_(end),
211f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
212f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual ~RangeGenerator() {}
213f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
214f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual ParamIteratorInterface<T>* Begin() const {
215f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new Iterator(this, begin_, 0, step_);
216f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
217f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual ParamIteratorInterface<T>* End() const {
218f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new Iterator(this, end_, end_index_, step_);
219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
220f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
221f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
222f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  class Iterator : public ParamIteratorInterface<T> {
223f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch   public:
224f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
225f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch             IncrementT step)
226f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        : base_(base), value_(value), index_(index), step_(step) {}
227f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    virtual ~Iterator() {}
228f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
229f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
230f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return base_;
231f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
232f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    virtual void Advance() {
233f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      value_ = static_cast<T>(value_ + step_);
234f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      index_++;
235f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
236f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    virtual ParamIteratorInterface<T>* Clone() const {
237f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return new Iterator(*this);
238f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
239f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    virtual const T* Current() const { return &value_; }
240f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    virtual bool Equals(const ParamIteratorInterface<T>& other) const {
241f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // Having the same base generator guarantees that the other
242f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // iterator is of the same type and we can downcast.
243f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          << "The program attempted to compare iterators "
245f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          << "from different generators." << std::endl;
246f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      const int other_index =
247f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          CheckedDowncastToActualType<const Iterator>(&other)->index_;
248f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return index_ == other_index;
249f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
250f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
251f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch   private:
252f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Iterator(const Iterator& other)
253f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        : ParamIteratorInterface<T>(),
254f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          base_(other.base_), value_(other.value_), index_(other.index_),
255f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          step_(other.step_) {}
256f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
257f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // No implementation - assignment is unsupported.
258f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    void operator=(const Iterator& other);
259f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
260f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    const ParamGeneratorInterface<T>* const base_;
261f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    T value_;
262f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int index_;
263f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    const IncrementT step_;
264f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  };  // class RangeGenerator::Iterator
265f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
266f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int CalculateEndIndex(const T& begin,
267f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                               const T& end,
268f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                               const IncrementT& step) {
269f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int end_index = 0;
270f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    for (T i = begin; i < end; i = static_cast<T>(i + step))
271f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      end_index++;
272f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return end_index;
273f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
274f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
275f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // No implementation - assignment is unsupported.
276f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void operator=(const RangeGenerator& other);
277f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
278f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const T begin_;
279f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const T end_;
280f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const IncrementT step_;
281f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // The index for the end() iterator. All the elements in the generated
282f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // sequence are indexed (0-based) to aid iterator comparison.
283f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const int end_index_;
284f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};  // class RangeGenerator
285f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
286f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
287f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Generates values from a pair of STL-style iterators. Used in the
288f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ValuesIn() function. The elements are copied from the source range
289f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// since the source can be located on the stack, and the generator
290f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// is likely to persist beyond that stack frame.
291f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename T>
292f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
293f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
294f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  template <typename ForwardIterator>
295f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
296f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : container_(begin, end) {}
297f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual ~ValuesInIteratorRangeGenerator() {}
298f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
299f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual ParamIteratorInterface<T>* Begin() const {
300f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new Iterator(this, container_.begin());
301f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
302f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual ParamIteratorInterface<T>* End() const {
303f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new Iterator(this, container_.end());
304f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
305f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
306f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
307f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  typedef typename ::std::vector<T> ContainerType;
308f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
309f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  class Iterator : public ParamIteratorInterface<T> {
310f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch   public:
311f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Iterator(const ParamGeneratorInterface<T>* base,
312f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch             typename ContainerType::const_iterator iterator)
313f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        : base_(base), iterator_(iterator) {}
314f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    virtual ~Iterator() {}
315f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
316f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
317f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return base_;
318f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
319f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    virtual void Advance() {
320f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ++iterator_;
321f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      value_.reset();
322f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
323f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    virtual ParamIteratorInterface<T>* Clone() const {
324f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return new Iterator(*this);
325f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
326f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // We need to use cached value referenced by iterator_ because *iterator_
327f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // can return a temporary object (and of type other then T), so just
328f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // having "return &*iterator_;" doesn't work.
329f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // value_ is updated here and not in Advance() because Advance()
330f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // can advance iterator_ beyond the end of the range, and we cannot
331f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // detect that fact. The client code, on the other hand, is
332f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // responsible for not calling Current() on an out-of-range iterator.
333f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    virtual const T* Current() const {
334f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (value_.get() == NULL)
335f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        value_.reset(new T(*iterator_));
336f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return value_.get();
337f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
338f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    virtual bool Equals(const ParamIteratorInterface<T>& other) const {
339f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // Having the same base generator guarantees that the other
340f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // iterator is of the same type and we can downcast.
341f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
342f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          << "The program attempted to compare iterators "
343f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          << "from different generators." << std::endl;
344f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return iterator_ ==
345f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
346f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
347f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
348f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch   private:
349f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Iterator(const Iterator& other)
350f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          // The explicit constructor call suppresses a false warning
351f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          // emitted by gcc when supplied with the -Wextra option.
352f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        : ParamIteratorInterface<T>(),
353f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          base_(other.base_),
354f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          iterator_(other.iterator_) {}
355f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
356f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    const ParamGeneratorInterface<T>* const base_;
357f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    typename ContainerType::const_iterator iterator_;
358f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // A cached value of *iterator_. We keep it here to allow access by
359f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // pointer in the wrapping iterator's operator->().
360f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // value_ needs to be mutable to be accessed in Current().
361f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // Use of scoped_ptr helps manage cached value's lifetime,
362f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // which is bound by the lifespan of the iterator itself.
363f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    mutable scoped_ptr<const T> value_;
364f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  };  // class ValuesInIteratorRangeGenerator::Iterator
365f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
366f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // No implementation - assignment is unsupported.
367f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void operator=(const ValuesInIteratorRangeGenerator& other);
368f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
369f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const ContainerType container_;
370f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};  // class ValuesInIteratorRangeGenerator
371f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
372f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
373f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
374f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Default parameterized test name generator, returns a string containing the
375f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// integer test parameter index.
376f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <class ParamType>
377f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstd::string DefaultParamName(const TestParamInfo<ParamType>& info) {
378f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Message name_stream;
379f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  name_stream << info.index;
380f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return name_stream.GetString();
381f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
382f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
383f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
384f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
385f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Parameterized test name overload helpers, which help the
386f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// INSTANTIATE_TEST_CASE_P macro choose between the default parameterized
387f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// test name generator and user param name generator.
388f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <class ParamType, class ParamNameGenFunctor>
389f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochParamNameGenFunctor GetParamNameGen(ParamNameGenFunctor func) {
390f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return func;
391f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
392f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
393f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <class ParamType>
394f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct ParamNameGenFunc {
395f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  typedef std::string Type(const TestParamInfo<ParamType>&);
396f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
397f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
398f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <class ParamType>
399f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypename ParamNameGenFunc<ParamType>::Type *GetParamNameGen() {
400f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return DefaultParamName;
401f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
402f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
403f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
404f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
405f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Stores a parameter value and later creates tests parameterized with that
406f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// value.
407f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <class TestClass>
408f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass ParameterizedTestFactory : public TestFactoryBase {
409f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
410f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  typedef typename TestClass::ParamType ParamType;
411f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  explicit ParameterizedTestFactory(ParamType parameter) :
412f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      parameter_(parameter) {}
413f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual Test* CreateTest() {
414f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    TestClass::SetParam(&parameter_);
415f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new TestClass();
416f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
417f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
418f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
419f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const ParamType parameter_;
420f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
421f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory);
422f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
423f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
424f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
425f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
426f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// TestMetaFactoryBase is a base class for meta-factories that create
427f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// test factories for passing into MakeAndRegisterTestInfo function.
428f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <class ParamType>
429f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass TestMetaFactoryBase {
430f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
431f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual ~TestMetaFactoryBase() {}
432f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
433f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
434f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
435f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
436f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
437f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
438f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// TestMetaFactory creates test factories for passing into
439f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
440f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ownership of test factory pointer, same factory object cannot be passed
441f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// into that method twice. But ParameterizedTestCaseInfo is going to call
442f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// it for each Test/Parameter value combination. Thus it needs meta factory
443f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// creator class.
444f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <class TestCase>
445f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass TestMetaFactory
446f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    : public TestMetaFactoryBase<typename TestCase::ParamType> {
447f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
448f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  typedef typename TestCase::ParamType ParamType;
449f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
450f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  TestMetaFactory() {}
451f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
452f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) {
453f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new ParameterizedTestFactory<TestCase>(parameter);
454f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
455f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
456f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
457f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory);
458f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
459f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
460f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
461f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
462f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ParameterizedTestCaseInfoBase is a generic interface
463f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase
464f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// accumulates test information provided by TEST_P macro invocations
465f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations
466f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// and uses that information to register all resulting test instances
467f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// in RegisterTests method. The ParameterizeTestCaseRegistry class holds
468f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// a collection of pointers to the ParameterizedTestCaseInfo objects
469f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// and calls RegisterTests() on each of them when asked.
470f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass ParameterizedTestCaseInfoBase {
471f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
472f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual ~ParameterizedTestCaseInfoBase() {}
473f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
474f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Base part of test case name for display purposes.
475f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual const string& GetTestCaseName() const = 0;
476f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Test case id to verify identity.
477f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual TypeId GetTestCaseTypeId() const = 0;
478f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // UnitTest class invokes this method to register tests in this
479f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // test case right before running them in RUN_ALL_TESTS macro.
480f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // This method should not be called more then once on any single
481f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // instance of a ParameterizedTestCaseInfoBase derived class.
482f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual void RegisterTests() = 0;
483f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
484f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch protected:
485f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ParameterizedTestCaseInfoBase() {}
486f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
487f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
488f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase);
489f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
490f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
491f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
492f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
493f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P
494f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// macro invocations for a particular test case and generators
495f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that
496f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// test case. It registers tests with all values generated by all
497f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// generators when asked.
498f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <class TestCase>
499f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
500f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
501f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // ParamType and GeneratorCreationFunc are private types but are required
502f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // for declarations of public methods AddTestPattern() and
503f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // AddTestCaseInstantiation().
504f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  typedef typename TestCase::ParamType ParamType;
505f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // A function that returns an instance of appropriate generator type.
506f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
507f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  typedef typename ParamNameGenFunc<ParamType>::Type ParamNameGeneratorFunc;
508f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
509f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  explicit ParameterizedTestCaseInfo(
510f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      const char* name, CodeLocation code_location)
511f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : test_case_name_(name), code_location_(code_location) {}
512f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
513f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Test case base name for display purposes.
514f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual const string& GetTestCaseName() const { return test_case_name_; }
515f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Test case id to verify identity.
516f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); }
517f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // TEST_P macro uses AddTestPattern() to record information
518f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // about a single test in a LocalTestInfo structure.
519f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // test_case_name is the base name of the test case (without invocation
520f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // prefix). test_base_name is the name of an individual test without
521f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
522f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // test case base name and DoBar is test base name.
523f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void AddTestPattern(const char* test_case_name,
524f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                      const char* test_base_name,
525f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                      TestMetaFactoryBase<ParamType>* meta_factory) {
526f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name,
527f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                       test_base_name,
528f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                       meta_factory)));
529f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
530f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information
531f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // about a generator.
532f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int AddTestCaseInstantiation(const string& instantiation_name,
533f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                               GeneratorCreationFunc* func,
534f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                               ParamNameGeneratorFunc* name_func,
535f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                               const char* file,
536f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                               int line) {
537f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    instantiations_.push_back(
538f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        InstantiationInfo(instantiation_name, func, name_func, file, line));
539f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return 0;  // Return value used only to run this method in namespace scope.
540f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
541f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // UnitTest class invokes this method to register tests in this test case
542f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // test cases right before running tests in RUN_ALL_TESTS macro.
543f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // This method should not be called more then once on any single
544f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // instance of a ParameterizedTestCaseInfoBase derived class.
545f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // UnitTest has a guard to prevent from calling this method more then once.
546f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual void RegisterTests() {
547f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    for (typename TestInfoContainer::iterator test_it = tests_.begin();
548f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch         test_it != tests_.end(); ++test_it) {
549f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      linked_ptr<TestInfo> test_info = *test_it;
550f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      for (typename InstantiationContainer::iterator gen_it =
551f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               instantiations_.begin(); gen_it != instantiations_.end();
552f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               ++gen_it) {
553f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        const string& instantiation_name = gen_it->name;
554f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        ParamGenerator<ParamType> generator((*gen_it->generator)());
555f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        ParamNameGeneratorFunc* name_func = gen_it->name_func;
556f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        const char* file = gen_it->file;
557f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        int line = gen_it->line;
558f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
559f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        string test_case_name;
560f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        if ( !instantiation_name.empty() )
561f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          test_case_name = instantiation_name + "/";
562f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        test_case_name += test_info->test_case_base_name;
563f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
564f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        size_t i = 0;
565f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        std::set<std::string> test_param_names;
566f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        for (typename ParamGenerator<ParamType>::iterator param_it =
567f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                 generator.begin();
568f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch             param_it != generator.end(); ++param_it, ++i) {
569f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          Message test_name_stream;
570f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
571f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          std::string param_name = name_func(
572f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              TestParamInfo<ParamType>(*param_it, i));
573f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
574f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          GTEST_CHECK_(IsValidParamName(param_name))
575f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              << "Parameterized test name '" << param_name
576f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              << "' is invalid, in " << file
577f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              << " line " << line << std::endl;
578f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
579f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          GTEST_CHECK_(test_param_names.count(param_name) == 0)
580f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              << "Duplicate parameterized test name '" << param_name
581f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              << "', in " << file << " line " << line << std::endl;
582f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
583f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          test_param_names.insert(param_name);
584f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
585f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          test_name_stream << test_info->test_base_name << "/" << param_name;
586f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          MakeAndRegisterTestInfo(
587f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              test_case_name.c_str(),
588f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              test_name_stream.GetString().c_str(),
589f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              NULL,  // No type parameter.
590f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              PrintToString(*param_it).c_str(),
591f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              code_location_,
592f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              GetTestCaseTypeId(),
593f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              TestCase::SetUpTestCase,
594f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              TestCase::TearDownTestCase,
595f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              test_info->test_meta_factory->CreateTestFactory(*param_it));
596f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        }  // for param_it
597f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }  // for gen_it
598f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }  // for test_it
599f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }  // RegisterTests
600f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
601f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
602f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // LocalTestInfo structure keeps information about a single test registered
603f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // with TEST_P macro.
604f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  struct TestInfo {
605f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    TestInfo(const char* a_test_case_base_name,
606f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch             const char* a_test_base_name,
607f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch             TestMetaFactoryBase<ParamType>* a_test_meta_factory) :
608f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        test_case_base_name(a_test_case_base_name),
609f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        test_base_name(a_test_base_name),
610f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        test_meta_factory(a_test_meta_factory) {}
611f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
612f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    const string test_case_base_name;
613f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    const string test_base_name;
614f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
615f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  };
616f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;
617f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Records data received from INSTANTIATE_TEST_CASE_P macros:
618f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  //  <Instantiation name, Sequence generator creation function,
619f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  //     Name generator function, Source file, Source line>
620f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  struct InstantiationInfo {
621f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      InstantiationInfo(const std::string &name_in,
622f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                        GeneratorCreationFunc* generator_in,
623f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                        ParamNameGeneratorFunc* name_func_in,
624f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                        const char* file_in,
625f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                        int line_in)
626f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          : name(name_in),
627f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            generator(generator_in),
628f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            name_func(name_func_in),
629f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            file(file_in),
630f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            line(line_in) {}
631f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
632f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      std::string name;
633f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      GeneratorCreationFunc* generator;
634f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ParamNameGeneratorFunc* name_func;
635f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      const char* file;
636f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      int line;
637f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  };
638f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  typedef ::std::vector<InstantiationInfo> InstantiationContainer;
639f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
640f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static bool IsValidParamName(const std::string& name) {
641f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // Check for empty string
642f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (name.empty())
643f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return false;
644f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
645f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // Check for invalid characters
646f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    for (std::string::size_type index = 0; index < name.size(); ++index) {
647f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (!isalnum(name[index]) && name[index] != '_')
648f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        return false;
649f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
650f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
651f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return true;
652f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
653f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
654f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const string test_case_name_;
655f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CodeLocation code_location_;
656f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  TestInfoContainer tests_;
657f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  InstantiationContainer instantiations_;
658f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
659f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo);
660f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};  // class ParameterizedTestCaseInfo
661f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
662f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
663f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
664f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase
665f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P
666f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// macros use it to locate their corresponding ParameterizedTestCaseInfo
667f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// descriptors.
668f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass ParameterizedTestCaseRegistry {
669f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
670f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ParameterizedTestCaseRegistry() {}
671f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ~ParameterizedTestCaseRegistry() {
672f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
673f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch         it != test_case_infos_.end(); ++it) {
674f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      delete *it;
675f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
676f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
677f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
678f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Looks up or creates and returns a structure containing information about
679f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // tests and instantiations of a particular test case.
680f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  template <class TestCase>
681f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
682f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      const char* test_case_name,
683f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      CodeLocation code_location) {
684f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;
685f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
686f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch         it != test_case_infos_.end(); ++it) {
687f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if ((*it)->GetTestCaseName() == test_case_name) {
688f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) {
689f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          // Complain about incorrect usage of Google Test facilities
690f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          // and terminate the program since we cannot guaranty correct
691f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          // test case setup and tear-down in this case.
692f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          ReportInvalidTestCaseType(test_case_name, code_location);
693f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          posix::Abort();
694f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        } else {
695f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          // At this point we are sure that the object we found is of the same
696f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          // type we are looking for, so we downcast it to that type
697f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          // without further checks.
698f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          typed_test_info = CheckedDowncastToActualType<
699f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              ParameterizedTestCaseInfo<TestCase> >(*it);
700f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        }
701f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        break;
702f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
703f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
704f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (typed_test_info == NULL) {
705f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      typed_test_info = new ParameterizedTestCaseInfo<TestCase>(
706f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          test_case_name, code_location);
707f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      test_case_infos_.push_back(typed_test_info);
708f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
709f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return typed_test_info;
710f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
711f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void RegisterTests() {
712f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
713f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch         it != test_case_infos_.end(); ++it) {
714f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      (*it)->RegisterTests();
715f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
716f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
717f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
718f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
719f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer;
720f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
721f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  TestCaseInfoContainer test_case_infos_;
722f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
723f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry);
724f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
725f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
726f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}  // namespace internal
727f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}  // namespace testing
728f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
729f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#endif  //  GTEST_HAS_PARAM_TEST
730f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
732