GCC Code Coverage Report


Directory: ./
File: include/CXXIter/src/op/FilterMap.h
Date: 2023-01-04 16:32:12
Exec Total Coverage
Lines: 19 19 100.0%
Functions: 23 23 100.0%
Branches: 11 16 68.8%

Line Branch Exec Source
1 #pragma once
2
3 #include "../Common.h"
4 #include "../util/TraitImpl.h"
5
6 namespace CXXIter {
7
8 // ################################################################################################
9 // FILTERMAP
10 // ################################################################################################
11 namespace op {
12 /** @private */
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 22 constexpr FilterMap(TChainInput&& input, TFilterMapFn filterMapFn) : input(std::move(input)), filterMapFn(filterMapFn) {}
22 };
23 }
24 // ------------------------------------------------------------------------------------------------
25 /** @private */
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 79 static constexpr inline IterValue<Item> next(Self& self) {
35
3/4
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 3 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
42 while(true) {
36
1/2
✓ Branch 1 taken 43 times.
✗ Branch 2 not taken.
79 auto item = ChainInputIterator::next(self.input);
37
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 33 times.
109 if(!item.has_value()) [[unlikely]] { return {}; }
38
2/4
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 5 times.
✗ Branch 6 not taken.
60 std::optional<Item> value(self.filterMapFn(std::forward<InputItem>( item.value() )));
39
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 19 times.
60 if(!value) { continue; }
40
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
34 return *value;
41 }
42 }
43 8 static constexpr inline SizeHint sizeHint(const Self& self) {
44 8 SizeHint input = ChainInputIterator::sizeHint(self.input);
45 16 return SizeHint(0, input.upperBound);
46 }
47 1 static constexpr inline size_t advanceBy(Self& self, size_t n) { return util::advanceByPull(self, n); }
48 };
49 /** @private */
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 10 static constexpr inline IterValue<Item> nextBack(Self& self) {
59 3 while(true) {
60 10 auto item = ChainInputIterator::nextBack(self.input);
61 15 if(!item.has_value()) [[unlikely]] { return {}; }
62 8 std::optional<Item> value(self.filterMapFn(std::forward<InputItem>( item.value() )));
63 8 if(!value) { continue; }
64 5 return *value;
65 }
66 }
67 };
68
69 }
70