| 11140 | |
| 11141 | template <typename... T> |
| 11142 | class CartesianProductGenerator |
| 11143 | : public ParamGeneratorInterface<::std::tuple<T...>> { |
| 11144 | public: |
| 11145 | typedef ::std::tuple<T...> ParamType; |
| 11146 | |
| 11147 | CartesianProductGenerator(const std::tuple<ParamGenerator<T>...>& g) |
| 11148 | : generators_(g) {} |
| 11149 | ~CartesianProductGenerator() override {} |
| 11150 | |
| 11151 | ParamIteratorInterface<ParamType>* Begin() const override { |
| 11152 | return new Iterator(this, generators_, false); |
| 11153 | } |
| 11154 | ParamIteratorInterface<ParamType>* End() const override { |
| 11155 | return new Iterator(this, generators_, true); |
| 11156 | } |
| 11157 | |
| 11158 | private: |
| 11159 | template <class I> |
| 11160 | class IteratorImpl; |
| 11161 | template <size_t... I> |
| 11162 | class IteratorImpl<IndexSequence<I...>> |
| 11163 | : public ParamIteratorInterface<ParamType> { |
| 11164 | public: |
| 11165 | IteratorImpl(const ParamGeneratorInterface<ParamType>* base, |
| 11166 | const std::tuple<ParamGenerator<T>...>& generators, bool is_end) |
| 11167 | : base_(base), |
| 11168 | begin_(std::get<I>(generators).begin()...), |
| 11169 | end_(std::get<I>(generators).end()...), |
| 11170 | current_(is_end ? end_ : begin_) { |
| 11171 | ComputeCurrentValue(); |
| 11172 | } |
| 11173 | ~IteratorImpl() override {} |
| 11174 | |
| 11175 | const ParamGeneratorInterface<ParamType>* BaseGenerator() const override { |
| 11176 | return base_; |
| 11177 | } |
| 11178 | // Advance should not be called on beyond-of-range iterators |
| 11179 | // so no component iterators must be beyond end of range, either. |
| 11180 | void Advance() override { |
| 11181 | assert(!AtEnd()); |
| 11182 | // Advance the last iterator. |
| 11183 | ++std::get<sizeof...(T) - 1>(current_); |
| 11184 | // if that reaches end, propagate that up. |
| 11185 | AdvanceIfEnd<sizeof...(T) - 1>(); |
| 11186 | ComputeCurrentValue(); |
| 11187 | } |
| 11188 | ParamIteratorInterface<ParamType>* Clone() const override { |
| 11189 | return new IteratorImpl(*this); |
| 11190 | } |
| 11191 | |
| 11192 | const ParamType* Current() const override { return current_value_.get(); } |
| 11193 | |
| 11194 | bool Equals(const ParamIteratorInterface<ParamType>& other) const override { |
| 11195 | // Having the same base generator guarantees that the other |
| 11196 | // iterator is of the same type and we can downcast. |
| 11197 | GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) |
| 11198 | << "The program attempted to compare iterators " |
| 11199 | << "from different generators." << std::endl; |
nothing calls this directly
no outgoing calls
no test coverage detected