4#include "../util/TraitImpl.h"
13 template<
typename TChainInput,
typename TFilterFn>
14 class [[nodiscard(CXXITER_CHAINER_NODISCARD_WARNING)]] Filter :
public IterApi<Filter<TChainInput, TFilterFn>> {
15 friend struct trait::Iterator<Filter<TChainInput, TFilterFn>>;
16 friend struct trait::DoubleEndedIterator<Filter<TChainInput, TFilterFn>>;
18 using InputItem =
typename TChainInput::Item;
23 constexpr Filter(TChainInput&& input, TFilterFn filterFn) : input(std::move(input)), filterFn(filterFn) {}
28 template<
typename TChainInput,
typename TFilterFn>
29 struct trait::Iterator<op::Filter<TChainInput, TFilterFn>> {
30 using ChainInputIterator = trait::Iterator<TChainInput>;
32 using Self = op::Filter<TChainInput, TFilterFn>;
33 using Item =
typename ChainInputIterator::Item;
35 static constexpr inline IterValue<Item> next(Self& self) {
37 auto item = ChainInputIterator::next(self.input);
38 if(!item.has_value()) [[unlikely]] {
return {}; }
39 if(self.filterFn(item.value())) {
return item; }
42 static constexpr inline SizeHint sizeHint(
const Self& self) {
43 SizeHint input = ChainInputIterator::sizeHint(self.input);
44 return SizeHint(0, input.upperBound);
46 static constexpr inline size_t advanceBy(Self& self,
size_t n) {
return util::advanceByPull(self, n); }
49 template<CXXIterDoubleEndedIterator TChainInput,
typename TFilterFn>
50 struct trait::DoubleEndedIterator<op::Filter<TChainInput, TFilterFn>> {
51 using ChainInputIterator = trait::DoubleEndedIterator<TChainInput>;
53 using Self = op::Filter<TChainInput, TFilterFn>;
54 using Item =
typename ChainInputIterator::Item;
56 static constexpr inline IterValue<Item> nextBack(Self& self) {
58 auto item = ChainInputIterator::nextBack(self.input);
59 if(!item.has_value()) [[unlikely]] {
return {}; }
60 if(self.filterFn(item.value())) {
return item; }