GCC Code Coverage Report


Directory: ./
File: include/CXXIter/src/sources/ContainerSources.h
Date: 2023-01-04 16:32:12
Exec Total Coverage
Lines: 38 38 100.0%
Functions: 141 141 100.0%
Branches: 12 12 100.0%

Line Branch Exec Source
1 #pragma once
2
3 #include <memory>
4
5 #include "../Common.h"
6 #include "Concepts.h"
7
8 namespace CXXIter {
9
10 // ################################################################################################
11 // SOURCE (MOVE / CONSUME)
12 // ################################################################################################
13
14 /**
15 * @brief CXXIter iterator source that takes over the input item source, and moves its items
16 * through the element stream, essentially "consuming" them.
17 */
18 template<typename TContainer>
19 requires concepts::SourceContainer<std::remove_cvref_t<TContainer>>
20 class SrcMov : public IterApi<SrcMov<TContainer>> {
21 friend struct trait::Iterator<SrcMov<TContainer>>;
22 friend struct trait::DoubleEndedIterator<SrcMov<TContainer>>;
23 friend struct trait::ExactSizeIterator<SrcMov<TContainer>>;
24 friend struct trait::ContiguousMemoryIterator<SrcMov<TContainer>>;
25 using Src = trait::Source<TContainer>;
26 private:
27 std::unique_ptr<TContainer> container;
28 typename Src::IteratorState iter;
29 public:
30 132 SrcMov(TContainer&& container) : container(std::make_unique<TContainer>(std::move(container))), iter(Src::initIterator(*this->container)) {}
31 };
32 // ------------------------------------------------------------------------------------------------
33 /** @private */
34 template<typename TContainer>
35 struct trait::Iterator<SrcMov<TContainer>> {
36 using Src = trait::Source<TContainer>;
37 // CXXIter Interface
38 using Self = SrcMov<TContainer>;
39 using Item = typename Src::Item;
40
41 424 static constexpr inline IterValue<Item> next(Self& self) {
42
2/2
✓ Branch 2 taken 59 times.
✓ Branch 3 taken 156 times.
424 if(!Src::hasNext(*self.container, self.iter)) [[unlikely]] { return {}; }
43 307 return std::move(Src::next(*self.container, self.iter));
44 }
45 22 static constexpr inline SizeHint sizeHint(const Self& self) { return Src::sizeHint(*self.container); }
46 8 static constexpr inline size_t advanceBy(Self& self, size_t n) {
47 8 return Src::skipN(*self.container, self.iter, n);
48 }
49 };
50 /** @private */
51 template<typename TContainer>
52 requires concepts::DoubleEndedSourceContainer<std::remove_cvref_t<TContainer>>
53 struct trait::DoubleEndedIterator<SrcMov<TContainer>> {
54 using Src = trait::Source<TContainer>;
55 using Item = typename Src::Item;
56
57 // CXXIter Interface
58 148 static constexpr inline IterValue<Item> nextBack(SrcMov<TContainer>& self) {
59
2/2
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 63 times.
148 if(!Src::hasNext(*self.container, self.iter)) [[unlikely]] { return {}; }
60 111 return std::move(Src::nextBack(*self.container, self.iter));
61 }
62 };
63 /** @private */
64 template<typename TContainer>
65 struct trait::ExactSizeIterator<SrcMov<TContainer>> {
66 static constexpr inline size_t size(const SrcMov<TContainer>& self) { return self.container->size(); }
67 };
68 /** @private */
69 template<typename TContainer>
70 requires util::ContiguousMemoryContainer<TContainer>
71 struct trait::ContiguousMemoryIterator<SrcMov<TContainer>> {
72 using ItemPtr = std::add_pointer_t<std::remove_reference_t<typename SrcMov<TContainer>::Item>>;
73 1 static constexpr inline ItemPtr currentPtr(SrcMov<TContainer>& self) {
74 1 return &trait::Source<TContainer>::peekNext(*self.container, self.iter);
75 }
76 };
77
78
79
80 // ################################################################################################
81 // SOURCE (MUTABLE REFERENCE)
82 // ################################################################################################
83
84 /**
85 * @brief CXXIter iterator source that mutably borrows the input item source, and passes mutable
86 * references to the items of the source through the iterator.
87 * @details This allows the iterator to modify the items while leaving them in the original
88 * item source.
89 */
90 template<typename TContainer>
91 requires concepts::SourceContainer<std::remove_cvref_t<TContainer>>
92 class SrcRef : public IterApi<SrcRef<TContainer>> {
93 friend struct trait::Iterator<SrcRef<TContainer>>;
94 friend struct trait::DoubleEndedIterator<SrcRef<TContainer>>;
95 friend struct trait::ExactSizeIterator<SrcRef<TContainer>>;
96 friend struct trait::ContiguousMemoryIterator<SrcRef<TContainer>>;
97 using Src = trait::Source<TContainer>;
98 private:
99 TContainer& container;
100 typename Src::IteratorState iter;
101 public:
102 743 SrcRef(TContainer& container) : container(container), iter(Src::initIterator(this->container)) {}
103 };
104 // ------------------------------------------------------------------------------------------------
105 /** @private */
106 template<typename TContainer>
107 struct trait::Iterator<SrcRef<TContainer>> {
108 using Src = trait::Source<TContainer>;
109 // CXXIter Interface
110 using Self = SrcRef<TContainer>;
111 using Item = typename Src::ItemRef;
112
113 2322 static constexpr inline IterValue<Item> next(Self& self) {
114
2/2
✓ Branch 1 taken 227 times.
✓ Branch 2 taken 934 times.
2322 if(!Src::hasNext(self.container, self.iter)) [[unlikely]] { return {}; }
115 1868 return Src::next(self.container, self.iter);
116 }
117 508 static constexpr inline SizeHint sizeHint(const Self& self) { return Src::sizeHint(self.container); }
118 94 static constexpr inline size_t advanceBy(Self& self, size_t n) {
119 94 return Src::skipN(self.container, self.iter, n);
120 }
121 };
122 /** @private */
123 template<typename TContainer>
124 requires concepts::DoubleEndedSourceContainer<std::remove_cvref_t<TContainer>>
125 struct trait::DoubleEndedIterator<SrcRef<TContainer>> {
126 using Src = trait::Source<TContainer>;
127 using Item = typename Src::ItemRef;
128
129 // CXXIter Interface
130 57 static constexpr inline IterValue<Item> nextBack(SrcRef<TContainer>& self) {
131
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 27 times.
57 if(!Src::hasNext(self.container, self.iter)) [[unlikely]] { return {}; }
132 44 return Src::nextBack(self.container, self.iter);
133 }
134 };
135 /** @private */
136 template<typename TContainer>
137 struct trait::ExactSizeIterator<SrcRef<TContainer>> {
138 24 static constexpr inline size_t size(const SrcRef<TContainer>& self) { return self.container.size(); }
139 };
140 /** @private */
141 template<typename TContainer>
142 requires util::ContiguousMemoryContainer<TContainer>
143 struct trait::ContiguousMemoryIterator<SrcRef<TContainer>> {
144 using ItemPtr = std::add_pointer_t<std::remove_reference_t<typename SrcRef<TContainer>::Item>>;
145 37 static constexpr inline ItemPtr currentPtr(SrcRef<TContainer>& self) {
146 37 return &trait::Source<TContainer>::peekNext(self.container, self.iter);
147 }
148 };
149
150
151
152 // ################################################################################################
153 // SOURCE (CONST REFERENCE)
154 // ################################################################################################
155
156 /**
157 * @brief CXXIter iterator source that immutably borrows the input item source, and passes immutable
158 * references to the items of the source through the iterator.
159 * @details This guarantees the original source to stay untouched & unmodified.
160 */
161 template<typename TContainer>
162 requires concepts::SourceContainer<std::remove_cvref_t<TContainer>>
163 class SrcCRef : public IterApi<SrcCRef<TContainer>> {
164 friend struct trait::Iterator<SrcCRef<TContainer>>;
165 friend struct trait::DoubleEndedIterator<SrcCRef<TContainer>>;
166 friend struct trait::ExactSizeIterator<SrcCRef<TContainer>>;
167 friend struct trait::ContiguousMemoryIterator<SrcCRef<TContainer>>;
168 using Src = trait::Source<TContainer>;
169 private:
170 const TContainer& container;
171 typename Src::ConstIteratorState iter;
172 public:
173 78 constexpr SrcCRef(const TContainer& container) : container(container), iter(Src::initIterator(this->container)) {}
174 };
175 // ------------------------------------------------------------------------------------------------
176 /** @private */
177 template<typename TContainer>
178 struct trait::Iterator<SrcCRef<TContainer>> {
179 using Src = trait::Source<TContainer>;
180 // CXXIter Interface
181 using Self = SrcCRef<TContainer>;
182 using Item = typename Src::ItemConstRef;
183
184 108 static constexpr inline IterValue<Item> next(Self& self) {
185
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 17 times.
108 if(!Src::hasNext(self.container, self.iter)) [[unlikely]] { return {}; }
186 89 return Src::next(self.container, self.iter);
187 }
188 6 static constexpr inline SizeHint sizeHint(const Self& self) { return Src::sizeHint(self.container); }
189 7 static constexpr inline size_t advanceBy(Self& self, size_t n) {
190 7 return Src::skipN(self.container, self.iter, n);
191 }
192 };
193 /** @private */
194 template<typename TContainer>
195 requires concepts::DoubleEndedSourceContainer<std::remove_cvref_t<TContainer>>
196 struct trait::DoubleEndedIterator<SrcCRef<TContainer>> {
197 using Src = trait::Source<TContainer>;
198 using Item = typename Src::ItemConstRef;
199
200 // CXXIter Interface
201 8 static constexpr inline IterValue<Item> nextBack(SrcCRef<TContainer>& self) {
202
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 5 times.
8 if(!Src::hasNext(self.container, self.iter)) [[unlikely]] { return {}; }
203 5 return Src::nextBack(self.container, self.iter);
204 }
205 };
206 /** @private */
207 template<typename TContainer>
208 struct trait::ExactSizeIterator<SrcCRef<TContainer>> {
209 2 static constexpr inline size_t size(const SrcCRef<TContainer>& self) { return self.container.size(); }
210 };
211 /** @private */
212 template<typename TContainer>
213 requires util::ContiguousMemoryContainer<TContainer>
214 struct trait::ContiguousMemoryIterator<SrcCRef<TContainer>> {
215 using ItemPtr = std::add_pointer_t<std::remove_reference_t<typename SrcCRef<TContainer>::Item>>;
216 3 static constexpr inline ItemPtr currentPtr(SrcCRef<TContainer>& self) {
217 3 return &trait::Source<TContainer>::peekNext(self.container, self.iter);
218 }
219 };
220
221 }
222