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