CXXIter 0.2
Loading...
Searching...
No Matches
SkipN.h
1#pragma once
2
3#include <cstdlib>
4
5#include "../Common.h"
6
7namespace CXXIter {
8
9 // ################################################################################################
10 // SKIP WHILE
11 // ################################################################################################
12 namespace op {
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 constexpr SkipN(TChainInput&& input, size_t n) : input(std::move(input)), n(n) {}
25 };
26 }
27 // ------------------------------------------------------------------------------------------------
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 static constexpr inline IterValue<Item> next(Self& self) {
38 if(!self.skipEnded) [[unlikely]] { // first call -> skip requested now
39 ChainInputIterator::advanceBy(self.input, self.n);
40 self.skipEnded = true;
41 }
42 return ChainInputIterator::next(self.input);
43 }
44 static constexpr inline SizeHint sizeHint(const Self& self) {
45 SizeHint result = ChainInputIterator::sizeHint(self.input);
46 result.subtract(self.n);
47 return result;
48 }
49 static constexpr inline size_t advanceBy(Self& self, size_t n) {
50 if(!self.skipEnded) [[unlikely]] {
51 size_t skippedCnt = ChainInputIterator::advanceBy(self.input, n + self.n);
52 self.skipEnded = true;
53 if(skippedCnt <= self.n) { return 0; }
54 return (skippedCnt - self.n);
55 } else {
56 return ChainInputIterator::advanceBy(self.input, n);
57 }
58 }
59 };
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 };
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 static constexpr inline ItemPtr currentPtr(op::SkipN<TChainInput>& self) {
72 size_t offset = (self.skipEnded) ? 0 : self.n;
73 return (trait::ContiguousMemoryIterator<TChainInput>::currentPtr(self.input) + offset);
74 }
75 };
76
77}
CXXIter.
Definition: CXXIter.h:48