GCC Code Coverage Report


Directory: ./
File: include/CXXIter/src/op/SkipN.h
Date: 2023-01-04 16:32:12
Exec Total Coverage
Lines: 19 20 95.0%
Functions: 12 12 100.0%
Branches: 6 8 75.0%

Line Branch Exec Source
1 #pragma once
2
3 #include <cstdlib>
4
5 #include "../Common.h"
6
7 namespace CXXIter {
8
9 // ################################################################################################
10 // SKIP WHILE
11 // ################################################################################################
12 namespace op {
13 /** @private */
14 template<typename TChainInput>
15 class [[nodiscard(CXXITER_CHAINER_NODISCARD_WARNING)]] SkipN : public IterApi<SkipN<TChainInput>> {
16 friend struct trait::Iterator<SkipN<TChainInput>>;
17 friend struct trait::ExactSizeIterator<SkipN<TChainInput>>;
18 friend struct trait::ContiguousMemoryIterator<SkipN<TChainInput>>;
19 private:
20 TChainInput input;
21 size_t n;
22 bool skipEnded = false;
23 public:
24 38 constexpr SkipN(TChainInput&& input, size_t n) : input(std::move(input)), n(n) {}
25 };
26 }
27 // ------------------------------------------------------------------------------------------------
28 /** @private */
29 template<typename TChainInput>
30 struct trait::Iterator<op::SkipN<TChainInput>> {
31 using ChainInputIterator = trait::Iterator<TChainInput>;
32 using InputItem = typename TChainInput::Item;
33 // CXXIter Interface
34 using Self = op::SkipN<TChainInput>;
35 using Item = InputItem;
36
37 57 static constexpr inline IterValue<Item> next(Self& self) {
38
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 18 times.
57 if(!self.skipEnded) [[unlikely]] { // first call -> skip requested now
39 19 ChainInputIterator::advanceBy(self.input, self.n);
40 19 self.skipEnded = true;
41 }
42 57 return ChainInputIterator::next(self.input);
43 }
44 26 static constexpr inline SizeHint sizeHint(const Self& self) {
45 26 SizeHint result = ChainInputIterator::sizeHint(self.input);
46 26 result.subtract(self.n);
47 26 return result;
48 }
49 3 static constexpr inline size_t advanceBy(Self& self, size_t n) {
50
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(!self.skipEnded) [[unlikely]] {
51 3 size_t skippedCnt = ChainInputIterator::advanceBy(self.input, n + self.n);
52 3 self.skipEnded = true;
53
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if(skippedCnt <= self.n) { return 0; }
54 2 return (skippedCnt - self.n);
55 } else {
56 return ChainInputIterator::advanceBy(self.input, n);
57 }
58 }
59 };
60 /** @private */
61 template<CXXIterExactSizeIterator TChainInput>
62 struct trait::ExactSizeIterator<op::SkipN<TChainInput>> {
63 static constexpr inline size_t size(const op::SkipN<TChainInput>& self) {
64 return trait::Iterator<op::SkipN<TChainInput>>::sizeHint(self).lowerBound;
65 }
66 };
67 /** @private */
68 template<CXXIterContiguousMemoryIterator TChainInput>
69 struct trait::ContiguousMemoryIterator<op::SkipN<TChainInput>> {
70 using ItemPtr = std::add_pointer_t<std::remove_reference_t<typename op::SkipN<TChainInput>::Item>>;
71 1 static constexpr inline ItemPtr currentPtr(op::SkipN<TChainInput>& self) {
72
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 size_t offset = (self.skipEnded) ? 0 : self.n;
73 1 return (trait::ContiguousMemoryIterator<TChainInput>::currentPtr(self.input) + offset);
74 }
75 };
76
77 }
78