File indexing completed on 2025-09-15 09:01:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
0037 #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
0038
0039 #include <ctype.h>
0040
0041 #include <cassert>
0042 #include <functional>
0043 #include <iterator>
0044 #include <map>
0045 #include <memory>
0046 #include <ostream>
0047 #include <set>
0048 #include <string>
0049 #include <tuple>
0050 #include <type_traits>
0051 #include <unordered_map>
0052 #include <utility>
0053 #include <vector>
0054
0055 #include "gtest/gtest-printers.h"
0056 #include "gtest/gtest-test-part.h"
0057 #include "gtest/internal/gtest-internal.h"
0058 #include "gtest/internal/gtest-port.h"
0059
0060 namespace testing {
0061
0062
0063 template <class ParamType>
0064 struct TestParamInfo {
0065 TestParamInfo(const ParamType& a_param, size_t an_index)
0066 : param(a_param), index(an_index) {}
0067 ParamType param;
0068 size_t index;
0069 };
0070
0071
0072
0073 struct PrintToStringParamName {
0074 template <class ParamType>
0075 std::string operator()(const TestParamInfo<ParamType>& info) const {
0076 return PrintToString(info.param);
0077 }
0078 };
0079
0080 namespace internal {
0081
0082
0083
0084
0085
0086
0087
0088
0089 GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
0090 const CodeLocation& code_location);
0091
0092 template <typename>
0093 class ParamGeneratorInterface;
0094 template <typename>
0095 class ParamGenerator;
0096
0097
0098
0099 template <typename T>
0100 class ParamIteratorInterface {
0101 public:
0102 virtual ~ParamIteratorInterface() = default;
0103
0104
0105
0106 virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;
0107
0108
0109
0110
0111 virtual void Advance() = 0;
0112
0113
0114 virtual ParamIteratorInterface* Clone() const = 0;
0115
0116
0117
0118
0119 virtual const T* Current() const = 0;
0120
0121
0122
0123 virtual bool Equals(const ParamIteratorInterface& other) const = 0;
0124 };
0125
0126
0127
0128
0129 template <typename T>
0130 class ParamIterator {
0131 public:
0132 typedef T value_type;
0133 typedef const T& reference;
0134 typedef ptrdiff_t difference_type;
0135
0136
0137 ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
0138 ParamIterator& operator=(const ParamIterator& other) {
0139 if (this != &other) impl_.reset(other.impl_->Clone());
0140 return *this;
0141 }
0142
0143 const T& operator*() const { return *impl_->Current(); }
0144 const T* operator->() const { return impl_->Current(); }
0145
0146 ParamIterator& operator++() {
0147 impl_->Advance();
0148 return *this;
0149 }
0150
0151 ParamIterator operator++(int ) {
0152 ParamIteratorInterface<T>* clone = impl_->Clone();
0153 impl_->Advance();
0154 return ParamIterator(clone);
0155 }
0156 bool operator==(const ParamIterator& other) const {
0157 return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
0158 }
0159 bool operator!=(const ParamIterator& other) const {
0160 return !(*this == other);
0161 }
0162
0163 private:
0164 friend class ParamGenerator<T>;
0165 explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
0166 std::unique_ptr<ParamIteratorInterface<T>> impl_;
0167 };
0168
0169
0170
0171 template <typename T>
0172 class ParamGeneratorInterface {
0173 public:
0174 typedef T ParamType;
0175
0176 virtual ~ParamGeneratorInterface() = default;
0177
0178
0179 virtual ParamIteratorInterface<T>* Begin() const = 0;
0180 virtual ParamIteratorInterface<T>* End() const = 0;
0181 };
0182
0183
0184
0185
0186
0187
0188 template <typename T>
0189 class ParamGenerator {
0190 public:
0191 typedef ParamIterator<T> iterator;
0192
0193 explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}
0194 ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}
0195
0196 ParamGenerator& operator=(const ParamGenerator& other) {
0197 impl_ = other.impl_;
0198 return *this;
0199 }
0200
0201 iterator begin() const { return iterator(impl_->Begin()); }
0202 iterator end() const { return iterator(impl_->End()); }
0203
0204 private:
0205 std::shared_ptr<const ParamGeneratorInterface<T>> impl_;
0206 };
0207
0208
0209
0210
0211
0212 template <typename T, typename IncrementT>
0213 class RangeGenerator : public ParamGeneratorInterface<T> {
0214 public:
0215 RangeGenerator(T begin, T end, IncrementT step)
0216 : begin_(begin),
0217 end_(end),
0218 step_(step),
0219 end_index_(CalculateEndIndex(begin, end, step)) {}
0220 ~RangeGenerator() override = default;
0221
0222 ParamIteratorInterface<T>* Begin() const override {
0223 return new Iterator(this, begin_, 0, step_);
0224 }
0225 ParamIteratorInterface<T>* End() const override {
0226 return new Iterator(this, end_, end_index_, step_);
0227 }
0228
0229 private:
0230 class Iterator : public ParamIteratorInterface<T> {
0231 public:
0232 Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
0233 IncrementT step)
0234 : base_(base), value_(value), index_(index), step_(step) {}
0235 ~Iterator() override = default;
0236
0237 const ParamGeneratorInterface<T>* BaseGenerator() const override {
0238 return base_;
0239 }
0240 void Advance() override {
0241 value_ = static_cast<T>(value_ + step_);
0242 index_++;
0243 }
0244 ParamIteratorInterface<T>* Clone() const override {
0245 return new Iterator(*this);
0246 }
0247 const T* Current() const override { return &value_; }
0248 bool Equals(const ParamIteratorInterface<T>& other) const override {
0249
0250
0251 GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
0252 << "The program attempted to compare iterators "
0253 << "from different generators." << std::endl;
0254 const int other_index =
0255 CheckedDowncastToActualType<const Iterator>(&other)->index_;
0256 return index_ == other_index;
0257 }
0258
0259 private:
0260 Iterator(const Iterator& other)
0261 : ParamIteratorInterface<T>(),
0262 base_(other.base_),
0263 value_(other.value_),
0264 index_(other.index_),
0265 step_(other.step_) {}
0266
0267
0268 void operator=(const Iterator& other);
0269
0270 const ParamGeneratorInterface<T>* const base_;
0271 T value_;
0272 int index_;
0273 const IncrementT step_;
0274 };
0275
0276 static int CalculateEndIndex(const T& begin, const T& end,
0277 const IncrementT& step) {
0278 int end_index = 0;
0279 for (T i = begin; i < end; i = static_cast<T>(i + step)) end_index++;
0280 return end_index;
0281 }
0282
0283
0284 void operator=(const RangeGenerator& other);
0285
0286 const T begin_;
0287 const T end_;
0288 const IncrementT step_;
0289
0290
0291 const int end_index_;
0292 };
0293
0294
0295
0296
0297
0298 template <typename T>
0299 class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
0300 public:
0301 template <typename ForwardIterator>
0302 ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
0303 : container_(begin, end) {}
0304 ~ValuesInIteratorRangeGenerator() override = default;
0305
0306 ParamIteratorInterface<T>* Begin() const override {
0307 return new Iterator(this, container_.begin());
0308 }
0309 ParamIteratorInterface<T>* End() const override {
0310 return new Iterator(this, container_.end());
0311 }
0312
0313 private:
0314 typedef typename ::std::vector<T> ContainerType;
0315
0316 class Iterator : public ParamIteratorInterface<T> {
0317 public:
0318 Iterator(const ParamGeneratorInterface<T>* base,
0319 typename ContainerType::const_iterator iterator)
0320 : base_(base), iterator_(iterator) {}
0321 ~Iterator() override = default;
0322
0323 const ParamGeneratorInterface<T>* BaseGenerator() const override {
0324 return base_;
0325 }
0326 void Advance() override {
0327 ++iterator_;
0328 value_.reset();
0329 }
0330 ParamIteratorInterface<T>* Clone() const override {
0331 return new Iterator(*this);
0332 }
0333
0334
0335
0336
0337
0338
0339
0340 const T* Current() const override {
0341 if (value_.get() == nullptr) value_.reset(new T(*iterator_));
0342 return value_.get();
0343 }
0344 bool Equals(const ParamIteratorInterface<T>& other) const override {
0345
0346
0347 GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
0348 << "The program attempted to compare iterators "
0349 << "from different generators." << std::endl;
0350 return iterator_ ==
0351 CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
0352 }
0353
0354 private:
0355 Iterator(const Iterator& other)
0356
0357
0358 : ParamIteratorInterface<T>(),
0359 base_(other.base_),
0360 iterator_(other.iterator_) {}
0361
0362 const ParamGeneratorInterface<T>* const base_;
0363 typename ContainerType::const_iterator iterator_;
0364
0365
0366
0367
0368
0369 mutable std::unique_ptr<const T> value_;
0370 };
0371
0372
0373 void operator=(const ValuesInIteratorRangeGenerator& other);
0374
0375 const ContainerType container_;
0376 };
0377
0378
0379
0380
0381
0382 template <class ParamType>
0383 std::string DefaultParamName(const TestParamInfo<ParamType>& info) {
0384 return std::to_string(info.index);
0385 }
0386
0387 template <typename T = int>
0388 void TestNotEmpty() {
0389 static_assert(sizeof(T) == 0, "Empty arguments are not allowed.");
0390 }
0391 template <typename T = int>
0392 void TestNotEmpty(const T&) {}
0393
0394
0395
0396
0397
0398 template <class TestClass>
0399 class ParameterizedTestFactory : public TestFactoryBase {
0400 public:
0401 typedef typename TestClass::ParamType ParamType;
0402 explicit ParameterizedTestFactory(ParamType parameter)
0403 : parameter_(parameter) {}
0404 Test* CreateTest() override {
0405 TestClass::SetParam(¶meter_);
0406 return new TestClass();
0407 }
0408
0409 private:
0410 const ParamType parameter_;
0411
0412 ParameterizedTestFactory(const ParameterizedTestFactory&) = delete;
0413 ParameterizedTestFactory& operator=(const ParameterizedTestFactory&) = delete;
0414 };
0415
0416
0417
0418
0419
0420 template <class ParamType>
0421 class TestMetaFactoryBase {
0422 public:
0423 virtual ~TestMetaFactoryBase() = default;
0424
0425 virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
0426 };
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436 template <class TestSuite>
0437 class TestMetaFactory
0438 : public TestMetaFactoryBase<typename TestSuite::ParamType> {
0439 public:
0440 using ParamType = typename TestSuite::ParamType;
0441
0442 TestMetaFactory() = default;
0443
0444 TestFactoryBase* CreateTestFactory(ParamType parameter) override {
0445 return new ParameterizedTestFactory<TestSuite>(parameter);
0446 }
0447
0448 private:
0449 TestMetaFactory(const TestMetaFactory&) = delete;
0450 TestMetaFactory& operator=(const TestMetaFactory&) = delete;
0451 };
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463 class ParameterizedTestSuiteInfoBase {
0464 public:
0465 virtual ~ParameterizedTestSuiteInfoBase() = default;
0466
0467
0468 virtual const std::string& GetTestSuiteName() const = 0;
0469
0470 virtual TypeId GetTestSuiteTypeId() const = 0;
0471
0472
0473
0474
0475 virtual void RegisterTests() = 0;
0476
0477 protected:
0478 ParameterizedTestSuiteInfoBase() {}
0479
0480 private:
0481 ParameterizedTestSuiteInfoBase(const ParameterizedTestSuiteInfoBase&) =
0482 delete;
0483 ParameterizedTestSuiteInfoBase& operator=(
0484 const ParameterizedTestSuiteInfoBase&) = delete;
0485 };
0486
0487
0488
0489
0490
0491 struct GTEST_API_ MarkAsIgnored {
0492 explicit MarkAsIgnored(const char* test_suite);
0493 };
0494
0495 GTEST_API_ void InsertSyntheticTestCase(const std::string& name,
0496 CodeLocation location, bool has_test_p);
0497
0498
0499
0500
0501
0502
0503
0504
0505 template <class TestSuite>
0506 class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
0507 public:
0508
0509
0510
0511 using ParamType = typename TestSuite::ParamType;
0512
0513 typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
0514 using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&);
0515
0516 explicit ParameterizedTestSuiteInfo(std::string name,
0517 CodeLocation code_location)
0518 : test_suite_name_(std::move(name)),
0519 code_location_(std::move(code_location)) {}
0520
0521
0522 const std::string& GetTestSuiteName() const override {
0523 return test_suite_name_;
0524 }
0525
0526 TypeId GetTestSuiteTypeId() const override { return GetTypeId<TestSuite>(); }
0527
0528
0529
0530
0531
0532
0533 void AddTestPattern(const char*, const char* test_base_name,
0534 TestMetaFactoryBase<ParamType>* meta_factory,
0535 CodeLocation code_location) {
0536 tests_.emplace_back(
0537 new TestInfo(test_base_name, meta_factory, std::move(code_location)));
0538 }
0539
0540
0541 int AddTestSuiteInstantiation(std::string instantiation_name,
0542 GeneratorCreationFunc* func,
0543 ParamNameGeneratorFunc* name_func,
0544 const char* file, int line) {
0545 instantiations_.emplace_back(std::move(instantiation_name), func, name_func,
0546 file, line);
0547 return 0;
0548 }
0549
0550
0551
0552
0553
0554 void RegisterTests() override {
0555 bool generated_instantiations = false;
0556
0557 std::string test_suite_name;
0558 std::string test_name;
0559 for (const std::shared_ptr<TestInfo>& test_info : tests_) {
0560 for (const InstantiationInfo& instantiation : instantiations_) {
0561 const std::string& instantiation_name = instantiation.name;
0562 ParamGenerator<ParamType> generator((*instantiation.generator)());
0563 ParamNameGeneratorFunc* name_func = instantiation.name_func;
0564 const char* file = instantiation.file;
0565 int line = instantiation.line;
0566
0567 if (!instantiation_name.empty())
0568 test_suite_name = instantiation_name + "/";
0569 else
0570 test_suite_name.clear();
0571 test_suite_name += test_suite_name_;
0572
0573 size_t i = 0;
0574 std::set<std::string> test_param_names;
0575 for (const auto& param : generator) {
0576 generated_instantiations = true;
0577
0578 test_name.clear();
0579
0580 std::string param_name =
0581 name_func(TestParamInfo<ParamType>(param, i));
0582
0583 GTEST_CHECK_(IsValidParamName(param_name))
0584 << "Parameterized test name '" << param_name
0585 << "' is invalid (contains spaces, dashes, or any "
0586 "non-alphanumeric characters other than underscores), in "
0587 << file << " line " << line << "" << std::endl;
0588
0589 GTEST_CHECK_(test_param_names.count(param_name) == 0)
0590 << "Duplicate parameterized test name '" << param_name << "', in "
0591 << file << " line " << line << std::endl;
0592
0593 if (!test_info->test_base_name.empty()) {
0594 test_name.append(test_info->test_base_name).append("/");
0595 }
0596 test_name += param_name;
0597
0598 test_param_names.insert(std::move(param_name));
0599
0600 MakeAndRegisterTestInfo(
0601 test_suite_name, test_name.c_str(),
0602 nullptr,
0603 PrintToString(param).c_str(), test_info->code_location,
0604 GetTestSuiteTypeId(),
0605 SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),
0606 SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),
0607 test_info->test_meta_factory->CreateTestFactory(param));
0608 ++i;
0609 }
0610 }
0611 }
0612
0613 if (!generated_instantiations) {
0614
0615 InsertSyntheticTestCase(GetTestSuiteName(), code_location_,
0616 !tests_.empty());
0617 }
0618 }
0619
0620 private:
0621
0622
0623 struct TestInfo {
0624 TestInfo(const char* a_test_base_name,
0625 TestMetaFactoryBase<ParamType>* a_test_meta_factory,
0626 CodeLocation a_code_location)
0627 : test_base_name(a_test_base_name),
0628 test_meta_factory(a_test_meta_factory),
0629 code_location(std::move(a_code_location)) {}
0630
0631 const std::string test_base_name;
0632 const std::unique_ptr<TestMetaFactoryBase<ParamType>> test_meta_factory;
0633 const CodeLocation code_location;
0634 };
0635 using TestInfoContainer = ::std::vector<std::shared_ptr<TestInfo>>;
0636
0637
0638
0639 struct InstantiationInfo {
0640 InstantiationInfo(std::string name_in, GeneratorCreationFunc* generator_in,
0641 ParamNameGeneratorFunc* name_func_in, const char* file_in,
0642 int line_in)
0643 : name(std::move(name_in)),
0644 generator(generator_in),
0645 name_func(name_func_in),
0646 file(file_in),
0647 line(line_in) {}
0648
0649 std::string name;
0650 GeneratorCreationFunc* generator;
0651 ParamNameGeneratorFunc* name_func;
0652 const char* file;
0653 int line;
0654 };
0655 typedef ::std::vector<InstantiationInfo> InstantiationContainer;
0656
0657 static bool IsValidParamName(const std::string& name) {
0658
0659 if (name.empty()) return false;
0660
0661
0662 for (std::string::size_type index = 0; index < name.size(); ++index) {
0663 if (!IsAlNum(name[index]) && name[index] != '_') return false;
0664 }
0665
0666 return true;
0667 }
0668
0669 const std::string test_suite_name_;
0670 CodeLocation code_location_;
0671 TestInfoContainer tests_;
0672 InstantiationContainer instantiations_;
0673
0674 ParameterizedTestSuiteInfo(const ParameterizedTestSuiteInfo&) = delete;
0675 ParameterizedTestSuiteInfo& operator=(const ParameterizedTestSuiteInfo&) =
0676 delete;
0677 };
0678
0679
0680 #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
0681 template <class TestCase>
0682 using ParameterizedTestCaseInfo = ParameterizedTestSuiteInfo<TestCase>;
0683 #endif
0684
0685
0686
0687
0688
0689
0690
0691 class ParameterizedTestSuiteRegistry {
0692 public:
0693 ParameterizedTestSuiteRegistry() = default;
0694 ~ParameterizedTestSuiteRegistry() {
0695 for (auto& test_suite_info : test_suite_infos_) {
0696 delete test_suite_info;
0697 }
0698 }
0699
0700
0701
0702 template <class TestSuite>
0703 ParameterizedTestSuiteInfo<TestSuite>* GetTestSuitePatternHolder(
0704 std::string test_suite_name, CodeLocation code_location) {
0705 ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr;
0706
0707 auto item_it = suite_name_to_info_index_.find(test_suite_name);
0708 if (item_it != suite_name_to_info_index_.end()) {
0709 auto* test_suite_info = test_suite_infos_[item_it->second];
0710 if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
0711
0712
0713
0714 ReportInvalidTestSuiteType(test_suite_name.c_str(), code_location);
0715 posix::Abort();
0716 } else {
0717
0718
0719
0720 typed_test_info =
0721 CheckedDowncastToActualType<ParameterizedTestSuiteInfo<TestSuite>>(
0722 test_suite_info);
0723 }
0724 }
0725 if (typed_test_info == nullptr) {
0726 typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>(
0727 test_suite_name, std::move(code_location));
0728 suite_name_to_info_index_.emplace(std::move(test_suite_name),
0729 test_suite_infos_.size());
0730 test_suite_infos_.push_back(typed_test_info);
0731 }
0732 return typed_test_info;
0733 }
0734 void RegisterTests() {
0735 for (auto& test_suite_info : test_suite_infos_) {
0736 test_suite_info->RegisterTests();
0737 }
0738 }
0739
0740 #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
0741 template <class TestCase>
0742 ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
0743 std::string test_case_name, CodeLocation code_location) {
0744 return GetTestSuitePatternHolder<TestCase>(std::move(test_case_name),
0745 std::move(code_location));
0746 }
0747
0748 #endif
0749
0750 private:
0751 using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;
0752
0753 TestSuiteInfoContainer test_suite_infos_;
0754 ::std::unordered_map<std::string, size_t> suite_name_to_info_index_;
0755
0756 ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry&) =
0757 delete;
0758 ParameterizedTestSuiteRegistry& operator=(
0759 const ParameterizedTestSuiteRegistry&) = delete;
0760 };
0761
0762
0763
0764
0765 class TypeParameterizedTestSuiteRegistry {
0766 public:
0767
0768 void RegisterTestSuite(const char* test_suite_name,
0769 CodeLocation code_location);
0770
0771
0772 void RegisterInstantiation(const char* test_suite_name);
0773
0774
0775
0776 void CheckForInstantiations();
0777
0778 private:
0779 struct TypeParameterizedTestSuiteInfo {
0780 explicit TypeParameterizedTestSuiteInfo(CodeLocation c)
0781 : code_location(std::move(c)), instantiated(false) {}
0782
0783 CodeLocation code_location;
0784 bool instantiated;
0785 };
0786
0787 std::map<std::string, TypeParameterizedTestSuiteInfo> suites_;
0788 };
0789
0790 }
0791
0792
0793
0794 template <class Container>
0795 internal::ParamGenerator<typename Container::value_type> ValuesIn(
0796 const Container& container);
0797
0798 namespace internal {
0799
0800
0801 GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
0802
0803 template <typename... Ts>
0804 class ValueArray {
0805 public:
0806 explicit ValueArray(Ts... v) : v_(FlatTupleConstructTag{}, std::move(v)...) {}
0807
0808 template <typename T>
0809 operator ParamGenerator<T>() const {
0810 return ValuesIn(MakeVector<T>(std::make_index_sequence<sizeof...(Ts)>()));
0811 }
0812
0813 private:
0814 template <typename T, size_t... I>
0815 std::vector<T> MakeVector(std::index_sequence<I...>) const {
0816 return std::vector<T>{static_cast<T>(v_.template Get<I>())...};
0817 }
0818
0819 FlatTuple<Ts...> v_;
0820 };
0821
0822 GTEST_DISABLE_MSC_WARNINGS_POP_()
0823
0824 template <typename... T>
0825 class CartesianProductGenerator
0826 : public ParamGeneratorInterface<::std::tuple<T...>> {
0827 public:
0828 typedef ::std::tuple<T...> ParamType;
0829
0830 CartesianProductGenerator(const std::tuple<ParamGenerator<T>...>& g)
0831 : generators_(g) {}
0832 ~CartesianProductGenerator() override = default;
0833
0834 ParamIteratorInterface<ParamType>* Begin() const override {
0835 return new Iterator(this, generators_, false);
0836 }
0837 ParamIteratorInterface<ParamType>* End() const override {
0838 return new Iterator(this, generators_, true);
0839 }
0840
0841 private:
0842 template <class I>
0843 class IteratorImpl;
0844 template <size_t... I>
0845 class IteratorImpl<std::index_sequence<I...>>
0846 : public ParamIteratorInterface<ParamType> {
0847 public:
0848 IteratorImpl(const ParamGeneratorInterface<ParamType>* base,
0849 const std::tuple<ParamGenerator<T>...>& generators,
0850 bool is_end)
0851 : base_(base),
0852 begin_(std::get<I>(generators).begin()...),
0853 end_(std::get<I>(generators).end()...),
0854 current_(is_end ? end_ : begin_) {
0855 ComputeCurrentValue();
0856 }
0857 ~IteratorImpl() override = default;
0858
0859 const ParamGeneratorInterface<ParamType>* BaseGenerator() const override {
0860 return base_;
0861 }
0862
0863
0864 void Advance() override {
0865 assert(!AtEnd());
0866
0867 ++std::get<sizeof...(T) - 1>(current_);
0868
0869 AdvanceIfEnd<sizeof...(T) - 1>();
0870 ComputeCurrentValue();
0871 }
0872 ParamIteratorInterface<ParamType>* Clone() const override {
0873 return new IteratorImpl(*this);
0874 }
0875
0876 const ParamType* Current() const override { return current_value_.get(); }
0877
0878 bool Equals(const ParamIteratorInterface<ParamType>& other) const override {
0879
0880
0881 GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
0882 << "The program attempted to compare iterators "
0883 << "from different generators." << std::endl;
0884 const IteratorImpl* typed_other =
0885 CheckedDowncastToActualType<const IteratorImpl>(&other);
0886
0887
0888
0889
0890 if (AtEnd() && typed_other->AtEnd()) return true;
0891
0892 bool same = true;
0893 bool dummy[] = {
0894 (same = same && std::get<I>(current_) ==
0895 std::get<I>(typed_other->current_))...};
0896 (void)dummy;
0897 return same;
0898 }
0899
0900 private:
0901 template <size_t ThisI>
0902 void AdvanceIfEnd() {
0903 if (std::get<ThisI>(current_) != std::get<ThisI>(end_)) return;
0904
0905 bool last = ThisI == 0;
0906 if (last) {
0907
0908 return;
0909 }
0910
0911 constexpr size_t NextI = ThisI - (ThisI != 0);
0912 std::get<ThisI>(current_) = std::get<ThisI>(begin_);
0913 ++std::get<NextI>(current_);
0914 AdvanceIfEnd<NextI>();
0915 }
0916
0917 void ComputeCurrentValue() {
0918 if (!AtEnd())
0919 current_value_ = std::make_shared<ParamType>(*std::get<I>(current_)...);
0920 }
0921 bool AtEnd() const {
0922 bool at_end = false;
0923 bool dummy[] = {
0924 (at_end = at_end || std::get<I>(current_) == std::get<I>(end_))...};
0925 (void)dummy;
0926 return at_end;
0927 }
0928
0929 const ParamGeneratorInterface<ParamType>* const base_;
0930 std::tuple<typename ParamGenerator<T>::iterator...> begin_;
0931 std::tuple<typename ParamGenerator<T>::iterator...> end_;
0932 std::tuple<typename ParamGenerator<T>::iterator...> current_;
0933 std::shared_ptr<ParamType> current_value_;
0934 };
0935
0936 using Iterator = IteratorImpl<std::make_index_sequence<sizeof...(T)>>;
0937
0938 std::tuple<ParamGenerator<T>...> generators_;
0939 };
0940
0941 template <class... Gen>
0942 class CartesianProductHolder {
0943 public:
0944 CartesianProductHolder(const Gen&... g) : generators_(g...) {}
0945 template <typename... T>
0946 operator ParamGenerator<::std::tuple<T...>>() const {
0947 return ParamGenerator<::std::tuple<T...>>(
0948 new CartesianProductGenerator<T...>(generators_));
0949 }
0950
0951 private:
0952 std::tuple<Gen...> generators_;
0953 };
0954
0955 template <typename From, typename To, typename Func>
0956 class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
0957 public:
0958 ParamGeneratorConverter(ParamGenerator<From> gen, Func converter)
0959 : generator_(std::move(gen)), converter_(std::move(converter)) {}
0960
0961 ParamIteratorInterface<To>* Begin() const override {
0962 return new Iterator(this, generator_.begin(), generator_.end());
0963 }
0964 ParamIteratorInterface<To>* End() const override {
0965 return new Iterator(this, generator_.end(), generator_.end());
0966 }
0967
0968
0969
0970
0971
0972 const Func& TypeConverter() const { return converter_; }
0973
0974 private:
0975 class Iterator : public ParamIteratorInterface<To> {
0976 public:
0977 Iterator(const ParamGeneratorConverter* base, ParamIterator<From> it,
0978 ParamIterator<From> end)
0979 : base_(base), it_(it), end_(end) {
0980 if (it_ != end_)
0981 value_ =
0982 std::make_shared<To>(static_cast<To>(base->TypeConverter()(*it_)));
0983 }
0984 ~Iterator() override = default;
0985
0986 const ParamGeneratorInterface<To>* BaseGenerator() const override {
0987 return base_;
0988 }
0989 void Advance() override {
0990 ++it_;
0991 if (it_ != end_)
0992 value_ =
0993 std::make_shared<To>(static_cast<To>(base_->TypeConverter()(*it_)));
0994 }
0995 ParamIteratorInterface<To>* Clone() const override {
0996 return new Iterator(*this);
0997 }
0998 const To* Current() const override { return value_.get(); }
0999 bool Equals(const ParamIteratorInterface<To>& other) const override {
1000
1001
1002 GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
1003 << "The program attempted to compare iterators "
1004 << "from different generators." << std::endl;
1005 const ParamIterator<From> other_it =
1006 CheckedDowncastToActualType<const Iterator>(&other)->it_;
1007 return it_ == other_it;
1008 }
1009
1010 private:
1011 Iterator(const Iterator& other) = default;
1012
1013 const ParamGeneratorConverter* const base_;
1014 ParamIterator<From> it_;
1015 ParamIterator<From> end_;
1016 std::shared_ptr<To> value_;
1017 };
1018
1019 ParamGenerator<From> generator_;
1020 Func converter_;
1021 };
1022
1023 template <class GeneratedT,
1024 typename StdFunction =
1025 std::function<const GeneratedT&(const GeneratedT&)>>
1026 class ParamConverterGenerator {
1027 public:
1028 ParamConverterGenerator(ParamGenerator<GeneratedT> g)
1029 : generator_(std::move(g)), converter_(Identity) {}
1030
1031 ParamConverterGenerator(ParamGenerator<GeneratedT> g, StdFunction converter)
1032 : generator_(std::move(g)), converter_(std::move(converter)) {}
1033
1034 template <typename T>
1035 operator ParamGenerator<T>() const {
1036 return ParamGenerator<T>(
1037 new ParamGeneratorConverter<GeneratedT, T, StdFunction>(generator_,
1038 converter_));
1039 }
1040
1041 private:
1042 static const GeneratedT& Identity(const GeneratedT& v) { return v; }
1043
1044 ParamGenerator<GeneratedT> generator_;
1045 StdFunction converter_;
1046 };
1047
1048
1049 template <typename T>
1050 struct FuncSingleParamType;
1051 template <typename R, typename P>
1052 struct FuncSingleParamType<std::function<R(P)>> {
1053 using type = std::remove_cv_t<std::remove_reference_t<P>>;
1054 };
1055
1056 template <typename T>
1057 struct IsSingleArgStdFunction : public std::false_type {};
1058 template <typename R, typename P>
1059 struct IsSingleArgStdFunction<std::function<R(P)>> : public std::true_type {};
1060
1061 }
1062 }
1063
1064 #endif