TLA Line data Source code
1 : // Copyright (c) 2014-2022 Thomas Fussell
2 : // Copyright (c) 2024-2025 xlnt-community
3 : //
4 : // Permission is hereby granted, free of charge, to any person obtaining a copy
5 : // of this software and associated documentation files (the "Software"), to deal
6 : // in the Software without restriction, including without limitation the rights
7 : // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 : // copies of the Software, and to permit persons to whom the Software is
9 : // furnished to do so, subject to the following conditions:
10 : //
11 : // The above copyright notice and this permission notice shall be included in
12 : // all copies or substantial portions of the Software.
13 : //
14 : // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 : // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 : // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 : // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 : // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 : // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 : // THE SOFTWARE
21 : //
22 : // @license: http://www.opensource.org/licenses/mit-license.php
23 : // @author: see AUTHORS file
24 :
25 : #pragma once
26 :
27 : #include <cstdint>
28 : #include <string>
29 :
30 : #include <xlnt/xlnt_config.hpp>
31 :
32 : // We might want to change these types for various optimizations in the future
33 : // so use typedefs.
34 :
35 : namespace xlnt {
36 :
37 : /// <summary>
38 : /// All rows should be referred to by an instance of this type.
39 : /// </summary>
40 : using row_t = std::uint32_t;
41 :
42 : /// <summary>
43 : /// Columns can be referred to as a string A,B,...Z,AA,AB,..,ZZ,AAA,...,ZZZ
44 : /// or as a 1-indexed index. This class encapsulates both of these forms of
45 : /// column referencing and allows for conversions between them.
46 : /// </summary>
47 : class XLNT_API column_t
48 : {
49 : public:
50 : /// <summary>
51 : /// Alias declaration for the internal numeric type of this column.
52 : /// </summary>
53 : using index_t = std::uint32_t;
54 :
55 : /// <summary>
56 : /// Convert a column letter into a column number (e.g. B -> 2)
57 : /// </summary>
58 : /// <remarks>
59 : /// Excel only supports 1 - 3 letter column names from A->ZZZ, so we
60 : /// restrict our column names to 1 - 3 characters, each in the range A - Z.
61 : /// Strings outside this range and malformed strings will throw column_string_index_exception.
62 : /// </remarks>
63 : static index_t column_index_from_string(const std::string &column_string);
64 :
65 : /// <summary>
66 : /// Convert a column number into a column letter (3 -> 'C')
67 : /// </summary>
68 : /// <remarks>
69 : /// Right shift the column, column_index, by 26 to find column letters in reverse
70 : /// order. These indices are 1-based, and can be converted to ASCII
71 : /// ordinals by adding 64.
72 : /// </remarks>
73 : static std::string column_string_from_index(index_t column_index);
74 :
75 : /// <summary>
76 : /// Default constructor. The column points to the "A" column.
77 : /// </summary>
78 : column_t();
79 :
80 : /// <summary>
81 : /// Constructs a column from a number.
82 : /// </summary>
83 : column_t(index_t column_index);
84 :
85 : /// <summary>
86 : /// Constructs a column from a string.
87 : /// </summary>
88 : column_t(const std::string &column_string);
89 :
90 : /// <summary>
91 : /// Constructs a column from a string.
92 : /// </summary>
93 : column_t(const char *column_string);
94 :
95 : /// <summary>
96 : /// Returns a string representation of this column index.
97 : /// </summary>
98 : std::string column_string() const;
99 :
100 : /// <summary>
101 : /// Sets this column to be equal to rhs and return reference to self.
102 : /// </summary>
103 : column_t &operator=(const std::string &rhs);
104 :
105 : /// <summary>
106 : /// Sets this column to be equal to rhs and return reference to self.
107 : /// </summary>
108 : column_t &operator=(const char *rhs);
109 :
110 : /// <summary>
111 : /// Returns true if this column refers to the same column as other.
112 : /// </summary>
113 : bool operator==(const column_t &other) const;
114 :
115 : /// <summary>
116 : /// Returns true if this column doesn't refer to the same column as other.
117 : /// </summary>
118 : bool operator!=(const column_t &other) const;
119 :
120 : /// <summary>
121 : /// Returns true if this column refers to the same column as other.
122 : /// </summary>
123 : bool operator==(int other) const;
124 :
125 : /// <summary>
126 : /// Returns true if this column refers to the same column as other.
127 : /// </summary>
128 : bool operator==(index_t other) const;
129 :
130 : /// <summary>
131 : /// Returns true if this column refers to the same column as other.
132 : /// </summary>
133 : bool operator==(const std::string &other) const;
134 :
135 : /// <summary>
136 : /// Returns true if this column refers to the same column as other.
137 : /// </summary>
138 : bool operator==(const char *other) const;
139 :
140 : /// <summary>
141 : /// Returns true if this column doesn't refer to the same column as other.
142 : /// </summary>
143 : bool operator!=(int other) const;
144 :
145 : /// <summary>
146 : /// Returns true if this column doesn't refer to the same column as other.
147 : /// </summary>
148 : bool operator!=(index_t other) const;
149 :
150 : /// <summary>
151 : /// Returns true if this column doesn't refer to the same column as other.
152 : /// </summary>
153 : bool operator!=(const std::string &other) const;
154 :
155 : /// <summary>
156 : /// Returns true if this column doesn't refer to the same column as other.
157 : /// </summary>
158 : bool operator!=(const char *other) const;
159 :
160 : /// <summary>
161 : /// Returns true if other is to the right of this column.
162 : /// </summary>
163 : bool operator>(const column_t &other) const;
164 :
165 : /// <summary>
166 : /// Returns true if other is to the right of or equal to this column.
167 : /// </summary>
168 : bool operator>=(const column_t &other) const;
169 :
170 : /// <summary>
171 : /// Returns true if other is to the left of this column.
172 : /// </summary>
173 : bool operator<(const column_t &other) const;
174 :
175 : /// <summary>
176 : /// Returns true if other is to the left of or equal to this column.
177 : /// </summary>
178 : bool operator<=(const column_t &other) const;
179 :
180 : /// <summary>
181 : /// Returns true if other is to the right of this column.
182 : /// </summary>
183 : bool operator>(const column_t::index_t &other) const;
184 :
185 : /// <summary>
186 : /// Returns true if other is to the right of or equal to this column.
187 : /// </summary>
188 : bool operator>=(const column_t::index_t &other) const;
189 :
190 : /// <summary>
191 : /// Returns true if other is to the left of this column.
192 : /// </summary>
193 : bool operator<(const column_t::index_t &other) const;
194 :
195 : /// <summary>
196 : /// Returns true if other is to the left of or equal to this column.
197 : /// </summary>
198 : bool operator<=(const column_t::index_t &other) const;
199 :
200 : /// <summary>
201 : /// Pre-increments this column, making it point to the column one to the right and returning a reference to it.
202 : /// </summary>
203 : column_t &operator++();
204 :
205 : /// <summary>
206 : /// Pre-deccrements this column, making it point to the column one to the left and returning a reference to it.
207 : /// </summary>
208 : column_t &operator--();
209 :
210 : /// <summary>
211 : /// Post-increments this column, making it point to the column one to the right and returning the old column.
212 : /// </summary>
213 : column_t operator++(int);
214 :
215 : /// <summary>
216 : /// Post-decrements this column, making it point to the column one to the left and returning the old column.
217 : /// </summary>
218 : column_t operator--(int);
219 :
220 : /// <summary>
221 : /// Returns the result of adding rhs to this column.
222 : /// </summary>
223 : friend XLNT_API column_t operator+(column_t lhs, const column_t &rhs);
224 :
225 : /// <summary>
226 : /// Returns the result of subtracing lhs by rhs column.
227 : /// </summary>
228 : friend XLNT_API column_t operator-(column_t lhs, const column_t &rhs);
229 :
230 : /// <summary>
231 : /// Adds rhs to this column and returns a reference to this column.
232 : /// </summary>
233 : column_t &operator+=(const column_t &rhs);
234 :
235 : /// <summary>
236 : /// Subtracts rhs from this column and returns a reference to this column.
237 : /// </summary>
238 : column_t &operator-=(const column_t &rhs);
239 :
240 : /// <summary>
241 : /// Returns true if other is to the right of this column.
242 : /// </summary>
243 : friend XLNT_API bool operator>(const column_t::index_t &left, const column_t &right);
244 :
245 : /// <summary>
246 : /// Returns true if other is to the right of or equal to this column.
247 : /// </summary>
248 : friend XLNT_API bool operator>=(const column_t::index_t &left, const column_t &right);
249 :
250 : /// <summary>
251 : /// Returns true if other is to the left of this column.
252 : /// </summary>
253 : friend XLNT_API bool operator<(const column_t::index_t &left, const column_t &right);
254 :
255 : /// <summary>
256 : /// Returns true if other is to the left of or equal to this column.
257 : /// </summary>
258 : friend XLNT_API bool operator<=(const column_t::index_t &left, const column_t &right);
259 :
260 : /// <summary>
261 : /// Swaps the columns that left and right refer to.
262 : /// </summary>
263 : friend XLNT_API void swap(column_t &left, column_t &right);
264 :
265 : /// <summary>
266 : /// Internal numeric value of this column index.
267 : /// </summary>
268 : index_t index;
269 : };
270 :
271 : enum class row_or_col_t : int
272 : {
273 : row,
274 : column
275 : };
276 :
277 : /// <summary>
278 : /// Functor for hashing a column.
279 : /// Allows for use of std::unordered_set<column_t, column_hash> and similar.
280 : /// </summary>
281 : struct XLNT_API column_hash
282 : {
283 : /// <summary>
284 : /// Returns the result of hashing column k.
285 : /// </summary>
286 : std::size_t operator()(const column_t &k) const;
287 : };
288 :
289 : } // namespace xlnt
290 :
291 : namespace std {
292 :
293 : /// <summary>
294 : /// Template specialization to allow xlnt::column_t to be used as a key in a std container.
295 : /// </summary>
296 : template <>
297 : struct hash<xlnt::column_t>
298 : {
299 : /// <summary>
300 : /// Returns the result of hashing column k.
301 : /// </summary>
302 CBC 95523 : size_t operator()(const xlnt::column_t &k) const
303 : {
304 : static xlnt::column_hash hasher;
305 95523 : return hasher(k);
306 : }
307 : };
308 :
309 : } // namespace std
|