Coverage Report

Created: 2026-11-06 11:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/basegfx/range/basicrange.hxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#pragma once
21
22
#include <sal/types.h>
23
#include <float.h>
24
#include <basegfx/numeric/ftools.hxx>
25
26
27
namespace basegfx
28
{
29
    template< typename T, typename Traits > class BasicRange
30
    {
31
    protected:
32
        T mnMinimum;
33
        T mnMaximum;
34
35
    public:
36
        typedef T       ValueType;
37
        typedef Traits  TraitsType;
38
39
        BasicRange() :
40
17.9M
            mnMinimum(Traits::maxVal()),
41
17.9M
            mnMaximum(Traits::minVal())
42
17.9M
        {
43
17.9M
        }
basegfx::BasicRange<double, basegfx::DoubleTraits>::BasicRange()
Line
Count
Source
40
17.4M
            mnMinimum(Traits::maxVal()),
41
17.4M
            mnMaximum(Traits::minVal())
42
17.4M
        {
43
17.4M
        }
basegfx::BasicRange<int, basegfx::Int32Traits>::BasicRange()
Line
Count
Source
40
511k
            mnMinimum(Traits::maxVal()),
41
511k
            mnMaximum(Traits::minVal())
42
511k
        {
43
511k
        }
44
45
        explicit BasicRange( T nValue ) :
46
2.71G
            mnMinimum(nValue),
47
2.71G
            mnMaximum(nValue)
48
2.71G
        {
49
2.71G
        }
basegfx::BasicRange<double, basegfx::DoubleTraits>::BasicRange(double)
Line
Count
Source
46
2.71G
            mnMinimum(nValue),
47
2.71G
            mnMaximum(nValue)
48
2.71G
        {
49
2.71G
        }
basegfx::BasicRange<int, basegfx::Int32Traits>::BasicRange(int)
Line
Count
Source
46
380k
            mnMinimum(nValue),
47
380k
            mnMaximum(nValue)
48
380k
        {
49
380k
        }
50
51
        void reset()
52
6.85M
        {
53
6.85M
            mnMinimum = Traits::maxVal();
54
6.85M
            mnMaximum = Traits::minVal();
55
6.85M
        }
basegfx::BasicRange<double, basegfx::DoubleTraits>::reset()
Line
Count
Source
52
6.85M
        {
53
6.85M
            mnMinimum = Traits::maxVal();
54
6.85M
            mnMaximum = Traits::minVal();
55
6.85M
        }
Unexecuted instantiation: basegfx::BasicRange<int, basegfx::Int32Traits>::reset()
56
57
        bool isEmpty() const
58
7.03G
        {
59
7.03G
            return Traits::maxVal() == mnMinimum;
60
7.03G
        }
basegfx::BasicRange<double, basegfx::DoubleTraits>::isEmpty() const
Line
Count
Source
58
7.03G
        {
59
7.03G
            return Traits::maxVal() == mnMinimum;
60
7.03G
        }
basegfx::BasicRange<int, basegfx::Int32Traits>::isEmpty() const
Line
Count
Source
58
463k
        {
59
463k
            return Traits::maxVal() == mnMinimum;
60
463k
        }
61
62
118M
        T getMinimum() const { return mnMinimum; }
basegfx::BasicRange<double, basegfx::DoubleTraits>::getMinimum() const
Line
Count
Source
62
118M
        T getMinimum() const { return mnMinimum; }
basegfx::BasicRange<int, basegfx::Int32Traits>::getMinimum() const
Line
Count
Source
62
38.0k
        T getMinimum() const { return mnMinimum; }
63
118M
        T getMaximum() const { return mnMaximum; }
basegfx::BasicRange<double, basegfx::DoubleTraits>::getMaximum() const
Line
Count
Source
63
118M
        T getMaximum() const { return mnMaximum; }
basegfx::BasicRange<int, basegfx::Int32Traits>::getMaximum() const
Line
Count
Source
63
38.0k
        T getMaximum() const { return mnMaximum; }
64
65
        double getCenter() const
66
24.1k
        {
67
24.1k
            if(isEmpty())
68
0
            {
69
0
                return 0.0;
70
0
            }
71
24.1k
            else
72
24.1k
            {
73
24.1k
                return ((mnMaximum + mnMinimum) / 2.0);
74
24.1k
            }
75
24.1k
        }
76
77
        bool isInside(T nValue) const
78
662M
        {
79
662M
            if(isEmpty())
80
0
            {
81
0
                return false;
82
0
            }
83
662M
            else
84
662M
            {
85
662M
                return (nValue >= mnMinimum) && (nValue <= mnMaximum);
86
662M
            }
87
662M
        }
basegfx::BasicRange<double, basegfx::DoubleTraits>::isInside(double) const
Line
Count
Source
78
662M
        {
79
662M
            if(isEmpty())
80
0
            {
81
0
                return false;
82
0
            }
83
662M
            else
84
662M
            {
85
662M
                return (nValue >= mnMinimum) && (nValue <= mnMaximum);
86
662M
            }
87
662M
        }
basegfx::BasicRange<int, basegfx::Int32Traits>::isInside(int) const
Line
Count
Source
78
41.6k
        {
79
41.6k
            if(isEmpty())
80
0
            {
81
0
                return false;
82
0
            }
83
41.6k
            else
84
41.6k
            {
85
41.6k
                return (nValue >= mnMinimum) && (nValue <= mnMaximum);
86
41.6k
            }
87
41.6k
        }
88
89
        bool isInside(const BasicRange& rRange) const
90
22.7M
        {
91
22.7M
            if(isEmpty())
92
0
            {
93
0
                return false;
94
0
            }
95
22.7M
            else
96
22.7M
            {
97
22.7M
                if(rRange.isEmpty())
98
55
                {
99
55
                    return false;
100
55
                }
101
22.7M
                else
102
22.7M
                {
103
22.7M
                    return (rRange.mnMinimum >= mnMinimum) && (rRange.mnMaximum <= mnMaximum);
104
22.7M
                }
105
22.7M
            }
106
22.7M
        }
107
108
        bool overlaps(const BasicRange& rRange) const
109
1.37G
        {
110
1.37G
            if(isEmpty())
111
773k
            {
112
773k
                return false;
113
773k
            }
114
1.37G
            else
115
1.37G
            {
116
1.37G
                if(rRange.isEmpty())
117
6.32k
                {
118
6.32k
                    return false;
119
6.32k
                }
120
1.37G
                else
121
1.37G
                {
122
1.37G
                    return (rRange.mnMaximum >= mnMinimum) && (rRange.mnMinimum <= mnMaximum);
123
1.37G
                }
124
1.37G
            }
125
1.37G
        }
basegfx::BasicRange<double, basegfx::DoubleTraits>::overlaps(basegfx::BasicRange<double, basegfx::DoubleTraits> const&) const
Line
Count
Source
109
1.37G
        {
110
1.37G
            if(isEmpty())
111
773k
            {
112
773k
                return false;
113
773k
            }
114
1.37G
            else
115
1.37G
            {
116
1.37G
                if(rRange.isEmpty())
117
6.32k
                {
118
6.32k
                    return false;
119
6.32k
                }
120
1.37G
                else
121
1.37G
                {
122
1.37G
                    return (rRange.mnMaximum >= mnMinimum) && (rRange.mnMinimum <= mnMaximum);
123
1.37G
                }
124
1.37G
            }
125
1.37G
        }
Unexecuted instantiation: basegfx::BasicRange<int, basegfx::Int32Traits>::overlaps(basegfx::BasicRange<int, basegfx::Int32Traits> const&) const
126
127
        bool overlapsMore(const BasicRange& rRange) const
128
58.9M
        {
129
58.9M
            if(isEmpty() || rRange.isEmpty())
130
0
                return false;
131
            // returns true if the overlap is more than just a touching at the limits
132
58.9M
            return ((rRange.mnMaximum > mnMinimum) && (rRange.mnMinimum < mnMaximum));
133
58.9M
        }
134
135
        bool operator==( const BasicRange& rRange ) const
136
892
        {
137
892
            return (mnMinimum == rRange.mnMinimum && mnMaximum == rRange.mnMaximum);
138
892
        }
Unexecuted instantiation: basegfx::BasicRange<int, basegfx::Int32Traits>::operator==(basegfx::BasicRange<int, basegfx::Int32Traits> const&) const
basegfx::BasicRange<double, basegfx::DoubleTraits>::operator==(basegfx::BasicRange<double, basegfx::DoubleTraits> const&) const
Line
Count
Source
136
892
        {
137
892
            return (mnMinimum == rRange.mnMinimum && mnMaximum == rRange.mnMaximum);
138
892
        }
139
140
        bool operator!=( const BasicRange& rRange ) const
141
429k
        {
142
429k
            return (mnMinimum != rRange.mnMinimum || mnMaximum != rRange.mnMaximum);
143
429k
        }
Unexecuted instantiation: basegfx::BasicRange<int, basegfx::Int32Traits>::operator!=(basegfx::BasicRange<int, basegfx::Int32Traits> const&) const
basegfx::BasicRange<double, basegfx::DoubleTraits>::operator!=(basegfx::BasicRange<double, basegfx::DoubleTraits> const&) const
Line
Count
Source
141
429k
        {
142
429k
            return (mnMinimum != rRange.mnMinimum || mnMaximum != rRange.mnMaximum);
143
429k
        }
144
145
        bool equal(const BasicRange& rRange) const
146
5.36k
        {
147
5.36k
            return (
148
5.36k
                fTools::equal(mnMinimum, rRange.mnMinimum) &&
149
960
                fTools::equal(mnMaximum, rRange.mnMaximum));
150
5.36k
        }
151
152
        /// true when both limits differ by fSmallValue or less
153
        bool equal(const BasicRange& rRange, T fSmallValue) const
154
0
        {
155
0
            return (
156
0
                fTools::equal(mnMinimum, rRange.mnMinimum, fSmallValue) &&
157
0
                fTools::equal(mnMaximum, rRange.mnMaximum, fSmallValue));
158
0
        }
159
160
        void expand(T nValue)
161
3.10G
        {
162
3.10G
            if(isEmpty())
163
3.07M
            {
164
3.07M
                mnMinimum = mnMaximum = nValue;
165
3.07M
            }
166
3.10G
            else
167
3.10G
            {
168
// Silence over-eager warning emitted at least by GCC 4.9.2 in certain
169
// instantiations:
170
#if defined __GNUC__ && !defined __clang__
171
#pragma GCC diagnostic push
172
#pragma GCC diagnostic ignored "-Wstrict-overflow"
173
#endif
174
3.10G
                if(nValue < mnMinimum)
175
#if defined __GNUC__ && !defined __clang__
176
#pragma GCC diagnostic pop
177
#endif
178
979M
                {
179
979M
                    mnMinimum = nValue;
180
979M
                }
181
182
3.10G
                if(nValue > mnMaximum)
183
1.10G
                {
184
1.10G
                    mnMaximum = nValue;
185
1.10G
                }
186
3.10G
            }
187
3.10G
        }
basegfx::BasicRange<double, basegfx::DoubleTraits>::expand(double)
Line
Count
Source
161
3.10G
        {
162
3.10G
            if(isEmpty())
163
3.07M
            {
164
3.07M
                mnMinimum = mnMaximum = nValue;
165
3.07M
            }
166
3.10G
            else
167
3.10G
            {
168
// Silence over-eager warning emitted at least by GCC 4.9.2 in certain
169
// instantiations:
170
#if defined __GNUC__ && !defined __clang__
171
#pragma GCC diagnostic push
172
#pragma GCC diagnostic ignored "-Wstrict-overflow"
173
#endif
174
3.10G
                if(nValue < mnMinimum)
175
#if defined __GNUC__ && !defined __clang__
176
#pragma GCC diagnostic pop
177
#endif
178
979M
                {
179
979M
                    mnMinimum = nValue;
180
979M
                }
181
182
3.10G
                if(nValue > mnMaximum)
183
1.10G
                {
184
1.10G
                    mnMaximum = nValue;
185
1.10G
                }
186
3.10G
            }
187
3.10G
        }
basegfx::BasicRange<int, basegfx::Int32Traits>::expand(int)
Line
Count
Source
161
380k
        {
162
380k
            if(isEmpty())
163
0
            {
164
0
                mnMinimum = mnMaximum = nValue;
165
0
            }
166
380k
            else
167
380k
            {
168
// Silence over-eager warning emitted at least by GCC 4.9.2 in certain
169
// instantiations:
170
#if defined __GNUC__ && !defined __clang__
171
#pragma GCC diagnostic push
172
#pragma GCC diagnostic ignored "-Wstrict-overflow"
173
#endif
174
380k
                if(nValue < mnMinimum)
175
#if defined __GNUC__ && !defined __clang__
176
#pragma GCC diagnostic pop
177
#endif
178
350
                {
179
350
                    mnMinimum = nValue;
180
350
                }
181
182
380k
                if(nValue > mnMaximum)
183
380k
                {
184
380k
                    mnMaximum = nValue;
185
380k
                }
186
380k
            }
187
380k
        }
188
189
        void expand(const BasicRange& rRange)
190
119M
        {
191
119M
            if(isEmpty())
192
6.91M
            {
193
6.91M
                mnMinimum = rRange.mnMinimum;
194
6.91M
                mnMaximum = rRange.mnMaximum;
195
6.91M
            }
196
112M
            else
197
112M
            {
198
112M
                if(!rRange.isEmpty())
199
112M
                {
200
112M
                    if(rRange.mnMinimum < mnMinimum)
201
2.29M
                    {
202
2.29M
                        mnMinimum = rRange.mnMinimum;
203
2.29M
                    }
204
205
112M
                    if(rRange.mnMaximum > mnMaximum)
206
57.1M
                    {
207
57.1M
                        mnMaximum = rRange.mnMaximum;
208
57.1M
                    }
209
112M
                }
210
112M
            }
211
119M
        }
212
213
        void intersect(const BasicRange& rRange)
214
810k
        {
215
            // here, overlaps also tests all isEmpty() conditions already.
216
810k
            if( !overlaps( rRange ) )
217
758k
            {
218
758k
                reset();
219
758k
            }
220
52.1k
            else
221
52.1k
            {
222
52.1k
                if(rRange.mnMinimum > mnMinimum)
223
118
                {
224
118
                    mnMinimum = rRange.mnMinimum;
225
118
                }
226
227
52.1k
                if(rRange.mnMaximum < mnMaximum)
228
935
                {
229
935
                    mnMaximum = rRange.mnMaximum;
230
935
                }
231
52.1k
            }
232
810k
        }
basegfx::BasicRange<double, basegfx::DoubleTraits>::intersect(basegfx::BasicRange<double, basegfx::DoubleTraits> const&)
Line
Count
Source
214
810k
        {
215
            // here, overlaps also tests all isEmpty() conditions already.
216
810k
            if( !overlaps( rRange ) )
217
758k
            {
218
758k
                reset();
219
758k
            }
220
52.1k
            else
221
52.1k
            {
222
52.1k
                if(rRange.mnMinimum > mnMinimum)
223
118
                {
224
118
                    mnMinimum = rRange.mnMinimum;
225
118
                }
226
227
52.1k
                if(rRange.mnMaximum < mnMaximum)
228
935
                {
229
935
                    mnMaximum = rRange.mnMaximum;
230
935
                }
231
52.1k
            }
232
810k
        }
Unexecuted instantiation: basegfx::BasicRange<int, basegfx::Int32Traits>::intersect(basegfx::BasicRange<int, basegfx::Int32Traits> const&)
233
234
        void grow(T nValue)
235
705k
        {
236
705k
            if(isEmpty())
237
56
                return;
238
239
705k
            bool bLessThanZero(nValue < 0);
240
241
705k
            if(nValue > 0 || bLessThanZero)
242
705k
            {
243
705k
                mnMinimum -= nValue;
244
705k
                mnMaximum += nValue;
245
246
705k
                if(bLessThanZero)
247
90
                {
248
                    // test if range did collapse
249
90
                    if(mnMinimum > mnMaximum)
250
70
                    {
251
                        // if yes, collapse to center
252
70
                        mnMinimum = mnMaximum = (mnMinimum + mnMaximum) / 2;
253
70
                    }
254
90
                }
255
705k
            }
256
705k
        }
257
258
        T clamp(T nValue) const
259
0
        {
260
0
            if(isEmpty())
261
0
            {
262
0
                return nValue;
263
0
            }
264
0
            else
265
0
            {
266
0
                if(nValue < mnMinimum)
267
0
                {
268
0
                    return mnMinimum;
269
0
                }
270
0
271
0
                if(nValue > mnMaximum)
272
0
                {
273
0
                    return mnMaximum;
274
0
                }
275
0
276
0
                return nValue;
277
0
            }
278
0
        }
279
280
#if defined _MSC_VER && defined(_M_ARM64)
281
#pragma warning(push)
282
#pragma warning(disable: 4723) /* ignore: warning for (C4723) potential divide by 0 on windows arm64 build */
283
#endif
284
        typename Traits::DifferenceType getRange() const
285
620k
        {
286
620k
            if(isEmpty())
287
46.9k
            {
288
46.9k
                return Traits::neutral();
289
46.9k
            }
290
573k
            else
291
573k
            {
292
573k
                return (mnMaximum - mnMinimum);
293
573k
            }
294
620k
        }
basegfx::BasicRange<double, basegfx::DoubleTraits>::getRange() const
Line
Count
Source
285
620k
        {
286
620k
            if(isEmpty())
287
46.9k
            {
288
46.9k
                return Traits::neutral();
289
46.9k
            }
290
573k
            else
291
573k
            {
292
573k
                return (mnMaximum - mnMinimum);
293
573k
            }
294
620k
        }
Unexecuted instantiation: basegfx::BasicRange<int, basegfx::Int32Traits>::getRange() const
295
#if defined _MSC_VER && defined(_M_ARM64)
296
#pragma warning( pop )
297
#endif
298
    };
299
300
    // some pre-fabricated traits
301
    struct DoubleTraits
302
    {
303
24.2M
        static constexpr double minVal() { return DBL_MIN; };
304
7.05G
        static constexpr double maxVal() { return DBL_MAX; };
305
46.9k
        static constexpr double neutral() { return 0.0; };
306
307
        typedef double DifferenceType;
308
    };
309
310
    struct Int32Traits
311
    {
312
511k
        static constexpr sal_Int32 minVal() { return SAL_MIN_INT32; };
313
975k
        static constexpr sal_Int32 maxVal() { return SAL_MAX_INT32; };
314
0
        static constexpr sal_Int32 neutral() { return 0; };
315
316
        typedef sal_Int64 DifferenceType;
317
    };
318
319
} // end of namespace basegfx
320
321
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */