GCC Code Coverage Report


source/XpertMassCore/src/
File: source/XpertMassCore/src/IndexRange.cpp
Date: 2025-11-20 01:41:33
Lines:
51/58
87.9%
Functions:
15/16
93.8%
Branches:
20/56
35.7%

Line Branch Exec Source
1 /* BEGIN software license
2 *
3 * MsXpertSuite - mass spectrometry software suite
4 * -----------------------------------------------
5 * Copyright(C) 2009,...,2018 Filippo Rusconi
6 *
7 * http://www.msxpertsuite.org
8 *
9 * This file is part of the MsXpertSuite project.
10 *
11 * The MsXpertSuite project is the successor of the massXpert project. This
12 * project now includes various indepstopent modules:
13 *
14 * - massXpert, model polymer chemistries and simulate mass spectrometric data;
15 * - mineXpert, a powerful TIC chromatogram/mass spectrum viewer/miner;
16 *
17 * This program is free software: you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation, either version 3 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program. If not, see <http://www.gnu.org/licenses/>.
29 *
30 * END software license
31 */
32
33
34 /////////////////////// Qt includes
35 #include <QDebug>
36 #include <QStringList>
37 #include <QRegularExpression>
38 #include <QRegularExpressionMatch>
39
40 /////////////////////// Local includes
41 #include "MsXpS/libXpertMassCore/globals.hpp"
42 #include "MsXpS/libXpertMassCore/Utils.hpp"
43 #include "MsXpS/libXpertMassCore/IndexRangeCollection.hpp"
44
45 namespace MsXpS
46 {
47 namespace libXpertMassCore
48 {
49
50
51 /*!
52 \class MsXpS::libXpertMassCore::IndexRange
53 \inmodule libXpertMassCore
54 \ingroup XpertMassCalculations
55 \inheaderfile IndexRangeCollection.hpp
56
57 \brief The IndexRange class provides a range of indices that delimit a
58 region of interest in a \l{Polymer}'s \l{Sequence} instance.
59
60 One major IndexRange use case is when defining for what sequence region of a
61 Polymer the masses or the elemental composition is to be computed. Another use
62 case is when performing Sequence cleavages or Oligomer fragmentations: the
63 IndexRange enables the delimitation of the sequence of interest inside a given
64 \l{Polymer}'s \l{Sequence} instance.
65
66 When instantiating a new IndexRange, the start and stop values are automatically
67 sorted in ascending order (start <= stop).
68
69 \sa IndexRangeCollection, sortAscending(), sortDescending()
70 */
71
72 /*!
73 \variable MsXpS::libXpertMassCore::IndexRange::m_start
74
75 \brief Index that marks the start of the index range.
76 */
77
78 /*!
79 \variable MsXpS::libXpertMassCore::IndexRange::m_stop
80
81 \brief Index that marks the stop of the index range.
82 */
83
84
85 /*!
86 \brief Constructs an IndexRange instance using \a parent as the parent object of
87 this new instance.
88
89 Upon construction, the member data m_start and m_stop are initialized with
90 std::numeric_limits<std::size_t>::max() values as a means to check if the
91 IndexRange was initialized by the user or not.
92 */
93 575 IndexRange::IndexRange(QObject *parent): QObject(parent)
94 {
95 575 }
96
97 /*!
98 \ brief Constructs an IndexRange instance initializing the* start and stop
99 members to the \a index_start and \a index_stop values, respectively.
100
101 The values are sorted in ascending order upon construction.
102 */
103 5287 IndexRange::IndexRange(qsizetype index_start,
104 qsizetype index_stop,
105 5287 QObject *parent)
106 5287 : QObject(parent), m_start(index_start), m_stop(index_stop)
107 {
108
1/2
✓ Branch 1 taken 5287 times.
✗ Branch 2 not taken.
5287 sortAscending();
109 5287 }
110
111 /*!
112 \brief Constructs an IndexRange instance using \a other as a template and \a
113 parent as the parent of this new instance.
114
115 The values are sorted in ascending order upon construction.
116
117 \sa sortAscending(), sortDescending()
118 */
119 1004 IndexRange::IndexRange(const IndexRange &other, QObject *parent)
120 1004 : QObject(parent), m_start(other.m_start), m_stop(other.m_stop)
121 {
122
1/2
✓ Branch 1 taken 1004 times.
✗ Branch 2 not taken.
1004 sortAscending();
123 1004 }
124
125 /*!
126 \ brief Destructs this IndexRange instance.
127 */
128 24126 IndexRange::~IndexRange()
129 {
130 24126 }
131
132 /*!
133 \brief Initializes this instance using \a other. The parent of this instance is
134 unchanged.
135
136 The values are sorted in ascending order upon initialization.
137
138 \sa sortAscending(), sortDescending()
139 */
140 void
141 568 IndexRange::initialize(const IndexRange &other)
142 {
143 568 m_start = other.m_start;
144 568 m_stop = other.m_stop;
145 568 sortAscending();
146 568 }
147
148 /*!
149 \brief Allocates an returns a new IndexRange instance, initializing it using
150 this instance's member values and setting its parent to \a parent.
151
152 The values are sorted in ascending order in the clone.
153
154 \sa sortAscending(), sortDescending()
155 */
156 IndexRange *
157 1 IndexRange::clone(QObject *parent)
158 {
159
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 IndexRange *copy_p = new IndexRange(parent);
160 1 copy_p->initialize(*this);
161 1 copy_p->sortAscending();
162 1 return copy_p;
163 }
164
165 /*!
166 \ br*ief Allocates an returns a new IndexRange instance, initializing it using
167 \a other and setting its parent to \a parent.
168
169 The values are sorted in ascending order in the clone.
170
171 \sa sortAscending(), sortDescending()
172 */
173 IndexRange *
174 1 IndexRange::clone(const IndexRange &other, QObject *parent)
175 {
176
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 IndexRange *copy_p = new IndexRange(parent);
177 1 copy_p->initialize(other);
178 1 copy_p->sortAscending();
179 1 return copy_p;
180 }
181
182 /*!
183 \brief Returns true if this and \a other IndexRange instances are identical.
184
185 The parent is not checked.
186 */
187 bool
188 60 IndexRange::operator==(const IndexRange &other) const
189 {
190
4/6
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 52 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
60 return m_start == other.m_start && m_stop == other.m_stop;
191 };
192
193 /*!
194 \brief Returns true if this and \a other IndexRange instances are different.
195
196 The parent is not checked.
197
198 Return the negation of \l{operator==()}.
199 */
200 bool
201 23 IndexRange::operator!=(const IndexRange &other) const
202 {
203
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
23 return !operator==(other);
204 }
205
206 /*!
207 \brief Makes sure that \l m_start is <= to \l m_stop.
208 */
209 void
210 6863 IndexRange::sortAscending()
211 {
212
2/16
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6862 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
6863 if(m_stop < m_start)
213 1 std::swap(m_start, m_stop);
214 6863 }
215
216 /*!
217 \brief Makes sure that \l m_start is >= to \l m_stop.
218 */
219 void
220 2 IndexRange::sortDescending()
221 {
222
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(m_stop > m_start)
223 1 std::swap(m_start, m_stop);
224 2 }
225
226 /*!
227 \brief Returns true if this instance is valid.
228
229 The IndexRange intance is considered valid if \l m_start and \l m_stop contain
230 valid values, that is, not the default-assigned values.
231 */
232 bool
233 11 IndexRange::isValid() const
234 {
235
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 3 times.
11 return m_start < std::numeric_limits<qsizetype>::max() &&
236
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 5 times.
8 m_stop < std::numeric_limits<qsizetype>::max();
237 }
238
239 /*!
240 \brief Resets the member data to default values.
241 */
242 void
243 1 IndexRange::reset()
244 {
245 1 m_start = std::numeric_limits<qsizetype>::max();
246 1 m_stop = std::numeric_limits<qsizetype>::max();
247 1 }
248
249 /*!
250 \brief Returns a string representing this IndexRange instance in the form
251 "[start-stop]".
252
253 The start and stop values are indices (not positions).
254
255 \sa positionsAsText()
256 */
257 QString
258 2 IndexRange::indicesAsText() const
259 {
260
2/4
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
2 return QString("[%1-%2]").arg(m_start).arg(m_stop);
261 };
262
263 /*!
264 \brief Returns a string representing this IndexRange instance in the form
265 "[start-stop]".
266
267 \note The start and stop values are positions (not indices). This means that the
268 returned values correspond to \l m_start and \l m_stop both incremented by one
269 unit.
270
271 \sa indicesAsText()
272 */
273 QString
274 1 IndexRange::positionsAsText() const
275 {
276
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
1 return QString("[%1-%2]").arg(m_start + 1).arg(m_stop + 1);
277 };
278
279 void
280 IndexRange::registerJsConstructor(QJSEngine *engine)
281
282 {
283 if(!engine)
284 {
285 qWarning() << "Cannot register IndexRange class: engine is null";
286 return;
287 }
288
289 // Register the meta object as a constructor
290
291 QJSValue jsMetaObject = engine->newQMetaObject(&IndexRange::staticMetaObject);
292 engine->globalObject().setProperty("IndexRange", jsMetaObject);
293 }
294
295
296 } // namespace libXpertMassCore
297 } // namespace MsXpS
298