Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/include/basegfx/range/basicrange.hxx
Line
Count
Source (jump to first uncovered line)
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
131M
            mnMinimum(Traits::maxVal()),
41
131M
            mnMaximum(Traits::minVal())
42
131M
        {
43
131M
        }
basegfx::BasicRange<double, basegfx::DoubleTraits>::BasicRange()
Line
Count
Source
40
130M
            mnMinimum(Traits::maxVal()),
41
130M
            mnMaximum(Traits::minVal())
42
130M
        {
43
130M
        }
basegfx::BasicRange<int, basegfx::Int32Traits>::BasicRange()
Line
Count
Source
40
423k
            mnMinimum(Traits::maxVal()),
41
423k
            mnMaximum(Traits::minVal())
42
423k
        {
43
423k
        }
44
45
        explicit BasicRange( T nValue ) :
46
1.77G
            mnMinimum(nValue),
47
1.77G
            mnMaximum(nValue)
48
1.77G
        {
49
1.77G
        }
basegfx::BasicRange<double, basegfx::DoubleTraits>::BasicRange(double)
Line
Count
Source
46
1.77G
            mnMinimum(nValue),
47
1.77G
            mnMaximum(nValue)
48
1.77G
        {
49
1.77G
        }
basegfx::BasicRange<int, basegfx::Int32Traits>::BasicRange(int)
Line
Count
Source
46
2.32M
            mnMinimum(nValue),
47
2.32M
            mnMaximum(nValue)
48
2.32M
        {
49
2.32M
        }
50
51
        void reset()
52
68.2M
        {
53
68.2M
            mnMinimum = Traits::maxVal();
54
68.2M
            mnMaximum = Traits::minVal();
55
68.2M
        }
basegfx::BasicRange<double, basegfx::DoubleTraits>::reset()
Line
Count
Source
52
68.2M
        {
53
68.2M
            mnMinimum = Traits::maxVal();
54
68.2M
            mnMaximum = Traits::minVal();
55
68.2M
        }
Unexecuted instantiation: basegfx::BasicRange<int, basegfx::Int32Traits>::reset()
56
57
        bool isEmpty() const
58
10.3G
        {
59
10.3G
            return Traits::maxVal() == mnMinimum;
60
10.3G
        }
basegfx::BasicRange<double, basegfx::DoubleTraits>::isEmpty() const
Line
Count
Source
58
10.3G
        {
59
10.3G
            return Traits::maxVal() == mnMinimum;
60
10.3G
        }
basegfx::BasicRange<int, basegfx::Int32Traits>::isEmpty() const
Line
Count
Source
58
2.39M
        {
59
2.39M
            return Traits::maxVal() == mnMinimum;
60
2.39M
        }
61
62
1.46G
        T getMinimum() const { return mnMinimum; }
basegfx::BasicRange<double, basegfx::DoubleTraits>::getMinimum() const
Line
Count
Source
62
1.46G
        T getMinimum() const { return mnMinimum; }
basegfx::BasicRange<int, basegfx::Int32Traits>::getMinimum() const
Line
Count
Source
62
2.03M
        T getMinimum() const { return mnMinimum; }
63
1.46G
        T getMaximum() const { return mnMaximum; }
basegfx::BasicRange<double, basegfx::DoubleTraits>::getMaximum() const
Line
Count
Source
63
1.46G
        T getMaximum() const { return mnMaximum; }
basegfx::BasicRange<int, basegfx::Int32Traits>::getMaximum() const
Line
Count
Source
63
2.03M
        T getMaximum() const { return mnMaximum; }
64
65
        double getCenter() const
66
14.8k
        {
67
14.8k
            if(isEmpty())
68
0
            {
69
0
                return 0.0;
70
0
            }
71
14.8k
            else
72
14.8k
            {
73
14.8k
                return ((mnMaximum + mnMinimum) / 2.0);
74
14.8k
            }
75
14.8k
        }
76
77
        bool isInside(T nValue) const
78
3.23G
        {
79
3.23G
            if(isEmpty())
80
0
            {
81
0
                return false;
82
0
            }
83
3.23G
            else
84
3.23G
            {
85
3.23G
                return (nValue >= mnMinimum) && (nValue <= mnMaximum);
86
3.23G
            }
87
3.23G
        }
basegfx::BasicRange<double, basegfx::DoubleTraits>::isInside(double) const
Line
Count
Source
78
3.23G
        {
79
3.23G
            if(isEmpty())
80
0
            {
81
0
                return false;
82
0
            }
83
3.23G
            else
84
3.23G
            {
85
3.23G
                return (nValue >= mnMinimum) && (nValue <= mnMaximum);
86
3.23G
            }
87
3.23G
        }
basegfx::BasicRange<int, basegfx::Int32Traits>::isInside(int) const
Line
Count
Source
78
37.1k
        {
79
37.1k
            if(isEmpty())
80
0
            {
81
0
                return false;
82
0
            }
83
37.1k
            else
84
37.1k
            {
85
37.1k
                return (nValue >= mnMinimum) && (nValue <= mnMaximum);
86
37.1k
            }
87
37.1k
        }
88
89
        bool isInside(const BasicRange& rRange) const
90
13.2M
        {
91
13.2M
            if(isEmpty())
92
0
            {
93
0
                return false;
94
0
            }
95
13.2M
            else
96
13.2M
            {
97
13.2M
                if(rRange.isEmpty())
98
0
                {
99
0
                    return false;
100
0
                }
101
13.2M
                else
102
13.2M
                {
103
13.2M
                    return (rRange.mnMinimum >= mnMinimum) && (rRange.mnMaximum <= mnMaximum);
104
13.2M
                }
105
13.2M
            }
106
13.2M
        }
107
108
        bool overlaps(const BasicRange& rRange) const
109
242M
        {
110
242M
            if(isEmpty())
111
2.58M
            {
112
2.58M
                return false;
113
2.58M
            }
114
239M
            else
115
239M
            {
116
239M
                if(rRange.isEmpty())
117
96.6k
                {
118
96.6k
                    return false;
119
96.6k
                }
120
239M
                else
121
239M
                {
122
239M
                    return (rRange.mnMaximum >= mnMinimum) && (rRange.mnMinimum <= mnMaximum);
123
239M
                }
124
239M
            }
125
242M
        }
basegfx::BasicRange<double, basegfx::DoubleTraits>::overlaps(basegfx::BasicRange<double, basegfx::DoubleTraits> const&) const
Line
Count
Source
109
242M
        {
110
242M
            if(isEmpty())
111
2.58M
            {
112
2.58M
                return false;
113
2.58M
            }
114
239M
            else
115
239M
            {
116
239M
                if(rRange.isEmpty())
117
96.6k
                {
118
96.6k
                    return false;
119
96.6k
                }
120
239M
                else
121
239M
                {
122
239M
                    return (rRange.mnMaximum >= mnMinimum) && (rRange.mnMinimum <= mnMaximum);
123
239M
                }
124
239M
            }
125
242M
        }
Unexecuted instantiation: basegfx::BasicRange<int, basegfx::Int32Traits>::overlaps(basegfx::BasicRange<int, basegfx::Int32Traits> const&) const
126
127
        bool overlapsMore(const BasicRange& rRange) const
128
21.8M
        {
129
21.8M
            if(isEmpty() || rRange.isEmpty())
130
0
                return false;
131
            // returns true if the overlap is more than just a touching at the limits
132
21.8M
            return ((rRange.mnMaximum > mnMinimum) && (rRange.mnMinimum < mnMaximum));
133
21.8M
        }
134
135
        bool operator==( const BasicRange& rRange ) const
136
978
        {
137
978
            return (mnMinimum == rRange.mnMinimum && mnMaximum == rRange.mnMaximum);
138
978
        }
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
978
        {
137
978
            return (mnMinimum == rRange.mnMinimum && mnMaximum == rRange.mnMaximum);
138
978
        }
139
140
        bool operator!=( const BasicRange& rRange ) const
141
354k
        {
142
354k
            return (mnMinimum != rRange.mnMinimum || mnMaximum != rRange.mnMaximum);
143
354k
        }
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
354k
        {
142
354k
            return (mnMinimum != rRange.mnMinimum || mnMaximum != rRange.mnMaximum);
143
354k
        }
144
145
        bool equal(const BasicRange& rRange) const
146
51.7k
        {
147
51.7k
            return (
148
51.7k
                fTools::equal(mnMinimum, rRange.mnMinimum) &&
149
51.7k
                fTools::equal(mnMaximum, rRange.mnMaximum));
150
51.7k
        }
151
152
        void expand(T nValue)
153
2.15G
        {
154
2.15G
            if(isEmpty())
155
25.7M
            {
156
25.7M
                mnMinimum = mnMaximum = nValue;
157
25.7M
            }
158
2.13G
            else
159
2.13G
            {
160
// Silence over-eager warning emitted at least by GCC 4.9.2 in certain
161
// instantiations:
162
#if defined __GNUC__ && !defined __clang__
163
#pragma GCC diagnostic push
164
#pragma GCC diagnostic ignored "-Wstrict-overflow"
165
#endif
166
2.13G
                if(nValue < mnMinimum)
167
#if defined __GNUC__ && !defined __clang__
168
#pragma GCC diagnostic pop
169
#endif
170
165M
                {
171
165M
                    mnMinimum = nValue;
172
165M
                }
173
174
2.13G
                if(nValue > mnMaximum)
175
1.59G
                {
176
1.59G
                    mnMaximum = nValue;
177
1.59G
                }
178
2.13G
            }
179
2.15G
        }
basegfx::BasicRange<double, basegfx::DoubleTraits>::expand(double)
Line
Count
Source
153
2.15G
        {
154
2.15G
            if(isEmpty())
155
25.7M
            {
156
25.7M
                mnMinimum = mnMaximum = nValue;
157
25.7M
            }
158
2.12G
            else
159
2.12G
            {
160
// Silence over-eager warning emitted at least by GCC 4.9.2 in certain
161
// instantiations:
162
#if defined __GNUC__ && !defined __clang__
163
#pragma GCC diagnostic push
164
#pragma GCC diagnostic ignored "-Wstrict-overflow"
165
#endif
166
2.12G
                if(nValue < mnMinimum)
167
#if defined __GNUC__ && !defined __clang__
168
#pragma GCC diagnostic pop
169
#endif
170
165M
                {
171
165M
                    mnMinimum = nValue;
172
165M
                }
173
174
2.12G
                if(nValue > mnMaximum)
175
1.59G
                {
176
1.59G
                    mnMaximum = nValue;
177
1.59G
                }
178
2.12G
            }
179
2.15G
        }
basegfx::BasicRange<int, basegfx::Int32Traits>::expand(int)
Line
Count
Source
153
2.32M
        {
154
2.32M
            if(isEmpty())
155
0
            {
156
0
                mnMinimum = mnMaximum = nValue;
157
0
            }
158
2.32M
            else
159
2.32M
            {
160
// Silence over-eager warning emitted at least by GCC 4.9.2 in certain
161
// instantiations:
162
#if defined __GNUC__ && !defined __clang__
163
#pragma GCC diagnostic push
164
#pragma GCC diagnostic ignored "-Wstrict-overflow"
165
#endif
166
2.32M
                if(nValue < mnMinimum)
167
#if defined __GNUC__ && !defined __clang__
168
#pragma GCC diagnostic pop
169
#endif
170
499
                {
171
499
                    mnMinimum = nValue;
172
499
                }
173
174
2.32M
                if(nValue > mnMaximum)
175
2.28M
                {
176
2.28M
                    mnMaximum = nValue;
177
2.28M
                }
178
2.32M
            }
179
2.32M
        }
180
181
        void expand(const BasicRange& rRange)
182
1.45G
        {
183
1.45G
            if(isEmpty())
184
54.0M
            {
185
54.0M
                mnMinimum = rRange.mnMinimum;
186
54.0M
                mnMaximum = rRange.mnMaximum;
187
54.0M
            }
188
1.39G
            else
189
1.39G
            {
190
1.39G
                if(!rRange.isEmpty())
191
1.39G
                {
192
1.39G
                    if(rRange.mnMinimum < mnMinimum)
193
14.3M
                    {
194
14.3M
                        mnMinimum = rRange.mnMinimum;
195
14.3M
                    }
196
197
1.39G
                    if(rRange.mnMaximum > mnMaximum)
198
703M
                    {
199
703M
                        mnMaximum = rRange.mnMaximum;
200
703M
                    }
201
1.39G
                }
202
1.39G
            }
203
1.45G
        }
204
205
        void intersect(const BasicRange& rRange)
206
15.1M
        {
207
            // here, overlaps also tests all isEmpty() conditions already.
208
15.1M
            if( !overlaps( rRange ) )
209
13.9M
            {
210
13.9M
                reset();
211
13.9M
            }
212
1.19M
            else
213
1.19M
            {
214
1.19M
                if(rRange.mnMinimum > mnMinimum)
215
772k
                {
216
772k
                    mnMinimum = rRange.mnMinimum;
217
772k
                }
218
219
1.19M
                if(rRange.mnMaximum < mnMaximum)
220
920k
                {
221
920k
                    mnMaximum = rRange.mnMaximum;
222
920k
                }
223
1.19M
            }
224
15.1M
        }
basegfx::BasicRange<double, basegfx::DoubleTraits>::intersect(basegfx::BasicRange<double, basegfx::DoubleTraits> const&)
Line
Count
Source
206
15.1M
        {
207
            // here, overlaps also tests all isEmpty() conditions already.
208
15.1M
            if( !overlaps( rRange ) )
209
13.9M
            {
210
13.9M
                reset();
211
13.9M
            }
212
1.19M
            else
213
1.19M
            {
214
1.19M
                if(rRange.mnMinimum > mnMinimum)
215
772k
                {
216
772k
                    mnMinimum = rRange.mnMinimum;
217
772k
                }
218
219
1.19M
                if(rRange.mnMaximum < mnMaximum)
220
920k
                {
221
920k
                    mnMaximum = rRange.mnMaximum;
222
920k
                }
223
1.19M
            }
224
15.1M
        }
Unexecuted instantiation: basegfx::BasicRange<int, basegfx::Int32Traits>::intersect(basegfx::BasicRange<int, basegfx::Int32Traits> const&)
225
226
        void grow(T nValue)
227
1.45k
        {
228
1.45k
            if(isEmpty())
229
0
                return;
230
231
1.45k
            bool bLessThanZero(nValue < 0);
232
233
1.45k
            if(nValue > 0 || bLessThanZero)
234
1.45k
            {
235
1.45k
                mnMinimum -= nValue;
236
1.45k
                mnMaximum += nValue;
237
238
1.45k
                if(bLessThanZero)
239
0
                {
240
                    // test if range did collapse
241
0
                    if(mnMinimum > mnMaximum)
242
0
                    {
243
                        // if yes, collapse to center
244
0
                        mnMinimum = mnMaximum = (mnMinimum + mnMaximum) / 2;
245
0
                    }
246
0
                }
247
1.45k
            }
248
1.45k
        }
249
250
        T clamp(T nValue) const
251
0
        {
252
0
            if(isEmpty())
253
0
            {
254
0
                return nValue;
255
0
            }
256
0
            else
257
0
            {
258
0
                if(nValue < mnMinimum)
259
0
                {
260
0
                    return mnMinimum;
261
0
                }
262
0
263
0
                if(nValue > mnMaximum)
264
0
                {
265
0
                    return mnMaximum;
266
0
                }
267
0
268
0
                return nValue;
269
0
            }
270
0
        }
271
272
#if defined _MSC_VER && defined(_M_ARM64)
273
#pragma warning(push)
274
#pragma warning(disable: 4723) /* ignore: warning for (C4723) potential divide by 0 on windows arm64 build */
275
#endif
276
        typename Traits::DifferenceType getRange() const
277
17.1M
        {
278
17.1M
            if(isEmpty())
279
53.0k
            {
280
53.0k
                return Traits::neutral();
281
53.0k
            }
282
17.0M
            else
283
17.0M
            {
284
17.0M
                return (mnMaximum - mnMinimum);
285
17.0M
            }
286
17.1M
        }
basegfx::BasicRange<double, basegfx::DoubleTraits>::getRange() const
Line
Count
Source
277
17.1M
        {
278
17.1M
            if(isEmpty())
279
53.0k
            {
280
53.0k
                return Traits::neutral();
281
53.0k
            }
282
17.0M
            else
283
17.0M
            {
284
17.0M
                return (mnMaximum - mnMinimum);
285
17.0M
            }
286
17.1M
        }
Unexecuted instantiation: basegfx::BasicRange<int, basegfx::Int32Traits>::getRange() const
287
#if defined _MSC_VER && defined(_M_ARM64)
288
#pragma warning( pop )
289
#endif
290
    };
291
292
    // some pre-fabricated traits
293
    struct DoubleTraits
294
    {
295
198M
        static constexpr double minVal() { return DBL_MIN; };
296
10.5G
        static constexpr double maxVal() { return DBL_MAX; };
297
53.0k
        static constexpr double neutral() { return 0.0; };
298
299
        typedef double DifferenceType;
300
    };
301
302
    struct Int32Traits
303
    {
304
423k
        static constexpr sal_Int32 minVal() { return SAL_MIN_INT32; };
305
2.82M
        static constexpr sal_Int32 maxVal() { return SAL_MAX_INT32; };
306
0
        static constexpr sal_Int32 neutral() { return 0; };
307
308
        typedef sal_Int64 DifferenceType;
309
    };
310
311
} // end of namespace basegfx
312
313
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */