CXXIter 0.2
Loading...
Searching...
No Matches
FilterMap.h
1#pragma once
2
3#include "../Common.h"
4#include "../util/TraitImpl.h"
5
6namespace CXXIter {
7
8 // ################################################################################################
9 // FILTERMAP
10 // ################################################################################################
11 namespace op {
13 template<typename TChainInput, typename TFilterMapFn, typename TItem>
14 class [[nodiscard(CXXITER_CHAINER_NODISCARD_WARNING)]] FilterMap : public IterApi<FilterMap<TChainInput, TFilterMapFn, TItem>> {
15 friend struct trait::Iterator<FilterMap<TChainInput, TFilterMapFn, TItem>>;
16 friend struct trait::DoubleEndedIterator<FilterMap<TChainInput, TFilterMapFn, TItem>>;
17 private:
18 TChainInput input;
19 TFilterMapFn filterMapFn;
20 public:
21 constexpr FilterMap(TChainInput&& input, TFilterMapFn filterMapFn) : input(std::move(input)), filterMapFn(filterMapFn) {}
22 };
23 }
24 // ------------------------------------------------------------------------------------------------
26 template<typename TChainInput, typename TFilterMapFn, typename TItem>
27 struct trait::Iterator<op::FilterMap<TChainInput, TFilterMapFn, TItem>> {
28 using ChainInputIterator = trait::Iterator<TChainInput>;
29 using InputItem = typename TChainInput::Item;
30 // CXXIter Interface
31 using Self = op::FilterMap<TChainInput, TFilterMapFn, TItem>;
32 using Item = TItem;
33
34 static constexpr inline IterValue<Item> next(Self& self) {
35 while(true) {
36 auto item = ChainInputIterator::next(self.input);
37 if(!item.has_value()) [[unlikely]] { return {}; }
38 std::optional<Item> value(self.filterMapFn(std::forward<InputItem>( item.value() )));
39 if(!value) { continue; }
40 return *value;
41 }
42 }
43 static constexpr inline SizeHint sizeHint(const Self& self) {
44 SizeHint input = ChainInputIterator::sizeHint(self.input);
45 return SizeHint(0, input.upperBound);
46 }
47 static constexpr inline size_t advanceBy(Self& self, size_t n) { return util::advanceByPull(self, n); }
48 };
50 template<CXXIterDoubleEndedIterator TChainInput, typename TFilterMapFn, typename TItem>
51 struct trait::DoubleEndedIterator<op::FilterMap<TChainInput, TFilterMapFn, TItem>> {
52 using ChainInputIterator = trait::DoubleEndedIterator<TChainInput>;
53 using InputItem = typename TChainInput::Item;
54 // CXXIter Interface
55 using Self = op::FilterMap<TChainInput, TFilterMapFn, TItem>;
56 using Item = TItem;
57
58 static constexpr inline IterValue<Item> nextBack(Self& self) {
59 while(true) {
60 auto item = ChainInputIterator::nextBack(self.input);
61 if(!item.has_value()) [[unlikely]] { return {}; }
62 std::optional<Item> value(self.filterMapFn(std::forward<InputItem>( item.value() )));
63 if(!value) { continue; }
64 return *value;
65 }
66 }
67 };
68
69}
CXXIter.
Definition: CXXIter.h:48