GCC Code Coverage Report


Directory: ./
File: include/CXXIter/src/op/InplaceModifier.h
Date: 2023-01-04 16:32:12
Exec Total Coverage
Lines: 13 13 100.0%
Functions: 20 20 100.0%
Branches: 10 16 62.5%

Line Branch Exec Source
1 #pragma once
2
3 #include <cstdlib>
4 #include <type_traits>
5
6 #include "../Common.h"
7
8 namespace CXXIter {
9
10 // ################################################################################################
11 // INPLACE MODIFIER
12 // ################################################################################################
13 namespace op {
14 /** @private */
15 template<typename TChainInput, typename TModifierFn>
16 requires std::is_object_v<typename trait::Iterator<TChainInput>::Item> || (!std::is_const_v<typename trait::Iterator<TChainInput>::Item>)
17 class [[nodiscard(CXXITER_CHAINER_NODISCARD_WARNING)]] InplaceModifier : public IterApi<InplaceModifier<TChainInput, TModifierFn>> {
18 friend struct trait::Iterator<InplaceModifier<TChainInput, TModifierFn>>;
19 friend struct trait::DoubleEndedIterator<InplaceModifier<TChainInput, TModifierFn>>;
20 friend struct trait::ExactSizeIterator<InplaceModifier<TChainInput, TModifierFn>>;
21 private:
22 using InputItem = typename TChainInput::Item;
23
24 TChainInput input;
25 TModifierFn modifierFn;
26 public:
27 12 constexpr InplaceModifier(TChainInput&& input, TModifierFn modifierFn) : input(std::move(input)), modifierFn(modifierFn) {}
28 };
29 }
30 // ------------------------------------------------------------------------------------------------
31 /** @private */
32 template<typename TChainInput, typename TModifierFn>
33 struct trait::Iterator<op::InplaceModifier<TChainInput, TModifierFn>> {
34 using ChainInputIterator = trait::Iterator<TChainInput>;
35 // CXXIter Interface
36 using Self = op::InplaceModifier<TChainInput, TModifierFn>;
37 using Item = typename ChainInputIterator::Item;
38
39 28 static constexpr inline IterValue<Item> next(Self& self) {
40
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
28 auto item = ChainInputIterator::next(self.input);
41
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 10 times.
28 if(!item.has_value()) [[unlikely]] { return {}; }
42
2/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
18 self.modifierFn(item.value());
43 18 return item;
44 }
45 10 static constexpr inline SizeHint sizeHint(const Self& self) { return ChainInputIterator::sizeHint(self.input); }
46 1 static constexpr inline size_t advanceBy(Self& self, size_t n) { return ChainInputIterator::advanceBy(self.input, n); }
47 };
48 /** @private */
49 template<CXXIterDoubleEndedIterator TChainInput, typename TModifierFn>
50 struct trait::DoubleEndedIterator<op::InplaceModifier<TChainInput, TModifierFn>> {
51 using ChainInputIterator = trait::DoubleEndedIterator<TChainInput>;
52 // CXXIter Interface
53 using Self = op::InplaceModifier<TChainInput, TModifierFn>;
54 using Item = typename ChainInputIterator::Item;
55
56 5 static constexpr inline IterValue<Item> nextBack(Self& self) {
57
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 auto item = ChainInputIterator::nextBack(self.input);
58
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 4 times.
5 if(!item.has_value()) [[unlikely]] { return {}; }
59
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 self.modifierFn(item.value());
60 4 return item;
61 }
62 };
63 /** @private */
64 template<CXXIterExactSizeIterator TChainInput, typename TItem>
65 struct trait::ExactSizeIterator<op::InplaceModifier<TChainInput, TItem>> {
66 static constexpr inline size_t size(const op::InplaceModifier<TChainInput, TItem>& self) { return trait::ExactSizeIterator<TChainInput>::size(self.input); }
67 };
68
69 }
70