PageRenderTime 3ms CodeModel.GetById 16ms app.highlight 30ms RepoModel.GetById 2ms app.codeStats 0ms

/Unittests/googletest/include/gtest/internal/gtest-param-util.h

http://unladen-swallow.googlecode.com/
C++ Header | 638 lines | 380 code | 74 blank | 184 comment | 32 complexity | 6cb50bcd9105e7f9cbed906a65d943ac MD5 | raw 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// Author: vladl@google.com (Vlad Losev)
 31
 32// Type and function utilities for implementing parameterized tests.
 33
 34#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
 35#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
 36
 37#include <iterator>
 38#include <utility>
 39#include <vector>
 40
 41#include <gtest/internal/gtest-port.h>
 42
 43#if GTEST_HAS_PARAM_TEST
 44
 45#if GTEST_HAS_RTTI
 46#include <typeinfo>
 47#endif  // GTEST_HAS_RTTI
 48
 49#include <gtest/internal/gtest-linked_ptr.h>
 50#include <gtest/internal/gtest-internal.h>
 51
 52namespace testing {
 53namespace internal {
 54
 55// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
 56//
 57// Outputs a message explaining invalid registration of different
 58// fixture class for the same test case. This may happen when
 59// TEST_P macro is used to define two tests with the same name
 60// but in different namespaces.
 61void ReportInvalidTestCaseType(const char* test_case_name,
 62                               const char* file, int line);
 63
 64// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
 65//
 66// Downcasts the pointer of type Base to Derived.
 67// Derived must be a subclass of Base. The parameter MUST
 68// point to a class of type Derived, not any subclass of it.
 69// When RTTI is available, the function performs a runtime
 70// check to enforce this.
 71template <class Derived, class Base>
 72Derived* CheckedDowncastToActualType(Base* base) {
 73#if GTEST_HAS_RTTI
 74  GTEST_CHECK_(typeid(*base) == typeid(Derived));
 75  Derived* derived = dynamic_cast<Derived*>(base);  // NOLINT
 76#else
 77  Derived* derived = static_cast<Derived*>(base);  // Poor man's downcast.
 78#endif  // GTEST_HAS_RTTI
 79  return derived;
 80}
 81
 82template <typename> class ParamGeneratorInterface;
 83template <typename> class ParamGenerator;
 84
 85// Interface for iterating over elements provided by an implementation
 86// of ParamGeneratorInterface<T>.
 87template <typename T>
 88class ParamIteratorInterface {
 89 public:
 90  virtual ~ParamIteratorInterface() {}
 91  // A pointer to the base generator instance.
 92  // Used only for the purposes of iterator comparison
 93  // to make sure that two iterators belong to the same generator.
 94  virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;
 95  // Advances iterator to point to the next element
 96  // provided by the generator. The caller is responsible
 97  // for not calling Advance() on an iterator equal to
 98  // BaseGenerator()->End().
 99  virtual void Advance() = 0;
100  // Clones the iterator object. Used for implementing copy semantics
101  // of ParamIterator<T>.
102  virtual ParamIteratorInterface* Clone() const = 0;
103  // Dereferences the current iterator and provides (read-only) access
104  // to the pointed value. It is the caller's responsibility not to call
105  // Current() on an iterator equal to BaseGenerator()->End().
106  // Used for implementing ParamGenerator<T>::operator*().
107  virtual const T* Current() const = 0;
108  // Determines whether the given iterator and other point to the same
109  // element in the sequence generated by the generator.
110  // Used for implementing ParamGenerator<T>::operator==().
111  virtual bool Equals(const ParamIteratorInterface& other) const = 0;
112};
113
114// Class iterating over elements provided by an implementation of
115// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
116// and implements the const forward iterator concept.
117template <typename T>
118class ParamIterator {
119 public:
120  typedef T value_type;
121  typedef const T& reference;
122  typedef ptrdiff_t difference_type;
123
124  // ParamIterator assumes ownership of the impl_ pointer.
125  ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
126  ParamIterator& operator=(const ParamIterator& other) {
127    if (this != &other)
128      impl_.reset(other.impl_->Clone());
129    return *this;
130  }
131
132  const T& operator*() const { return *impl_->Current(); }
133  const T* operator->() const { return impl_->Current(); }
134  // Prefix version of operator++.
135  ParamIterator& operator++() {
136    impl_->Advance();
137    return *this;
138  }
139  // Postfix version of operator++.
140  ParamIterator operator++(int /*unused*/) {
141    ParamIteratorInterface<T>* clone = impl_->Clone();
142    impl_->Advance();
143    return ParamIterator(clone);
144  }
145  bool operator==(const ParamIterator& other) const {
146    return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
147  }
148  bool operator!=(const ParamIterator& other) const {
149    return !(*this == other);
150  }
151
152 private:
153  friend class ParamGenerator<T>;
154  explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
155  scoped_ptr<ParamIteratorInterface<T> > impl_;
156};
157
158// ParamGeneratorInterface<T> is the binary interface to access generators
159// defined in other translation units.
160template <typename T>
161class ParamGeneratorInterface {
162 public:
163  typedef T ParamType;
164
165  virtual ~ParamGeneratorInterface() {}
166
167  // Generator interface definition
168  virtual ParamIteratorInterface<T>* Begin() const = 0;
169  virtual ParamIteratorInterface<T>* End() const = 0;
170};
171
172// Wraps ParamGeneratorInetrface<T> and provides general generator syntax
173// compatible with the STL Container concept.
174// This class implements copy initialization semantics and the contained
175// ParamGeneratorInterface<T> instance is shared among all copies
176// of the original object. This is possible because that instance is immutable.
177template<typename T>
178class ParamGenerator {
179 public:
180  typedef ParamIterator<T> iterator;
181
182  explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}
183  ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}
184
185  ParamGenerator& operator=(const ParamGenerator& other) {
186    impl_ = other.impl_;
187    return *this;
188  }
189
190  iterator begin() const { return iterator(impl_->Begin()); }
191  iterator end() const { return iterator(impl_->End()); }
192
193 private:
194  ::testing::internal::linked_ptr<const ParamGeneratorInterface<T> > impl_;
195};
196
197// Generates values from a range of two comparable values. Can be used to
198// generate sequences of user-defined types that implement operator+() and
199// operator<().
200// This class is used in the Range() function.
201template <typename T, typename IncrementT>
202class RangeGenerator : public ParamGeneratorInterface<T> {
203 public:
204  RangeGenerator(T begin, T end, IncrementT step)
205      : begin_(begin), end_(end),
206        step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
207  virtual ~RangeGenerator() {}
208
209  virtual ParamIteratorInterface<T>* Begin() const {
210    return new Iterator(this, begin_, 0, step_);
211  }
212  virtual ParamIteratorInterface<T>* End() const {
213    return new Iterator(this, end_, end_index_, step_);
214  }
215
216 private:
217  class Iterator : public ParamIteratorInterface<T> {
218   public:
219    Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
220             IncrementT step)
221        : base_(base), value_(value), index_(index), step_(step) {}
222    virtual ~Iterator() {}
223
224    virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
225      return base_;
226    }
227    virtual void Advance() {
228      value_ = value_ + step_;
229      index_++;
230    }
231    virtual ParamIteratorInterface<T>* Clone() const {
232      return new Iterator(*this);
233    }
234    virtual const T* Current() const { return &value_; }
235    virtual bool Equals(const ParamIteratorInterface<T>& other) const {
236      // Having the same base generator guarantees that the other
237      // iterator is of the same type and we can downcast.
238      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
239          << "The program attempted to compare iterators "
240          << "from different generators." << std::endl;
241      const int other_index =
242          CheckedDowncastToActualType<const Iterator>(&other)->index_;
243      return index_ == other_index;
244    }
245
246   private:
247    Iterator(const Iterator& other)
248        : base_(other.base_), value_(other.value_), index_(other.index_),
249          step_(other.step_) {}
250
251    // No implementation - assignment is unsupported.
252    void operator=(const Iterator& other);
253
254    const ParamGeneratorInterface<T>* const base_;
255    T value_;
256    int index_;
257    const IncrementT step_;
258  };  // class RangeGenerator::Iterator
259
260  static int CalculateEndIndex(const T& begin,
261                               const T& end,
262                               const IncrementT& step) {
263    int end_index = 0;
264    for (T i = begin; i < end; i = i + step)
265      end_index++;
266    return end_index;
267  }
268
269  // No implementation - assignment is unsupported.
270  void operator=(const RangeGenerator& other);
271
272  const T begin_;
273  const T end_;
274  const IncrementT step_;
275  // The index for the end() iterator. All the elements in the generated
276  // sequence are indexed (0-based) to aid iterator comparison.
277  const int end_index_;
278};  // class RangeGenerator
279
280
281// Generates values from a pair of STL-style iterators. Used in the
282// ValuesIn() function. The elements are copied from the source range
283// since the source can be located on the stack, and the generator
284// is likely to persist beyond that stack frame.
285template <typename T>
286class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
287 public:
288  template <typename ForwardIterator>
289  ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
290      : container_(begin, end) {}
291  virtual ~ValuesInIteratorRangeGenerator() {}
292
293  virtual ParamIteratorInterface<T>* Begin() const {
294    return new Iterator(this, container_.begin());
295  }
296  virtual ParamIteratorInterface<T>* End() const {
297    return new Iterator(this, container_.end());
298  }
299
300 private:
301  typedef typename ::std::vector<T> ContainerType;
302
303  class Iterator : public ParamIteratorInterface<T> {
304   public:
305    Iterator(const ParamGeneratorInterface<T>* base,
306             typename ContainerType::const_iterator iterator)
307        :  base_(base), iterator_(iterator) {}
308    virtual ~Iterator() {}
309
310    virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
311      return base_;
312    }
313    virtual void Advance() {
314      ++iterator_;
315      value_.reset();
316    }
317    virtual ParamIteratorInterface<T>* Clone() const {
318      return new Iterator(*this);
319    }
320    // We need to use cached value referenced by iterator_ because *iterator_
321    // can return a temporary object (and of type other then T), so just
322    // having "return &*iterator_;" doesn't work.
323    // value_ is updated here and not in Advance() because Advance()
324    // can advance iterator_ beyond the end of the range, and we cannot
325    // detect that fact. The client code, on the other hand, is
326    // responsible for not calling Current() on an out-of-range iterator.
327    virtual const T* Current() const {
328      if (value_.get() == NULL)
329        value_.reset(new T(*iterator_));
330      return value_.get();
331    }
332    virtual bool Equals(const ParamIteratorInterface<T>& other) const {
333      // Having the same base generator guarantees that the other
334      // iterator is of the same type and we can downcast.
335      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
336          << "The program attempted to compare iterators "
337          << "from different generators." << std::endl;
338      return iterator_ ==
339          CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
340    }
341
342   private:
343    Iterator(const Iterator& other)
344          // The explicit constructor call suppresses a false warning
345          // emitted by gcc when supplied with the -Wextra option.
346        : ParamIteratorInterface<T>(),
347          base_(other.base_),
348          iterator_(other.iterator_) {}
349
350    const ParamGeneratorInterface<T>* const base_;
351    typename ContainerType::const_iterator iterator_;
352    // A cached value of *iterator_. We keep it here to allow access by
353    // pointer in the wrapping iterator's operator->().
354    // value_ needs to be mutable to be accessed in Current().
355    // Use of scoped_ptr helps manage cached value's lifetime,
356    // which is bound by the lifespan of the iterator itself.
357    mutable scoped_ptr<const T> value_;
358  };  // class ValuesInIteratorRangeGenerator::Iterator
359
360  // No implementation - assignment is unsupported.
361  void operator=(const ValuesInIteratorRangeGenerator& other);
362
363  const ContainerType container_;
364};  // class ValuesInIteratorRangeGenerator
365
366// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
367//
368// Stores a parameter value and later creates tests parameterized with that
369// value.
370template <class TestClass>
371class ParameterizedTestFactory : public TestFactoryBase {
372 public:
373  typedef typename TestClass::ParamType ParamType;
374  explicit ParameterizedTestFactory(ParamType parameter) :
375      parameter_(parameter) {}
376  virtual Test* CreateTest() {
377    TestClass::SetParam(&parameter_);
378    return new TestClass();
379  }
380
381 private:
382  const ParamType parameter_;
383
384  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory);
385};
386
387// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
388//
389// TestMetaFactoryBase is a base class for meta-factories that create
390// test factories for passing into MakeAndRegisterTestInfo function.
391template <class ParamType>
392class TestMetaFactoryBase {
393 public:
394  virtual ~TestMetaFactoryBase() {}
395
396  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
397};
398
399// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
400//
401// TestMetaFactory creates test factories for passing into
402// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
403// ownership of test factory pointer, same factory object cannot be passed
404// into that method twice. But ParameterizedTestCaseInfo is going to call
405// it for each Test/Parameter value combination. Thus it needs meta factory
406// creator class.
407template <class TestCase>
408class TestMetaFactory
409    : public TestMetaFactoryBase<typename TestCase::ParamType> {
410 public:
411  typedef typename TestCase::ParamType ParamType;
412
413  TestMetaFactory() {}
414
415  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) {
416    return new ParameterizedTestFactory<TestCase>(parameter);
417  }
418
419 private:
420  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory);
421};
422
423// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
424//
425// ParameterizedTestCaseInfoBase is a generic interface
426// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase
427// accumulates test information provided by TEST_P macro invocations
428// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations
429// and uses that information to register all resulting test instances
430// in RegisterTests method. The ParameterizeTestCaseRegistry class holds
431// a collection of pointers to the ParameterizedTestCaseInfo objects
432// and calls RegisterTests() on each of them when asked.
433class ParameterizedTestCaseInfoBase {
434 public:
435  virtual ~ParameterizedTestCaseInfoBase() {}
436
437  // Base part of test case name for display purposes.
438  virtual const String& GetTestCaseName() const = 0;
439  // Test case id to verify identity.
440  virtual TypeId GetTestCaseTypeId() const = 0;
441  // UnitTest class invokes this method to register tests in this
442  // test case right before running them in RUN_ALL_TESTS macro.
443  // This method should not be called more then once on any single
444  // instance of a ParameterizedTestCaseInfoBase derived class.
445  virtual void RegisterTests() = 0;
446
447 protected:
448  ParameterizedTestCaseInfoBase() {}
449
450 private:
451  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase);
452};
453
454// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
455//
456// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P
457// macro invocations for a particular test case and generators
458// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that
459// test case. It registers tests with all values generated by all
460// generators when asked.
461template <class TestCase>
462class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
463 public:
464  // ParamType and GeneratorCreationFunc are private types but are required
465  // for declarations of public methods AddTestPattern() and
466  // AddTestCaseInstantiation().
467  typedef typename TestCase::ParamType ParamType;
468  // A function that returns an instance of appropriate generator type.
469  typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
470
471  explicit ParameterizedTestCaseInfo(const char* name)
472      : test_case_name_(name) {}
473
474  // Test case base name for display purposes.
475  virtual const String& GetTestCaseName() const { return test_case_name_; }
476  // Test case id to verify identity.
477  virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); }
478  // TEST_P macro uses AddTestPattern() to record information
479  // about a single test in a LocalTestInfo structure.
480  // test_case_name is the base name of the test case (without invocation
481  // prefix). test_base_name is the name of an individual test without
482  // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
483  // test case base name and DoBar is test base name.
484  void AddTestPattern(const char* test_case_name,
485                      const char* test_base_name,
486                      TestMetaFactoryBase<ParamType>* meta_factory) {
487    tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name,
488                                                       test_base_name,
489                                                       meta_factory)));
490  }
491  // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information
492  // about a generator.
493  int AddTestCaseInstantiation(const char* instantiation_name,
494                               GeneratorCreationFunc* func,
495                               const char* /* file */,
496                               int /* line */) {
497    instantiations_.push_back(::std::make_pair(instantiation_name, func));
498    return 0;  // Return value used only to run this method in namespace scope.
499  }
500  // UnitTest class invokes this method to register tests in this test case
501  // test cases right before running tests in RUN_ALL_TESTS macro.
502  // This method should not be called more then once on any single
503  // instance of a ParameterizedTestCaseInfoBase derived class.
504  // UnitTest has a guard to prevent from calling this method more then once.
505  virtual void RegisterTests() {
506    for (typename TestInfoContainer::iterator test_it = tests_.begin();
507         test_it != tests_.end(); ++test_it) {
508      linked_ptr<TestInfo> test_info = *test_it;
509      for (typename InstantiationContainer::iterator gen_it =
510               instantiations_.begin(); gen_it != instantiations_.end();
511               ++gen_it) {
512        const String& instantiation_name = gen_it->first;
513        ParamGenerator<ParamType> generator((*gen_it->second)());
514
515        Message test_case_name_stream;
516        if ( !instantiation_name.empty() )
517          test_case_name_stream << instantiation_name.c_str() << "/";
518        test_case_name_stream << test_info->test_case_base_name.c_str();
519
520        int i = 0;
521        for (typename ParamGenerator<ParamType>::iterator param_it =
522                 generator.begin();
523             param_it != generator.end(); ++param_it, ++i) {
524          Message test_name_stream;
525          test_name_stream << test_info->test_base_name.c_str() << "/" << i;
526          ::testing::internal::MakeAndRegisterTestInfo(
527              test_case_name_stream.GetString().c_str(),
528              test_name_stream.GetString().c_str(),
529              "",  // test_case_comment
530              "",  // comment; TODO(vladl@google.com): provide parameter value
531                   //                                  representation.
532              GetTestCaseTypeId(),
533              TestCase::SetUpTestCase,
534              TestCase::TearDownTestCase,
535              test_info->test_meta_factory->CreateTestFactory(*param_it));
536        }  // for param_it
537      }  // for gen_it
538    }  // for test_it
539  }  // RegisterTests
540
541 private:
542  // LocalTestInfo structure keeps information about a single test registered
543  // with TEST_P macro.
544  struct TestInfo {
545    TestInfo(const char* test_case_base_name,
546             const char* test_base_name,
547             TestMetaFactoryBase<ParamType>* test_meta_factory) :
548        test_case_base_name(test_case_base_name),
549        test_base_name(test_base_name),
550        test_meta_factory(test_meta_factory) {}
551
552    const String test_case_base_name;
553    const String test_base_name;
554    const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
555  };
556  typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;
557  // Keeps pairs of <Instantiation name, Sequence generator creation function>
558  // received from INSTANTIATE_TEST_CASE_P macros.
559  typedef ::std::vector<std::pair<String, GeneratorCreationFunc*> >
560      InstantiationContainer;
561
562  const String test_case_name_;
563  TestInfoContainer tests_;
564  InstantiationContainer instantiations_;
565
566  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo);
567};  // class ParameterizedTestCaseInfo
568
569// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
570//
571// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase
572// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P
573// macros use it to locate their corresponding ParameterizedTestCaseInfo
574// descriptors.
575class ParameterizedTestCaseRegistry {
576 public:
577  ParameterizedTestCaseRegistry() {}
578  ~ParameterizedTestCaseRegistry() {
579    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
580         it != test_case_infos_.end(); ++it) {
581      delete *it;
582    }
583  }
584
585  // Looks up or creates and returns a structure containing information about
586  // tests and instantiations of a particular test case.
587  template <class TestCase>
588  ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
589      const char* test_case_name,
590      const char* file,
591      int line) {
592    ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;
593    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
594         it != test_case_infos_.end(); ++it) {
595      if ((*it)->GetTestCaseName() == test_case_name) {
596        if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) {
597          // Complain about incorrect usage of Google Test facilities
598          // and terminate the program since we cannot guaranty correct
599          // test case setup and tear-down in this case.
600          ReportInvalidTestCaseType(test_case_name,  file, line);
601          abort();
602        } else {
603          // At this point we are sure that the object we found is of the same
604          // type we are looking for, so we downcast it to that type
605          // without further checks.
606          typed_test_info = CheckedDowncastToActualType<
607              ParameterizedTestCaseInfo<TestCase> >(*it);
608        }
609        break;
610      }
611    }
612    if (typed_test_info == NULL) {
613      typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name);
614      test_case_infos_.push_back(typed_test_info);
615    }
616    return typed_test_info;
617  }
618  void RegisterTests() {
619    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
620         it != test_case_infos_.end(); ++it) {
621      (*it)->RegisterTests();
622    }
623  }
624
625 private:
626  typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer;
627
628  TestCaseInfoContainer test_case_infos_;
629
630  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry);
631};
632
633}  // namespace internal
634}  // namespace testing
635
636#endif  //  GTEST_HAS_PARAM_TEST
637
638#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_