GCC Code Coverage Report


Directory: ./
File: include/CXXIter/src/op/Unique.h
Date: 2023-01-04 16:32:12
Exec Total Coverage
Lines: 14 14 100.0%
Functions: 6 6 100.0%
Branches: 11 18 61.1%

Line Branch Exec Source
1 #pragma once
2
3 #include <unordered_set>
4
5 #include "../Common.h"
6 #include "../sources/ContainerSources.h"
7 #include "../util/TraitImpl.h"
8
9 namespace CXXIter {
10
11 // ################################################################################################
12 // UNIQUE
13 // ################################################################################################
14 namespace op {
15 /** @private */
16 template<typename TChainInput, typename TMapFn>
17 class [[nodiscard(CXXITER_CHAINER_NODISCARD_WARNING)]] Unique : public IterApi<Unique<TChainInput, TMapFn>> {
18 friend struct trait::Iterator<Unique<TChainInput, TMapFn>>;
19 private:
20 using OwnedInputItem = typename TChainInput::ItemOwned;
21
22 TChainInput input;
23 TMapFn mapFn;
24 std::unordered_set<OwnedInputItem> uniqueCache;
25 public:
26 8 constexpr Unique(TChainInput&& input, TMapFn mapFn) : input(std::move(input)), mapFn(mapFn) {
27
3/6
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
8 uniqueCache.reserve(this->input.sizeHint().expectedResultSize());
28 8 }
29 };
30 }
31 // ------------------------------------------------------------------------------------------------
32 /** @private */
33 template<typename TChainInput, typename TMapFn>
34 struct trait::Iterator<op::Unique<TChainInput, TMapFn>> {
35 using ChainInputIterator = trait::Iterator<TChainInput>;
36 using InputItem = typename TChainInput::Item;
37 using OwnedInputItem = typename TChainInput::ItemOwned;
38 // CXXIter Interface
39 using Self = op::Unique<TChainInput, TMapFn>;
40 using Item = InputItem;
41
42 58 static constexpr inline IterValue<Item> next(Self& self) {
43 18 while(true) {
44
1/2
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
58 auto item = ChainInputIterator::next(self.input);
45
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 26 times.
92 if(!item.has_value()) [[unlikely]] { return {}; } // reached end of input
46
47
1/2
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
52 auto itemUniqueValue = self.mapFn(item.value());
48
3/4
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 17 times.
52 if(self.uniqueCache.contains(itemUniqueValue)) { continue; } // uniqueness-property violated, ignore item
49
1/2
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
34 self.uniqueCache.insert(std::move(itemUniqueValue));
50 34 return item;
51 }
52 }
53 4 static constexpr inline SizeHint sizeHint(const Self& self) {
54 4 SizeHint input = ChainInputIterator::sizeHint(self.input);
55 8 return SizeHint(0, input.upperBound);
56 }
57 static constexpr inline size_t advanceBy(Self& self, size_t n) { return util::advanceByPull(self, n); }
58 };
59
60 }
61