7#include "../util/TraitImpl.h"
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>>;
22 template<
typename TItem>
23 struct trait::Iterator<Empty<TItem>> {
25 using Self = Empty<TItem>;
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; }
33 template<
typename TItem>
34 struct trait::ExactSizeIterator<Empty<TItem>> {
35 static constexpr inline size_t size(
const Empty<TItem>&) {
return 0; }
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>>;
48 TGeneratorFn generatorFn;
50 FunctionGenerator(TGeneratorFn generatorFn) : generatorFn(generatorFn) {}
54 template<
typename TItem,
typename TGeneratorFn>
55 struct trait::Iterator<FunctionGenerator<TItem, TGeneratorFn>> {
57 using Self = FunctionGenerator<TItem, TGeneratorFn>;
60 static constexpr inline IterValue<Item>
next(
Self& self) {
61 auto item = self.generatorFn();
62 if(!item.has_value()) [[unlikely]] {
return {}; }
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); }
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>>;
81 std::optional<size_t> repetitions;
82 size_t repetitionsRemaining;
84 Repeater(
const TItem& item, std::optional<size_t> repetitions) : item(item), repetitions(repetitions), repetitionsRemaining(repetitions.value_or(0)) {}
88 template<
typename TItem>
89 struct trait::Iterator<Repeater<TItem>> {
91 using Self = Repeater<TItem>;
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;
101 static constexpr inline SizeHint
sizeHint(
const Self& self) {
103 self.repetitions.value_or(SizeHint::INFINITE),
107 static constexpr inline size_t advanceBy(
Self& self,
size_t n) {
return util::advanceByPull(self, n); }
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; }
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>>;
131 constexpr Range(TValue from, TValue to, TValue step) : current(
from),
from(
from), to(to), step(step) {}
135 template<
typename TValue>
136 struct trait::Iterator<Range<TValue>> {
138 using Self = Range<TValue>;
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;
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);
151 static constexpr inline size_t advanceBy(
Self& self,
size_t n) {
return util::advanceByPull(self, n); }
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; }
161#ifdef CXXITER_HAS_COROUTINE
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>>;
171 TGenerator generator;
173 CoroutineGenerator(TGenerator&& generator) : generator(std::forward<TGenerator>(generator)) {}
177 template<
typename TGeneratorFn>
178 struct trait::Iterator<CoroutineGenerator<TGeneratorFn>> {
180 using Self = CoroutineGenerator<TGeneratorFn>;
181 using Item =
typename TGeneratorFn::value_type;
183 static constexpr inline IterValue<Item>
next(
Self& self) {
184 return self.generator.next();
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); }
constexpr const TValueDeref & value() const
Get the contained value (if any).
constexpr SrcMov< std::remove_cvref_t< TContainer > > from(TContainer &&container)
Construct a CXXIter move source from the given container.
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.
trait::Iterator< T > Self
Self-Type. This is the type of the struct for which the trait::Iterator is being specialized.
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.