GCC Code Coverage Report


Directory: ./
File: include/CXXIter/src/sources/GeneratorSources.h
Date: 2023-01-04 16:32:12
Exec Total Coverage
Lines: 32 32 100.0%
Functions: 31 31 100.0%
Branches: 9 12 75.0%

Line Branch Exec Source
1 #pragma once
2
3 #include <cstdlib>
4 #include <optional>
5
6 #include "../Common.h"
7 #include "../util/TraitImpl.h"
8
9 namespace CXXIter {
10
11 // ################################################################################################
12 // GENERATOR EMPTY
13 // ################################################################################################
14 /** @private */
15 template<typename TItem>
16 class Empty : public IterApi<Empty<TItem>> {
17 friend struct trait::Iterator<Empty<TItem>>;
18 friend struct trait::ExactSizeIterator<Empty<TItem>>;
19 };
20 // ------------------------------------------------------------------------------------------------
21 /** @private */
22 template<typename TItem>
23 struct trait::Iterator<Empty<TItem>> {
24 // CXXIter Interface
25 using Self = Empty<TItem>;
26 using Item = TItem;
27
28 1 static constexpr inline IterValue<Item> next(Self&) { return {}; }
29 13 static constexpr inline SizeHint sizeHint(const Self&) { return SizeHint(0, 0); }
30 static constexpr inline size_t advanceBy(Self&, size_t) { return 0; }
31 };
32 /** @private */
33 template<typename TItem>
34 struct trait::ExactSizeIterator<Empty<TItem>> {
35 1 static constexpr inline size_t size(const Empty<TItem>&) { return 0; }
36 };
37
38
39 // ################################################################################################
40 // GENERATOR FUNCTION
41 // ################################################################################################
42 /** @private */
43 template<typename TItem, typename TGeneratorFn>
44 class FunctionGenerator : public IterApi<FunctionGenerator<TItem, TGeneratorFn>> {
45 friend struct trait::Iterator<FunctionGenerator<TItem, TGeneratorFn>>;
46 friend struct trait::ExactSizeIterator<FunctionGenerator<TItem, TGeneratorFn>>;
47 private:
48 TGeneratorFn generatorFn;
49 public:
50 1 FunctionGenerator(TGeneratorFn generatorFn) : generatorFn(generatorFn) {}
51 };
52 // ------------------------------------------------------------------------------------------------
53 /** @private */
54 template<typename TItem, typename TGeneratorFn>
55 struct trait::Iterator<FunctionGenerator<TItem, TGeneratorFn>> {
56 // CXXIter Interface
57 using Self = FunctionGenerator<TItem, TGeneratorFn>;
58 using Item = TItem;
59
60 100 static constexpr inline IterValue<Item> next(Self& self) {
61
1/2
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
100 auto item = self.generatorFn();
62
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 100 times.
100 if(!item.has_value()) [[unlikely]] { return {}; }
63
1/2
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
100 return item.value();
64 }
65 1 static constexpr inline SizeHint sizeHint(const Self&) { return SizeHint(); }
66 static constexpr inline size_t advanceBy(Self& self, size_t n) { return util::advanceByPull(self, n); }
67 };
68
69
70
71 // ################################################################################################
72 // GENERATOR REPEAT
73 // ################################################################################################
74 /** @private */
75 template<typename TItem>
76 class Repeater : public IterApi<Repeater<TItem>> {
77 friend struct trait::Iterator<Repeater<TItem>>;
78 friend struct trait::ExactSizeIterator<Repeater<TItem>>;
79 private:
80 TItem item;
81 std::optional<size_t> repetitions;
82 size_t repetitionsRemaining;
83 public:
84 40 Repeater(const TItem& item, std::optional<size_t> repetitions) : item(item), repetitions(repetitions), repetitionsRemaining(repetitions.value_or(0)) {}
85 };
86 // ------------------------------------------------------------------------------------------------
87 /** @private */
88 template<typename TItem>
89 struct trait::Iterator<Repeater<TItem>> {
90 // CXXIter Interface
91 using Self = Repeater<TItem>;
92 using Item = TItem;
93
94 18 static constexpr inline IterValue<Item> next(Self& self) {
95
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 7 times.
18 if(self.repetitions.has_value()) {
96
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if(self.repetitionsRemaining == 0) { return {}; }
97 3 self.repetitionsRemaining -= 1;
98 }
99 17 return self.item;
100 }
101 24 static constexpr inline SizeHint sizeHint(const Self& self) {
102 return SizeHint(
103 self.repetitions.value_or(SizeHint::INFINITE),
104 self.repetitions
105 24 );
106 }
107 static constexpr inline size_t advanceBy(Self& self, size_t n) { return util::advanceByPull(self, n); }
108 };
109 /** @private */
110 template<typename TItem>
111 struct trait::ExactSizeIterator<Repeater<TItem>> {
112 1 static constexpr inline size_t size(const Repeater<TItem>& self) { return trait::Iterator<Repeater<TItem>>::sizeHint(self).lowerBound; }
113 };
114
115
116
117 // ################################################################################################
118 // GENERATOR RANGE
119 // ################################################################################################
120 /** @private */
121 template<typename TValue>
122 class Range : public IterApi<Range<TValue>> {
123 friend struct trait::Iterator<Range<TValue>>;
124 friend struct trait::ExactSizeIterator<Range<TValue>>;
125 private:
126 TValue current;
127 TValue from;
128 TValue to;
129 TValue step;
130 public:
131 6 constexpr Range(TValue from, TValue to, TValue step) : current(from), from(from), to(to), step(step) {}
132 };
133 // ------------------------------------------------------------------------------------------------
134 /** @private */
135 template<typename TValue>
136 struct trait::Iterator<Range<TValue>> {
137 // CXXIter Interface
138 using Self = Range<TValue>;
139 using Item = TValue;
140
141 26 static constexpr inline IterValue<Item> next(Self& self) {
142
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 16 times.
26 if(self.current > self.to) [[unlikely]] { return {}; }
143 21 TValue current = self.current;
144 21 self.current += self.step;
145 21 return current;
146 }
147 7 static constexpr inline SizeHint sizeHint(const Self& self) {
148 7 size_t cnt = static_cast<size_t>((self.to - self.from) / self.step) + 1;
149 7 return SizeHint(cnt, cnt);
150 }
151 static constexpr inline size_t advanceBy(Self& self, size_t n) { return util::advanceByPull(self, n); }
152 };
153 /** @private */
154 template<typename TItem>
155 struct trait::ExactSizeIterator<Range<TItem>> {
156 1 static constexpr inline size_t size(const Range<TItem>& self) { return trait::Iterator<Range<TItem>>::sizeHint(self).lowerBound; }
157 };
158
159
160
161 #ifdef CXXITER_HAS_COROUTINE
162 // ################################################################################################
163 // COROUTINE GENERATOR
164 // ################################################################################################
165 /** @private */
166 template<typename TGenerator>
167 class CoroutineGenerator : public IterApi<CoroutineGenerator<TGenerator>> {
168 friend struct trait::Iterator<CoroutineGenerator<TGenerator>>;
169 friend struct trait::ExactSizeIterator<CoroutineGenerator<TGenerator>>;
170 private:
171 TGenerator generator;
172 public:
173 2 CoroutineGenerator(TGenerator&& generator) : generator(std::forward<TGenerator>(generator)) {}
174 };
175 // ------------------------------------------------------------------------------------------------
176 /** @private */
177 template<typename TGeneratorFn>
178 struct trait::Iterator<CoroutineGenerator<TGeneratorFn>> {
179 // CXXIter Interface
180 using Self = CoroutineGenerator<TGeneratorFn>;
181 using Item = typename TGeneratorFn::value_type;
182
183 1003 static constexpr inline IterValue<Item> next(Self& self) {
184 1003 return self.generator.next();
185 }
186 2 static constexpr inline SizeHint sizeHint(const Self&) { return SizeHint(); }
187 static constexpr inline size_t advanceBy(Self& self, size_t n) { return util::advanceByPull(self, n); }
188 };
189 #endif
190
191 }
192