QUDA  v1.1.0
A library for QCD on GPUs
gtest-param-util.h
Go to the documentation of this file.
1 // Copyright 2008 Google Inc.
2 // All Rights Reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 
31 // Type and function utilities for implementing parameterized tests.
32 
33 // GOOGLETEST_CM0001 DO NOT DELETE
34 
35 #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
36 #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
37 
38 #include <ctype.h>
39 
40 #include <cassert>
41 #include <iterator>
42 #include <memory>
43 #include <set>
44 #include <tuple>
45 #include <utility>
46 #include <vector>
47 
50 #include "gtest/gtest-printers.h"
51 
52 namespace testing {
53 // Input to a parameterized test name generator, describing a test parameter.
54 // Consists of the parameter value and the integer parameter index.
55 template <class ParamType>
56 struct TestParamInfo {
57  TestParamInfo(const ParamType& a_param, size_t an_index) :
58  param(a_param),
59  index(an_index) {}
60  ParamType param;
61  size_t index;
62 };
63 
64 // A builtin parameterized test name generator which returns the result of
65 // testing::PrintToString.
67  template <class ParamType>
69  return PrintToString(info.param);
70  }
71 };
72 
73 namespace internal {
74 
75 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
76 // Utility Functions
77 
78 // Outputs a message explaining invalid registration of different
79 // fixture class for the same test suite. This may happen when
80 // TEST_P macro is used to define two tests with the same name
81 // but in different namespaces.
82 GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
83  CodeLocation code_location);
84 
85 template <typename> class ParamGeneratorInterface;
86 template <typename> class ParamGenerator;
87 
88 // Interface for iterating over elements provided by an implementation
89 // of ParamGeneratorInterface<T>.
90 template <typename T>
92  public:
94  // A pointer to the base generator instance.
95  // Used only for the purposes of iterator comparison
96  // to make sure that two iterators belong to the same generator.
97  virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;
98  // Advances iterator to point to the next element
99  // provided by the generator. The caller is responsible
100  // for not calling Advance() on an iterator equal to
101  // BaseGenerator()->End().
102  virtual void Advance() = 0;
103  // Clones the iterator object. Used for implementing copy semantics
104  // of ParamIterator<T>.
105  virtual ParamIteratorInterface* Clone() const = 0;
106  // Dereferences the current iterator and provides (read-only) access
107  // to the pointed value. It is the caller's responsibility not to call
108  // Current() on an iterator equal to BaseGenerator()->End().
109  // Used for implementing ParamGenerator<T>::operator*().
110  virtual const T* Current() const = 0;
111  // Determines whether the given iterator and other point to the same
112  // element in the sequence generated by the generator.
113  // Used for implementing ParamGenerator<T>::operator==().
114  virtual bool Equals(const ParamIteratorInterface& other) const = 0;
115 };
116 
117 // Class iterating over elements provided by an implementation of
118 // ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
119 // and implements the const forward iterator concept.
120 template <typename T>
122  public:
123  typedef T value_type;
124  typedef const T& reference;
125  typedef ptrdiff_t difference_type;
126 
127  // ParamIterator assumes ownership of the impl_ pointer.
128  ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
130  if (this != &other)
131  impl_.reset(other.impl_->Clone());
132  return *this;
133  }
134 
135  const T& operator*() const { return *impl_->Current(); }
136  const T* operator->() const { return impl_->Current(); }
137  // Prefix version of operator++.
139  impl_->Advance();
140  return *this;
141  }
142  // Postfix version of operator++.
143  ParamIterator operator++(int /*unused*/) {
144  ParamIteratorInterface<T>* clone = impl_->Clone();
145  impl_->Advance();
146  return ParamIterator(clone);
147  }
148  bool operator==(const ParamIterator& other) const {
149  return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
150  }
151  bool operator!=(const ParamIterator& other) const {
152  return !(*this == other);
153  }
154 
155  private:
156  friend class ParamGenerator<T>;
157  explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
158  std::unique_ptr<ParamIteratorInterface<T> > impl_;
159 };
160 
161 // ParamGeneratorInterface<T> is the binary interface to access generators
162 // defined in other translation units.
163 template <typename T>
165  public:
166  typedef T ParamType;
167 
169 
170  // Generator interface definition
171  virtual ParamIteratorInterface<T>* Begin() const = 0;
172  virtual ParamIteratorInterface<T>* End() const = 0;
173 };
174 
175 // Wraps ParamGeneratorInterface<T> and provides general generator syntax
176 // compatible with the STL Container concept.
177 // This class implements copy initialization semantics and the contained
178 // ParamGeneratorInterface<T> instance is shared among all copies
179 // of the original object. This is possible because that instance is immutable.
180 template<typename T>
182  public:
184 
185  explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}
186  ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}
187 
189  impl_ = other.impl_;
190  return *this;
191  }
192 
193  iterator begin() const { return iterator(impl_->Begin()); }
194  iterator end() const { return iterator(impl_->End()); }
195 
196  private:
197  std::shared_ptr<const ParamGeneratorInterface<T> > impl_;
198 };
199 
200 // Generates values from a range of two comparable values. Can be used to
201 // generate sequences of user-defined types that implement operator+() and
202 // operator<().
203 // This class is used in the Range() function.
204 template <typename T, typename IncrementT>
206  public:
207  RangeGenerator(T begin, T end, IncrementT step)
208  : begin_(begin), end_(end),
209  step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
210  ~RangeGenerator() override {}
211 
212  ParamIteratorInterface<T>* Begin() const override {
213  return new Iterator(this, begin_, 0, step_);
214  }
215  ParamIteratorInterface<T>* End() const override {
216  return new Iterator(this, end_, end_index_, step_);
217  }
218 
219  private:
220  class Iterator : public ParamIteratorInterface<T> {
221  public:
222  Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
223  IncrementT step)
224  : base_(base), value_(value), index_(index), step_(step) {}
225  ~Iterator() override {}
226 
227  const ParamGeneratorInterface<T>* BaseGenerator() const override {
228  return base_;
229  }
230  void Advance() override {
231  value_ = static_cast<T>(value_ + step_);
232  index_++;
233  }
234  ParamIteratorInterface<T>* Clone() const override {
235  return new Iterator(*this);
236  }
237  const T* Current() const override { return &value_; }
238  bool Equals(const ParamIteratorInterface<T>& other) const override {
239  // Having the same base generator guarantees that the other
240  // iterator is of the same type and we can downcast.
241  GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
242  << "The program attempted to compare iterators "
243  << "from different generators." << std::endl;
244  const int other_index =
245  CheckedDowncastToActualType<const Iterator>(&other)->index_;
246  return index_ == other_index;
247  }
248 
249  private:
250  Iterator(const Iterator& other)
251  : ParamIteratorInterface<T>(),
252  base_(other.base_), value_(other.value_), index_(other.index_),
253  step_(other.step_) {}
254 
255  // No implementation - assignment is unsupported.
256  void operator=(const Iterator& other);
257 
258  const ParamGeneratorInterface<T>* const base_;
259  T value_;
260  int index_;
261  const IncrementT step_;
262  }; // class RangeGenerator::Iterator
263 
264  static int CalculateEndIndex(const T& begin,
265  const T& end,
266  const IncrementT& step) {
267  int end_index = 0;
268  for (T i = begin; i < end; i = static_cast<T>(i + step))
269  end_index++;
270  return end_index;
271  }
272 
273  // No implementation - assignment is unsupported.
274  void operator=(const RangeGenerator& other);
275 
276  const T begin_;
277  const T end_;
278  const IncrementT step_;
279  // The index for the end() iterator. All the elements in the generated
280  // sequence are indexed (0-based) to aid iterator comparison.
281  const int end_index_;
282 }; // class RangeGenerator
283 
284 
285 // Generates values from a pair of STL-style iterators. Used in the
286 // ValuesIn() function. The elements are copied from the source range
287 // since the source can be located on the stack, and the generator
288 // is likely to persist beyond that stack frame.
289 template <typename T>
291  public:
292  template <typename ForwardIterator>
293  ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
294  : container_(begin, end) {}
296 
297  ParamIteratorInterface<T>* Begin() const override {
298  return new Iterator(this, container_.begin());
299  }
300  ParamIteratorInterface<T>* End() const override {
301  return new Iterator(this, container_.end());
302  }
303 
304  private:
305  typedef typename ::std::vector<T> ContainerType;
306 
307  class Iterator : public ParamIteratorInterface<T> {
308  public:
309  Iterator(const ParamGeneratorInterface<T>* base,
310  typename ContainerType::const_iterator iterator)
311  : base_(base), iterator_(iterator) {}
312  ~Iterator() override {}
313 
314  const ParamGeneratorInterface<T>* BaseGenerator() const override {
315  return base_;
316  }
317  void Advance() override {
318  ++iterator_;
319  value_.reset();
320  }
321  ParamIteratorInterface<T>* Clone() const override {
322  return new Iterator(*this);
323  }
324  // We need to use cached value referenced by iterator_ because *iterator_
325  // can return a temporary object (and of type other then T), so just
326  // having "return &*iterator_;" doesn't work.
327  // value_ is updated here and not in Advance() because Advance()
328  // can advance iterator_ beyond the end of the range, and we cannot
329  // detect that fact. The client code, on the other hand, is
330  // responsible for not calling Current() on an out-of-range iterator.
331  const T* Current() const override {
332  if (value_.get() == nullptr) value_.reset(new T(*iterator_));
333  return value_.get();
334  }
335  bool Equals(const ParamIteratorInterface<T>& other) const override {
336  // Having the same base generator guarantees that the other
337  // iterator is of the same type and we can downcast.
338  GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
339  << "The program attempted to compare iterators "
340  << "from different generators." << std::endl;
341  return iterator_ ==
342  CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
343  }
344 
345  private:
346  Iterator(const Iterator& other)
347  // The explicit constructor call suppresses a false warning
348  // emitted by gcc when supplied with the -Wextra option.
349  : ParamIteratorInterface<T>(),
350  base_(other.base_),
351  iterator_(other.iterator_) {}
352 
353  const ParamGeneratorInterface<T>* const base_;
354  typename ContainerType::const_iterator iterator_;
355  // A cached value of *iterator_. We keep it here to allow access by
356  // pointer in the wrapping iterator's operator->().
357  // value_ needs to be mutable to be accessed in Current().
358  // Use of std::unique_ptr helps manage cached value's lifetime,
359  // which is bound by the lifespan of the iterator itself.
360  mutable std::unique_ptr<const T> value_;
361  }; // class ValuesInIteratorRangeGenerator::Iterator
362 
363  // No implementation - assignment is unsupported.
364  void operator=(const ValuesInIteratorRangeGenerator& other);
365 
366  const ContainerType container_;
367 }; // class ValuesInIteratorRangeGenerator
368 
369 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
370 //
371 // Default parameterized test name generator, returns a string containing the
372 // integer test parameter index.
373 template <class ParamType>
375  Message name_stream;
376  name_stream << info.index;
377  return name_stream.GetString();
378 }
379 
380 template <typename T = int>
381 void TestNotEmpty() {
382  static_assert(sizeof(T) == 0, "Empty arguments are not allowed.");
383 }
384 template <typename T = int>
385 void TestNotEmpty(const T&) {}
386 
387 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
388 //
389 // Stores a parameter value and later creates tests parameterized with that
390 // value.
391 template <class TestClass>
393  public:
394  typedef typename TestClass::ParamType ParamType;
395  explicit ParameterizedTestFactory(ParamType parameter) :
396  parameter_(parameter) {}
397  Test* CreateTest() override {
398  TestClass::SetParam(&parameter_);
399  return new TestClass();
400  }
401 
402  private:
403  const ParamType parameter_;
404 
405  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory);
406 };
407 
408 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
409 //
410 // TestMetaFactoryBase is a base class for meta-factories that create
411 // test factories for passing into MakeAndRegisterTestInfo function.
412 template <class ParamType>
414  public:
415  virtual ~TestMetaFactoryBase() {}
416 
417  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
418 };
419 
420 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
421 //
422 // TestMetaFactory creates test factories for passing into
423 // MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
424 // ownership of test factory pointer, same factory object cannot be passed
425 // into that method twice. But ParameterizedTestSuiteInfo is going to call
426 // it for each Test/Parameter value combination. Thus it needs meta factory
427 // creator class.
428 template <class TestSuite>
430  : public TestMetaFactoryBase<typename TestSuite::ParamType> {
431  public:
432  using ParamType = typename TestSuite::ParamType;
433 
435 
437  return new ParameterizedTestFactory<TestSuite>(parameter);
438  }
439 
440  private:
441  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory);
442 };
443 
444 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
445 //
446 // ParameterizedTestSuiteInfoBase is a generic interface
447 // to ParameterizedTestSuiteInfo classes. ParameterizedTestSuiteInfoBase
448 // accumulates test information provided by TEST_P macro invocations
449 // and generators provided by INSTANTIATE_TEST_SUITE_P macro invocations
450 // and uses that information to register all resulting test instances
451 // in RegisterTests method. The ParameterizeTestSuiteRegistry class holds
452 // a collection of pointers to the ParameterizedTestSuiteInfo objects
453 // and calls RegisterTests() on each of them when asked.
455  public:
457 
458  // Base part of test suite name for display purposes.
459  virtual const std::string& GetTestSuiteName() const = 0;
460  // Test case id to verify identity.
461  virtual TypeId GetTestSuiteTypeId() const = 0;
462  // UnitTest class invokes this method to register tests in this
463  // test suite right before running them in RUN_ALL_TESTS macro.
464  // This method should not be called more then once on any single
465  // instance of a ParameterizedTestSuiteInfoBase derived class.
466  virtual void RegisterTests() = 0;
467 
468  protected:
470 
471  private:
472  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfoBase);
473 };
474 
475 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
476 //
477 // ParameterizedTestSuiteInfo accumulates tests obtained from TEST_P
478 // macro invocations for a particular test suite and generators
479 // obtained from INSTANTIATE_TEST_SUITE_P macro invocations for that
480 // test suite. It registers tests with all values generated by all
481 // generators when asked.
482 template <class TestSuite>
484  public:
485  // ParamType and GeneratorCreationFunc are private types but are required
486  // for declarations of public methods AddTestPattern() and
487  // AddTestSuiteInstantiation().
488  using ParamType = typename TestSuite::ParamType;
489  // A function that returns an instance of appropriate generator type.
490  typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
492 
493  explicit ParameterizedTestSuiteInfo(const char* name,
494  CodeLocation code_location)
495  : test_suite_name_(name), code_location_(code_location) {}
496 
497  // Test case base name for display purposes.
498  const std::string& GetTestSuiteName() const override {
499  return test_suite_name_;
500  }
501  // Test case id to verify identity.
502  TypeId GetTestSuiteTypeId() const override { return GetTypeId<TestSuite>(); }
503  // TEST_P macro uses AddTestPattern() to record information
504  // about a single test in a LocalTestInfo structure.
505  // test_suite_name is the base name of the test suite (without invocation
506  // prefix). test_base_name is the name of an individual test without
507  // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
508  // test suite base name and DoBar is test base name.
509  void AddTestPattern(const char* test_suite_name, const char* test_base_name,
510  TestMetaFactoryBase<ParamType>* meta_factory) {
511  tests_.push_back(std::shared_ptr<TestInfo>(
512  new TestInfo(test_suite_name, test_base_name, meta_factory)));
513  }
514  // INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information
515  // about a generator.
516  int AddTestSuiteInstantiation(const std::string& instantiation_name,
517  GeneratorCreationFunc* func,
518  ParamNameGeneratorFunc* name_func,
519  const char* file, int line) {
520  instantiations_.push_back(
521  InstantiationInfo(instantiation_name, func, name_func, file, line));
522  return 0; // Return value used only to run this method in namespace scope.
523  }
524  // UnitTest class invokes this method to register tests in this test suite
525  // test suites right before running tests in RUN_ALL_TESTS macro.
526  // This method should not be called more then once on any single
527  // instance of a ParameterizedTestSuiteInfoBase derived class.
528  // UnitTest has a guard to prevent from calling this method more then once.
529  void RegisterTests() override {
530  for (typename TestInfoContainer::iterator test_it = tests_.begin();
531  test_it != tests_.end(); ++test_it) {
532  std::shared_ptr<TestInfo> test_info = *test_it;
533  for (typename InstantiationContainer::iterator gen_it =
534  instantiations_.begin(); gen_it != instantiations_.end();
535  ++gen_it) {
536  const std::string& instantiation_name = gen_it->name;
537  ParamGenerator<ParamType> generator((*gen_it->generator)());
538  ParamNameGeneratorFunc* name_func = gen_it->name_func;
539  const char* file = gen_it->file;
540  int line = gen_it->line;
541 
542  std::string test_suite_name;
543  if ( !instantiation_name.empty() )
544  test_suite_name = instantiation_name + "/";
545  test_suite_name += test_info->test_suite_base_name;
546 
547  size_t i = 0;
548  std::set<std::string> test_param_names;
549  for (typename ParamGenerator<ParamType>::iterator param_it =
550  generator.begin();
551  param_it != generator.end(); ++param_it, ++i) {
552  Message test_name_stream;
553 
554  std::string param_name = name_func(
555  TestParamInfo<ParamType>(*param_it, i));
556 
557  GTEST_CHECK_(IsValidParamName(param_name))
558  << "Parameterized test name '" << param_name
559  << "' is invalid, in " << file
560  << " line " << line << std::endl;
561 
562  GTEST_CHECK_(test_param_names.count(param_name) == 0)
563  << "Duplicate parameterized test name '" << param_name
564  << "', in " << file << " line " << line << std::endl;
565 
566  test_param_names.insert(param_name);
567 
568  test_name_stream << test_info->test_base_name << "/" << param_name;
570  test_suite_name.c_str(), test_name_stream.GetString().c_str(),
571  nullptr, // No type parameter.
572  PrintToString(*param_it).c_str(), code_location_,
576  test_info->test_meta_factory->CreateTestFactory(*param_it));
577  } // for param_it
578  } // for gen_it
579  } // for test_it
580  } // RegisterTests
581 
582  private:
583  // LocalTestInfo structure keeps information about a single test registered
584  // with TEST_P macro.
585  struct TestInfo {
586  TestInfo(const char* a_test_suite_base_name, const char* a_test_base_name,
587  TestMetaFactoryBase<ParamType>* a_test_meta_factory)
588  : test_suite_base_name(a_test_suite_base_name),
589  test_base_name(a_test_base_name),
590  test_meta_factory(a_test_meta_factory) {}
591 
592  const std::string test_suite_base_name;
593  const std::string test_base_name;
594  const std::unique_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
595  };
596  using TestInfoContainer = ::std::vector<std::shared_ptr<TestInfo> >;
597  // Records data received from INSTANTIATE_TEST_SUITE_P macros:
598  // <Instantiation name, Sequence generator creation function,
599  // Name generator function, Source file, Source line>
600  struct InstantiationInfo {
601  InstantiationInfo(const std::string &name_in,
602  GeneratorCreationFunc* generator_in,
603  ParamNameGeneratorFunc* name_func_in,
604  const char* file_in,
605  int line_in)
606  : name(name_in),
607  generator(generator_in),
608  name_func(name_func_in),
609  file(file_in),
610  line(line_in) {}
611 
612  std::string name;
613  GeneratorCreationFunc* generator;
614  ParamNameGeneratorFunc* name_func;
615  const char* file;
616  int line;
617  };
618  typedef ::std::vector<InstantiationInfo> InstantiationContainer;
619 
620  static bool IsValidParamName(const std::string& name) {
621  // Check for empty string
622  if (name.empty())
623  return false;
624 
625  // Check for invalid characters
626  for (std::string::size_type index = 0; index < name.size(); ++index) {
627  if (!isalnum(name[index]) && name[index] != '_')
628  return false;
629  }
630 
631  return true;
632  }
633 
634  const std::string test_suite_name_;
635  CodeLocation code_location_;
636  TestInfoContainer tests_;
637  InstantiationContainer instantiations_;
638 
639  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfo);
640 }; // class ParameterizedTestSuiteInfo
641 
642 // Legacy API is deprecated but still available
643 #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
644 template <class TestCase>
646 #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
647 
648 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
649 //
650 // ParameterizedTestSuiteRegistry contains a map of
651 // ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P
652 // and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding
653 // ParameterizedTestSuiteInfo descriptors.
655  public:
658  for (auto& test_suite_info : test_suite_infos_) {
659  delete test_suite_info;
660  }
661  }
662 
663  // Looks up or creates and returns a structure containing information about
664  // tests and instantiations of a particular test suite.
665  template <class TestSuite>
667  const char* test_suite_name, CodeLocation code_location) {
668  ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr;
669  for (auto& test_suite_info : test_suite_infos_) {
670  if (test_suite_info->GetTestSuiteName() == test_suite_name) {
671  if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
672  // Complain about incorrect usage of Google Test facilities
673  // and terminate the program since we cannot guaranty correct
674  // test suite setup and tear-down in this case.
675  ReportInvalidTestSuiteType(test_suite_name, code_location);
676  posix::Abort();
677  } else {
678  // At this point we are sure that the object we found is of the same
679  // type we are looking for, so we downcast it to that type
680  // without further checks.
681  typed_test_info = CheckedDowncastToActualType<
682  ParameterizedTestSuiteInfo<TestSuite> >(test_suite_info);
683  }
684  break;
685  }
686  }
687  if (typed_test_info == nullptr) {
688  typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>(
689  test_suite_name, code_location);
690  test_suite_infos_.push_back(typed_test_info);
691  }
692  return typed_test_info;
693  }
694  void RegisterTests() {
695  for (auto& test_suite_info : test_suite_infos_) {
696  test_suite_info->RegisterTests();
697  }
698  }
699 // Legacy API is deprecated but still available
700 #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
701  template <class TestCase>
703  const char* test_case_name, CodeLocation code_location) {
704  return GetTestSuitePatternHolder<TestCase>(test_case_name, code_location);
705  }
706 
707 #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
708 
709  private:
710  using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;
711 
712  TestSuiteInfoContainer test_suite_infos_;
713 
714  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteRegistry);
715 };
716 
717 } // namespace internal
718 
719 // Forward declarations of ValuesIn(), which is implemented in
720 // include/gtest/gtest-param-test.h.
721 template <class Container>
722 internal::ParamGenerator<typename Container::value_type> ValuesIn(
723  const Container& container);
724 
725 namespace internal {
726 // Used in the Values() function to provide polymorphic capabilities.
727 
728 template <typename... Ts>
729 class ValueArray {
730  public:
731  ValueArray(Ts... v) : v_{std::move(v)...} {}
732 
733  template <typename T>
734  operator ParamGenerator<T>() const { // NOLINT
735  return ValuesIn(MakeVector<T>(MakeIndexSequence<sizeof...(Ts)>()));
736  }
737 
738  private:
739  template <typename T, size_t... I>
740  std::vector<T> MakeVector(IndexSequence<I...>) const {
741  return std::vector<T>{static_cast<T>(v_.template Get<I>())...};
742  }
743 
744  FlatTuple<Ts...> v_;
745 };
746 
747 template <typename... T>
749  : public ParamGeneratorInterface<::std::tuple<T...>> {
750  public:
751  typedef ::std::tuple<T...> ParamType;
752 
754  : generators_(g) {}
756 
758  return new Iterator(this, generators_, false);
759  }
761  return new Iterator(this, generators_, true);
762  }
763 
764  private:
765  template <class I>
766  class IteratorImpl;
767  template <size_t... I>
768  class IteratorImpl<IndexSequence<I...>>
769  : public ParamIteratorInterface<ParamType> {
770  public:
771  IteratorImpl(const ParamGeneratorInterface<ParamType>* base,
772  const std::tuple<ParamGenerator<T>...>& generators, bool is_end)
773  : base_(base),
774  begin_(std::get<I>(generators).begin()...),
775  end_(std::get<I>(generators).end()...),
776  current_(is_end ? end_ : begin_) {
777  ComputeCurrentValue();
778  }
779  ~IteratorImpl() override {}
780 
781  const ParamGeneratorInterface<ParamType>* BaseGenerator() const override {
782  return base_;
783  }
784  // Advance should not be called on beyond-of-range iterators
785  // so no component iterators must be beyond end of range, either.
786  void Advance() override {
787  assert(!AtEnd());
788  // Advance the last iterator.
789  ++std::get<sizeof...(T) - 1>(current_);
790  // if that reaches end, propagate that up.
791  AdvanceIfEnd<sizeof...(T) - 1>();
792  ComputeCurrentValue();
793  }
794  ParamIteratorInterface<ParamType>* Clone() const override {
795  return new IteratorImpl(*this);
796  }
797 
798  const ParamType* Current() const override { return current_value_.get(); }
799 
800  bool Equals(const ParamIteratorInterface<ParamType>& other) const override {
801  // Having the same base generator guarantees that the other
802  // iterator is of the same type and we can downcast.
803  GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
804  << "The program attempted to compare iterators "
805  << "from different generators." << std::endl;
806  const IteratorImpl* typed_other =
807  CheckedDowncastToActualType<const IteratorImpl>(&other);
808 
809  // We must report iterators equal if they both point beyond their
810  // respective ranges. That can happen in a variety of fashions,
811  // so we have to consult AtEnd().
812  if (AtEnd() && typed_other->AtEnd()) return true;
813 
814  bool same = true;
815  bool dummy[] = {
816  (same = same && std::get<I>(current_) ==
817  std::get<I>(typed_other->current_))...};
818  (void)dummy;
819  return same;
820  }
821 
822  private:
823  template <size_t ThisI>
824  void AdvanceIfEnd() {
825  if (std::get<ThisI>(current_) != std::get<ThisI>(end_)) return;
826 
827  bool last = ThisI == 0;
828  if (last) {
829  // We are done. Nothing else to propagate.
830  return;
831  }
832 
833  constexpr size_t NextI = ThisI - (ThisI != 0);
834  std::get<ThisI>(current_) = std::get<ThisI>(begin_);
835  ++std::get<NextI>(current_);
836  AdvanceIfEnd<NextI>();
837  }
838 
839  void ComputeCurrentValue() {
840  if (!AtEnd())
841  current_value_ = std::make_shared<ParamType>(*std::get<I>(current_)...);
842  }
843  bool AtEnd() const {
844  bool at_end = false;
845  bool dummy[] = {
846  (at_end = at_end || std::get<I>(current_) == std::get<I>(end_))...};
847  (void)dummy;
848  return at_end;
849  }
850 
851  const ParamGeneratorInterface<ParamType>* const base_;
852  std::tuple<typename ParamGenerator<T>::iterator...> begin_;
853  std::tuple<typename ParamGenerator<T>::iterator...> end_;
854  std::tuple<typename ParamGenerator<T>::iterator...> current_;
855  std::shared_ptr<ParamType> current_value_;
856  };
857 
858  using Iterator = IteratorImpl<typename MakeIndexSequence<sizeof...(T)>::type>;
859 
860  std::tuple<ParamGenerator<T>...> generators_;
861 };
862 
863 template <class... Gen>
865  public:
866  CartesianProductHolder(const Gen&... g) : generators_(g...) {}
867  template <typename... T>
868  operator ParamGenerator<::std::tuple<T...>>() const {
869  return ParamGenerator<::std::tuple<T...>>(
870  new CartesianProductGenerator<T...>(generators_));
871  }
872 
873  private:
874  std::tuple<Gen...> generators_;
875 };
876 
877 } // namespace internal
878 } // namespace testing
879 
880 #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
std::string GetString() const
ParamIteratorInterface< ParamType > * Begin() const override
ParamIteratorInterface< ParamType > * End() const override
CartesianProductGenerator(const std::tuple< ParamGenerator< T >... > &g)
ParamGenerator(const ParamGenerator &other)
ParamGenerator & operator=(const ParamGenerator &other)
ParamGenerator(ParamGeneratorInterface< T > *impl)
virtual ParamIteratorInterface< T > * Begin() const =0
virtual ParamIteratorInterface< T > * End() const =0
bool operator!=(const ParamIterator &other) const
ParamIterator & operator=(const ParamIterator &other)
ParamIterator(const ParamIterator &other)
bool operator==(const ParamIterator &other) const
virtual const ParamGeneratorInterface< T > * BaseGenerator() const =0
virtual ParamIteratorInterface * Clone() const =0
virtual bool Equals(const ParamIteratorInterface &other) const =0
virtual const T * Current() const =0
virtual const std::string & GetTestSuiteName() const =0
void AddTestPattern(const char *test_suite_name, const char *test_base_name, TestMetaFactoryBase< ParamType > *meta_factory)
int AddTestSuiteInstantiation(const std::string &instantiation_name, GeneratorCreationFunc *func, ParamNameGeneratorFunc *name_func, const char *file, int line)
std::string(const TestParamInfo< ParamType > &) ParamNameGeneratorFunc
const std::string & GetTestSuiteName() const override
ParameterizedTestSuiteInfo(const char *name, CodeLocation code_location)
ParameterizedTestCaseInfo< TestCase > * GetTestCasePatternHolder(const char *test_case_name, CodeLocation code_location)
ParameterizedTestSuiteInfo< TestSuite > * GetTestSuitePatternHolder(const char *test_suite_name, CodeLocation code_location)
ParamIteratorInterface< T > * Begin() const override
RangeGenerator(T begin, T end, IncrementT step)
ParamIteratorInterface< T > * End() const override
virtual TestFactoryBase * CreateTestFactory(ParamType parameter)=0
typename TestSuite::ParamType ParamType
TestFactoryBase * CreateTestFactory(ParamType parameter) override
ParamIteratorInterface< T > * End() const override
ParamIteratorInterface< T > * Begin() const override
ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
void end(void)
#define GTEST_API_
Definition: gtest-port.h:774
#define GTEST_CHECK_(condition)
Definition: gtest-port.h:1046
__host__ __device__ __forceinline__ T & get(array< T, m > &src)
Definition: array.h:87
GTEST_API_ void ReportInvalidTestSuiteType(const char *test_suite_name, CodeLocation code_location)
GTEST_API_ TestInfo * MakeAndRegisterTestInfo(const char *test_suite_name, const char *name, const char *type_param, const char *value_param, CodeLocation code_location, TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc, TearDownTestSuiteFunc tear_down_tc, TestFactoryBase *factory)
::std::string string
Definition: gtest-port.h:891
std::string DefaultParamName(const TestParamInfo< ParamType > &info)
const void * TypeId
Derived * CheckedDowncastToActualType(Base *base)
Definition: gtest-port.h:1167
internal::ParamGenerator< typename ::testing::internal::IteratorTraits< ForwardIterator >::value_type > ValuesIn(ForwardIterator begin, ForwardIterator end)
::std::string PrintToString(const T &value)
std::string operator()(const TestParamInfo< ParamType > &info) const
TestParamInfo(const ParamType &a_param, size_t an_index)