11cb0ef41Sopenharmony_ci// Copyright 2008 Google Inc.
21cb0ef41Sopenharmony_ci// All Rights Reserved.
31cb0ef41Sopenharmony_ci//
41cb0ef41Sopenharmony_ci// Redistribution and use in source and binary forms, with or without
51cb0ef41Sopenharmony_ci// modification, are permitted provided that the following conditions are
61cb0ef41Sopenharmony_ci// met:
71cb0ef41Sopenharmony_ci//
81cb0ef41Sopenharmony_ci//     * Redistributions of source code must retain the above copyright
91cb0ef41Sopenharmony_ci// notice, this list of conditions and the following disclaimer.
101cb0ef41Sopenharmony_ci//     * Redistributions in binary form must reproduce the above
111cb0ef41Sopenharmony_ci// copyright notice, this list of conditions and the following disclaimer
121cb0ef41Sopenharmony_ci// in the documentation and/or other materials provided with the
131cb0ef41Sopenharmony_ci// distribution.
141cb0ef41Sopenharmony_ci//     * Neither the name of Google Inc. nor the names of its
151cb0ef41Sopenharmony_ci// contributors may be used to endorse or promote products derived from
161cb0ef41Sopenharmony_ci// this software without specific prior written permission.
171cb0ef41Sopenharmony_ci//
181cb0ef41Sopenharmony_ci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
191cb0ef41Sopenharmony_ci// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
201cb0ef41Sopenharmony_ci// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
211cb0ef41Sopenharmony_ci// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
221cb0ef41Sopenharmony_ci// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
231cb0ef41Sopenharmony_ci// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
241cb0ef41Sopenharmony_ci// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
251cb0ef41Sopenharmony_ci// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
261cb0ef41Sopenharmony_ci// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
271cb0ef41Sopenharmony_ci// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
281cb0ef41Sopenharmony_ci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci// Type and function utilities for implementing parameterized tests.
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci// IWYU pragma: private, include "gtest/gtest.h"
331cb0ef41Sopenharmony_ci// IWYU pragma: friend gtest/.*
341cb0ef41Sopenharmony_ci// IWYU pragma: friend gmock/.*
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
371cb0ef41Sopenharmony_ci#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci#include <ctype.h>
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci#include <cassert>
421cb0ef41Sopenharmony_ci#include <iterator>
431cb0ef41Sopenharmony_ci#include <map>
441cb0ef41Sopenharmony_ci#include <memory>
451cb0ef41Sopenharmony_ci#include <ostream>
461cb0ef41Sopenharmony_ci#include <set>
471cb0ef41Sopenharmony_ci#include <string>
481cb0ef41Sopenharmony_ci#include <tuple>
491cb0ef41Sopenharmony_ci#include <type_traits>
501cb0ef41Sopenharmony_ci#include <utility>
511cb0ef41Sopenharmony_ci#include <vector>
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci#include "gtest/gtest-printers.h"
541cb0ef41Sopenharmony_ci#include "gtest/gtest-test-part.h"
551cb0ef41Sopenharmony_ci#include "gtest/internal/gtest-internal.h"
561cb0ef41Sopenharmony_ci#include "gtest/internal/gtest-port.h"
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_cinamespace testing {
591cb0ef41Sopenharmony_ci// Input to a parameterized test name generator, describing a test parameter.
601cb0ef41Sopenharmony_ci// Consists of the parameter value and the integer parameter index.
611cb0ef41Sopenharmony_citemplate <class ParamType>
621cb0ef41Sopenharmony_cistruct TestParamInfo {
631cb0ef41Sopenharmony_ci  TestParamInfo(const ParamType& a_param, size_t an_index)
641cb0ef41Sopenharmony_ci      : param(a_param), index(an_index) {}
651cb0ef41Sopenharmony_ci  ParamType param;
661cb0ef41Sopenharmony_ci  size_t index;
671cb0ef41Sopenharmony_ci};
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci// A builtin parameterized test name generator which returns the result of
701cb0ef41Sopenharmony_ci// testing::PrintToString.
711cb0ef41Sopenharmony_cistruct PrintToStringParamName {
721cb0ef41Sopenharmony_ci  template <class ParamType>
731cb0ef41Sopenharmony_ci  std::string operator()(const TestParamInfo<ParamType>& info) const {
741cb0ef41Sopenharmony_ci    return PrintToString(info.param);
751cb0ef41Sopenharmony_ci  }
761cb0ef41Sopenharmony_ci};
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_cinamespace internal {
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
811cb0ef41Sopenharmony_ci// Utility Functions
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ci// Outputs a message explaining invalid registration of different
841cb0ef41Sopenharmony_ci// fixture class for the same test suite. This may happen when
851cb0ef41Sopenharmony_ci// TEST_P macro is used to define two tests with the same name
861cb0ef41Sopenharmony_ci// but in different namespaces.
871cb0ef41Sopenharmony_ciGTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
881cb0ef41Sopenharmony_ci                                           CodeLocation code_location);
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_citemplate <typename>
911cb0ef41Sopenharmony_ciclass ParamGeneratorInterface;
921cb0ef41Sopenharmony_citemplate <typename>
931cb0ef41Sopenharmony_ciclass ParamGenerator;
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci// Interface for iterating over elements provided by an implementation
961cb0ef41Sopenharmony_ci// of ParamGeneratorInterface<T>.
971cb0ef41Sopenharmony_citemplate <typename T>
981cb0ef41Sopenharmony_ciclass ParamIteratorInterface {
991cb0ef41Sopenharmony_ci public:
1001cb0ef41Sopenharmony_ci  virtual ~ParamIteratorInterface() = default;
1011cb0ef41Sopenharmony_ci  // A pointer to the base generator instance.
1021cb0ef41Sopenharmony_ci  // Used only for the purposes of iterator comparison
1031cb0ef41Sopenharmony_ci  // to make sure that two iterators belong to the same generator.
1041cb0ef41Sopenharmony_ci  virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;
1051cb0ef41Sopenharmony_ci  // Advances iterator to point to the next element
1061cb0ef41Sopenharmony_ci  // provided by the generator. The caller is responsible
1071cb0ef41Sopenharmony_ci  // for not calling Advance() on an iterator equal to
1081cb0ef41Sopenharmony_ci  // BaseGenerator()->End().
1091cb0ef41Sopenharmony_ci  virtual void Advance() = 0;
1101cb0ef41Sopenharmony_ci  // Clones the iterator object. Used for implementing copy semantics
1111cb0ef41Sopenharmony_ci  // of ParamIterator<T>.
1121cb0ef41Sopenharmony_ci  virtual ParamIteratorInterface* Clone() const = 0;
1131cb0ef41Sopenharmony_ci  // Dereferences the current iterator and provides (read-only) access
1141cb0ef41Sopenharmony_ci  // to the pointed value. It is the caller's responsibility not to call
1151cb0ef41Sopenharmony_ci  // Current() on an iterator equal to BaseGenerator()->End().
1161cb0ef41Sopenharmony_ci  // Used for implementing ParamGenerator<T>::operator*().
1171cb0ef41Sopenharmony_ci  virtual const T* Current() const = 0;
1181cb0ef41Sopenharmony_ci  // Determines whether the given iterator and other point to the same
1191cb0ef41Sopenharmony_ci  // element in the sequence generated by the generator.
1201cb0ef41Sopenharmony_ci  // Used for implementing ParamGenerator<T>::operator==().
1211cb0ef41Sopenharmony_ci  virtual bool Equals(const ParamIteratorInterface& other) const = 0;
1221cb0ef41Sopenharmony_ci};
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci// Class iterating over elements provided by an implementation of
1251cb0ef41Sopenharmony_ci// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
1261cb0ef41Sopenharmony_ci// and implements the const forward iterator concept.
1271cb0ef41Sopenharmony_citemplate <typename T>
1281cb0ef41Sopenharmony_ciclass ParamIterator {
1291cb0ef41Sopenharmony_ci public:
1301cb0ef41Sopenharmony_ci  typedef T value_type;
1311cb0ef41Sopenharmony_ci  typedef const T& reference;
1321cb0ef41Sopenharmony_ci  typedef ptrdiff_t difference_type;
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ci  // ParamIterator assumes ownership of the impl_ pointer.
1351cb0ef41Sopenharmony_ci  ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
1361cb0ef41Sopenharmony_ci  ParamIterator& operator=(const ParamIterator& other) {
1371cb0ef41Sopenharmony_ci    if (this != &other) impl_.reset(other.impl_->Clone());
1381cb0ef41Sopenharmony_ci    return *this;
1391cb0ef41Sopenharmony_ci  }
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_ci  const T& operator*() const { return *impl_->Current(); }
1421cb0ef41Sopenharmony_ci  const T* operator->() const { return impl_->Current(); }
1431cb0ef41Sopenharmony_ci  // Prefix version of operator++.
1441cb0ef41Sopenharmony_ci  ParamIterator& operator++() {
1451cb0ef41Sopenharmony_ci    impl_->Advance();
1461cb0ef41Sopenharmony_ci    return *this;
1471cb0ef41Sopenharmony_ci  }
1481cb0ef41Sopenharmony_ci  // Postfix version of operator++.
1491cb0ef41Sopenharmony_ci  ParamIterator operator++(int /*unused*/) {
1501cb0ef41Sopenharmony_ci    ParamIteratorInterface<T>* clone = impl_->Clone();
1511cb0ef41Sopenharmony_ci    impl_->Advance();
1521cb0ef41Sopenharmony_ci    return ParamIterator(clone);
1531cb0ef41Sopenharmony_ci  }
1541cb0ef41Sopenharmony_ci  bool operator==(const ParamIterator& other) const {
1551cb0ef41Sopenharmony_ci    return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
1561cb0ef41Sopenharmony_ci  }
1571cb0ef41Sopenharmony_ci  bool operator!=(const ParamIterator& other) const {
1581cb0ef41Sopenharmony_ci    return !(*this == other);
1591cb0ef41Sopenharmony_ci  }
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_ci private:
1621cb0ef41Sopenharmony_ci  friend class ParamGenerator<T>;
1631cb0ef41Sopenharmony_ci  explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
1641cb0ef41Sopenharmony_ci  std::unique_ptr<ParamIteratorInterface<T>> impl_;
1651cb0ef41Sopenharmony_ci};
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ci// ParamGeneratorInterface<T> is the binary interface to access generators
1681cb0ef41Sopenharmony_ci// defined in other translation units.
1691cb0ef41Sopenharmony_citemplate <typename T>
1701cb0ef41Sopenharmony_ciclass ParamGeneratorInterface {
1711cb0ef41Sopenharmony_ci public:
1721cb0ef41Sopenharmony_ci  typedef T ParamType;
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_ci  virtual ~ParamGeneratorInterface() = default;
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ci  // Generator interface definition
1771cb0ef41Sopenharmony_ci  virtual ParamIteratorInterface<T>* Begin() const = 0;
1781cb0ef41Sopenharmony_ci  virtual ParamIteratorInterface<T>* End() const = 0;
1791cb0ef41Sopenharmony_ci};
1801cb0ef41Sopenharmony_ci
1811cb0ef41Sopenharmony_ci// Wraps ParamGeneratorInterface<T> and provides general generator syntax
1821cb0ef41Sopenharmony_ci// compatible with the STL Container concept.
1831cb0ef41Sopenharmony_ci// This class implements copy initialization semantics and the contained
1841cb0ef41Sopenharmony_ci// ParamGeneratorInterface<T> instance is shared among all copies
1851cb0ef41Sopenharmony_ci// of the original object. This is possible because that instance is immutable.
1861cb0ef41Sopenharmony_citemplate <typename T>
1871cb0ef41Sopenharmony_ciclass ParamGenerator {
1881cb0ef41Sopenharmony_ci public:
1891cb0ef41Sopenharmony_ci  typedef ParamIterator<T> iterator;
1901cb0ef41Sopenharmony_ci
1911cb0ef41Sopenharmony_ci  explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}
1921cb0ef41Sopenharmony_ci  ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}
1931cb0ef41Sopenharmony_ci
1941cb0ef41Sopenharmony_ci  ParamGenerator& operator=(const ParamGenerator& other) {
1951cb0ef41Sopenharmony_ci    impl_ = other.impl_;
1961cb0ef41Sopenharmony_ci    return *this;
1971cb0ef41Sopenharmony_ci  }
1981cb0ef41Sopenharmony_ci
1991cb0ef41Sopenharmony_ci  iterator begin() const { return iterator(impl_->Begin()); }
2001cb0ef41Sopenharmony_ci  iterator end() const { return iterator(impl_->End()); }
2011cb0ef41Sopenharmony_ci
2021cb0ef41Sopenharmony_ci private:
2031cb0ef41Sopenharmony_ci  std::shared_ptr<const ParamGeneratorInterface<T>> impl_;
2041cb0ef41Sopenharmony_ci};
2051cb0ef41Sopenharmony_ci
2061cb0ef41Sopenharmony_ci// Generates values from a range of two comparable values. Can be used to
2071cb0ef41Sopenharmony_ci// generate sequences of user-defined types that implement operator+() and
2081cb0ef41Sopenharmony_ci// operator<().
2091cb0ef41Sopenharmony_ci// This class is used in the Range() function.
2101cb0ef41Sopenharmony_citemplate <typename T, typename IncrementT>
2111cb0ef41Sopenharmony_ciclass RangeGenerator : public ParamGeneratorInterface<T> {
2121cb0ef41Sopenharmony_ci public:
2131cb0ef41Sopenharmony_ci  RangeGenerator(T begin, T end, IncrementT step)
2141cb0ef41Sopenharmony_ci      : begin_(begin),
2151cb0ef41Sopenharmony_ci        end_(end),
2161cb0ef41Sopenharmony_ci        step_(step),
2171cb0ef41Sopenharmony_ci        end_index_(CalculateEndIndex(begin, end, step)) {}
2181cb0ef41Sopenharmony_ci  ~RangeGenerator() override = default;
2191cb0ef41Sopenharmony_ci
2201cb0ef41Sopenharmony_ci  ParamIteratorInterface<T>* Begin() const override {
2211cb0ef41Sopenharmony_ci    return new Iterator(this, begin_, 0, step_);
2221cb0ef41Sopenharmony_ci  }
2231cb0ef41Sopenharmony_ci  ParamIteratorInterface<T>* End() const override {
2241cb0ef41Sopenharmony_ci    return new Iterator(this, end_, end_index_, step_);
2251cb0ef41Sopenharmony_ci  }
2261cb0ef41Sopenharmony_ci
2271cb0ef41Sopenharmony_ci private:
2281cb0ef41Sopenharmony_ci  class Iterator : public ParamIteratorInterface<T> {
2291cb0ef41Sopenharmony_ci   public:
2301cb0ef41Sopenharmony_ci    Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
2311cb0ef41Sopenharmony_ci             IncrementT step)
2321cb0ef41Sopenharmony_ci        : base_(base), value_(value), index_(index), step_(step) {}
2331cb0ef41Sopenharmony_ci    ~Iterator() override = default;
2341cb0ef41Sopenharmony_ci
2351cb0ef41Sopenharmony_ci    const ParamGeneratorInterface<T>* BaseGenerator() const override {
2361cb0ef41Sopenharmony_ci      return base_;
2371cb0ef41Sopenharmony_ci    }
2381cb0ef41Sopenharmony_ci    void Advance() override {
2391cb0ef41Sopenharmony_ci      value_ = static_cast<T>(value_ + step_);
2401cb0ef41Sopenharmony_ci      index_++;
2411cb0ef41Sopenharmony_ci    }
2421cb0ef41Sopenharmony_ci    ParamIteratorInterface<T>* Clone() const override {
2431cb0ef41Sopenharmony_ci      return new Iterator(*this);
2441cb0ef41Sopenharmony_ci    }
2451cb0ef41Sopenharmony_ci    const T* Current() const override { return &value_; }
2461cb0ef41Sopenharmony_ci    bool Equals(const ParamIteratorInterface<T>& other) const override {
2471cb0ef41Sopenharmony_ci      // Having the same base generator guarantees that the other
2481cb0ef41Sopenharmony_ci      // iterator is of the same type and we can downcast.
2491cb0ef41Sopenharmony_ci      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
2501cb0ef41Sopenharmony_ci          << "The program attempted to compare iterators "
2511cb0ef41Sopenharmony_ci          << "from different generators." << std::endl;
2521cb0ef41Sopenharmony_ci      const int other_index =
2531cb0ef41Sopenharmony_ci          CheckedDowncastToActualType<const Iterator>(&other)->index_;
2541cb0ef41Sopenharmony_ci      return index_ == other_index;
2551cb0ef41Sopenharmony_ci    }
2561cb0ef41Sopenharmony_ci
2571cb0ef41Sopenharmony_ci   private:
2581cb0ef41Sopenharmony_ci    Iterator(const Iterator& other)
2591cb0ef41Sopenharmony_ci        : ParamIteratorInterface<T>(),
2601cb0ef41Sopenharmony_ci          base_(other.base_),
2611cb0ef41Sopenharmony_ci          value_(other.value_),
2621cb0ef41Sopenharmony_ci          index_(other.index_),
2631cb0ef41Sopenharmony_ci          step_(other.step_) {}
2641cb0ef41Sopenharmony_ci
2651cb0ef41Sopenharmony_ci    // No implementation - assignment is unsupported.
2661cb0ef41Sopenharmony_ci    void operator=(const Iterator& other);
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_ci    const ParamGeneratorInterface<T>* const base_;
2691cb0ef41Sopenharmony_ci    T value_;
2701cb0ef41Sopenharmony_ci    int index_;
2711cb0ef41Sopenharmony_ci    const IncrementT step_;
2721cb0ef41Sopenharmony_ci  };  // class RangeGenerator::Iterator
2731cb0ef41Sopenharmony_ci
2741cb0ef41Sopenharmony_ci  static int CalculateEndIndex(const T& begin, const T& end,
2751cb0ef41Sopenharmony_ci                               const IncrementT& step) {
2761cb0ef41Sopenharmony_ci    int end_index = 0;
2771cb0ef41Sopenharmony_ci    for (T i = begin; i < end; i = static_cast<T>(i + step)) end_index++;
2781cb0ef41Sopenharmony_ci    return end_index;
2791cb0ef41Sopenharmony_ci  }
2801cb0ef41Sopenharmony_ci
2811cb0ef41Sopenharmony_ci  // No implementation - assignment is unsupported.
2821cb0ef41Sopenharmony_ci  void operator=(const RangeGenerator& other);
2831cb0ef41Sopenharmony_ci
2841cb0ef41Sopenharmony_ci  const T begin_;
2851cb0ef41Sopenharmony_ci  const T end_;
2861cb0ef41Sopenharmony_ci  const IncrementT step_;
2871cb0ef41Sopenharmony_ci  // The index for the end() iterator. All the elements in the generated
2881cb0ef41Sopenharmony_ci  // sequence are indexed (0-based) to aid iterator comparison.
2891cb0ef41Sopenharmony_ci  const int end_index_;
2901cb0ef41Sopenharmony_ci};  // class RangeGenerator
2911cb0ef41Sopenharmony_ci
2921cb0ef41Sopenharmony_ci// Generates values from a pair of STL-style iterators. Used in the
2931cb0ef41Sopenharmony_ci// ValuesIn() function. The elements are copied from the source range
2941cb0ef41Sopenharmony_ci// since the source can be located on the stack, and the generator
2951cb0ef41Sopenharmony_ci// is likely to persist beyond that stack frame.
2961cb0ef41Sopenharmony_citemplate <typename T>
2971cb0ef41Sopenharmony_ciclass ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
2981cb0ef41Sopenharmony_ci public:
2991cb0ef41Sopenharmony_ci  template <typename ForwardIterator>
3001cb0ef41Sopenharmony_ci  ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
3011cb0ef41Sopenharmony_ci      : container_(begin, end) {}
3021cb0ef41Sopenharmony_ci  ~ValuesInIteratorRangeGenerator() override = default;
3031cb0ef41Sopenharmony_ci
3041cb0ef41Sopenharmony_ci  ParamIteratorInterface<T>* Begin() const override {
3051cb0ef41Sopenharmony_ci    return new Iterator(this, container_.begin());
3061cb0ef41Sopenharmony_ci  }
3071cb0ef41Sopenharmony_ci  ParamIteratorInterface<T>* End() const override {
3081cb0ef41Sopenharmony_ci    return new Iterator(this, container_.end());
3091cb0ef41Sopenharmony_ci  }
3101cb0ef41Sopenharmony_ci
3111cb0ef41Sopenharmony_ci private:
3121cb0ef41Sopenharmony_ci  typedef typename ::std::vector<T> ContainerType;
3131cb0ef41Sopenharmony_ci
3141cb0ef41Sopenharmony_ci  class Iterator : public ParamIteratorInterface<T> {
3151cb0ef41Sopenharmony_ci   public:
3161cb0ef41Sopenharmony_ci    Iterator(const ParamGeneratorInterface<T>* base,
3171cb0ef41Sopenharmony_ci             typename ContainerType::const_iterator iterator)
3181cb0ef41Sopenharmony_ci        : base_(base), iterator_(iterator) {}
3191cb0ef41Sopenharmony_ci    ~Iterator() override = default;
3201cb0ef41Sopenharmony_ci
3211cb0ef41Sopenharmony_ci    const ParamGeneratorInterface<T>* BaseGenerator() const override {
3221cb0ef41Sopenharmony_ci      return base_;
3231cb0ef41Sopenharmony_ci    }
3241cb0ef41Sopenharmony_ci    void Advance() override {
3251cb0ef41Sopenharmony_ci      ++iterator_;
3261cb0ef41Sopenharmony_ci      value_.reset();
3271cb0ef41Sopenharmony_ci    }
3281cb0ef41Sopenharmony_ci    ParamIteratorInterface<T>* Clone() const override {
3291cb0ef41Sopenharmony_ci      return new Iterator(*this);
3301cb0ef41Sopenharmony_ci    }
3311cb0ef41Sopenharmony_ci    // We need to use cached value referenced by iterator_ because *iterator_
3321cb0ef41Sopenharmony_ci    // can return a temporary object (and of type other then T), so just
3331cb0ef41Sopenharmony_ci    // having "return &*iterator_;" doesn't work.
3341cb0ef41Sopenharmony_ci    // value_ is updated here and not in Advance() because Advance()
3351cb0ef41Sopenharmony_ci    // can advance iterator_ beyond the end of the range, and we cannot
3361cb0ef41Sopenharmony_ci    // detect that fact. The client code, on the other hand, is
3371cb0ef41Sopenharmony_ci    // responsible for not calling Current() on an out-of-range iterator.
3381cb0ef41Sopenharmony_ci    const T* Current() const override {
3391cb0ef41Sopenharmony_ci      if (value_.get() == nullptr) value_.reset(new T(*iterator_));
3401cb0ef41Sopenharmony_ci      return value_.get();
3411cb0ef41Sopenharmony_ci    }
3421cb0ef41Sopenharmony_ci    bool Equals(const ParamIteratorInterface<T>& other) const override {
3431cb0ef41Sopenharmony_ci      // Having the same base generator guarantees that the other
3441cb0ef41Sopenharmony_ci      // iterator is of the same type and we can downcast.
3451cb0ef41Sopenharmony_ci      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
3461cb0ef41Sopenharmony_ci          << "The program attempted to compare iterators "
3471cb0ef41Sopenharmony_ci          << "from different generators." << std::endl;
3481cb0ef41Sopenharmony_ci      return iterator_ ==
3491cb0ef41Sopenharmony_ci             CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
3501cb0ef41Sopenharmony_ci    }
3511cb0ef41Sopenharmony_ci
3521cb0ef41Sopenharmony_ci   private:
3531cb0ef41Sopenharmony_ci    Iterator(const Iterator& other)
3541cb0ef41Sopenharmony_ci        // The explicit constructor call suppresses a false warning
3551cb0ef41Sopenharmony_ci        // emitted by gcc when supplied with the -Wextra option.
3561cb0ef41Sopenharmony_ci        : ParamIteratorInterface<T>(),
3571cb0ef41Sopenharmony_ci          base_(other.base_),
3581cb0ef41Sopenharmony_ci          iterator_(other.iterator_) {}
3591cb0ef41Sopenharmony_ci
3601cb0ef41Sopenharmony_ci    const ParamGeneratorInterface<T>* const base_;
3611cb0ef41Sopenharmony_ci    typename ContainerType::const_iterator iterator_;
3621cb0ef41Sopenharmony_ci    // A cached value of *iterator_. We keep it here to allow access by
3631cb0ef41Sopenharmony_ci    // pointer in the wrapping iterator's operator->().
3641cb0ef41Sopenharmony_ci    // value_ needs to be mutable to be accessed in Current().
3651cb0ef41Sopenharmony_ci    // Use of std::unique_ptr helps manage cached value's lifetime,
3661cb0ef41Sopenharmony_ci    // which is bound by the lifespan of the iterator itself.
3671cb0ef41Sopenharmony_ci    mutable std::unique_ptr<const T> value_;
3681cb0ef41Sopenharmony_ci  };  // class ValuesInIteratorRangeGenerator::Iterator
3691cb0ef41Sopenharmony_ci
3701cb0ef41Sopenharmony_ci  // No implementation - assignment is unsupported.
3711cb0ef41Sopenharmony_ci  void operator=(const ValuesInIteratorRangeGenerator& other);
3721cb0ef41Sopenharmony_ci
3731cb0ef41Sopenharmony_ci  const ContainerType container_;
3741cb0ef41Sopenharmony_ci};  // class ValuesInIteratorRangeGenerator
3751cb0ef41Sopenharmony_ci
3761cb0ef41Sopenharmony_ci// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
3771cb0ef41Sopenharmony_ci//
3781cb0ef41Sopenharmony_ci// Default parameterized test name generator, returns a string containing the
3791cb0ef41Sopenharmony_ci// integer test parameter index.
3801cb0ef41Sopenharmony_citemplate <class ParamType>
3811cb0ef41Sopenharmony_cistd::string DefaultParamName(const TestParamInfo<ParamType>& info) {
3821cb0ef41Sopenharmony_ci  Message name_stream;
3831cb0ef41Sopenharmony_ci  name_stream << info.index;
3841cb0ef41Sopenharmony_ci  return name_stream.GetString();
3851cb0ef41Sopenharmony_ci}
3861cb0ef41Sopenharmony_ci
3871cb0ef41Sopenharmony_citemplate <typename T = int>
3881cb0ef41Sopenharmony_civoid TestNotEmpty() {
3891cb0ef41Sopenharmony_ci  static_assert(sizeof(T) == 0, "Empty arguments are not allowed.");
3901cb0ef41Sopenharmony_ci}
3911cb0ef41Sopenharmony_citemplate <typename T = int>
3921cb0ef41Sopenharmony_civoid TestNotEmpty(const T&) {}
3931cb0ef41Sopenharmony_ci
3941cb0ef41Sopenharmony_ci// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
3951cb0ef41Sopenharmony_ci//
3961cb0ef41Sopenharmony_ci// Stores a parameter value and later creates tests parameterized with that
3971cb0ef41Sopenharmony_ci// value.
3981cb0ef41Sopenharmony_citemplate <class TestClass>
3991cb0ef41Sopenharmony_ciclass ParameterizedTestFactory : public TestFactoryBase {
4001cb0ef41Sopenharmony_ci public:
4011cb0ef41Sopenharmony_ci  typedef typename TestClass::ParamType ParamType;
4021cb0ef41Sopenharmony_ci  explicit ParameterizedTestFactory(ParamType parameter)
4031cb0ef41Sopenharmony_ci      : parameter_(parameter) {}
4041cb0ef41Sopenharmony_ci  Test* CreateTest() override {
4051cb0ef41Sopenharmony_ci    TestClass::SetParam(&parameter_);
4061cb0ef41Sopenharmony_ci    return new TestClass();
4071cb0ef41Sopenharmony_ci  }
4081cb0ef41Sopenharmony_ci
4091cb0ef41Sopenharmony_ci private:
4101cb0ef41Sopenharmony_ci  const ParamType parameter_;
4111cb0ef41Sopenharmony_ci
4121cb0ef41Sopenharmony_ci  ParameterizedTestFactory(const ParameterizedTestFactory&) = delete;
4131cb0ef41Sopenharmony_ci  ParameterizedTestFactory& operator=(const ParameterizedTestFactory&) = delete;
4141cb0ef41Sopenharmony_ci};
4151cb0ef41Sopenharmony_ci
4161cb0ef41Sopenharmony_ci// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
4171cb0ef41Sopenharmony_ci//
4181cb0ef41Sopenharmony_ci// TestMetaFactoryBase is a base class for meta-factories that create
4191cb0ef41Sopenharmony_ci// test factories for passing into MakeAndRegisterTestInfo function.
4201cb0ef41Sopenharmony_citemplate <class ParamType>
4211cb0ef41Sopenharmony_ciclass TestMetaFactoryBase {
4221cb0ef41Sopenharmony_ci public:
4231cb0ef41Sopenharmony_ci  virtual ~TestMetaFactoryBase() = default;
4241cb0ef41Sopenharmony_ci
4251cb0ef41Sopenharmony_ci  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
4261cb0ef41Sopenharmony_ci};
4271cb0ef41Sopenharmony_ci
4281cb0ef41Sopenharmony_ci// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
4291cb0ef41Sopenharmony_ci//
4301cb0ef41Sopenharmony_ci// TestMetaFactory creates test factories for passing into
4311cb0ef41Sopenharmony_ci// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
4321cb0ef41Sopenharmony_ci// ownership of test factory pointer, same factory object cannot be passed
4331cb0ef41Sopenharmony_ci// into that method twice. But ParameterizedTestSuiteInfo is going to call
4341cb0ef41Sopenharmony_ci// it for each Test/Parameter value combination. Thus it needs meta factory
4351cb0ef41Sopenharmony_ci// creator class.
4361cb0ef41Sopenharmony_citemplate <class TestSuite>
4371cb0ef41Sopenharmony_ciclass TestMetaFactory
4381cb0ef41Sopenharmony_ci    : public TestMetaFactoryBase<typename TestSuite::ParamType> {
4391cb0ef41Sopenharmony_ci public:
4401cb0ef41Sopenharmony_ci  using ParamType = typename TestSuite::ParamType;
4411cb0ef41Sopenharmony_ci
4421cb0ef41Sopenharmony_ci  TestMetaFactory() = default;
4431cb0ef41Sopenharmony_ci
4441cb0ef41Sopenharmony_ci  TestFactoryBase* CreateTestFactory(ParamType parameter) override {
4451cb0ef41Sopenharmony_ci    return new ParameterizedTestFactory<TestSuite>(parameter);
4461cb0ef41Sopenharmony_ci  }
4471cb0ef41Sopenharmony_ci
4481cb0ef41Sopenharmony_ci private:
4491cb0ef41Sopenharmony_ci  TestMetaFactory(const TestMetaFactory&) = delete;
4501cb0ef41Sopenharmony_ci  TestMetaFactory& operator=(const TestMetaFactory&) = delete;
4511cb0ef41Sopenharmony_ci};
4521cb0ef41Sopenharmony_ci
4531cb0ef41Sopenharmony_ci// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
4541cb0ef41Sopenharmony_ci//
4551cb0ef41Sopenharmony_ci// ParameterizedTestSuiteInfoBase is a generic interface
4561cb0ef41Sopenharmony_ci// to ParameterizedTestSuiteInfo classes. ParameterizedTestSuiteInfoBase
4571cb0ef41Sopenharmony_ci// accumulates test information provided by TEST_P macro invocations
4581cb0ef41Sopenharmony_ci// and generators provided by INSTANTIATE_TEST_SUITE_P macro invocations
4591cb0ef41Sopenharmony_ci// and uses that information to register all resulting test instances
4601cb0ef41Sopenharmony_ci// in RegisterTests method. The ParameterizeTestSuiteRegistry class holds
4611cb0ef41Sopenharmony_ci// a collection of pointers to the ParameterizedTestSuiteInfo objects
4621cb0ef41Sopenharmony_ci// and calls RegisterTests() on each of them when asked.
4631cb0ef41Sopenharmony_ciclass ParameterizedTestSuiteInfoBase {
4641cb0ef41Sopenharmony_ci public:
4651cb0ef41Sopenharmony_ci  virtual ~ParameterizedTestSuiteInfoBase() = default;
4661cb0ef41Sopenharmony_ci
4671cb0ef41Sopenharmony_ci  // Base part of test suite name for display purposes.
4681cb0ef41Sopenharmony_ci  virtual const std::string& GetTestSuiteName() const = 0;
4691cb0ef41Sopenharmony_ci  // Test suite id to verify identity.
4701cb0ef41Sopenharmony_ci  virtual TypeId GetTestSuiteTypeId() const = 0;
4711cb0ef41Sopenharmony_ci  // UnitTest class invokes this method to register tests in this
4721cb0ef41Sopenharmony_ci  // test suite right before running them in RUN_ALL_TESTS macro.
4731cb0ef41Sopenharmony_ci  // This method should not be called more than once on any single
4741cb0ef41Sopenharmony_ci  // instance of a ParameterizedTestSuiteInfoBase derived class.
4751cb0ef41Sopenharmony_ci  virtual void RegisterTests() = 0;
4761cb0ef41Sopenharmony_ci
4771cb0ef41Sopenharmony_ci protected:
4781cb0ef41Sopenharmony_ci  ParameterizedTestSuiteInfoBase() {}
4791cb0ef41Sopenharmony_ci
4801cb0ef41Sopenharmony_ci private:
4811cb0ef41Sopenharmony_ci  ParameterizedTestSuiteInfoBase(const ParameterizedTestSuiteInfoBase&) =
4821cb0ef41Sopenharmony_ci      delete;
4831cb0ef41Sopenharmony_ci  ParameterizedTestSuiteInfoBase& operator=(
4841cb0ef41Sopenharmony_ci      const ParameterizedTestSuiteInfoBase&) = delete;
4851cb0ef41Sopenharmony_ci};
4861cb0ef41Sopenharmony_ci
4871cb0ef41Sopenharmony_ci// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
4881cb0ef41Sopenharmony_ci//
4891cb0ef41Sopenharmony_ci// Report a the name of a test_suit as safe to ignore
4901cb0ef41Sopenharmony_ci// as the side effect of construction of this type.
4911cb0ef41Sopenharmony_cistruct GTEST_API_ MarkAsIgnored {
4921cb0ef41Sopenharmony_ci  explicit MarkAsIgnored(const char* test_suite);
4931cb0ef41Sopenharmony_ci};
4941cb0ef41Sopenharmony_ci
4951cb0ef41Sopenharmony_ciGTEST_API_ void InsertSyntheticTestCase(const std::string& name,
4961cb0ef41Sopenharmony_ci                                        CodeLocation location, bool has_test_p);
4971cb0ef41Sopenharmony_ci
4981cb0ef41Sopenharmony_ci// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
4991cb0ef41Sopenharmony_ci//
5001cb0ef41Sopenharmony_ci// ParameterizedTestSuiteInfo accumulates tests obtained from TEST_P
5011cb0ef41Sopenharmony_ci// macro invocations for a particular test suite and generators
5021cb0ef41Sopenharmony_ci// obtained from INSTANTIATE_TEST_SUITE_P macro invocations for that
5031cb0ef41Sopenharmony_ci// test suite. It registers tests with all values generated by all
5041cb0ef41Sopenharmony_ci// generators when asked.
5051cb0ef41Sopenharmony_citemplate <class TestSuite>
5061cb0ef41Sopenharmony_ciclass ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
5071cb0ef41Sopenharmony_ci public:
5081cb0ef41Sopenharmony_ci  // ParamType and GeneratorCreationFunc are private types but are required
5091cb0ef41Sopenharmony_ci  // for declarations of public methods AddTestPattern() and
5101cb0ef41Sopenharmony_ci  // AddTestSuiteInstantiation().
5111cb0ef41Sopenharmony_ci  using ParamType = typename TestSuite::ParamType;
5121cb0ef41Sopenharmony_ci  // A function that returns an instance of appropriate generator type.
5131cb0ef41Sopenharmony_ci  typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
5141cb0ef41Sopenharmony_ci  using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&);
5151cb0ef41Sopenharmony_ci
5161cb0ef41Sopenharmony_ci  explicit ParameterizedTestSuiteInfo(const char* name,
5171cb0ef41Sopenharmony_ci                                      CodeLocation code_location)
5181cb0ef41Sopenharmony_ci      : test_suite_name_(name), code_location_(code_location) {}
5191cb0ef41Sopenharmony_ci
5201cb0ef41Sopenharmony_ci  // Test suite base name for display purposes.
5211cb0ef41Sopenharmony_ci  const std::string& GetTestSuiteName() const override {
5221cb0ef41Sopenharmony_ci    return test_suite_name_;
5231cb0ef41Sopenharmony_ci  }
5241cb0ef41Sopenharmony_ci  // Test suite id to verify identity.
5251cb0ef41Sopenharmony_ci  TypeId GetTestSuiteTypeId() const override { return GetTypeId<TestSuite>(); }
5261cb0ef41Sopenharmony_ci  // TEST_P macro uses AddTestPattern() to record information
5271cb0ef41Sopenharmony_ci  // about a single test in a LocalTestInfo structure.
5281cb0ef41Sopenharmony_ci  // test_suite_name is the base name of the test suite (without invocation
5291cb0ef41Sopenharmony_ci  // prefix). test_base_name is the name of an individual test without
5301cb0ef41Sopenharmony_ci  // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
5311cb0ef41Sopenharmony_ci  // test suite base name and DoBar is test base name.
5321cb0ef41Sopenharmony_ci  void AddTestPattern(const char* test_suite_name, const char* test_base_name,
5331cb0ef41Sopenharmony_ci                      TestMetaFactoryBase<ParamType>* meta_factory,
5341cb0ef41Sopenharmony_ci                      CodeLocation code_location) {
5351cb0ef41Sopenharmony_ci    tests_.push_back(std::shared_ptr<TestInfo>(new TestInfo(
5361cb0ef41Sopenharmony_ci        test_suite_name, test_base_name, meta_factory, code_location)));
5371cb0ef41Sopenharmony_ci  }
5381cb0ef41Sopenharmony_ci  // INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information
5391cb0ef41Sopenharmony_ci  // about a generator.
5401cb0ef41Sopenharmony_ci  int AddTestSuiteInstantiation(const std::string& instantiation_name,
5411cb0ef41Sopenharmony_ci                                GeneratorCreationFunc* func,
5421cb0ef41Sopenharmony_ci                                ParamNameGeneratorFunc* name_func,
5431cb0ef41Sopenharmony_ci                                const char* file, int line) {
5441cb0ef41Sopenharmony_ci    instantiations_.push_back(
5451cb0ef41Sopenharmony_ci        InstantiationInfo(instantiation_name, func, name_func, file, line));
5461cb0ef41Sopenharmony_ci    return 0;  // Return value used only to run this method in namespace scope.
5471cb0ef41Sopenharmony_ci  }
5481cb0ef41Sopenharmony_ci  // UnitTest class invokes this method to register tests in this test suite
5491cb0ef41Sopenharmony_ci  // right before running tests in RUN_ALL_TESTS macro.
5501cb0ef41Sopenharmony_ci  // This method should not be called more than once on any single
5511cb0ef41Sopenharmony_ci  // instance of a ParameterizedTestSuiteInfoBase derived class.
5521cb0ef41Sopenharmony_ci  // UnitTest has a guard to prevent from calling this method more than once.
5531cb0ef41Sopenharmony_ci  void RegisterTests() override {
5541cb0ef41Sopenharmony_ci    bool generated_instantiations = false;
5551cb0ef41Sopenharmony_ci
5561cb0ef41Sopenharmony_ci    for (typename TestInfoContainer::iterator test_it = tests_.begin();
5571cb0ef41Sopenharmony_ci         test_it != tests_.end(); ++test_it) {
5581cb0ef41Sopenharmony_ci      std::shared_ptr<TestInfo> test_info = *test_it;
5591cb0ef41Sopenharmony_ci      for (typename InstantiationContainer::iterator gen_it =
5601cb0ef41Sopenharmony_ci               instantiations_.begin();
5611cb0ef41Sopenharmony_ci           gen_it != instantiations_.end(); ++gen_it) {
5621cb0ef41Sopenharmony_ci        const std::string& instantiation_name = gen_it->name;
5631cb0ef41Sopenharmony_ci        ParamGenerator<ParamType> generator((*gen_it->generator)());
5641cb0ef41Sopenharmony_ci        ParamNameGeneratorFunc* name_func = gen_it->name_func;
5651cb0ef41Sopenharmony_ci        const char* file = gen_it->file;
5661cb0ef41Sopenharmony_ci        int line = gen_it->line;
5671cb0ef41Sopenharmony_ci
5681cb0ef41Sopenharmony_ci        std::string test_suite_name;
5691cb0ef41Sopenharmony_ci        if (!instantiation_name.empty())
5701cb0ef41Sopenharmony_ci          test_suite_name = instantiation_name + "/";
5711cb0ef41Sopenharmony_ci        test_suite_name += test_info->test_suite_base_name;
5721cb0ef41Sopenharmony_ci
5731cb0ef41Sopenharmony_ci        size_t i = 0;
5741cb0ef41Sopenharmony_ci        std::set<std::string> test_param_names;
5751cb0ef41Sopenharmony_ci        for (typename ParamGenerator<ParamType>::iterator param_it =
5761cb0ef41Sopenharmony_ci                 generator.begin();
5771cb0ef41Sopenharmony_ci             param_it != generator.end(); ++param_it, ++i) {
5781cb0ef41Sopenharmony_ci          generated_instantiations = true;
5791cb0ef41Sopenharmony_ci
5801cb0ef41Sopenharmony_ci          Message test_name_stream;
5811cb0ef41Sopenharmony_ci
5821cb0ef41Sopenharmony_ci          std::string param_name =
5831cb0ef41Sopenharmony_ci              name_func(TestParamInfo<ParamType>(*param_it, i));
5841cb0ef41Sopenharmony_ci
5851cb0ef41Sopenharmony_ci          GTEST_CHECK_(IsValidParamName(param_name))
5861cb0ef41Sopenharmony_ci              << "Parameterized test name '" << param_name
5871cb0ef41Sopenharmony_ci              << "' is invalid (contains spaces, dashes, underscores, or "
5881cb0ef41Sopenharmony_ci                 "non-alphanumeric characters), in "
5891cb0ef41Sopenharmony_ci              << file << " line " << line << "" << std::endl;
5901cb0ef41Sopenharmony_ci
5911cb0ef41Sopenharmony_ci          GTEST_CHECK_(test_param_names.count(param_name) == 0)
5921cb0ef41Sopenharmony_ci              << "Duplicate parameterized test name '" << param_name << "', in "
5931cb0ef41Sopenharmony_ci              << file << " line " << line << std::endl;
5941cb0ef41Sopenharmony_ci
5951cb0ef41Sopenharmony_ci          test_param_names.insert(param_name);
5961cb0ef41Sopenharmony_ci
5971cb0ef41Sopenharmony_ci          if (!test_info->test_base_name.empty()) {
5981cb0ef41Sopenharmony_ci            test_name_stream << test_info->test_base_name << "/";
5991cb0ef41Sopenharmony_ci          }
6001cb0ef41Sopenharmony_ci          test_name_stream << param_name;
6011cb0ef41Sopenharmony_ci          MakeAndRegisterTestInfo(
6021cb0ef41Sopenharmony_ci              test_suite_name.c_str(), test_name_stream.GetString().c_str(),
6031cb0ef41Sopenharmony_ci              nullptr,  // No type parameter.
6041cb0ef41Sopenharmony_ci              PrintToString(*param_it).c_str(), test_info->code_location,
6051cb0ef41Sopenharmony_ci              GetTestSuiteTypeId(),
6061cb0ef41Sopenharmony_ci              SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),
6071cb0ef41Sopenharmony_ci              SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),
6081cb0ef41Sopenharmony_ci              test_info->test_meta_factory->CreateTestFactory(*param_it));
6091cb0ef41Sopenharmony_ci        }  // for param_it
6101cb0ef41Sopenharmony_ci      }    // for gen_it
6111cb0ef41Sopenharmony_ci    }      // for test_it
6121cb0ef41Sopenharmony_ci
6131cb0ef41Sopenharmony_ci    if (!generated_instantiations) {
6141cb0ef41Sopenharmony_ci      // There are no generaotrs, or they all generate nothing ...
6151cb0ef41Sopenharmony_ci      InsertSyntheticTestCase(GetTestSuiteName(), code_location_,
6161cb0ef41Sopenharmony_ci                              !tests_.empty());
6171cb0ef41Sopenharmony_ci    }
6181cb0ef41Sopenharmony_ci  }  // RegisterTests
6191cb0ef41Sopenharmony_ci
6201cb0ef41Sopenharmony_ci private:
6211cb0ef41Sopenharmony_ci  // LocalTestInfo structure keeps information about a single test registered
6221cb0ef41Sopenharmony_ci  // with TEST_P macro.
6231cb0ef41Sopenharmony_ci  struct TestInfo {
6241cb0ef41Sopenharmony_ci    TestInfo(const char* a_test_suite_base_name, const char* a_test_base_name,
6251cb0ef41Sopenharmony_ci             TestMetaFactoryBase<ParamType>* a_test_meta_factory,
6261cb0ef41Sopenharmony_ci             CodeLocation a_code_location)
6271cb0ef41Sopenharmony_ci        : test_suite_base_name(a_test_suite_base_name),
6281cb0ef41Sopenharmony_ci          test_base_name(a_test_base_name),
6291cb0ef41Sopenharmony_ci          test_meta_factory(a_test_meta_factory),
6301cb0ef41Sopenharmony_ci          code_location(a_code_location) {}
6311cb0ef41Sopenharmony_ci
6321cb0ef41Sopenharmony_ci    const std::string test_suite_base_name;
6331cb0ef41Sopenharmony_ci    const std::string test_base_name;
6341cb0ef41Sopenharmony_ci    const std::unique_ptr<TestMetaFactoryBase<ParamType>> test_meta_factory;
6351cb0ef41Sopenharmony_ci    const CodeLocation code_location;
6361cb0ef41Sopenharmony_ci  };
6371cb0ef41Sopenharmony_ci  using TestInfoContainer = ::std::vector<std::shared_ptr<TestInfo>>;
6381cb0ef41Sopenharmony_ci  // Records data received from INSTANTIATE_TEST_SUITE_P macros:
6391cb0ef41Sopenharmony_ci  //  <Instantiation name, Sequence generator creation function,
6401cb0ef41Sopenharmony_ci  //     Name generator function, Source file, Source line>
6411cb0ef41Sopenharmony_ci  struct InstantiationInfo {
6421cb0ef41Sopenharmony_ci    InstantiationInfo(const std::string& name_in,
6431cb0ef41Sopenharmony_ci                      GeneratorCreationFunc* generator_in,
6441cb0ef41Sopenharmony_ci                      ParamNameGeneratorFunc* name_func_in, const char* file_in,
6451cb0ef41Sopenharmony_ci                      int line_in)
6461cb0ef41Sopenharmony_ci        : name(name_in),
6471cb0ef41Sopenharmony_ci          generator(generator_in),
6481cb0ef41Sopenharmony_ci          name_func(name_func_in),
6491cb0ef41Sopenharmony_ci          file(file_in),
6501cb0ef41Sopenharmony_ci          line(line_in) {}
6511cb0ef41Sopenharmony_ci
6521cb0ef41Sopenharmony_ci    std::string name;
6531cb0ef41Sopenharmony_ci    GeneratorCreationFunc* generator;
6541cb0ef41Sopenharmony_ci    ParamNameGeneratorFunc* name_func;
6551cb0ef41Sopenharmony_ci    const char* file;
6561cb0ef41Sopenharmony_ci    int line;
6571cb0ef41Sopenharmony_ci  };
6581cb0ef41Sopenharmony_ci  typedef ::std::vector<InstantiationInfo> InstantiationContainer;
6591cb0ef41Sopenharmony_ci
6601cb0ef41Sopenharmony_ci  static bool IsValidParamName(const std::string& name) {
6611cb0ef41Sopenharmony_ci    // Check for empty string
6621cb0ef41Sopenharmony_ci    if (name.empty()) return false;
6631cb0ef41Sopenharmony_ci
6641cb0ef41Sopenharmony_ci    // Check for invalid characters
6651cb0ef41Sopenharmony_ci    for (std::string::size_type index = 0; index < name.size(); ++index) {
6661cb0ef41Sopenharmony_ci      if (!IsAlNum(name[index]) && name[index] != '_') return false;
6671cb0ef41Sopenharmony_ci    }
6681cb0ef41Sopenharmony_ci
6691cb0ef41Sopenharmony_ci    return true;
6701cb0ef41Sopenharmony_ci  }
6711cb0ef41Sopenharmony_ci
6721cb0ef41Sopenharmony_ci  const std::string test_suite_name_;
6731cb0ef41Sopenharmony_ci  CodeLocation code_location_;
6741cb0ef41Sopenharmony_ci  TestInfoContainer tests_;
6751cb0ef41Sopenharmony_ci  InstantiationContainer instantiations_;
6761cb0ef41Sopenharmony_ci
6771cb0ef41Sopenharmony_ci  ParameterizedTestSuiteInfo(const ParameterizedTestSuiteInfo&) = delete;
6781cb0ef41Sopenharmony_ci  ParameterizedTestSuiteInfo& operator=(const ParameterizedTestSuiteInfo&) =
6791cb0ef41Sopenharmony_ci      delete;
6801cb0ef41Sopenharmony_ci};  // class ParameterizedTestSuiteInfo
6811cb0ef41Sopenharmony_ci
6821cb0ef41Sopenharmony_ci//  Legacy API is deprecated but still available
6831cb0ef41Sopenharmony_ci#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
6841cb0ef41Sopenharmony_citemplate <class TestCase>
6851cb0ef41Sopenharmony_ciusing ParameterizedTestCaseInfo = ParameterizedTestSuiteInfo<TestCase>;
6861cb0ef41Sopenharmony_ci#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
6871cb0ef41Sopenharmony_ci
6881cb0ef41Sopenharmony_ci// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
6891cb0ef41Sopenharmony_ci//
6901cb0ef41Sopenharmony_ci// ParameterizedTestSuiteRegistry contains a map of
6911cb0ef41Sopenharmony_ci// ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P
6921cb0ef41Sopenharmony_ci// and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding
6931cb0ef41Sopenharmony_ci// ParameterizedTestSuiteInfo descriptors.
6941cb0ef41Sopenharmony_ciclass ParameterizedTestSuiteRegistry {
6951cb0ef41Sopenharmony_ci public:
6961cb0ef41Sopenharmony_ci  ParameterizedTestSuiteRegistry() = default;
6971cb0ef41Sopenharmony_ci  ~ParameterizedTestSuiteRegistry() {
6981cb0ef41Sopenharmony_ci    for (auto& test_suite_info : test_suite_infos_) {
6991cb0ef41Sopenharmony_ci      delete test_suite_info;
7001cb0ef41Sopenharmony_ci    }
7011cb0ef41Sopenharmony_ci  }
7021cb0ef41Sopenharmony_ci
7031cb0ef41Sopenharmony_ci  // Looks up or creates and returns a structure containing information about
7041cb0ef41Sopenharmony_ci  // tests and instantiations of a particular test suite.
7051cb0ef41Sopenharmony_ci  template <class TestSuite>
7061cb0ef41Sopenharmony_ci  ParameterizedTestSuiteInfo<TestSuite>* GetTestSuitePatternHolder(
7071cb0ef41Sopenharmony_ci      const char* test_suite_name, CodeLocation code_location) {
7081cb0ef41Sopenharmony_ci    ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr;
7091cb0ef41Sopenharmony_ci    for (auto& test_suite_info : test_suite_infos_) {
7101cb0ef41Sopenharmony_ci      if (test_suite_info->GetTestSuiteName() == test_suite_name) {
7111cb0ef41Sopenharmony_ci        if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
7121cb0ef41Sopenharmony_ci          // Complain about incorrect usage of Google Test facilities
7131cb0ef41Sopenharmony_ci          // and terminate the program since we cannot guaranty correct
7141cb0ef41Sopenharmony_ci          // test suite setup and tear-down in this case.
7151cb0ef41Sopenharmony_ci          ReportInvalidTestSuiteType(test_suite_name, code_location);
7161cb0ef41Sopenharmony_ci          posix::Abort();
7171cb0ef41Sopenharmony_ci        } else {
7181cb0ef41Sopenharmony_ci          // At this point we are sure that the object we found is of the same
7191cb0ef41Sopenharmony_ci          // type we are looking for, so we downcast it to that type
7201cb0ef41Sopenharmony_ci          // without further checks.
7211cb0ef41Sopenharmony_ci          typed_test_info = CheckedDowncastToActualType<
7221cb0ef41Sopenharmony_ci              ParameterizedTestSuiteInfo<TestSuite>>(test_suite_info);
7231cb0ef41Sopenharmony_ci        }
7241cb0ef41Sopenharmony_ci        break;
7251cb0ef41Sopenharmony_ci      }
7261cb0ef41Sopenharmony_ci    }
7271cb0ef41Sopenharmony_ci    if (typed_test_info == nullptr) {
7281cb0ef41Sopenharmony_ci      typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>(
7291cb0ef41Sopenharmony_ci          test_suite_name, code_location);
7301cb0ef41Sopenharmony_ci      test_suite_infos_.push_back(typed_test_info);
7311cb0ef41Sopenharmony_ci    }
7321cb0ef41Sopenharmony_ci    return typed_test_info;
7331cb0ef41Sopenharmony_ci  }
7341cb0ef41Sopenharmony_ci  void RegisterTests() {
7351cb0ef41Sopenharmony_ci    for (auto& test_suite_info : test_suite_infos_) {
7361cb0ef41Sopenharmony_ci      test_suite_info->RegisterTests();
7371cb0ef41Sopenharmony_ci    }
7381cb0ef41Sopenharmony_ci  }
7391cb0ef41Sopenharmony_ci//  Legacy API is deprecated but still available
7401cb0ef41Sopenharmony_ci#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
7411cb0ef41Sopenharmony_ci  template <class TestCase>
7421cb0ef41Sopenharmony_ci  ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
7431cb0ef41Sopenharmony_ci      const char* test_case_name, CodeLocation code_location) {
7441cb0ef41Sopenharmony_ci    return GetTestSuitePatternHolder<TestCase>(test_case_name, code_location);
7451cb0ef41Sopenharmony_ci  }
7461cb0ef41Sopenharmony_ci
7471cb0ef41Sopenharmony_ci#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
7481cb0ef41Sopenharmony_ci
7491cb0ef41Sopenharmony_ci private:
7501cb0ef41Sopenharmony_ci  using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;
7511cb0ef41Sopenharmony_ci
7521cb0ef41Sopenharmony_ci  TestSuiteInfoContainer test_suite_infos_;
7531cb0ef41Sopenharmony_ci
7541cb0ef41Sopenharmony_ci  ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry&) =
7551cb0ef41Sopenharmony_ci      delete;
7561cb0ef41Sopenharmony_ci  ParameterizedTestSuiteRegistry& operator=(
7571cb0ef41Sopenharmony_ci      const ParameterizedTestSuiteRegistry&) = delete;
7581cb0ef41Sopenharmony_ci};
7591cb0ef41Sopenharmony_ci
7601cb0ef41Sopenharmony_ci// Keep track of what type-parameterized test suite are defined and
7611cb0ef41Sopenharmony_ci// where as well as which are intatiated. This allows susequently
7621cb0ef41Sopenharmony_ci// identifying suits that are defined but never used.
7631cb0ef41Sopenharmony_ciclass TypeParameterizedTestSuiteRegistry {
7641cb0ef41Sopenharmony_ci public:
7651cb0ef41Sopenharmony_ci  // Add a suite definition
7661cb0ef41Sopenharmony_ci  void RegisterTestSuite(const char* test_suite_name,
7671cb0ef41Sopenharmony_ci                         CodeLocation code_location);
7681cb0ef41Sopenharmony_ci
7691cb0ef41Sopenharmony_ci  // Add an instantiation of a suit.
7701cb0ef41Sopenharmony_ci  void RegisterInstantiation(const char* test_suite_name);
7711cb0ef41Sopenharmony_ci
7721cb0ef41Sopenharmony_ci  // For each suit repored as defined but not reported as instantiation,
7731cb0ef41Sopenharmony_ci  // emit a test that reports that fact (configurably, as an error).
7741cb0ef41Sopenharmony_ci  void CheckForInstantiations();
7751cb0ef41Sopenharmony_ci
7761cb0ef41Sopenharmony_ci private:
7771cb0ef41Sopenharmony_ci  struct TypeParameterizedTestSuiteInfo {
7781cb0ef41Sopenharmony_ci    explicit TypeParameterizedTestSuiteInfo(CodeLocation c)
7791cb0ef41Sopenharmony_ci        : code_location(c), instantiated(false) {}
7801cb0ef41Sopenharmony_ci
7811cb0ef41Sopenharmony_ci    CodeLocation code_location;
7821cb0ef41Sopenharmony_ci    bool instantiated;
7831cb0ef41Sopenharmony_ci  };
7841cb0ef41Sopenharmony_ci
7851cb0ef41Sopenharmony_ci  std::map<std::string, TypeParameterizedTestSuiteInfo> suites_;
7861cb0ef41Sopenharmony_ci};
7871cb0ef41Sopenharmony_ci
7881cb0ef41Sopenharmony_ci}  // namespace internal
7891cb0ef41Sopenharmony_ci
7901cb0ef41Sopenharmony_ci// Forward declarations of ValuesIn(), which is implemented in
7911cb0ef41Sopenharmony_ci// include/gtest/gtest-param-test.h.
7921cb0ef41Sopenharmony_citemplate <class Container>
7931cb0ef41Sopenharmony_ciinternal::ParamGenerator<typename Container::value_type> ValuesIn(
7941cb0ef41Sopenharmony_ci    const Container& container);
7951cb0ef41Sopenharmony_ci
7961cb0ef41Sopenharmony_cinamespace internal {
7971cb0ef41Sopenharmony_ci// Used in the Values() function to provide polymorphic capabilities.
7981cb0ef41Sopenharmony_ci
7991cb0ef41Sopenharmony_ciGTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
8001cb0ef41Sopenharmony_ci
8011cb0ef41Sopenharmony_citemplate <typename... Ts>
8021cb0ef41Sopenharmony_ciclass ValueArray {
8031cb0ef41Sopenharmony_ci public:
8041cb0ef41Sopenharmony_ci  explicit ValueArray(Ts... v) : v_(FlatTupleConstructTag{}, std::move(v)...) {}
8051cb0ef41Sopenharmony_ci
8061cb0ef41Sopenharmony_ci  template <typename T>
8071cb0ef41Sopenharmony_ci  operator ParamGenerator<T>() const {  // NOLINT
8081cb0ef41Sopenharmony_ci    return ValuesIn(MakeVector<T>(MakeIndexSequence<sizeof...(Ts)>()));
8091cb0ef41Sopenharmony_ci  }
8101cb0ef41Sopenharmony_ci
8111cb0ef41Sopenharmony_ci private:
8121cb0ef41Sopenharmony_ci  template <typename T, size_t... I>
8131cb0ef41Sopenharmony_ci  std::vector<T> MakeVector(IndexSequence<I...>) const {
8141cb0ef41Sopenharmony_ci    return std::vector<T>{static_cast<T>(v_.template Get<I>())...};
8151cb0ef41Sopenharmony_ci  }
8161cb0ef41Sopenharmony_ci
8171cb0ef41Sopenharmony_ci  FlatTuple<Ts...> v_;
8181cb0ef41Sopenharmony_ci};
8191cb0ef41Sopenharmony_ci
8201cb0ef41Sopenharmony_ciGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4100
8211cb0ef41Sopenharmony_ci
8221cb0ef41Sopenharmony_citemplate <typename... T>
8231cb0ef41Sopenharmony_ciclass CartesianProductGenerator
8241cb0ef41Sopenharmony_ci    : public ParamGeneratorInterface<::std::tuple<T...>> {
8251cb0ef41Sopenharmony_ci public:
8261cb0ef41Sopenharmony_ci  typedef ::std::tuple<T...> ParamType;
8271cb0ef41Sopenharmony_ci
8281cb0ef41Sopenharmony_ci  CartesianProductGenerator(const std::tuple<ParamGenerator<T>...>& g)
8291cb0ef41Sopenharmony_ci      : generators_(g) {}
8301cb0ef41Sopenharmony_ci  ~CartesianProductGenerator() override = default;
8311cb0ef41Sopenharmony_ci
8321cb0ef41Sopenharmony_ci  ParamIteratorInterface<ParamType>* Begin() const override {
8331cb0ef41Sopenharmony_ci    return new Iterator(this, generators_, false);
8341cb0ef41Sopenharmony_ci  }
8351cb0ef41Sopenharmony_ci  ParamIteratorInterface<ParamType>* End() const override {
8361cb0ef41Sopenharmony_ci    return new Iterator(this, generators_, true);
8371cb0ef41Sopenharmony_ci  }
8381cb0ef41Sopenharmony_ci
8391cb0ef41Sopenharmony_ci private:
8401cb0ef41Sopenharmony_ci  template <class I>
8411cb0ef41Sopenharmony_ci  class IteratorImpl;
8421cb0ef41Sopenharmony_ci  template <size_t... I>
8431cb0ef41Sopenharmony_ci  class IteratorImpl<IndexSequence<I...>>
8441cb0ef41Sopenharmony_ci      : public ParamIteratorInterface<ParamType> {
8451cb0ef41Sopenharmony_ci   public:
8461cb0ef41Sopenharmony_ci    IteratorImpl(const ParamGeneratorInterface<ParamType>* base,
8471cb0ef41Sopenharmony_ci                 const std::tuple<ParamGenerator<T>...>& generators,
8481cb0ef41Sopenharmony_ci                 bool is_end)
8491cb0ef41Sopenharmony_ci        : base_(base),
8501cb0ef41Sopenharmony_ci          begin_(std::get<I>(generators).begin()...),
8511cb0ef41Sopenharmony_ci          end_(std::get<I>(generators).end()...),
8521cb0ef41Sopenharmony_ci          current_(is_end ? end_ : begin_) {
8531cb0ef41Sopenharmony_ci      ComputeCurrentValue();
8541cb0ef41Sopenharmony_ci    }
8551cb0ef41Sopenharmony_ci    ~IteratorImpl() override = default;
8561cb0ef41Sopenharmony_ci
8571cb0ef41Sopenharmony_ci    const ParamGeneratorInterface<ParamType>* BaseGenerator() const override {
8581cb0ef41Sopenharmony_ci      return base_;
8591cb0ef41Sopenharmony_ci    }
8601cb0ef41Sopenharmony_ci    // Advance should not be called on beyond-of-range iterators
8611cb0ef41Sopenharmony_ci    // so no component iterators must be beyond end of range, either.
8621cb0ef41Sopenharmony_ci    void Advance() override {
8631cb0ef41Sopenharmony_ci      assert(!AtEnd());
8641cb0ef41Sopenharmony_ci      // Advance the last iterator.
8651cb0ef41Sopenharmony_ci      ++std::get<sizeof...(T) - 1>(current_);
8661cb0ef41Sopenharmony_ci      // if that reaches end, propagate that up.
8671cb0ef41Sopenharmony_ci      AdvanceIfEnd<sizeof...(T) - 1>();
8681cb0ef41Sopenharmony_ci      ComputeCurrentValue();
8691cb0ef41Sopenharmony_ci    }
8701cb0ef41Sopenharmony_ci    ParamIteratorInterface<ParamType>* Clone() const override {
8711cb0ef41Sopenharmony_ci      return new IteratorImpl(*this);
8721cb0ef41Sopenharmony_ci    }
8731cb0ef41Sopenharmony_ci
8741cb0ef41Sopenharmony_ci    const ParamType* Current() const override { return current_value_.get(); }
8751cb0ef41Sopenharmony_ci
8761cb0ef41Sopenharmony_ci    bool Equals(const ParamIteratorInterface<ParamType>& other) const override {
8771cb0ef41Sopenharmony_ci      // Having the same base generator guarantees that the other
8781cb0ef41Sopenharmony_ci      // iterator is of the same type and we can downcast.
8791cb0ef41Sopenharmony_ci      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
8801cb0ef41Sopenharmony_ci          << "The program attempted to compare iterators "
8811cb0ef41Sopenharmony_ci          << "from different generators." << std::endl;
8821cb0ef41Sopenharmony_ci      const IteratorImpl* typed_other =
8831cb0ef41Sopenharmony_ci          CheckedDowncastToActualType<const IteratorImpl>(&other);
8841cb0ef41Sopenharmony_ci
8851cb0ef41Sopenharmony_ci      // We must report iterators equal if they both point beyond their
8861cb0ef41Sopenharmony_ci      // respective ranges. That can happen in a variety of fashions,
8871cb0ef41Sopenharmony_ci      // so we have to consult AtEnd().
8881cb0ef41Sopenharmony_ci      if (AtEnd() && typed_other->AtEnd()) return true;
8891cb0ef41Sopenharmony_ci
8901cb0ef41Sopenharmony_ci      bool same = true;
8911cb0ef41Sopenharmony_ci      bool dummy[] = {
8921cb0ef41Sopenharmony_ci          (same = same && std::get<I>(current_) ==
8931cb0ef41Sopenharmony_ci                              std::get<I>(typed_other->current_))...};
8941cb0ef41Sopenharmony_ci      (void)dummy;
8951cb0ef41Sopenharmony_ci      return same;
8961cb0ef41Sopenharmony_ci    }
8971cb0ef41Sopenharmony_ci
8981cb0ef41Sopenharmony_ci   private:
8991cb0ef41Sopenharmony_ci    template <size_t ThisI>
9001cb0ef41Sopenharmony_ci    void AdvanceIfEnd() {
9011cb0ef41Sopenharmony_ci      if (std::get<ThisI>(current_) != std::get<ThisI>(end_)) return;
9021cb0ef41Sopenharmony_ci
9031cb0ef41Sopenharmony_ci      bool last = ThisI == 0;
9041cb0ef41Sopenharmony_ci      if (last) {
9051cb0ef41Sopenharmony_ci        // We are done. Nothing else to propagate.
9061cb0ef41Sopenharmony_ci        return;
9071cb0ef41Sopenharmony_ci      }
9081cb0ef41Sopenharmony_ci
9091cb0ef41Sopenharmony_ci      constexpr size_t NextI = ThisI - (ThisI != 0);
9101cb0ef41Sopenharmony_ci      std::get<ThisI>(current_) = std::get<ThisI>(begin_);
9111cb0ef41Sopenharmony_ci      ++std::get<NextI>(current_);
9121cb0ef41Sopenharmony_ci      AdvanceIfEnd<NextI>();
9131cb0ef41Sopenharmony_ci    }
9141cb0ef41Sopenharmony_ci
9151cb0ef41Sopenharmony_ci    void ComputeCurrentValue() {
9161cb0ef41Sopenharmony_ci      if (!AtEnd())
9171cb0ef41Sopenharmony_ci        current_value_ = std::make_shared<ParamType>(*std::get<I>(current_)...);
9181cb0ef41Sopenharmony_ci    }
9191cb0ef41Sopenharmony_ci    bool AtEnd() const {
9201cb0ef41Sopenharmony_ci      bool at_end = false;
9211cb0ef41Sopenharmony_ci      bool dummy[] = {
9221cb0ef41Sopenharmony_ci          (at_end = at_end || std::get<I>(current_) == std::get<I>(end_))...};
9231cb0ef41Sopenharmony_ci      (void)dummy;
9241cb0ef41Sopenharmony_ci      return at_end;
9251cb0ef41Sopenharmony_ci    }
9261cb0ef41Sopenharmony_ci
9271cb0ef41Sopenharmony_ci    const ParamGeneratorInterface<ParamType>* const base_;
9281cb0ef41Sopenharmony_ci    std::tuple<typename ParamGenerator<T>::iterator...> begin_;
9291cb0ef41Sopenharmony_ci    std::tuple<typename ParamGenerator<T>::iterator...> end_;
9301cb0ef41Sopenharmony_ci    std::tuple<typename ParamGenerator<T>::iterator...> current_;
9311cb0ef41Sopenharmony_ci    std::shared_ptr<ParamType> current_value_;
9321cb0ef41Sopenharmony_ci  };
9331cb0ef41Sopenharmony_ci
9341cb0ef41Sopenharmony_ci  using Iterator = IteratorImpl<typename MakeIndexSequence<sizeof...(T)>::type>;
9351cb0ef41Sopenharmony_ci
9361cb0ef41Sopenharmony_ci  std::tuple<ParamGenerator<T>...> generators_;
9371cb0ef41Sopenharmony_ci};
9381cb0ef41Sopenharmony_ci
9391cb0ef41Sopenharmony_citemplate <class... Gen>
9401cb0ef41Sopenharmony_ciclass CartesianProductHolder {
9411cb0ef41Sopenharmony_ci public:
9421cb0ef41Sopenharmony_ci  CartesianProductHolder(const Gen&... g) : generators_(g...) {}
9431cb0ef41Sopenharmony_ci  template <typename... T>
9441cb0ef41Sopenharmony_ci  operator ParamGenerator<::std::tuple<T...>>() const {
9451cb0ef41Sopenharmony_ci    return ParamGenerator<::std::tuple<T...>>(
9461cb0ef41Sopenharmony_ci        new CartesianProductGenerator<T...>(generators_));
9471cb0ef41Sopenharmony_ci  }
9481cb0ef41Sopenharmony_ci
9491cb0ef41Sopenharmony_ci private:
9501cb0ef41Sopenharmony_ci  std::tuple<Gen...> generators_;
9511cb0ef41Sopenharmony_ci};
9521cb0ef41Sopenharmony_ci
9531cb0ef41Sopenharmony_citemplate <typename From, typename To>
9541cb0ef41Sopenharmony_ciclass ParamGeneratorConverter : public ParamGeneratorInterface<To> {
9551cb0ef41Sopenharmony_ci public:
9561cb0ef41Sopenharmony_ci  ParamGeneratorConverter(ParamGenerator<From> gen)  // NOLINT
9571cb0ef41Sopenharmony_ci      : generator_(std::move(gen)) {}
9581cb0ef41Sopenharmony_ci
9591cb0ef41Sopenharmony_ci  ParamIteratorInterface<To>* Begin() const override {
9601cb0ef41Sopenharmony_ci    return new Iterator(this, generator_.begin(), generator_.end());
9611cb0ef41Sopenharmony_ci  }
9621cb0ef41Sopenharmony_ci  ParamIteratorInterface<To>* End() const override {
9631cb0ef41Sopenharmony_ci    return new Iterator(this, generator_.end(), generator_.end());
9641cb0ef41Sopenharmony_ci  }
9651cb0ef41Sopenharmony_ci
9661cb0ef41Sopenharmony_ci private:
9671cb0ef41Sopenharmony_ci  class Iterator : public ParamIteratorInterface<To> {
9681cb0ef41Sopenharmony_ci   public:
9691cb0ef41Sopenharmony_ci    Iterator(const ParamGeneratorInterface<To>* base, ParamIterator<From> it,
9701cb0ef41Sopenharmony_ci             ParamIterator<From> end)
9711cb0ef41Sopenharmony_ci        : base_(base), it_(it), end_(end) {
9721cb0ef41Sopenharmony_ci      if (it_ != end_) value_ = std::make_shared<To>(static_cast<To>(*it_));
9731cb0ef41Sopenharmony_ci    }
9741cb0ef41Sopenharmony_ci    ~Iterator() override = default;
9751cb0ef41Sopenharmony_ci
9761cb0ef41Sopenharmony_ci    const ParamGeneratorInterface<To>* BaseGenerator() const override {
9771cb0ef41Sopenharmony_ci      return base_;
9781cb0ef41Sopenharmony_ci    }
9791cb0ef41Sopenharmony_ci    void Advance() override {
9801cb0ef41Sopenharmony_ci      ++it_;
9811cb0ef41Sopenharmony_ci      if (it_ != end_) value_ = std::make_shared<To>(static_cast<To>(*it_));
9821cb0ef41Sopenharmony_ci    }
9831cb0ef41Sopenharmony_ci    ParamIteratorInterface<To>* Clone() const override {
9841cb0ef41Sopenharmony_ci      return new Iterator(*this);
9851cb0ef41Sopenharmony_ci    }
9861cb0ef41Sopenharmony_ci    const To* Current() const override { return value_.get(); }
9871cb0ef41Sopenharmony_ci    bool Equals(const ParamIteratorInterface<To>& other) const override {
9881cb0ef41Sopenharmony_ci      // Having the same base generator guarantees that the other
9891cb0ef41Sopenharmony_ci      // iterator is of the same type and we can downcast.
9901cb0ef41Sopenharmony_ci      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
9911cb0ef41Sopenharmony_ci          << "The program attempted to compare iterators "
9921cb0ef41Sopenharmony_ci          << "from different generators." << std::endl;
9931cb0ef41Sopenharmony_ci      const ParamIterator<From> other_it =
9941cb0ef41Sopenharmony_ci          CheckedDowncastToActualType<const Iterator>(&other)->it_;
9951cb0ef41Sopenharmony_ci      return it_ == other_it;
9961cb0ef41Sopenharmony_ci    }
9971cb0ef41Sopenharmony_ci
9981cb0ef41Sopenharmony_ci   private:
9991cb0ef41Sopenharmony_ci    Iterator(const Iterator& other) = default;
10001cb0ef41Sopenharmony_ci
10011cb0ef41Sopenharmony_ci    const ParamGeneratorInterface<To>* const base_;
10021cb0ef41Sopenharmony_ci    ParamIterator<From> it_;
10031cb0ef41Sopenharmony_ci    ParamIterator<From> end_;
10041cb0ef41Sopenharmony_ci    std::shared_ptr<To> value_;
10051cb0ef41Sopenharmony_ci  };  // class ParamGeneratorConverter::Iterator
10061cb0ef41Sopenharmony_ci
10071cb0ef41Sopenharmony_ci  ParamGenerator<From> generator_;
10081cb0ef41Sopenharmony_ci};  // class ParamGeneratorConverter
10091cb0ef41Sopenharmony_ci
10101cb0ef41Sopenharmony_citemplate <class Gen>
10111cb0ef41Sopenharmony_ciclass ParamConverterGenerator {
10121cb0ef41Sopenharmony_ci public:
10131cb0ef41Sopenharmony_ci  ParamConverterGenerator(ParamGenerator<Gen> g)  // NOLINT
10141cb0ef41Sopenharmony_ci      : generator_(std::move(g)) {}
10151cb0ef41Sopenharmony_ci
10161cb0ef41Sopenharmony_ci  template <typename T>
10171cb0ef41Sopenharmony_ci  operator ParamGenerator<T>() const {  // NOLINT
10181cb0ef41Sopenharmony_ci    return ParamGenerator<T>(new ParamGeneratorConverter<Gen, T>(generator_));
10191cb0ef41Sopenharmony_ci  }
10201cb0ef41Sopenharmony_ci
10211cb0ef41Sopenharmony_ci private:
10221cb0ef41Sopenharmony_ci  ParamGenerator<Gen> generator_;
10231cb0ef41Sopenharmony_ci};
10241cb0ef41Sopenharmony_ci
10251cb0ef41Sopenharmony_ci}  // namespace internal
10261cb0ef41Sopenharmony_ci}  // namespace testing
10271cb0ef41Sopenharmony_ci
10281cb0ef41Sopenharmony_ci#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
1029