TLA Line data Source code
1 : // Copyright (c) 2014-2022 Thomas Fussell
2 : // Copyright (c) 2010-2015 openpyxl
3 : // Copyright (c) 2024-2025 xlnt-community
4 : //
5 : // Permission is hereby granted, free of charge, to any person obtaining a copy
6 : // of this software and associated documentation files (the "Software"), to deal
7 : // in the Software without restriction, including without limitation the rights
8 : // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : // copies of the Software, and to permit persons to whom the Software is
10 : // furnished to do so, subject to the following conditions:
11 : //
12 : // The above copyright notice and this permission notice shall be included in
13 : // all copies or substantial portions of the Software.
14 : //
15 : // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 : // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : // THE SOFTWARE
22 : //
23 : // @license: http://www.opensource.org/licenses/mit-license.php
24 : // @author: see AUTHORS file
25 :
26 : #pragma once
27 :
28 : #include <cstddef> // std::ptrdiff_t
29 : #include <iterator>
30 :
31 : #include <xlnt/xlnt_config.hpp>
32 : #include <xlnt/cell/cell_reference.hpp>
33 : #include <xlnt/worksheet/major_order.hpp>
34 : #include <xlnt/worksheet/range_reference.hpp>
35 : #include <xlnt/worksheet/worksheet.hpp>
36 :
37 : namespace xlnt {
38 :
39 : enum class major_order;
40 :
41 : class cell;
42 : class cell_reference;
43 : class range_reference;
44 :
45 : /// <summary>
46 : /// A cell iterator iterates over a 1D range by row or by column.
47 : /// </summary>
48 : class XLNT_API cell_iterator
49 : {
50 : public:
51 : /// <summary>
52 : /// iterator tags required for use with standard algorithms and adapters
53 : /// </summary>
54 : using iterator_category = std::bidirectional_iterator_tag;
55 : using value_type = cell;
56 : using difference_type = std::ptrdiff_t;
57 : using pointer = cell *;
58 : using reference = cell; // intentionally value
59 :
60 : /// <summary>
61 : /// Default constructs a cell_iterator
62 : /// </summary>
63 CBC 2 : cell_iterator() = default;
64 :
65 : /// <summary>
66 : /// Constructs a cell_iterator from a worksheet, range, and iteration settings.
67 : /// </summary>
68 : cell_iterator(worksheet ws, const cell_reference &start_cell,
69 : const range_reference &limits, major_order order, bool skip_null, bool wrap);
70 :
71 : /// <summary>
72 : /// Constructs a cell_iterator as a copy of an existing cell_iterator.
73 : /// </summary>
74 198 : cell_iterator(const cell_iterator &) = default;
75 :
76 : /// <summary>
77 : /// Assigns this iterator to match the data in rhs.
78 : /// </summary>
79 : cell_iterator &operator=(const cell_iterator &) = default;
80 :
81 : /// <summary>
82 : /// Constructs a cell_iterator by moving from a cell_iterator temporary
83 : /// </summary>
84 : cell_iterator(cell_iterator &&) = default;
85 :
86 : /// <summary>
87 : /// Assigns this iterator to from a cell_iterator temporary
88 : /// </summary>
89 2 : cell_iterator &operator=(cell_iterator &&) = default;
90 :
91 : /// <summary>
92 : /// destructor for const_cell_iterator
93 : /// </summary>
94 : ~cell_iterator() = default;
95 :
96 : /// <summary>
97 : /// Dereferences this iterator to return the cell it points to.
98 : /// </summary>
99 : reference operator*();
100 :
101 : /// <summary>
102 : /// Dereferences this iterator to return the cell it points to.
103 : /// </summary>
104 : const reference operator*() const;
105 :
106 : /// <summary>
107 : /// Returns true if this iterator is equivalent to other.
108 : /// </summary>
109 : bool operator==(const cell_iterator &other) const;
110 :
111 : /// <summary>
112 : /// Returns true if this iterator isn't equivalent to other.
113 : /// </summary>
114 : bool operator!=(const cell_iterator &other) const;
115 :
116 : /// <summary>
117 : /// Pre-decrements the iterator to point to the previous cell and
118 : /// returns a reference to the iterator.
119 : /// </summary>
120 : cell_iterator &operator--();
121 :
122 : /// <summary>
123 : /// Post-decrements the iterator to point to the previous cell and
124 : /// return a copy of the iterator before the decrement.
125 : /// </summary>
126 : cell_iterator operator--(int);
127 :
128 : /// <summary>
129 : /// Pre-increments the iterator to point to the previous cell and
130 : /// returns a reference to the iterator.
131 : /// </summary>
132 : cell_iterator &operator++();
133 :
134 : /// <summary>
135 : /// Post-increments the iterator to point to the previous cell and
136 : /// return a copy of the iterator before the decrement.
137 : /// </summary>
138 : cell_iterator operator++(int);
139 :
140 : /// <summary>
141 : /// When iterating over a range that doesn't ignore null cells, operator*()
142 : /// will throw when trying to access the cells that are null. This method
143 : /// checks the existence of a cell.
144 : /// </summary>
145 : bool has_value() const;
146 :
147 : private:
148 : /// <summary>
149 : /// If true, cells that don't exist in the worksheet will be skipped during iteration.
150 : /// </summary>
151 : bool skip_null_ = false;
152 :
153 : /// <summary>
154 : /// If true, when on the last column, the cursor will continue to the next row
155 : /// (and vice versa when iterating in column-major order) until reaching the
156 : /// bottom right corner of the range.
157 : /// </summary>
158 : bool wrap_ = false;
159 :
160 : /// <summary>
161 : /// The order this iterator will move, by column or by row. Note that
162 : /// this has the opposite meaning as in a range_iterator because after
163 : /// getting a row-major range_iterator, the row-major cell_iterator will
164 : /// iterate over a column and vice versa.
165 : /// </summary>
166 : major_order order_ = major_order::column;
167 :
168 : /// <summary>
169 : /// The worksheet this iterator will return cells from.
170 : /// </summary>
171 : worksheet ws_;
172 :
173 : /// <summary>
174 : /// The current cell the iterator points to
175 : /// </summary>
176 : cell_reference cursor_;
177 :
178 : /// <summary>
179 : /// The range of cells this iterator is restricted to
180 : /// </summary>
181 : range_reference bounds_;
182 : };
183 :
184 : /// <summary>
185 : /// A cell iterator iterates over a 1D range by row or by column.
186 : /// </summary>
187 : class XLNT_API const_cell_iterator
188 : {
189 : public:
190 : /// <summary>
191 : /// iterator tags required for use with standard algorithms and adapters
192 : /// </summary>
193 : using iterator_category = std::bidirectional_iterator_tag;
194 : using value_type = const cell;
195 : using difference_type = std::ptrdiff_t;
196 : using pointer = const cell *;
197 : using reference = const cell; // intentionally value
198 :
199 : /// <summary>
200 : /// Default constructs a cell_iterator
201 : /// </summary>
202 2 : const_cell_iterator() = default;
203 :
204 : /// <summary>
205 : /// Constructs a cell_iterator from a worksheet, range, and iteration settings.
206 : /// </summary>
207 : const_cell_iterator(worksheet ws, const cell_reference &start_cell,
208 : const range_reference &limits, major_order order, bool skip_null, bool wrap);
209 :
210 : /// <summary>
211 : /// Constructs a const_cell_iterator as a copy of an existing cell_iterator.
212 : /// </summary>
213 517 : const_cell_iterator(const const_cell_iterator &) = default;
214 :
215 : /// <summary>
216 : /// Assigns this iterator to match the data in rhs.
217 : /// </summary>
218 : const_cell_iterator &operator=(const const_cell_iterator &) = default;
219 :
220 : /// <summary>
221 : /// Constructs a const_cell_iterator by moving from a const_cell_iterator temporary
222 : /// </summary>
223 : const_cell_iterator(const_cell_iterator &&) = default;
224 :
225 : /// <summary>
226 : /// Assigns this iterator to from a const_cell_iterator temporary
227 : /// </summary>
228 : const_cell_iterator &operator=(const_cell_iterator &&) = default;
229 :
230 : /// <summary>
231 : /// destructor for const_cell_iterator
232 : /// </summary>
233 : ~const_cell_iterator() = default;
234 :
235 : /// <summary>
236 : /// Dereferences this iterator to return the cell it points to.
237 : /// </summary>
238 : const reference operator*() const;
239 :
240 : /// <summary>
241 : /// Returns true if this iterator is equivalent to other.
242 : /// </summary>
243 : bool operator==(const const_cell_iterator &other) const;
244 :
245 : /// <summary>
246 : /// Returns true if this iterator isn't equivalent to other.
247 : /// </summary>
248 : bool operator!=(const const_cell_iterator &other) const;
249 :
250 : /// <summary>
251 : /// Pre-decrements the iterator to point to the previous cell and
252 : /// returns a reference to the iterator.
253 : /// </summary>
254 : const_cell_iterator &operator--();
255 :
256 : /// <summary>
257 : /// Post-decrements the iterator to point to the previous cell and
258 : /// return a copy of the iterator before the decrement.
259 : /// </summary>
260 : const_cell_iterator operator--(int);
261 :
262 : /// <summary>
263 : /// Pre-increments the iterator to point to the previous cell and
264 : /// returns a reference to the iterator.
265 : /// </summary>
266 : const_cell_iterator &operator++();
267 :
268 : /// <summary>
269 : /// Post-increments the iterator to point to the previous cell and
270 : /// return a copy of the iterator before the decrement.
271 : /// </summary>
272 : const_cell_iterator operator++(int);
273 :
274 : /// <summary>
275 : /// When iterating over a range that doesn't ignore null cells, operator*()
276 : /// will throw when trying to access the cells that are null. This method
277 : /// checks the existence of a cell.
278 : /// </summary>
279 : bool has_value() const;
280 :
281 : private:
282 : /// <summary>
283 : /// If true, cells that don't exist in the worksheet will be skipped during iteration.
284 : /// </summary>
285 : bool skip_null_ = false;
286 :
287 : /// <summary>
288 : /// If true, when on the last column, the cursor will continue to the next row
289 : /// (and vice versa when iterating in column-major order) until reaching the
290 : /// bottom right corner of the range.
291 : /// </summary>
292 : bool wrap_ = false;
293 :
294 : /// <summary>
295 : /// The order this iterator will move, by column or by row. Note that
296 : /// this has the opposite meaning as in a range_iterator because after
297 : /// getting a row-major range_iterator, the row-major cell_iterator will
298 : /// iterate over a column and vice versa.
299 : /// </summary>
300 : major_order order_ = major_order::column;
301 :
302 : /// <summary>
303 : /// The worksheet this iterator will return cells from.
304 : /// </summary>
305 : worksheet ws_;
306 :
307 : /// <summary>
308 : /// The current cell the iterator points to
309 : /// </summary>
310 : cell_reference cursor_;
311 :
312 : /// <summary>
313 : /// The range of cells this iterator is restricted to
314 : /// </summary>
315 : range_reference bounds_;
316 : };
317 :
318 : } // namespace xlnt
|