• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

xlnt-community / xlnt / b5325487-b953-4fb3-ae7c-12335ef12dcb

02 Feb 2025 07:13PM UTC coverage: 81.7% (-1.8%) from 83.482%
b5325487-b953-4fb3-ae7c-12335ef12dcb

Pull #55

circleci

doomlaur
Fix CI to use the correct Docker image for code coverage tests
Pull Request #55: Add support for C++20 and C++23, and experimental support for C++26

78 of 142 new or added lines in 8 files covered. (54.93%)

304 existing lines in 28 files now uncovered.

11460 of 14027 relevant lines covered (81.7%)

1191795.07 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.64
./source/cell/cell_reference.cpp
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
#include <cctype>
27

28
#include <xlnt/cell/cell_reference.hpp>
29
#include <xlnt/utils/exceptions.hpp>
30
#include <xlnt/worksheet/range_reference.hpp>
31

32
#include <detail/constants.hpp>
33
#include <detail/serialization/parsers.hpp>
34

35
namespace xlnt {
36

37
std::size_t cell_reference_hash::operator()(const cell_reference &k) const
4✔
38
{
39
    return k.row() * constants::max_column().index + k.column_index();
4✔
40
}
41

42
cell_reference &cell_reference::make_absolute(bool absolute_column, bool absolute_row)
10✔
43
{
44
    column_absolute(absolute_column);
10✔
45
    row_absolute(absolute_row);
10✔
46

47
    return *this;
10✔
48
}
49

50
cell_reference::cell_reference()
8✔
51
    : cell_reference(1, 1)
8✔
52
{
53
}
8✔
54

55
cell_reference::cell_reference(const std::string &string)
1,567✔
56
{
57
    auto split = split_reference(string, absolute_column_, absolute_row_);
1,567✔
58

59
    column(split.first);
1,565✔
60
    row(split.second);
1,565✔
61
}
1,565✔
62

63
cell_reference::cell_reference(const char *reference_string)
785✔
64
    : cell_reference(std::string(reference_string))
787✔
65
{
66
}
783✔
67

68
cell_reference::cell_reference(column_t column_index, row_t row)
86,981,718✔
69
    : column_(column_index), row_(row), absolute_row_(false), absolute_column_(false)
86,981,718✔
70
{
71
    if (row_ == 0
173,963,436✔
72
        || column_ == 0
86,981,717✔
73
        || !(row_ <= constants::max_row())
86,981,717✔
74
        || !(column_ <= constants::max_column()))
173,963,435✔
75
    {
76
        throw invalid_cell_reference(column_, row_);
1✔
77
    }
78
}
86,981,717✔
79

80
range_reference cell_reference::operator,(const xlnt::cell_reference &other) const
1✔
81
{
82
    return range_reference(*this, other);
1✔
83
}
84

85
std::string cell_reference::to_string() const
14,221,850✔
86
{
87
    std::string string_representation;
14,221,850✔
88

89
    if (absolute_column_)
14,221,850✔
90
    {
91
        string_representation.append("$");
8✔
92
    }
93

94
    string_representation.append(column_.column_string());
14,221,850✔
95

96
    if (absolute_row_)
14,221,850✔
97
    {
98
        string_representation.append("$");
8✔
99
    }
100

101
    string_representation.append(std::to_string(row_));
14,221,850✔
102

103
    return string_representation;
14,221,850✔
UNCOV
104
}
×
105

106
range_reference cell_reference::to_range() const
×
107
{
108
    return range_reference(column_, row_, column_, row_);
×
109
}
110

111
std::pair<std::string, row_t> cell_reference::split_reference(const std::string &reference_string)
12✔
112
{
113
    bool ignore1, ignore2;
114
    return split_reference(reference_string, ignore1, ignore2);
16✔
115
}
116

117
std::pair<std::string, row_t> cell_reference::split_reference(
1,579✔
118
    const std::string &reference_string, bool &absolute_column, bool &absolute_row)
119
{
120
    absolute_column = false;
1,579✔
121
    absolute_row = false;
1,579✔
122

123
    // Convert a coordinate string like 'B12' to a tuple ('B', 12)
124
    bool column_part = true;
1,579✔
125

126
    std::string column_string;
1,579✔
127

128
    for (auto character : reference_string)
5,002✔
129
    {
130
        auto upper = static_cast<char>(std::toupper(static_cast<std::uint8_t>(character)));
3,431✔
131

132
        if (std::isalpha(character))
3,431✔
133
        {
134
            if (column_part)
1,623✔
135
            {
136
                column_string.append(1, upper);
1,616✔
137
            }
138
            else
139
            {
140
                throw invalid_cell_reference(reference_string);
7✔
141
            }
142
        }
143
        else if (character == '$')
1,808✔
144
        {
145
            if (column_part)
16✔
146
            {
147
                if (column_string.empty())
16✔
148
                {
149
                    column_string.append(1, upper);
8✔
150
                }
151
                else
152
                {
153
                    column_part = false;
8✔
154
                }
155
            }
156
        }
157
        else
158
        {
159
            if (column_part)
1,792✔
160
            {
161
                column_part = false;
1,569✔
162
            }
163
            else if (!std::isdigit(character))
223✔
164
            {
165
                throw invalid_cell_reference(reference_string);
1✔
166
            }
167
        }
168
    }
169

170
    std::string row_string = reference_string.substr(column_string.length());
1,571✔
171

172
    if (row_string.length() == 0)
1,571✔
173
    {
174
        throw invalid_cell_reference(reference_string);
2✔
175
    }
176

177
    if (column_string[0] == '$')
1,569✔
178
    {
179
        absolute_column = true;
8✔
180
        column_string = column_string.substr(1);
8✔
181
    }
182

183
    if (row_string[0] == '$')
1,569✔
184
    {
185
        absolute_row = true;
8✔
186
        row_string = row_string.substr(1);
8✔
187
    }
188

189
    xlnt::row_t row = 0;
1,569✔
190
    if (detail::parse(row_string, row) != std::errc())
1,569✔
191
    {
192
        throw invalid_cell_reference(reference_string);
×
193
    }
194

195
    return {column_string, row};
3,138✔
196
}
1,581✔
197

198
bool cell_reference::column_absolute() const
3✔
199
{
200
    return absolute_column_;
3✔
201
}
202

203
void cell_reference::column_absolute(bool absolute_column)
10✔
204
{
205
    absolute_column_ = absolute_column;
10✔
206
}
10✔
207

208
bool cell_reference::row_absolute() const
3✔
209
{
210
    return absolute_row_;
3✔
211
}
212

213
void cell_reference::row_absolute(bool absolute_row)
10✔
214
{
215
    absolute_row_ = absolute_row;
10✔
216
}
10✔
217

218
column_t cell_reference::column() const
99,760,930✔
219
{
220
    return column_;
99,760,930✔
221
}
222

223
void cell_reference::column(const std::string &column_string)
1,565✔
224
{
225
    column_ = column_t(column_string);
1,565✔
226
}
1,565✔
227

228
column_t::index_t cell_reference::column_index() const
101,269,048✔
229
{
230
    return column_.index;
101,269,048✔
231
}
232

233
void cell_reference::column_index(column_t column)
14,039,650✔
234
{
235
    column_ = column;
14,039,650✔
236
}
14,039,650✔
237

238
row_t cell_reference::row() const
144,156,940✔
239
{
240
    return row_;
144,156,940✔
241
}
242

243
void cell_reference::row(row_t row)
15,849✔
244
{
245
    row_ = row;
15,849✔
246
}
15,849✔
247

248
bool cell_reference::operator==(const std::string &reference_string) const
38✔
249
{
250
    return *this == cell_reference(reference_string);
38✔
251
}
252

253
bool cell_reference::operator==(const char *reference_string) const
36✔
254
{
255
    return *this == std::string(reference_string);
72✔
256
}
257

258
bool cell_reference::operator!=(const cell_reference &comparand) const
48✔
259
{
260
    return !(*this == comparand);
48✔
261
}
262

263
bool cell_reference::operator!=(const std::string &reference_string) const
1✔
264
{
265
    return *this != cell_reference(reference_string);
1✔
266
}
267

268
bool cell_reference::operator!=(const char *reference_string) const
1✔
269
{
270
    return *this != std::string(reference_string);
2✔
271
}
272

273
cell_reference cell_reference::make_offset(int column_offset, int row_offset) const
39✔
274
{
275
    // TODO: check for overflow/underflow
276
    auto relative_column = static_cast<column_t::index_t>(static_cast<int>(column_.index) + column_offset);
39✔
277
    auto relative_row = static_cast<row_t>(static_cast<int>(row_) + row_offset);
39✔
278

279
    return cell_reference(relative_column, relative_row);
39✔
280
}
281

282
bool cell_reference::operator==(const cell_reference &comparand) const
69,957,114✔
283
{
284
    return comparand.column_ == column_
69,957,114✔
285
        && comparand.row_ == row_
69,955,666✔
286
        && absolute_column_ == comparand.absolute_column_
69,955,383✔
287
        && absolute_row_ == comparand.absolute_row_;
139,912,780✔
288
}
289

290
} // namespace xlnt
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc