CXXIter 0.2
Loading...
Searching...
No Matches
GeneratorSources.h
1#pragma once
2
3#include <cstdlib>
4#include <optional>
5
6#include "../Common.h"
7#include "../util/TraitImpl.h"
8
9namespace CXXIter {
10
11 // ################################################################################################
12 // GENERATOR EMPTY
13 // ################################################################################################
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 // ------------------------------------------------------------------------------------------------
22 template<typename TItem>
23 struct trait::Iterator<Empty<TItem>> {
24 // CXXIter Interface
25 using Self = Empty<TItem>;
26 using Item = TItem;
27
28 static constexpr inline IterValue<Item> next(Self&) { return {}; }
29 static constexpr inline SizeHint sizeHint(const Self&) { return SizeHint(0, 0); }
30 static constexpr inline size_t advanceBy(Self&, size_t) { return 0; }
31 };
33 template<typename TItem>
34 struct trait::ExactSizeIterator<Empty<TItem>> {
35 static constexpr inline size_t size(const Empty<TItem>&) { return 0; }
36 };
37
38
39 // ################################################################################################
40 // GENERATOR FUNCTION
41 // ################################################################################################
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 FunctionGenerator(TGeneratorFn generatorFn) : generatorFn(generatorFn) {}
51 };
52 // ------------------------------------------------------------------------------------------------
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 static constexpr inline IterValue<Item> next(Self& self) {
61 auto item = self.generatorFn();
62 if(!item.has_value()) [[unlikely]] { return {}; }
63 return item.value();
64 }
65 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 // ################################################################################################
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 Repeater(const TItem& item, std::optional<size_t> repetitions) : item(item), repetitions(repetitions), repetitionsRemaining(repetitions.value_or(0)) {}
85 };
86 // ------------------------------------------------------------------------------------------------
88 template<typename TItem>
89 struct trait::Iterator<Repeater<TItem>> {
90 // CXXIter Interface
91 using Self = Repeater<TItem>;
92 using Item = TItem;
93
94 static constexpr inline IterValue<Item> next(Self& self) {
95 if(self.repetitions.has_value()) {
96 if(self.repetitionsRemaining == 0) { return {}; }
97 self.repetitionsRemaining -= 1;
98 }
99 return self.item;
100 }
101 static constexpr inline SizeHint sizeHint(const Self& self) {
102 return SizeHint(
103 self.repetitions.value_or(SizeHint::INFINITE),
104 self.repetitions
105 );
106 }
107 static constexpr inline size_t advanceBy(Self& self, size_t n) { return util::advanceByPull(self, n); }
108 };
110 template<typename TItem>
111 struct trait::ExactSizeIterator<Repeater<TItem>> {
112 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 // ################################################################################################
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 constexpr Range(TValue from, TValue to, TValue step) : current(from), from(from), to(to), step(step) {}
132 };
133 // ------------------------------------------------------------------------------------------------
135 template<typename TValue>
136 struct trait::Iterator<Range<TValue>> {
137 // CXXIter Interface
138 using Self = Range<TValue>;
139 using Item = TValue;
140
141 static constexpr inline IterValue<Item> next(Self& self) {
142 if(self.current > self.to) [[unlikely]] { return {}; }
143 TValue current = self.current;
144 self.current += self.step;
145 return current;
146 }
147 static constexpr inline SizeHint sizeHint(const Self& self) {
148 size_t cnt = static_cast<size_t>((self.to - self.from) / self.step) + 1;
149 return SizeHint(cnt, cnt);
150 }
151 static constexpr inline size_t advanceBy(Self& self, size_t n) { return util::advanceByPull(self, n); }
152 };
154 template<typename TItem>
155 struct trait::ExactSizeIterator<Range<TItem>> {
156 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 // ################################################################################################
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 CoroutineGenerator(TGenerator&& generator) : generator(std::forward<TGenerator>(generator)) {}
174 };
175 // ------------------------------------------------------------------------------------------------
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 static constexpr inline IterValue<Item> next(Self& self) {
184 return self.generator.next();
185 }
186 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}
constexpr const TValueDeref & value() const
Get the contained value (if any).
Definition: IterValue.h:62
CXXIter.
Definition: CXXIter.h:48
constexpr SrcMov< std::remove_cvref_t< TContainer > > from(TContainer &&container)
Construct a CXXIter move source from the given container.
Definition: CXXIter.h:2188
static constexpr size_t size(const typename trait::Iterator< T >::Self &self)=delete
Get the iterator's exact number of elements.
static constexpr IterValue< Item > next(Self &self)=delete
Pull one element from the iterator pipeline previous to this pipeline-element.
void Item
Item-Type. This is the type of elements that can be pulled from this pipeline-element.
Definition: Traits.h:32
trait::Iterator< T > Self
Self-Type. This is the type of the struct for which the trait::Iterator is being specialized.
Definition: Traits.h:28
static constexpr SizeHint sizeHint(const Self &self)=delete
Get the bounds on the remaining length of the iterator pipeline until this pipeline-element,...
static constexpr size_t advanceBy(Self &self, size_t n)=delete
Advance the iterator by n elements.