36 #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ 37 #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ 49 #include <type_traits> 61 template <
class ParamType>
72 template <
class ParamType>
88 CodeLocation code_location);
109 virtual void Advance() = 0;
117 virtual const T* Current()
const = 0;
127 template <
typename T>
137 if (
this != &other) impl_.reset(other.impl_->Clone());
141 const T&
operator*()
const {
return *impl_->Current(); }
155 return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
158 return !(*
this == other);
164 std::unique_ptr<ParamIteratorInterface<T>> impl_;
169 template <
typename T>
186 template <
typename T>
199 iterator
begin()
const {
return iterator(impl_->Begin()); }
200 iterator
end()
const {
return iterator(impl_->End()); }
203 std::shared_ptr<const ParamGeneratorInterface<T>> impl_;
210 template <
typename T,
typename IncrementT>
217 end_index_(CalculateEndIndex(begin, end, step)) {}
221 return new Iterator(
this, begin_, 0, step_);
224 return new Iterator(
this, end_, end_index_, step_);
232 : base_(base), value_(value), index_(index), step_(step) {}
233 ~Iterator()
override {}
238 void Advance()
override {
239 value_ =
static_cast<T
>(value_ + step_);
243 return new Iterator(*
this);
245 const T* Current()
const override {
return &value_; }
250 <<
"The program attempted to compare iterators " 251 <<
"from different generators." << std::endl;
252 const int other_index =
253 CheckedDowncastToActualType<const Iterator>(&other)->index_;
254 return index_ == other_index;
258 Iterator(
const Iterator& other)
261 value_(other.value_),
262 index_(other.index_),
263 step_(other.step_) {}
266 void operator=(
const Iterator& other);
271 const IncrementT step_;
274 static int CalculateEndIndex(
const T& begin,
const T& end,
275 const IncrementT& step) {
277 for (T
i = begin; i < end; i = static_cast<T>(
i + step)) end_index++;
286 const IncrementT step_;
289 const int end_index_;
296 template <
typename T>
299 template <
typename ForwardIterator>
301 : container_(begin, end) {}
305 return new Iterator(
this, container_.begin());
308 return new Iterator(
this, container_.end());
312 typedef typename ::std::vector<T> ContainerType;
317 typename ContainerType::const_iterator iterator)
318 : base_(base), iterator_(iterator) {}
319 ~Iterator()
override {}
324 void Advance()
override {
329 return new Iterator(*
this);
338 const T* Current()
const override {
339 if (value_.get() ==
nullptr) value_.reset(
new T(*iterator_));
346 <<
"The program attempted to compare iterators " 347 <<
"from different generators." << std::endl;
349 CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
353 Iterator(
const Iterator& other)
358 iterator_(other.iterator_) {}
361 typename ContainerType::const_iterator iterator_;
367 mutable std::unique_ptr<const T> value_;
373 const ContainerType container_;
380 template <
class ParamType>
383 name_stream << info.
index;
387 template <
typename T =
int>
389 static_assert(
sizeof(T) == 0,
"Empty arguments are not allowed.");
391 template <
typename T =
int>
398 template <
class TestClass>
403 : parameter_(parameter) {}
405 TestClass::SetParam(¶meter_);
406 return new TestClass();
410 const ParamType parameter_;
420 template <
class ParamType>
436 template <
class TestSuite>
468 virtual const std::string& GetTestSuiteName()
const = 0;
470 virtual TypeId GetTestSuiteTypeId()
const = 0;
475 virtual void RegisterTests() = 0;
505 template <
class TestSuite>
518 : test_suite_name_(name), code_location_(code_location) {}
522 return test_suite_name_;
535 tests_.push_back(std::shared_ptr<TestInfo>(
new TestInfo(
536 test_suite_name, test_base_name, meta_factory, code_location)));
541 GeneratorCreationFunc* func,
543 const char* file,
int line) {
544 instantiations_.push_back(
545 InstantiationInfo(instantiation_name, func, name_func, file, line));
554 bool generated_instantiations =
false;
556 for (
typename TestInfoContainer::iterator test_it = tests_.begin();
557 test_it != tests_.end(); ++test_it) {
558 std::shared_ptr<TestInfo> test_info = *test_it;
559 for (
typename InstantiationContainer::iterator gen_it =
560 instantiations_.begin();
561 gen_it != instantiations_.end(); ++gen_it) {
562 const std::string& instantiation_name = gen_it->name;
565 const char* file = gen_it->file;
566 int line = gen_it->line;
568 std::string test_suite_name;
569 if (!instantiation_name.empty())
570 test_suite_name = instantiation_name +
"/";
571 test_suite_name += test_info->test_suite_base_name;
574 std::set<std::string> test_param_names;
577 param_it != generator.
end(); ++param_it, ++
i) {
578 generated_instantiations =
true;
582 std::string param_name =
586 <<
"Parameterized test name '" << param_name
587 <<
"' is invalid, in " << file <<
" line " << line << std::endl;
590 <<
"Duplicate parameterized test name '" << param_name <<
"', in " 591 << file <<
" line " << line << std::endl;
593 test_param_names.insert(param_name);
595 if (!test_info->test_base_name.empty()) {
596 test_name_stream << test_info->test_base_name <<
"/";
598 test_name_stream << param_name;
600 test_suite_name.c_str(), test_name_stream.
GetString().c_str(),
603 GetTestSuiteTypeId(),
606 test_info->test_meta_factory->CreateTestFactory(*param_it));
611 if (!generated_instantiations) {
622 TestInfo(
const char* a_test_suite_base_name,
const char* a_test_base_name,
625 : test_suite_base_name(a_test_suite_base_name),
626 test_base_name(a_test_base_name),
627 test_meta_factory(a_test_meta_factory),
628 code_location(a_code_location) {}
630 const std::string test_suite_base_name;
631 const std::string test_base_name;
632 const std::unique_ptr<TestMetaFactoryBase<ParamType>> test_meta_factory;
635 using TestInfoContainer = ::std::vector<std::shared_ptr<TestInfo>>;
639 struct InstantiationInfo {
640 InstantiationInfo(
const std::string& name_in,
641 GeneratorCreationFunc* generator_in,
645 generator(generator_in),
646 name_func(name_func_in),
651 GeneratorCreationFunc* generator;
656 typedef ::std::vector<InstantiationInfo> InstantiationContainer;
658 static bool IsValidParamName(
const std::string& name) {
660 if (name.empty())
return false;
670 const std::string test_suite_name_;
672 TestInfoContainer tests_;
673 InstantiationContainer instantiations_;
681 #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ 682 template <
class TestCase>
684 #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ 696 for (
auto& test_suite_info : test_suite_infos_) {
697 delete test_suite_info;
703 template <
class TestSuite>
705 const char* test_suite_name,
CodeLocation code_location) {
707 for (
auto& test_suite_info : test_suite_infos_) {
708 if (test_suite_info->GetTestSuiteName() == test_suite_name) {
709 if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
725 if (typed_test_info ==
nullptr) {
727 test_suite_name, code_location);
728 test_suite_infos_.push_back(typed_test_info);
730 return typed_test_info;
733 for (
auto& test_suite_info : test_suite_infos_) {
734 test_suite_info->RegisterTests();
738 #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ 739 template <
class TestCase>
741 const char* test_case_name,
CodeLocation code_location) {
742 return GetTestSuitePatternHolder<TestCase>(test_case_name, code_location);
745 #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ 748 using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;
750 TestSuiteInfoContainer test_suite_infos_;
764 void RegisterTestSuite(
const char* test_suite_name,
768 void RegisterInstantiation(
const char* test_suite_name);
772 void CheckForInstantiations();
775 struct TypeParameterizedTestSuiteInfo {
777 : code_location(c), instantiated(
false) {}
783 std::map<std::string, TypeParameterizedTestSuiteInfo> suites_;
790 template <
class Container>
792 const Container& container);
798 #pragma warning(push) 799 #pragma warning(disable : 4100) 802 template <
typename... Ts>
807 template <
typename T>
813 template <
typename T,
size_t... I>
815 return std::vector<T>{
static_cast<T
>(v_.template Get<I>())...};
825 template <
typename... T>
836 return new Iterator(
this, generators_,
false);
839 return new Iterator(
this, generators_,
true);
845 template <
size_t... I>
846 class IteratorImpl<IndexSequence<I...>>
853 begin_(std::get<I>(generators).begin()...),
854 end_(std::get<I>(generators).end()...),
855 current_(is_end ? end_ : begin_) {
856 ComputeCurrentValue();
858 ~IteratorImpl()
override {}
865 void Advance()
override {
868 ++std::get<
sizeof...(T) - 1>(current_);
870 AdvanceIfEnd<
sizeof...(T) - 1>();
871 ComputeCurrentValue();
874 return new IteratorImpl(*
this);
877 const ParamType* Current()
const override {
return current_value_.get(); }
883 <<
"The program attempted to compare iterators " 884 <<
"from different generators." << std::endl;
885 const IteratorImpl* typed_other =
886 CheckedDowncastToActualType<const IteratorImpl>(&other);
891 if (AtEnd() && typed_other->AtEnd())
return true;
895 (same = same && std::get<I>(current_) ==
896 std::get<I>(typed_other->current_))...};
902 template <
size_t ThisI>
903 void AdvanceIfEnd() {
904 if (std::get<ThisI>(current_) != std::get<ThisI>(end_))
return;
906 bool last = ThisI == 0;
912 constexpr
size_t NextI = ThisI - (ThisI != 0);
913 std::get<ThisI>(current_) = std::get<ThisI>(begin_);
914 ++std::get<NextI>(current_);
915 AdvanceIfEnd<NextI>();
918 void ComputeCurrentValue() {
920 current_value_ = std::make_shared<ParamType>(*std::get<I>(current_)...);
925 (at_end = at_end || std::get<I>(current_) == std::get<I>(end_))...};
931 std::tuple<typename ParamGenerator<T>::iterator...> begin_;
932 std::tuple<typename ParamGenerator<T>::iterator...> end_;
933 std::tuple<typename ParamGenerator<T>::iterator...> current_;
934 std::shared_ptr<ParamType> current_value_;
939 std::tuple<ParamGenerator<T>...> generators_;
942 template <
class... Gen>
946 template <
typename... T>
953 std::tuple<Gen...> generators_;
956 template <
typename From,
typename To>
960 : generator_(
std::move(gen)) {}
963 return new Iterator(
this, generator_.begin(), generator_.end());
966 return new Iterator(
this, generator_.end(), generator_.end());
974 : base_(base), it_(it), end_(end) {
975 if (it_ != end_) value_ = std::make_shared<To>(
static_cast<To
>(*it_));
977 ~Iterator()
override {}
982 void Advance()
override {
984 if (it_ != end_) value_ = std::make_shared<To>(
static_cast<To
>(*it_));
987 return new Iterator(*
this);
989 const To* Current()
const override {
return value_.get(); }
994 <<
"The program attempted to compare iterators " 995 <<
"from different generators." << std::endl;
997 CheckedDowncastToActualType<const Iterator>(&other)->it_;
998 return it_ == other_it;
1002 Iterator(
const Iterator& other) =
default;
1007 std::shared_ptr<To> value_;
1013 template <
class Gen>
1017 : generator_(
std::move(g)) {}
1019 template <
typename T>
1031 #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ void TestNotEmpty(const T &)
GTEST_API_ void InsertSyntheticTestCase(const std::string &name, CodeLocation location, bool has_test_p)
virtual ~ParamIteratorInterface()
TypeId GetTestSuiteTypeId() const override
std::string operator()(const TestParamInfo< ParamType > &info) const
~ParameterizedTestSuiteRegistry()
~CartesianProductGenerator() override
ParamIteratorInterface< T > * End() const override
::std::string PrintToString(const T &value)
constexpr bool Equals(const char(&a)[N], const char(&b)[M])
ParamConverterGenerator(ParamGenerator< Gen > g)
TestParamInfo(const ParamType &a_param, size_t an_index)
ParamGenerator(const ParamGenerator &other)
ParamIteratorInterface< To > * Begin() const override
RangeGenerator(T begin, T end, IncrementT step)
ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
internal::ParamGenerator< typename std::iterator_traits< ForwardIterator >::value_type > ValuesIn(ForwardIterator begin, ForwardIterator end)
void AddTestPattern(const char *test_suite_name, const char *test_base_name, TestMetaFactoryBase< ParamType > *meta_factory, CodeLocation code_location)
ParamIterator(const ParamIterator &other)
Test * CreateTest() override
ParamIteratorInterface< T > * Begin() const override
virtual ~ParameterizedTestSuiteInfoBase()
ParameterizedTestSuiteRegistry()
typename MakeIndexSequenceImpl< N >::type MakeIndexSequence
ParamIteratorInterface< To > * End() const override
void RegisterTests() override
CartesianProductHolder(const Gen &... g)
int AddTestSuiteInstantiation(const std::string &instantiation_name, GeneratorCreationFunc *func, ParamNameGeneratorFunc *name_func, const char *file, int line)
#define GTEST_CHECK_(condition)
~RangeGenerator() override
TestClass::ParamType ParamType
ParameterizedTestSuiteInfoBase()
ParamIterator operator++(int)
ptrdiff_t difference_type
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)
bool operator==(const ParamIterator &other) const
std::string(const TestParamInfo< ParamType > &) ParamNameGeneratorFunc
ParamGeneratorConverter(ParamGenerator< From > gen)
virtual ~ParamGeneratorInterface()
ParamIterator< T > iterator
CartesianProductGenerator(const std::tuple< ParamGenerator< T >... > &g)
ParameterizedTestSuiteInfo(const char *name, CodeLocation code_location)
ParameterizedTestSuiteInfo< TestSuite > * GetTestSuitePatternHolder(const char *test_suite_name, CodeLocation code_location)
::std::tuple< T... > ParamType
std::string DefaultParamName(const TestParamInfo< ParamType > &info)
std::string GetString() const
virtual const ParamGeneratorInterface< T > * BaseGenerator() const =0
const T & operator*() const
ParamIteratorInterface< T > * Begin() const override
GTEST_API_ void ReportInvalidTestSuiteType(const char *test_suite_name, CodeLocation code_location)
ParameterizedTestFactory(ParamType parameter)
ParamIteratorInterface< T > * End() const override
bool operator!=(const ParamIterator &other) const
ParamGenerator & operator=(const ParamGenerator &other)
ParamIteratorInterface< ParamType > * Begin() const override
ParameterizedTestCaseInfo< TestCase > * GetTestCasePatternHolder(const char *test_case_name, CodeLocation code_location)
~ValuesInIteratorRangeGenerator() override
const std::string & GetTestSuiteName() const override
const T * operator->() const
virtual ParamIteratorInterface * Clone() const =0
ParamGenerator(ParamGeneratorInterface< T > *impl)
Derived * CheckedDowncastToActualType(Base *base)
typename TestSuite::ParamType ParamType
ParamIterator & operator=(const ParamIterator &other)
ParamIteratorInterface< ParamType > * End() const override
ParamIterator & operator++()