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