LibreOffice Module basegfx (master) 1
basicrange.hxx
Go to the documentation of this file.
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>
25
26
27namespace basegfx
28{
29 template< typename T, typename Traits > class BasicRange
30 {
31 protected:
34
35 public:
36 typedef T ValueType;
37 typedef Traits TraitsType;
38
40 mnMinimum(Traits::maxVal()),
41 mnMaximum(Traits::minVal())
42 {
43 }
44
45 explicit BasicRange( T nValue ) :
48 {
49 }
50
51 void reset()
52 {
53 mnMinimum = Traits::maxVal();
54 mnMaximum = Traits::minVal();
55 }
56
57 bool isEmpty() const
58 {
59 return Traits::maxVal() == mnMinimum;
60 }
61
62 T getMinimum() const { return mnMinimum; }
63 T getMaximum() const { return mnMaximum; }
64
65 double getCenter() const
66 {
67 if(isEmpty())
68 {
69 return 0.0;
70 }
71 else
72 {
73 return ((mnMaximum + mnMinimum) / 2.0);
74 }
75 }
76
77 bool isInside(T nValue) const
78 {
79 if(isEmpty())
80 {
81 return false;
82 }
83 else
84 {
85 return (nValue >= mnMinimum) && (nValue <= mnMaximum);
86 }
87 }
88
89 bool isInside(const BasicRange& rRange) const
90 {
91 if(isEmpty())
92 {
93 return false;
94 }
95 else
96 {
97 if(rRange.isEmpty())
98 {
99 return false;
100 }
101 else
102 {
103 return (rRange.mnMinimum >= mnMinimum) && (rRange.mnMaximum <= mnMaximum);
104 }
105 }
106 }
107
108 bool overlaps(const BasicRange& rRange) const
109 {
110 if(isEmpty())
111 {
112 return false;
113 }
114 else
115 {
116 if(rRange.isEmpty())
117 {
118 return false;
119 }
120 else
121 {
122 return (rRange.mnMaximum >= mnMinimum) && (rRange.mnMinimum <= mnMaximum);
123 }
124 }
125 }
126
127 bool overlapsMore(const BasicRange& rRange) const
128 {
129 if(isEmpty() || rRange.isEmpty())
130 return false;
131 // returns true if the overlap is more than just a touching at the limits
132 return ((rRange.mnMaximum > mnMinimum) && (rRange.mnMinimum < mnMaximum));
133 }
134
135 bool operator==( const BasicRange& rRange ) const
136 {
137 return (mnMinimum == rRange.mnMinimum && mnMaximum == rRange.mnMaximum);
138 }
139
140 bool operator!=( const BasicRange& rRange ) const
141 {
142 return (mnMinimum != rRange.mnMinimum || mnMaximum != rRange.mnMaximum);
143 }
144
145 bool equal(const BasicRange& rRange) const
146 {
147 return (
150 }
151
152 void expand(T nValue)
153 {
154 if(isEmpty())
155 {
157 }
158 else
159 {
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 if(nValue < mnMinimum)
167#if defined __GNUC__ && !defined __clang__
168#pragma GCC diagnostic pop
169#endif
170 {
172 }
173
174 if(nValue > mnMaximum)
175 {
177 }
178 }
179 }
180
181 void expand(const BasicRange& rRange)
182 {
183 if(isEmpty())
184 {
185 mnMinimum = rRange.mnMinimum;
186 mnMaximum = rRange.mnMaximum;
187 }
188 else
189 {
190 if(!rRange.isEmpty())
191 {
192 if(rRange.mnMinimum < mnMinimum)
193 {
194 mnMinimum = rRange.mnMinimum;
195 }
196
197 if(rRange.mnMaximum > mnMaximum)
198 {
199 mnMaximum = rRange.mnMaximum;
200 }
201 }
202 }
203 }
204
205 void intersect(const BasicRange& rRange)
206 {
207 // here, overlaps also tests all isEmpty() conditions already.
208 if( !overlaps( rRange ) )
209 {
210 reset();
211 }
212 else
213 {
214 if(rRange.mnMinimum > mnMinimum)
215 {
216 mnMinimum = rRange.mnMinimum;
217 }
218
219 if(rRange.mnMaximum < mnMaximum)
220 {
221 mnMaximum = rRange.mnMaximum;
222 }
223 }
224 }
225
226 void grow(T nValue)
227 {
228 if(isEmpty())
229 return;
230
231 bool bLessThanZero(nValue < 0);
232
233 if(nValue > 0 || bLessThanZero)
234 {
235 mnMinimum -= nValue;
236 mnMaximum += nValue;
237
238 if(bLessThanZero)
239 {
240 // test if range did collapse
241 if(mnMinimum > mnMaximum)
242 {
243 // if yes, collapse to center
245 }
246 }
247 }
248 }
249
250 T clamp(T nValue) const
251 {
252 if(isEmpty())
253 {
254 return nValue;
255 }
256 else
257 {
258 if(nValue < mnMinimum)
259 {
260 return mnMinimum;
261 }
262
263 if(nValue > mnMaximum)
264 {
265 return mnMaximum;
266 }
267
268 return nValue;
269 }
270 }
271
272#if defined _MSC_VER && defined(_M_ARM64)
273#pragma warning(push)
274#pragma warning(disable: 4723) /* ignore: warning for C4723 on windows arm64 build */
275#endif
276 typename Traits::DifferenceType getRange() const
277 {
278 if(isEmpty())
279 {
280 return Traits::neutral();
281 }
282 else
283 {
284 return (mnMaximum - mnMinimum);
285 }
286 }
287#if defined _MSC_VER && defined(_M_ARM64)
288#pragma warning( pop )
289#endif
290 };
291
292 // some pre-fabricated traits
294 {
295 static constexpr double minVal() { return DBL_MIN; };
296 static constexpr double maxVal() { return DBL_MAX; };
297 static constexpr double neutral() { return 0.0; };
298
299 typedef double DifferenceType;
300 };
301
303 {
304 static constexpr sal_Int32 minVal() { return SAL_MIN_INT32; };
305 static constexpr sal_Int32 maxVal() { return SAL_MAX_INT32; };
306 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: */
bool overlaps(const BasicRange &rRange) const
Definition: basicrange.hxx:108
T clamp(T nValue) const
Definition: basicrange.hxx:250
bool operator==(const BasicRange &rRange) const
Definition: basicrange.hxx:135
bool isEmpty() const
Definition: basicrange.hxx:57
bool overlapsMore(const BasicRange &rRange) const
Definition: basicrange.hxx:127
bool isInside(T nValue) const
Definition: basicrange.hxx:77
double getCenter() const
Definition: basicrange.hxx:65
bool operator!=(const BasicRange &rRange) const
Definition: basicrange.hxx:140
bool isInside(const BasicRange &rRange) const
Definition: basicrange.hxx:89
void expand(const BasicRange &rRange)
Definition: basicrange.hxx:181
void intersect(const BasicRange &rRange)
Definition: basicrange.hxx:205
bool equal(const BasicRange &rRange) const
Definition: basicrange.hxx:145
T getMaximum() const
Definition: basicrange.hxx:63
T getMinimum() const
Definition: basicrange.hxx:62
void grow(T nValue)
Definition: basicrange.hxx:226
void expand(T nValue)
Definition: basicrange.hxx:152
Traits::DifferenceType getRange() const
Definition: basicrange.hxx:276
BasicRange(T nValue)
Definition: basicrange.hxx:45
sal_Int16 nValue
bool equal(T const &rfValA, T const &rfValB)
Definition: ftools.hxx:169
static constexpr double maxVal()
Definition: basicrange.hxx:296
static constexpr double neutral()
Definition: basicrange.hxx:297
static constexpr double minVal()
Definition: basicrange.hxx:295
static constexpr sal_Int32 minVal()
Definition: basicrange.hxx:304
static constexpr sal_Int32 maxVal()
Definition: basicrange.hxx:305
static constexpr sal_Int32 neutral()
Definition: basicrange.hxx:306
sal_Int64 DifferenceType
Definition: basicrange.hxx:306
#define SAL_MAX_INT32
#define SAL_MIN_INT32