1af69d88dSmrg// Copyright 2008 Google Inc.
2af69d88dSmrg// All Rights Reserved.
3af69d88dSmrg//
4af69d88dSmrg// Redistribution and use in source and binary forms, with or without
5af69d88dSmrg// modification, are permitted provided that the following conditions are
6af69d88dSmrg// met:
7af69d88dSmrg//
8af69d88dSmrg//     * Redistributions of source code must retain the above copyright
9af69d88dSmrg// notice, this list of conditions and the following disclaimer.
10af69d88dSmrg//     * Redistributions in binary form must reproduce the above
11af69d88dSmrg// copyright notice, this list of conditions and the following disclaimer
12af69d88dSmrg// in the documentation and/or other materials provided with the
13af69d88dSmrg// distribution.
14af69d88dSmrg//     * Neither the name of Google Inc. nor the names of its
15af69d88dSmrg// contributors may be used to endorse or promote products derived from
16af69d88dSmrg// this software without specific prior written permission.
17af69d88dSmrg//
18af69d88dSmrg// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19af69d88dSmrg// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20af69d88dSmrg// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21af69d88dSmrg// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22af69d88dSmrg// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23af69d88dSmrg// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24af69d88dSmrg// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25af69d88dSmrg// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26af69d88dSmrg// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27af69d88dSmrg// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28af69d88dSmrg// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
297ec681f3Smrg
30af69d88dSmrg
31af69d88dSmrg// Type and function utilities for implementing parameterized tests.
32af69d88dSmrg
337ec681f3Smrg// GOOGLETEST_CM0001 DO NOT DELETE
347ec681f3Smrg
35af69d88dSmrg#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
36af69d88dSmrg#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
37af69d88dSmrg
3801e04c3fSmrg#include <ctype.h>
3901e04c3fSmrg
407ec681f3Smrg#include <cassert>
41af69d88dSmrg#include <iterator>
427ec681f3Smrg#include <memory>
4301e04c3fSmrg#include <set>
447ec681f3Smrg#include <tuple>
45af69d88dSmrg#include <utility>
46af69d88dSmrg#include <vector>
47af69d88dSmrg
48af69d88dSmrg#include "gtest/internal/gtest-internal.h"
49af69d88dSmrg#include "gtest/internal/gtest-port.h"
50af69d88dSmrg#include "gtest/gtest-printers.h"
51af69d88dSmrg
52af69d88dSmrgnamespace testing {
5301e04c3fSmrg// Input to a parameterized test name generator, describing a test parameter.
5401e04c3fSmrg// Consists of the parameter value and the integer parameter index.
5501e04c3fSmrgtemplate <class ParamType>
5601e04c3fSmrgstruct TestParamInfo {
5701e04c3fSmrg  TestParamInfo(const ParamType& a_param, size_t an_index) :
5801e04c3fSmrg    param(a_param),
5901e04c3fSmrg    index(an_index) {}
6001e04c3fSmrg  ParamType param;
6101e04c3fSmrg  size_t index;
6201e04c3fSmrg};
6301e04c3fSmrg
6401e04c3fSmrg// A builtin parameterized test name generator which returns the result of
6501e04c3fSmrg// testing::PrintToString.
6601e04c3fSmrgstruct PrintToStringParamName {
6701e04c3fSmrg  template <class ParamType>
6801e04c3fSmrg  std::string operator()(const TestParamInfo<ParamType>& info) const {
6901e04c3fSmrg    return PrintToString(info.param);
7001e04c3fSmrg  }
7101e04c3fSmrg};
7201e04c3fSmrg
73af69d88dSmrgnamespace internal {
74af69d88dSmrg
75af69d88dSmrg// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
767ec681f3Smrg// Utility Functions
777ec681f3Smrg
78af69d88dSmrg// Outputs a message explaining invalid registration of different
797ec681f3Smrg// fixture class for the same test suite. This may happen when
80af69d88dSmrg// TEST_P macro is used to define two tests with the same name
81af69d88dSmrg// but in different namespaces.
827ec681f3SmrgGTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
837ec681f3Smrg                                           CodeLocation code_location);
84af69d88dSmrg
85af69d88dSmrgtemplate <typename> class ParamGeneratorInterface;
86af69d88dSmrgtemplate <typename> class ParamGenerator;
87af69d88dSmrg
88af69d88dSmrg// Interface for iterating over elements provided by an implementation
89af69d88dSmrg// of ParamGeneratorInterface<T>.
90af69d88dSmrgtemplate <typename T>
91af69d88dSmrgclass ParamIteratorInterface {
92af69d88dSmrg public:
93af69d88dSmrg  virtual ~ParamIteratorInterface() {}
94af69d88dSmrg  // A pointer to the base generator instance.
95af69d88dSmrg  // Used only for the purposes of iterator comparison
96af69d88dSmrg  // to make sure that two iterators belong to the same generator.
97af69d88dSmrg  virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;
98af69d88dSmrg  // Advances iterator to point to the next element
99af69d88dSmrg  // provided by the generator. The caller is responsible
100af69d88dSmrg  // for not calling Advance() on an iterator equal to
101af69d88dSmrg  // BaseGenerator()->End().
102af69d88dSmrg  virtual void Advance() = 0;
103af69d88dSmrg  // Clones the iterator object. Used for implementing copy semantics
104af69d88dSmrg  // of ParamIterator<T>.
105af69d88dSmrg  virtual ParamIteratorInterface* Clone() const = 0;
106af69d88dSmrg  // Dereferences the current iterator and provides (read-only) access
107af69d88dSmrg  // to the pointed value. It is the caller's responsibility not to call
108af69d88dSmrg  // Current() on an iterator equal to BaseGenerator()->End().
109af69d88dSmrg  // Used for implementing ParamGenerator<T>::operator*().
110af69d88dSmrg  virtual const T* Current() const = 0;
111af69d88dSmrg  // Determines whether the given iterator and other point to the same
112af69d88dSmrg  // element in the sequence generated by the generator.
113af69d88dSmrg  // Used for implementing ParamGenerator<T>::operator==().
114af69d88dSmrg  virtual bool Equals(const ParamIteratorInterface& other) const = 0;
115af69d88dSmrg};
116af69d88dSmrg
117af69d88dSmrg// Class iterating over elements provided by an implementation of
118af69d88dSmrg// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
119af69d88dSmrg// and implements the const forward iterator concept.
120af69d88dSmrgtemplate <typename T>
121af69d88dSmrgclass ParamIterator {
122af69d88dSmrg public:
123af69d88dSmrg  typedef T value_type;
124af69d88dSmrg  typedef const T& reference;
125af69d88dSmrg  typedef ptrdiff_t difference_type;
126af69d88dSmrg
127af69d88dSmrg  // ParamIterator assumes ownership of the impl_ pointer.
128af69d88dSmrg  ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
129af69d88dSmrg  ParamIterator& operator=(const ParamIterator& other) {
130af69d88dSmrg    if (this != &other)
131af69d88dSmrg      impl_.reset(other.impl_->Clone());
132af69d88dSmrg    return *this;
133af69d88dSmrg  }
134af69d88dSmrg
135af69d88dSmrg  const T& operator*() const { return *impl_->Current(); }
136af69d88dSmrg  const T* operator->() const { return impl_->Current(); }
137af69d88dSmrg  // Prefix version of operator++.
138af69d88dSmrg  ParamIterator& operator++() {
139af69d88dSmrg    impl_->Advance();
140af69d88dSmrg    return *this;
141af69d88dSmrg  }
142af69d88dSmrg  // Postfix version of operator++.
143af69d88dSmrg  ParamIterator operator++(int /*unused*/) {
144af69d88dSmrg    ParamIteratorInterface<T>* clone = impl_->Clone();
145af69d88dSmrg    impl_->Advance();
146af69d88dSmrg    return ParamIterator(clone);
147af69d88dSmrg  }
148af69d88dSmrg  bool operator==(const ParamIterator& other) const {
149af69d88dSmrg    return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
150af69d88dSmrg  }
151af69d88dSmrg  bool operator!=(const ParamIterator& other) const {
152af69d88dSmrg    return !(*this == other);
153af69d88dSmrg  }
154af69d88dSmrg
155af69d88dSmrg private:
156af69d88dSmrg  friend class ParamGenerator<T>;
157af69d88dSmrg  explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
1587ec681f3Smrg  std::unique_ptr<ParamIteratorInterface<T> > impl_;
159af69d88dSmrg};
160af69d88dSmrg
161af69d88dSmrg// ParamGeneratorInterface<T> is the binary interface to access generators
162af69d88dSmrg// defined in other translation units.
163af69d88dSmrgtemplate <typename T>
164af69d88dSmrgclass ParamGeneratorInterface {
165af69d88dSmrg public:
166af69d88dSmrg  typedef T ParamType;
167af69d88dSmrg
168af69d88dSmrg  virtual ~ParamGeneratorInterface() {}
169af69d88dSmrg
170af69d88dSmrg  // Generator interface definition
171af69d88dSmrg  virtual ParamIteratorInterface<T>* Begin() const = 0;
172af69d88dSmrg  virtual ParamIteratorInterface<T>* End() const = 0;
173af69d88dSmrg};
174af69d88dSmrg
175af69d88dSmrg// Wraps ParamGeneratorInterface<T> and provides general generator syntax
176af69d88dSmrg// compatible with the STL Container concept.
177af69d88dSmrg// This class implements copy initialization semantics and the contained
178af69d88dSmrg// ParamGeneratorInterface<T> instance is shared among all copies
179af69d88dSmrg// of the original object. This is possible because that instance is immutable.
180af69d88dSmrgtemplate<typename T>
181af69d88dSmrgclass ParamGenerator {
182af69d88dSmrg public:
183af69d88dSmrg  typedef ParamIterator<T> iterator;
184af69d88dSmrg
185af69d88dSmrg  explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}
186af69d88dSmrg  ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}
187af69d88dSmrg
188af69d88dSmrg  ParamGenerator& operator=(const ParamGenerator& other) {
189af69d88dSmrg    impl_ = other.impl_;
190af69d88dSmrg    return *this;
191af69d88dSmrg  }
192af69d88dSmrg
193af69d88dSmrg  iterator begin() const { return iterator(impl_->Begin()); }
194af69d88dSmrg  iterator end() const { return iterator(impl_->End()); }
195af69d88dSmrg
196af69d88dSmrg private:
1977ec681f3Smrg  std::shared_ptr<const ParamGeneratorInterface<T> > impl_;
198af69d88dSmrg};
199af69d88dSmrg
200af69d88dSmrg// Generates values from a range of two comparable values. Can be used to
201af69d88dSmrg// generate sequences of user-defined types that implement operator+() and
202af69d88dSmrg// operator<().
203af69d88dSmrg// This class is used in the Range() function.
204af69d88dSmrgtemplate <typename T, typename IncrementT>
205af69d88dSmrgclass RangeGenerator : public ParamGeneratorInterface<T> {
206af69d88dSmrg public:
207af69d88dSmrg  RangeGenerator(T begin, T end, IncrementT step)
208af69d88dSmrg      : begin_(begin), end_(end),
209af69d88dSmrg        step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
2107ec681f3Smrg  ~RangeGenerator() override {}
211af69d88dSmrg
2127ec681f3Smrg  ParamIteratorInterface<T>* Begin() const override {
213af69d88dSmrg    return new Iterator(this, begin_, 0, step_);
214af69d88dSmrg  }
2157ec681f3Smrg  ParamIteratorInterface<T>* End() const override {
216af69d88dSmrg    return new Iterator(this, end_, end_index_, step_);
217af69d88dSmrg  }
218af69d88dSmrg
219af69d88dSmrg private:
220af69d88dSmrg  class Iterator : public ParamIteratorInterface<T> {
221af69d88dSmrg   public:
222af69d88dSmrg    Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
223af69d88dSmrg             IncrementT step)
224af69d88dSmrg        : base_(base), value_(value), index_(index), step_(step) {}
2257ec681f3Smrg    ~Iterator() override {}
226af69d88dSmrg
2277ec681f3Smrg    const ParamGeneratorInterface<T>* BaseGenerator() const override {
228af69d88dSmrg      return base_;
229af69d88dSmrg    }
2307ec681f3Smrg    void Advance() override {
23101e04c3fSmrg      value_ = static_cast<T>(value_ + step_);
232af69d88dSmrg      index_++;
233af69d88dSmrg    }
2347ec681f3Smrg    ParamIteratorInterface<T>* Clone() const override {
235af69d88dSmrg      return new Iterator(*this);
236af69d88dSmrg    }
2377ec681f3Smrg    const T* Current() const override { return &value_; }
2387ec681f3Smrg    bool Equals(const ParamIteratorInterface<T>& other) const override {
239af69d88dSmrg      // Having the same base generator guarantees that the other
240af69d88dSmrg      // iterator is of the same type and we can downcast.
241af69d88dSmrg      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
242af69d88dSmrg          << "The program attempted to compare iterators "
243af69d88dSmrg          << "from different generators." << std::endl;
244af69d88dSmrg      const int other_index =
245af69d88dSmrg          CheckedDowncastToActualType<const Iterator>(&other)->index_;
246af69d88dSmrg      return index_ == other_index;
247af69d88dSmrg    }
248af69d88dSmrg
249af69d88dSmrg   private:
250af69d88dSmrg    Iterator(const Iterator& other)
251af69d88dSmrg        : ParamIteratorInterface<T>(),
252af69d88dSmrg          base_(other.base_), value_(other.value_), index_(other.index_),
253af69d88dSmrg          step_(other.step_) {}
254af69d88dSmrg
255af69d88dSmrg    // No implementation - assignment is unsupported.
256af69d88dSmrg    void operator=(const Iterator& other);
257af69d88dSmrg
258af69d88dSmrg    const ParamGeneratorInterface<T>* const base_;
259af69d88dSmrg    T value_;
260af69d88dSmrg    int index_;
261af69d88dSmrg    const IncrementT step_;
262af69d88dSmrg  };  // class RangeGenerator::Iterator
263af69d88dSmrg
264af69d88dSmrg  static int CalculateEndIndex(const T& begin,
265af69d88dSmrg                               const T& end,
266af69d88dSmrg                               const IncrementT& step) {
267af69d88dSmrg    int end_index = 0;
26801e04c3fSmrg    for (T i = begin; i < end; i = static_cast<T>(i + step))
269af69d88dSmrg      end_index++;
270af69d88dSmrg    return end_index;
271af69d88dSmrg  }
272af69d88dSmrg
273af69d88dSmrg  // No implementation - assignment is unsupported.
274af69d88dSmrg  void operator=(const RangeGenerator& other);
275af69d88dSmrg
276af69d88dSmrg  const T begin_;
277af69d88dSmrg  const T end_;
278af69d88dSmrg  const IncrementT step_;
279af69d88dSmrg  // The index for the end() iterator. All the elements in the generated
280af69d88dSmrg  // sequence are indexed (0-based) to aid iterator comparison.
281af69d88dSmrg  const int end_index_;
282af69d88dSmrg};  // class RangeGenerator
283af69d88dSmrg
284af69d88dSmrg
285af69d88dSmrg// Generates values from a pair of STL-style iterators. Used in the
286af69d88dSmrg// ValuesIn() function. The elements are copied from the source range
287af69d88dSmrg// since the source can be located on the stack, and the generator
288af69d88dSmrg// is likely to persist beyond that stack frame.
289af69d88dSmrgtemplate <typename T>
290af69d88dSmrgclass ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
291af69d88dSmrg public:
292af69d88dSmrg  template <typename ForwardIterator>
293af69d88dSmrg  ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
294af69d88dSmrg      : container_(begin, end) {}
2957ec681f3Smrg  ~ValuesInIteratorRangeGenerator() override {}
296af69d88dSmrg
2977ec681f3Smrg  ParamIteratorInterface<T>* Begin() const override {
298af69d88dSmrg    return new Iterator(this, container_.begin());
299af69d88dSmrg  }
3007ec681f3Smrg  ParamIteratorInterface<T>* End() const override {
301af69d88dSmrg    return new Iterator(this, container_.end());
302af69d88dSmrg  }
303af69d88dSmrg
304af69d88dSmrg private:
305af69d88dSmrg  typedef typename ::std::vector<T> ContainerType;
306af69d88dSmrg
307af69d88dSmrg  class Iterator : public ParamIteratorInterface<T> {
308af69d88dSmrg   public:
309af69d88dSmrg    Iterator(const ParamGeneratorInterface<T>* base,
310af69d88dSmrg             typename ContainerType::const_iterator iterator)
311af69d88dSmrg        : base_(base), iterator_(iterator) {}
3127ec681f3Smrg    ~Iterator() override {}
313af69d88dSmrg
3147ec681f3Smrg    const ParamGeneratorInterface<T>* BaseGenerator() const override {
315af69d88dSmrg      return base_;
316af69d88dSmrg    }
3177ec681f3Smrg    void Advance() override {
318af69d88dSmrg      ++iterator_;
319af69d88dSmrg      value_.reset();
320af69d88dSmrg    }
3217ec681f3Smrg    ParamIteratorInterface<T>* Clone() const override {
322af69d88dSmrg      return new Iterator(*this);
323af69d88dSmrg    }
324af69d88dSmrg    // We need to use cached value referenced by iterator_ because *iterator_
325af69d88dSmrg    // can return a temporary object (and of type other then T), so just
326af69d88dSmrg    // having "return &*iterator_;" doesn't work.
327af69d88dSmrg    // value_ is updated here and not in Advance() because Advance()
328af69d88dSmrg    // can advance iterator_ beyond the end of the range, and we cannot
329af69d88dSmrg    // detect that fact. The client code, on the other hand, is
330af69d88dSmrg    // responsible for not calling Current() on an out-of-range iterator.
3317ec681f3Smrg    const T* Current() const override {
3327ec681f3Smrg      if (value_.get() == nullptr) value_.reset(new T(*iterator_));
333af69d88dSmrg      return value_.get();
334af69d88dSmrg    }
3357ec681f3Smrg    bool Equals(const ParamIteratorInterface<T>& other) const override {
336af69d88dSmrg      // Having the same base generator guarantees that the other
337af69d88dSmrg      // iterator is of the same type and we can downcast.
338af69d88dSmrg      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
339af69d88dSmrg          << "The program attempted to compare iterators "
340af69d88dSmrg          << "from different generators." << std::endl;
341af69d88dSmrg      return iterator_ ==
342af69d88dSmrg          CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
343af69d88dSmrg    }
344af69d88dSmrg
345af69d88dSmrg   private:
346af69d88dSmrg    Iterator(const Iterator& other)
347af69d88dSmrg          // The explicit constructor call suppresses a false warning
348af69d88dSmrg          // emitted by gcc when supplied with the -Wextra option.
349af69d88dSmrg        : ParamIteratorInterface<T>(),
350af69d88dSmrg          base_(other.base_),
351af69d88dSmrg          iterator_(other.iterator_) {}
352af69d88dSmrg
353af69d88dSmrg    const ParamGeneratorInterface<T>* const base_;
354af69d88dSmrg    typename ContainerType::const_iterator iterator_;
355af69d88dSmrg    // A cached value of *iterator_. We keep it here to allow access by
356af69d88dSmrg    // pointer in the wrapping iterator's operator->().
357af69d88dSmrg    // value_ needs to be mutable to be accessed in Current().
3587ec681f3Smrg    // Use of std::unique_ptr helps manage cached value's lifetime,
359af69d88dSmrg    // which is bound by the lifespan of the iterator itself.
3607ec681f3Smrg    mutable std::unique_ptr<const T> value_;
361af69d88dSmrg  };  // class ValuesInIteratorRangeGenerator::Iterator
362af69d88dSmrg
363af69d88dSmrg  // No implementation - assignment is unsupported.
364af69d88dSmrg  void operator=(const ValuesInIteratorRangeGenerator& other);
365af69d88dSmrg
366af69d88dSmrg  const ContainerType container_;
367af69d88dSmrg};  // class ValuesInIteratorRangeGenerator
368af69d88dSmrg
36901e04c3fSmrg// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
37001e04c3fSmrg//
37101e04c3fSmrg// Default parameterized test name generator, returns a string containing the
37201e04c3fSmrg// integer test parameter index.
37301e04c3fSmrgtemplate <class ParamType>
37401e04c3fSmrgstd::string DefaultParamName(const TestParamInfo<ParamType>& info) {
37501e04c3fSmrg  Message name_stream;
37601e04c3fSmrg  name_stream << info.index;
37701e04c3fSmrg  return name_stream.GetString();
37801e04c3fSmrg}
37901e04c3fSmrg
3807ec681f3Smrgtemplate <typename T = int>
3817ec681f3Smrgvoid TestNotEmpty() {
3827ec681f3Smrg  static_assert(sizeof(T) == 0, "Empty arguments are not allowed.");
38301e04c3fSmrg}
3847ec681f3Smrgtemplate <typename T = int>
3857ec681f3Smrgvoid TestNotEmpty(const T&) {}
38601e04c3fSmrg
387af69d88dSmrg// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
388af69d88dSmrg//
389af69d88dSmrg// Stores a parameter value and later creates tests parameterized with that
390af69d88dSmrg// value.
391af69d88dSmrgtemplate <class TestClass>
392af69d88dSmrgclass ParameterizedTestFactory : public TestFactoryBase {
393af69d88dSmrg public:
394af69d88dSmrg  typedef typename TestClass::ParamType ParamType;
395af69d88dSmrg  explicit ParameterizedTestFactory(ParamType parameter) :
396af69d88dSmrg      parameter_(parameter) {}
3977ec681f3Smrg  Test* CreateTest() override {
398af69d88dSmrg    TestClass::SetParam(&parameter_);
399af69d88dSmrg    return new TestClass();
400af69d88dSmrg  }
401af69d88dSmrg
402af69d88dSmrg private:
403af69d88dSmrg  const ParamType parameter_;
404af69d88dSmrg
405af69d88dSmrg  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory);
406af69d88dSmrg};
407af69d88dSmrg
408af69d88dSmrg// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
409af69d88dSmrg//
410af69d88dSmrg// TestMetaFactoryBase is a base class for meta-factories that create
411af69d88dSmrg// test factories for passing into MakeAndRegisterTestInfo function.
412af69d88dSmrgtemplate <class ParamType>
413af69d88dSmrgclass TestMetaFactoryBase {
414af69d88dSmrg public:
415af69d88dSmrg  virtual ~TestMetaFactoryBase() {}
416af69d88dSmrg
417af69d88dSmrg  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
418af69d88dSmrg};
419af69d88dSmrg
420af69d88dSmrg// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
421af69d88dSmrg//
422af69d88dSmrg// TestMetaFactory creates test factories for passing into
423af69d88dSmrg// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
424af69d88dSmrg// ownership of test factory pointer, same factory object cannot be passed
4257ec681f3Smrg// into that method twice. But ParameterizedTestSuiteInfo is going to call
426af69d88dSmrg// it for each Test/Parameter value combination. Thus it needs meta factory
427af69d88dSmrg// creator class.
4287ec681f3Smrgtemplate <class TestSuite>
429af69d88dSmrgclass TestMetaFactory
4307ec681f3Smrg    : public TestMetaFactoryBase<typename TestSuite::ParamType> {
431af69d88dSmrg public:
4327ec681f3Smrg  using ParamType = typename TestSuite::ParamType;
433af69d88dSmrg
434af69d88dSmrg  TestMetaFactory() {}
435af69d88dSmrg
4367ec681f3Smrg  TestFactoryBase* CreateTestFactory(ParamType parameter) override {
4377ec681f3Smrg    return new ParameterizedTestFactory<TestSuite>(parameter);
438af69d88dSmrg  }
439af69d88dSmrg
440af69d88dSmrg private:
441af69d88dSmrg  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory);
442af69d88dSmrg};
443af69d88dSmrg
444af69d88dSmrg// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
445af69d88dSmrg//
4467ec681f3Smrg// ParameterizedTestSuiteInfoBase is a generic interface
4477ec681f3Smrg// to ParameterizedTestSuiteInfo classes. ParameterizedTestSuiteInfoBase
448af69d88dSmrg// accumulates test information provided by TEST_P macro invocations
4497ec681f3Smrg// and generators provided by INSTANTIATE_TEST_SUITE_P macro invocations
450af69d88dSmrg// and uses that information to register all resulting test instances
4517ec681f3Smrg// in RegisterTests method. The ParameterizeTestSuiteRegistry class holds
4527ec681f3Smrg// a collection of pointers to the ParameterizedTestSuiteInfo objects
453af69d88dSmrg// and calls RegisterTests() on each of them when asked.
4547ec681f3Smrgclass ParameterizedTestSuiteInfoBase {
455af69d88dSmrg public:
4567ec681f3Smrg  virtual ~ParameterizedTestSuiteInfoBase() {}
457af69d88dSmrg
4587ec681f3Smrg  // Base part of test suite name for display purposes.
4597ec681f3Smrg  virtual const std::string& GetTestSuiteName() const = 0;
460af69d88dSmrg  // Test case id to verify identity.
4617ec681f3Smrg  virtual TypeId GetTestSuiteTypeId() const = 0;
462af69d88dSmrg  // UnitTest class invokes this method to register tests in this
4637ec681f3Smrg  // test suite right before running them in RUN_ALL_TESTS macro.
4647ec681f3Smrg  // This method should not be called more than once on any single
4657ec681f3Smrg  // instance of a ParameterizedTestSuiteInfoBase derived class.
466af69d88dSmrg  virtual void RegisterTests() = 0;
467af69d88dSmrg
468af69d88dSmrg protected:
4697ec681f3Smrg  ParameterizedTestSuiteInfoBase() {}
470af69d88dSmrg
471af69d88dSmrg private:
4727ec681f3Smrg  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfoBase);
473af69d88dSmrg};
474af69d88dSmrg
475af69d88dSmrg// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
476af69d88dSmrg//
4777ec681f3Smrg// ParameterizedTestSuiteInfo accumulates tests obtained from TEST_P
4787ec681f3Smrg// macro invocations for a particular test suite and generators
4797ec681f3Smrg// obtained from INSTANTIATE_TEST_SUITE_P macro invocations for that
4807ec681f3Smrg// test suite. It registers tests with all values generated by all
481af69d88dSmrg// generators when asked.
4827ec681f3Smrgtemplate <class TestSuite>
4837ec681f3Smrgclass ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
484af69d88dSmrg public:
485af69d88dSmrg  // ParamType and GeneratorCreationFunc are private types but are required
486af69d88dSmrg  // for declarations of public methods AddTestPattern() and
4877ec681f3Smrg  // AddTestSuiteInstantiation().
4887ec681f3Smrg  using ParamType = typename TestSuite::ParamType;
489af69d88dSmrg  // A function that returns an instance of appropriate generator type.
490af69d88dSmrg  typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
4917ec681f3Smrg  using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&);
492af69d88dSmrg
4937ec681f3Smrg  explicit ParameterizedTestSuiteInfo(const char* name,
4947ec681f3Smrg                                      CodeLocation code_location)
4957ec681f3Smrg      : test_suite_name_(name), code_location_(code_location) {}
496af69d88dSmrg
497af69d88dSmrg  // Test case base name for display purposes.
4987ec681f3Smrg  const std::string& GetTestSuiteName() const override {
4997ec681f3Smrg    return test_suite_name_;
5007ec681f3Smrg  }
501af69d88dSmrg  // Test case id to verify identity.
5027ec681f3Smrg  TypeId GetTestSuiteTypeId() const override { return GetTypeId<TestSuite>(); }
503af69d88dSmrg  // TEST_P macro uses AddTestPattern() to record information
504af69d88dSmrg  // about a single test in a LocalTestInfo structure.
5057ec681f3Smrg  // test_suite_name is the base name of the test suite (without invocation
506af69d88dSmrg  // prefix). test_base_name is the name of an individual test without
507af69d88dSmrg  // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
5087ec681f3Smrg  // test suite base name and DoBar is test base name.
5097ec681f3Smrg  void AddTestPattern(const char* test_suite_name, const char* test_base_name,
510af69d88dSmrg                      TestMetaFactoryBase<ParamType>* meta_factory) {
5117ec681f3Smrg    tests_.push_back(std::shared_ptr<TestInfo>(
5127ec681f3Smrg        new TestInfo(test_suite_name, test_base_name, meta_factory)));
513af69d88dSmrg  }
5147ec681f3Smrg  // INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information
515af69d88dSmrg  // about a generator.
5167ec681f3Smrg  int AddTestSuiteInstantiation(const std::string& instantiation_name,
5177ec681f3Smrg                                GeneratorCreationFunc* func,
5187ec681f3Smrg                                ParamNameGeneratorFunc* name_func,
5197ec681f3Smrg                                const char* file, int line) {
52001e04c3fSmrg    instantiations_.push_back(
52101e04c3fSmrg        InstantiationInfo(instantiation_name, func, name_func, file, line));
522af69d88dSmrg    return 0;  // Return value used only to run this method in namespace scope.
523af69d88dSmrg  }
5247ec681f3Smrg  // UnitTest class invokes this method to register tests in this test suite
5257ec681f3Smrg  // test suites right before running tests in RUN_ALL_TESTS macro.
5267ec681f3Smrg  // This method should not be called more than once on any single
5277ec681f3Smrg  // instance of a ParameterizedTestSuiteInfoBase derived class.
5287ec681f3Smrg  // UnitTest has a guard to prevent from calling this method more than once.
5297ec681f3Smrg  void RegisterTests() override {
530af69d88dSmrg    for (typename TestInfoContainer::iterator test_it = tests_.begin();
531af69d88dSmrg         test_it != tests_.end(); ++test_it) {
5327ec681f3Smrg      std::shared_ptr<TestInfo> test_info = *test_it;
533af69d88dSmrg      for (typename InstantiationContainer::iterator gen_it =
534af69d88dSmrg               instantiations_.begin(); gen_it != instantiations_.end();
535af69d88dSmrg               ++gen_it) {
5367ec681f3Smrg        const std::string& instantiation_name = gen_it->name;
53701e04c3fSmrg        ParamGenerator<ParamType> generator((*gen_it->generator)());
53801e04c3fSmrg        ParamNameGeneratorFunc* name_func = gen_it->name_func;
53901e04c3fSmrg        const char* file = gen_it->file;
54001e04c3fSmrg        int line = gen_it->line;
541af69d88dSmrg
5427ec681f3Smrg        std::string test_suite_name;
543af69d88dSmrg        if ( !instantiation_name.empty() )
5447ec681f3Smrg          test_suite_name = instantiation_name + "/";
5457ec681f3Smrg        test_suite_name += test_info->test_suite_base_name;
546af69d88dSmrg
54701e04c3fSmrg        size_t i = 0;
54801e04c3fSmrg        std::set<std::string> test_param_names;
549af69d88dSmrg        for (typename ParamGenerator<ParamType>::iterator param_it =
550af69d88dSmrg                 generator.begin();
551af69d88dSmrg             param_it != generator.end(); ++param_it, ++i) {
552af69d88dSmrg          Message test_name_stream;
55301e04c3fSmrg
55401e04c3fSmrg          std::string param_name = name_func(
55501e04c3fSmrg              TestParamInfo<ParamType>(*param_it, i));
55601e04c3fSmrg
55701e04c3fSmrg          GTEST_CHECK_(IsValidParamName(param_name))
55801e04c3fSmrg              << "Parameterized test name '" << param_name
55901e04c3fSmrg              << "' is invalid, in " << file
56001e04c3fSmrg              << " line " << line << std::endl;
56101e04c3fSmrg
56201e04c3fSmrg          GTEST_CHECK_(test_param_names.count(param_name) == 0)
56301e04c3fSmrg              << "Duplicate parameterized test name '" << param_name
56401e04c3fSmrg              << "', in " << file << " line " << line << std::endl;
56501e04c3fSmrg
56601e04c3fSmrg          test_param_names.insert(param_name);
56701e04c3fSmrg
5687ec681f3Smrg          if (!test_info->test_base_name.empty()) {
5697ec681f3Smrg            test_name_stream << test_info->test_base_name << "/";
5707ec681f3Smrg          }
5717ec681f3Smrg          test_name_stream << param_name;
572af69d88dSmrg          MakeAndRegisterTestInfo(
5737ec681f3Smrg              test_suite_name.c_str(), test_name_stream.GetString().c_str(),
5747ec681f3Smrg              nullptr,  // No type parameter.
5757ec681f3Smrg              PrintToString(*param_it).c_str(), code_location_,
5767ec681f3Smrg              GetTestSuiteTypeId(),
5777ec681f3Smrg              SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),
5787ec681f3Smrg              SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),
579af69d88dSmrg              test_info->test_meta_factory->CreateTestFactory(*param_it));
580af69d88dSmrg        }  // for param_it
581af69d88dSmrg      }  // for gen_it
582af69d88dSmrg    }  // for test_it
5837ec681f3Smrg  }    // RegisterTests
584af69d88dSmrg
585af69d88dSmrg private:
586af69d88dSmrg  // LocalTestInfo structure keeps information about a single test registered
587af69d88dSmrg  // with TEST_P macro.
588af69d88dSmrg  struct TestInfo {
5897ec681f3Smrg    TestInfo(const char* a_test_suite_base_name, const char* a_test_base_name,
5907ec681f3Smrg             TestMetaFactoryBase<ParamType>* a_test_meta_factory)
5917ec681f3Smrg        : test_suite_base_name(a_test_suite_base_name),
5927ec681f3Smrg          test_base_name(a_test_base_name),
5937ec681f3Smrg          test_meta_factory(a_test_meta_factory) {}
5947ec681f3Smrg
5957ec681f3Smrg    const std::string test_suite_base_name;
5967ec681f3Smrg    const std::string test_base_name;
5977ec681f3Smrg    const std::unique_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
598af69d88dSmrg  };
5997ec681f3Smrg  using TestInfoContainer = ::std::vector<std::shared_ptr<TestInfo> >;
6007ec681f3Smrg  // Records data received from INSTANTIATE_TEST_SUITE_P macros:
60101e04c3fSmrg  //  <Instantiation name, Sequence generator creation function,
60201e04c3fSmrg  //     Name generator function, Source file, Source line>
60301e04c3fSmrg  struct InstantiationInfo {
60401e04c3fSmrg      InstantiationInfo(const std::string &name_in,
60501e04c3fSmrg                        GeneratorCreationFunc* generator_in,
60601e04c3fSmrg                        ParamNameGeneratorFunc* name_func_in,
60701e04c3fSmrg                        const char* file_in,
60801e04c3fSmrg                        int line_in)
60901e04c3fSmrg          : name(name_in),
61001e04c3fSmrg            generator(generator_in),
61101e04c3fSmrg            name_func(name_func_in),
61201e04c3fSmrg            file(file_in),
61301e04c3fSmrg            line(line_in) {}
61401e04c3fSmrg
61501e04c3fSmrg      std::string name;
61601e04c3fSmrg      GeneratorCreationFunc* generator;
61701e04c3fSmrg      ParamNameGeneratorFunc* name_func;
61801e04c3fSmrg      const char* file;
61901e04c3fSmrg      int line;
62001e04c3fSmrg  };
62101e04c3fSmrg  typedef ::std::vector<InstantiationInfo> InstantiationContainer;
62201e04c3fSmrg
62301e04c3fSmrg  static bool IsValidParamName(const std::string& name) {
62401e04c3fSmrg    // Check for empty string
62501e04c3fSmrg    if (name.empty())
62601e04c3fSmrg      return false;
62701e04c3fSmrg
62801e04c3fSmrg    // Check for invalid characters
62901e04c3fSmrg    for (std::string::size_type index = 0; index < name.size(); ++index) {
63001e04c3fSmrg      if (!isalnum(name[index]) && name[index] != '_')
63101e04c3fSmrg        return false;
63201e04c3fSmrg    }
63301e04c3fSmrg
63401e04c3fSmrg    return true;
63501e04c3fSmrg  }
636af69d88dSmrg
6377ec681f3Smrg  const std::string test_suite_name_;
63801e04c3fSmrg  CodeLocation code_location_;
639af69d88dSmrg  TestInfoContainer tests_;
640af69d88dSmrg  InstantiationContainer instantiations_;
641af69d88dSmrg
6427ec681f3Smrg  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfo);
6437ec681f3Smrg};  // class ParameterizedTestSuiteInfo
6447ec681f3Smrg
6457ec681f3Smrg//  Legacy API is deprecated but still available
6467ec681f3Smrg#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
6477ec681f3Smrgtemplate <class TestCase>
6487ec681f3Smrgusing ParameterizedTestCaseInfo = ParameterizedTestSuiteInfo<TestCase>;
6497ec681f3Smrg#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
650af69d88dSmrg
651af69d88dSmrg// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
652af69d88dSmrg//
6537ec681f3Smrg// ParameterizedTestSuiteRegistry contains a map of
6547ec681f3Smrg// ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P
6557ec681f3Smrg// and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding
6567ec681f3Smrg// ParameterizedTestSuiteInfo descriptors.
6577ec681f3Smrgclass ParameterizedTestSuiteRegistry {
658af69d88dSmrg public:
6597ec681f3Smrg  ParameterizedTestSuiteRegistry() {}
6607ec681f3Smrg  ~ParameterizedTestSuiteRegistry() {
6617ec681f3Smrg    for (auto& test_suite_info : test_suite_infos_) {
6627ec681f3Smrg      delete test_suite_info;
663af69d88dSmrg    }
664af69d88dSmrg  }
665af69d88dSmrg
666af69d88dSmrg  // Looks up or creates and returns a structure containing information about
6677ec681f3Smrg  // tests and instantiations of a particular test suite.
6687ec681f3Smrg  template <class TestSuite>
6697ec681f3Smrg  ParameterizedTestSuiteInfo<TestSuite>* GetTestSuitePatternHolder(
6707ec681f3Smrg      const char* test_suite_name, CodeLocation code_location) {
6717ec681f3Smrg    ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr;
6727ec681f3Smrg    for (auto& test_suite_info : test_suite_infos_) {
6737ec681f3Smrg      if (test_suite_info->GetTestSuiteName() == test_suite_name) {
6747ec681f3Smrg        if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
675af69d88dSmrg          // Complain about incorrect usage of Google Test facilities
676af69d88dSmrg          // and terminate the program since we cannot guaranty correct
6777ec681f3Smrg          // test suite setup and tear-down in this case.
6787ec681f3Smrg          ReportInvalidTestSuiteType(test_suite_name, code_location);
679af69d88dSmrg          posix::Abort();
680af69d88dSmrg        } else {
681af69d88dSmrg          // At this point we are sure that the object we found is of the same
682af69d88dSmrg          // type we are looking for, so we downcast it to that type
683af69d88dSmrg          // without further checks.
684af69d88dSmrg          typed_test_info = CheckedDowncastToActualType<
6857ec681f3Smrg              ParameterizedTestSuiteInfo<TestSuite> >(test_suite_info);
686af69d88dSmrg        }
687af69d88dSmrg        break;
688af69d88dSmrg      }
689af69d88dSmrg    }
6907ec681f3Smrg    if (typed_test_info == nullptr) {
6917ec681f3Smrg      typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>(
6927ec681f3Smrg          test_suite_name, code_location);
6937ec681f3Smrg      test_suite_infos_.push_back(typed_test_info);
694af69d88dSmrg    }
695af69d88dSmrg    return typed_test_info;
696af69d88dSmrg  }
697af69d88dSmrg  void RegisterTests() {
6987ec681f3Smrg    for (auto& test_suite_info : test_suite_infos_) {
6997ec681f3Smrg      test_suite_info->RegisterTests();
700af69d88dSmrg    }
701af69d88dSmrg  }
7027ec681f3Smrg//  Legacy API is deprecated but still available
7037ec681f3Smrg#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
7047ec681f3Smrg  template <class TestCase>
7057ec681f3Smrg  ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
7067ec681f3Smrg      const char* test_case_name, CodeLocation code_location) {
7077ec681f3Smrg    return GetTestSuitePatternHolder<TestCase>(test_case_name, code_location);
7087ec681f3Smrg  }
7097ec681f3Smrg
7107ec681f3Smrg#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
711af69d88dSmrg
712af69d88dSmrg private:
7137ec681f3Smrg  using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;
714af69d88dSmrg
7157ec681f3Smrg  TestSuiteInfoContainer test_suite_infos_;
716af69d88dSmrg
7177ec681f3Smrg  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteRegistry);
718af69d88dSmrg};
719af69d88dSmrg
720af69d88dSmrg}  // namespace internal
721af69d88dSmrg
7227ec681f3Smrg// Forward declarations of ValuesIn(), which is implemented in
7237ec681f3Smrg// include/gtest/gtest-param-test.h.
7247ec681f3Smrgtemplate <class Container>
7257ec681f3Smrginternal::ParamGenerator<typename Container::value_type> ValuesIn(
7267ec681f3Smrg    const Container& container);
7277ec681f3Smrg
7287ec681f3Smrgnamespace internal {
7297ec681f3Smrg// Used in the Values() function to provide polymorphic capabilities.
7307ec681f3Smrg
7317ec681f3Smrgtemplate <typename... Ts>
7327ec681f3Smrgclass ValueArray {
7337ec681f3Smrg public:
7347ec681f3Smrg  ValueArray(Ts... v) : v_{std::move(v)...} {}
7357ec681f3Smrg
7367ec681f3Smrg  template <typename T>
7377ec681f3Smrg  operator ParamGenerator<T>() const {  // NOLINT
7387ec681f3Smrg    return ValuesIn(MakeVector<T>(MakeIndexSequence<sizeof...(Ts)>()));
7397ec681f3Smrg  }
7407ec681f3Smrg
7417ec681f3Smrg private:
7427ec681f3Smrg  template <typename T, size_t... I>
7437ec681f3Smrg  std::vector<T> MakeVector(IndexSequence<I...>) const {
7447ec681f3Smrg    return std::vector<T>{static_cast<T>(v_.template Get<I>())...};
7457ec681f3Smrg  }
7467ec681f3Smrg
7477ec681f3Smrg  FlatTuple<Ts...> v_;
7487ec681f3Smrg};
7497ec681f3Smrg
7507ec681f3Smrgtemplate <typename... T>
7517ec681f3Smrgclass CartesianProductGenerator
7527ec681f3Smrg    : public ParamGeneratorInterface<::std::tuple<T...>> {
7537ec681f3Smrg public:
7547ec681f3Smrg  typedef ::std::tuple<T...> ParamType;
7557ec681f3Smrg
7567ec681f3Smrg  CartesianProductGenerator(const std::tuple<ParamGenerator<T>...>& g)
7577ec681f3Smrg      : generators_(g) {}
7587ec681f3Smrg  ~CartesianProductGenerator() override {}
7597ec681f3Smrg
7607ec681f3Smrg  ParamIteratorInterface<ParamType>* Begin() const override {
7617ec681f3Smrg    return new Iterator(this, generators_, false);
7627ec681f3Smrg  }
7637ec681f3Smrg  ParamIteratorInterface<ParamType>* End() const override {
7647ec681f3Smrg    return new Iterator(this, generators_, true);
7657ec681f3Smrg  }
7667ec681f3Smrg
7677ec681f3Smrg private:
7687ec681f3Smrg  template <class I>
7697ec681f3Smrg  class IteratorImpl;
7707ec681f3Smrg  template <size_t... I>
7717ec681f3Smrg  class IteratorImpl<IndexSequence<I...>>
7727ec681f3Smrg      : public ParamIteratorInterface<ParamType> {
7737ec681f3Smrg   public:
7747ec681f3Smrg    IteratorImpl(const ParamGeneratorInterface<ParamType>* base,
7757ec681f3Smrg             const std::tuple<ParamGenerator<T>...>& generators, bool is_end)
7767ec681f3Smrg        : base_(base),
7777ec681f3Smrg          begin_(std::get<I>(generators).begin()...),
7787ec681f3Smrg          end_(std::get<I>(generators).end()...),
7797ec681f3Smrg          current_(is_end ? end_ : begin_) {
7807ec681f3Smrg      ComputeCurrentValue();
7817ec681f3Smrg    }
7827ec681f3Smrg    ~IteratorImpl() override {}
7837ec681f3Smrg
7847ec681f3Smrg    const ParamGeneratorInterface<ParamType>* BaseGenerator() const override {
7857ec681f3Smrg      return base_;
7867ec681f3Smrg    }
7877ec681f3Smrg    // Advance should not be called on beyond-of-range iterators
7887ec681f3Smrg    // so no component iterators must be beyond end of range, either.
7897ec681f3Smrg    void Advance() override {
7907ec681f3Smrg      assert(!AtEnd());
7917ec681f3Smrg      // Advance the last iterator.
7927ec681f3Smrg      ++std::get<sizeof...(T) - 1>(current_);
7937ec681f3Smrg      // if that reaches end, propagate that up.
7947ec681f3Smrg      AdvanceIfEnd<sizeof...(T) - 1>();
7957ec681f3Smrg      ComputeCurrentValue();
7967ec681f3Smrg    }
7977ec681f3Smrg    ParamIteratorInterface<ParamType>* Clone() const override {
7987ec681f3Smrg      return new IteratorImpl(*this);
7997ec681f3Smrg    }
8007ec681f3Smrg
8017ec681f3Smrg    const ParamType* Current() const override { return current_value_.get(); }
8027ec681f3Smrg
8037ec681f3Smrg    bool Equals(const ParamIteratorInterface<ParamType>& other) const override {
8047ec681f3Smrg      // Having the same base generator guarantees that the other
8057ec681f3Smrg      // iterator is of the same type and we can downcast.
8067ec681f3Smrg      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
8077ec681f3Smrg          << "The program attempted to compare iterators "
8087ec681f3Smrg          << "from different generators." << std::endl;
8097ec681f3Smrg      const IteratorImpl* typed_other =
8107ec681f3Smrg          CheckedDowncastToActualType<const IteratorImpl>(&other);
8117ec681f3Smrg
8127ec681f3Smrg      // We must report iterators equal if they both point beyond their
8137ec681f3Smrg      // respective ranges. That can happen in a variety of fashions,
8147ec681f3Smrg      // so we have to consult AtEnd().
8157ec681f3Smrg      if (AtEnd() && typed_other->AtEnd()) return true;
8167ec681f3Smrg
8177ec681f3Smrg      bool same = true;
8187ec681f3Smrg      bool dummy[] = {
8197ec681f3Smrg          (same = same && std::get<I>(current_) ==
8207ec681f3Smrg                              std::get<I>(typed_other->current_))...};
8217ec681f3Smrg      (void)dummy;
8227ec681f3Smrg      return same;
8237ec681f3Smrg    }
8247ec681f3Smrg
8257ec681f3Smrg   private:
8267ec681f3Smrg    template <size_t ThisI>
8277ec681f3Smrg    void AdvanceIfEnd() {
8287ec681f3Smrg      if (std::get<ThisI>(current_) != std::get<ThisI>(end_)) return;
8297ec681f3Smrg
8307ec681f3Smrg      bool last = ThisI == 0;
8317ec681f3Smrg      if (last) {
8327ec681f3Smrg        // We are done. Nothing else to propagate.
8337ec681f3Smrg        return;
8347ec681f3Smrg      }
8357ec681f3Smrg
8367ec681f3Smrg      constexpr size_t NextI = ThisI - (ThisI != 0);
8377ec681f3Smrg      std::get<ThisI>(current_) = std::get<ThisI>(begin_);
8387ec681f3Smrg      ++std::get<NextI>(current_);
8397ec681f3Smrg      AdvanceIfEnd<NextI>();
8407ec681f3Smrg    }
8417ec681f3Smrg
8427ec681f3Smrg    void ComputeCurrentValue() {
8437ec681f3Smrg      if (!AtEnd())
8447ec681f3Smrg        current_value_ = std::make_shared<ParamType>(*std::get<I>(current_)...);
8457ec681f3Smrg    }
8467ec681f3Smrg    bool AtEnd() const {
8477ec681f3Smrg      bool at_end = false;
8487ec681f3Smrg      bool dummy[] = {
8497ec681f3Smrg          (at_end = at_end || std::get<I>(current_) == std::get<I>(end_))...};
8507ec681f3Smrg      (void)dummy;
8517ec681f3Smrg      return at_end;
8527ec681f3Smrg    }
8537ec681f3Smrg
8547ec681f3Smrg    const ParamGeneratorInterface<ParamType>* const base_;
8557ec681f3Smrg    std::tuple<typename ParamGenerator<T>::iterator...> begin_;
8567ec681f3Smrg    std::tuple<typename ParamGenerator<T>::iterator...> end_;
8577ec681f3Smrg    std::tuple<typename ParamGenerator<T>::iterator...> current_;
8587ec681f3Smrg    std::shared_ptr<ParamType> current_value_;
8597ec681f3Smrg  };
8607ec681f3Smrg
8617ec681f3Smrg  using Iterator = IteratorImpl<typename MakeIndexSequence<sizeof...(T)>::type>;
8627ec681f3Smrg
8637ec681f3Smrg  std::tuple<ParamGenerator<T>...> generators_;
8647ec681f3Smrg};
8657ec681f3Smrg
8667ec681f3Smrgtemplate <class... Gen>
8677ec681f3Smrgclass CartesianProductHolder {
8687ec681f3Smrg public:
8697ec681f3Smrg  CartesianProductHolder(const Gen&... g) : generators_(g...) {}
8707ec681f3Smrg  template <typename... T>
8717ec681f3Smrg  operator ParamGenerator<::std::tuple<T...>>() const {
8727ec681f3Smrg    return ParamGenerator<::std::tuple<T...>>(
8737ec681f3Smrg        new CartesianProductGenerator<T...>(generators_));
8747ec681f3Smrg  }
8757ec681f3Smrg
8767ec681f3Smrg private:
8777ec681f3Smrg  std::tuple<Gen...> generators_;
8787ec681f3Smrg};
8797ec681f3Smrg
8807ec681f3Smrg}  // namespace internal
8817ec681f3Smrg}  // namespace testing
882af69d88dSmrg
883af69d88dSmrg#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
884