GCC Code Coverage Report


Directory: ./
File: include/2geom/interval.h
Date: 2024-03-18 17:01:34
Exec Total Coverage
Lines: 13 33 39.4%
Functions: 7 15 46.7%
Branches: 5 20 25.0%

Line Branch Exec Source
1 /**
2 * \file
3 * \brief Simple closed interval class
4 *//*
5 * Copyright 2007 Michael Sloan <mgsloan@gmail.com>
6 *
7 * Original Rect/Range code by:
8 * Lauris Kaplinski <lauris@kaplinski.com>
9 * Nathan Hurst <njh@mail.csse.monash.edu.au>
10 * bulia byak <buliabyak@users.sf.net>
11 * MenTaLguY <mental@rydia.net>
12 *
13 * This library is free software; you can redistribute it and/or
14 * modify it either under the terms of the GNU Lesser General Public
15 * License version 2.1 as published by the Free Software Foundation
16 * (the "LGPL") or, at your option, under the terms of the Mozilla
17 * Public License Version 1.1 (the "MPL"). If you do not alter this
18 * notice, a recipient may use your version of this file under either
19 * the MPL or the LGPL.
20 *
21 * You should have received a copy of the LGPL along with this library
22 * in the file COPYING-LGPL-2.1; if not, output to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 * You should have received a copy of the MPL along with this library
25 * in the file COPYING-MPL-1.1
26 *
27 * The contents of this file are subject to the Mozilla Public License
28 * Version 1.1 (the "License"); you may not use this file except in
29 * compliance with the License. You may obtain a copy of the License at
30 * http://www.mozilla.org/MPL/
31 *
32 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
33 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
34 * the specific language governing rights and limitations.
35 *
36 */
37 #ifndef LIB2GEOM_SEEN_INTERVAL_H
38 #define LIB2GEOM_SEEN_INTERVAL_H
39
40 #include <boost/none.hpp>
41 #include <boost/operators.hpp>
42 #include <2geom/coord.h>
43 #include <2geom/math-utils.h>
44 #include <2geom/generic-interval.h>
45 #include <2geom/int-interval.h>
46
47 namespace Geom {
48
49 /**
50 * @brief Range of real numbers that is never empty.
51 *
52 * Intervals are closed ranges \f$[a, b]\f$, which means they include their endpoints.
53 * To use them as open ranges, you can use the interiorContains() methods.
54 *
55 * @ingroup Primitives
56 */
57 class Interval
58 : public GenericInterval<Coord>
59 {
60 using Base = GenericInterval<Coord>;
61 public:
62 /// @name Create intervals.
63 /// @{
64 /** @brief Create an interval that contains only zero. */
65 constexpr Interval() = default;
66 /** @brief Create an interval that contains a single point. */
67 1797516 explicit constexpr Interval(Coord u) : Base(u) {}
68 /** @brief Create an interval that contains all points between @c u and @c v. */
69 288422 constexpr Interval(Coord u, Coord v) : Base(u, v) {}
70 /** @brief Convert from integer interval */
71 constexpr Interval(IntInterval const &i) : Base(i.min(), i.max()) {}
72 2124775 constexpr Interval(Base const &b) : Base(b) {}
73
74 /** @brief Create an interval containing a range of values.
75 * The resulting interval will contain all values from the given range.
76 * The return type of iterators must be convertible to Coord. The given range
77 * must not be empty. For potentially empty ranges, see OptInterval.
78 * @param start Beginning of the range
79 * @param end End of the range
80 * @return Interval that contains all values from [start, end). */
81 template <typename InputIterator>
82 static Interval from_range(InputIterator start, InputIterator end) {
83 return Base::from_range(start, end);
84 }
85 /** @brief Create an interval from a C-style array of values it should contain. */
86 1797516 static Interval from_array(Coord const *c, unsigned n) {
87 1797516 return Base::from_array(c, n);
88 }
89 /// @}
90
91 /// @name Inspect contained values.
92 /// @{
93 /// Check whether both endpoints are finite.
94 bool isFinite() const {
95 return std::isfinite(min()) && std::isfinite(max());
96 }
97 /** @brief Map the interval [0,1] onto this one.
98 * This method simply performs 1D linear interpolation between endpoints. */
99 1966 constexpr Coord valueAt(Coord t) const {
100 1966 return lerp(t, min(), max());
101 }
102 /** @brief Compute a time value that maps to the given value.
103 * The supplied value does not need to be in the interval for this method to work. */
104 constexpr Coord timeAt(Coord v) const {
105 return (v - min()) / extent();
106 }
107 /// Find closest time in [0,1] that maps to the given value. */
108 constexpr Coord nearestTime(Coord v) const {
109 if (v <= min()) return 0;
110 if (v >= max()) return 1;
111 return timeAt(v);
112 }
113 /// @}
114
115 /// @name Test coordinates and other intervals for inclusion.
116 /// @{
117 /** @brief Check whether the interior of the interval includes this number.
118 * Interior means all numbers in the interval except its ends. */
119 constexpr bool interiorContains(Coord val) const { return min() < val && val < max(); }
120 /** @brief Check whether the interior of the interval includes the given interval.
121 * Interior means all numbers in the interval except its ends. */
122 constexpr bool interiorContains(Interval const &val) const { return min() < val.min() && val.max() < max(); }
123 /// Check whether the number is contained in the union of the interior and the lower boundary.
124
4/4
✓ Branch 1 taken 455570 times.
✓ Branch 2 taken 110124 times.
✓ Branch 4 taken 333166 times.
✓ Branch 5 taken 122404 times.
565694 constexpr bool lowerContains(Coord val) const { return min() <= val && val < max(); }
125 /// Check whether the given interval is contained in the union of the interior and the lower boundary.
126 constexpr bool lowerContains(Interval const &val) const { return min() <= val.min() && val.max() < max(); }
127 /// Check whether the number is contained in the union of the interior and the upper boundary.
128 constexpr bool upperContains(Coord val) { return min() < val && val <= max(); }
129 /// Check whether the given interval is contained in the union of the interior and the upper boundary.
130 constexpr bool upperContains(Interval const &val) const { return min() < val.min() && val.max() <= max(); }
131 /** @brief Check whether the interiors of the intervals have any common elements.
132 * A single point in common is not considered an intersection. */
133 constexpr bool interiorIntersects(Interval const &val) const {
134 return std::max(min(), val.min()) < std::min(max(), val.max());
135 }
136 /// @}
137
138 /// @name Operators
139 /// @{
140 // IMPL: ScalableConcept
141 /** @brief Scale an interval */
142 41442 constexpr Interval &operator*=(Coord s) {
143 using std::swap;
144 41442 _b[0] *= s;
145 41442 _b[1] *= s;
146
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41442 times.
41442 if (s < 0) swap(_b[0], _b[1]);
147 41442 return *this;
148 }
149 /** @brief Scale an interval by the inverse of the specified value */
150 constexpr Interval &operator/=(Coord s) {
151 using std::swap;
152 _b[0] /= s;
153 _b[1] /= s;
154 if (s < 0) swap(_b[0], _b[1]);
155 return *this;
156 }
157 /** @brief Multiply two intervals.
158 * Product is defined as the set of points that can be obtained by multiplying
159 * any value from the second operand by any value from the first operand:
160 * \f$S = \{x \in A, y \in B: x * y\}\f$ */
161 constexpr Interval &operator*=(Interval const &o) {
162 // TODO implement properly
163 Coord mn = min(), mx = max();
164 expandTo(mn * o.min());
165 expandTo(mn * o.max());
166 expandTo(mx * o.min());
167 expandTo(mx * o.max());
168 return *this;
169 }
170 constexpr bool operator==(IntInterval const &ii) const {
171 return min() == Coord(ii.min()) && max() == Coord(ii.max());
172 }
173 constexpr bool operator==(Interval const &other) const {
174 return Base::operator==(other);
175 }
176 /// @}
177
178 /// @name Rounding to integer values
179 /// @{
180 /** @brief Return the smallest integer interval which contains this one. */
181 IntInterval roundOutwards() const {
182 return IntInterval(floor(min()), ceil(max()));
183 }
184 /** @brief Return the largest integer interval which is contained in this one. */
185 OptIntInterval roundInwards() const {
186 IntCoord u = ceil(min()), v = floor(max());
187 if (u > v) return {};
188 return IntInterval(u, v);
189 }
190 /// @}
191 };
192
193 /**
194 * @brief Range of real numbers that can be empty.
195 * @ingroup Primitives
196 */
197 class OptInterval
198 : public GenericOptInterval<Coord>
199 {
200 using Base = GenericOptInterval<Coord>;
201 public:
202 using Base::Base;
203 using Base::operator==;
204 using Base::operator!=;
205
206 constexpr OptInterval(Base const &b) : Base(b) {}
207
208 /** @brief Promote from IntInterval. */
209 constexpr OptInterval(IntInterval const &i) : Base(Interval(i)) {}
210 /** @brief Promote from OptIntInterval. */
211 constexpr OptInterval(OptIntInterval const &i) {
212 if (i) *this = Interval(*i);
213 }
214 };
215
216 // functions required for Python bindings
217 inline Interval unify(Interval const &a, Interval const &b) {
218 return a | b;
219 }
220 inline OptInterval intersect(Interval const &a, Interval const &b) {
221 return a & b;
222 }
223
224 } // namespace Geom
225
226 // Structured binding support
227 template <> struct std::tuple_size<Geom::Interval> : std::integral_constant<size_t, 2> {};
228 template <size_t I> struct std::tuple_element<I, Geom::Interval> { using type = Geom::Coord; };
229
230 // Hash support
231 template <> struct std::hash<Geom::Interval> : std::hash<Geom::GenericInterval<Geom::Coord>> {};
232
233 #endif // LIB2GEOM_SEEN_INTERVAL_H
234
235 /*
236 Local Variables:
237 mode:c++
238 c-file-style:"stroustrup"
239 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
240 indent-tabs-mode:nil
241 fill-column:99
242 End:
243 */
244 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
245