| 4154 | |
| 4155 | template <typename T, typename Predicate> |
| 4156 | class FilterGenerator : public IGenerator<T> { |
| 4157 | GeneratorWrapper<T> m_generator; |
| 4158 | Predicate m_predicate; |
| 4159 | public: |
| 4160 | template <typename P = Predicate> |
| 4161 | FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator): |
| 4162 | m_generator(std::move(generator)), |
| 4163 | m_predicate(std::forward<P>(pred)) |
| 4164 | { |
| 4165 | if (!m_predicate(m_generator.get())) { |
| 4166 | // It might happen that there are no values that pass the |
| 4167 | // filter. In that case we throw an exception. |
| 4168 | auto has_initial_value = nextImpl(); |
| 4169 | if (!has_initial_value) { |
| 4170 | Catch::throw_exception(GeneratorException("No valid value found in filtered generator")); |
| 4171 | } |
| 4172 | } |
| 4173 | } |
| 4174 | |
| 4175 | T const& get() const override { |
| 4176 | return m_generator.get(); |
| 4177 | } |
| 4178 | |
| 4179 | bool next() override { |
| 4180 | return nextImpl(); |
| 4181 | } |
| 4182 | |
| 4183 | private: |
| 4184 | bool nextImpl() { |
| 4185 | bool success = m_generator.next(); |
| 4186 | if (!success) { |
| 4187 | return false; |
| 4188 | } |
| 4189 | while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true); |
| 4190 | return success; |
| 4191 | } |
| 4192 | }; |
| 4193 | |
| 4194 | template <typename T, typename Predicate> |
| 4195 | GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) { |