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(¶meter_); 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