]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/numeric/interval/utility.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / numeric / interval / utility.hpp
1 /* Boost interval/utility.hpp template implementation file
2 *
3 * Copyright 2000 Jens Maurer
4 * Copyright 2002-2003 Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion
5 *
6 * Distributed under the Boost Software License, Version 1.0.
7 * (See accompanying file LICENSE_1_0.txt or
8 * copy at http://www.boost.org/LICENSE_1_0.txt)
9 */
10
11 #ifndef BOOST_NUMERIC_INTERVAL_UTILITY_HPP
12 #define BOOST_NUMERIC_INTERVAL_UTILITY_HPP
13
14 #include <boost/config.hpp>
15 #include <boost/numeric/interval/detail/interval_prototype.hpp>
16 #include <boost/numeric/interval/detail/test_input.hpp>
17 #include <boost/numeric/interval/detail/bugs.hpp>
18 #include <algorithm>
19 #include <utility>
20
21 /*
22 * Implementation of simple functions
23 */
24
25 namespace boost {
26 namespace numeric {
27
28 /*
29 * Utility Functions
30 */
31
32 template<class T, class Policies> inline
33 const T& lower(const interval<T, Policies>& x)
34 {
35 return x.lower();
36 }
37
38 template<class T, class Policies> inline
39 const T& upper(const interval<T, Policies>& x)
40 {
41 return x.upper();
42 }
43
44 template<class T, class Policies> inline
45 T checked_lower(const interval<T, Policies>& x)
46 {
47 if (empty(x)) {
48 typedef typename Policies::checking checking;
49 return checking::nan();
50 }
51 return x.lower();
52 }
53
54 template<class T, class Policies> inline
55 T checked_upper(const interval<T, Policies>& x)
56 {
57 if (empty(x)) {
58 typedef typename Policies::checking checking;
59 return checking::nan();
60 }
61 return x.upper();
62 }
63
64 template<class T, class Policies> inline
65 T width(const interval<T, Policies>& x)
66 {
67 if (interval_lib::detail::test_input(x)) return static_cast<T>(0);
68 typename Policies::rounding rnd;
69 return rnd.sub_up(x.upper(), x.lower());
70 }
71
72 template<class T, class Policies> inline
73 T median(const interval<T, Policies>& x)
74 {
75 if (interval_lib::detail::test_input(x)) {
76 typedef typename Policies::checking checking;
77 return checking::nan();
78 }
79 typename Policies::rounding rnd;
80 return rnd.median(x.lower(), x.upper());
81 }
82
83 template<class T, class Policies> inline
84 interval<T, Policies> widen(const interval<T, Policies>& x, const T& v)
85 {
86 if (interval_lib::detail::test_input(x))
87 return interval<T, Policies>::empty();
88 typename Policies::rounding rnd;
89 return interval<T, Policies>(rnd.sub_down(x.lower(), v),
90 rnd.add_up (x.upper(), v), true);
91 }
92
93 /*
94 * Set-like operations
95 */
96
97 template<class T, class Policies> inline
98 bool empty(const interval<T, Policies>& x)
99 {
100 return interval_lib::detail::test_input(x);
101 }
102
103 template<class T, class Policies> inline
104 bool zero_in(const interval<T, Policies>& x)
105 {
106 if (interval_lib::detail::test_input(x)) return false;
107 return (!interval_lib::user::is_pos(x.lower())) &&
108 (!interval_lib::user::is_neg(x.upper()));
109 }
110
111 template<class T, class Policies> inline
112 bool in_zero(const interval<T, Policies>& x) // DEPRECATED
113 {
114 return zero_in<T, Policies>(x);
115 }
116
117 template<class T, class Policies> inline
118 bool in(const T& x, const interval<T, Policies>& y)
119 {
120 if (interval_lib::detail::test_input(x, y)) return false;
121 return y.lower() <= x && x <= y.upper();
122 }
123
124 template<class T, class Policies> inline
125 bool subset(const interval<T, Policies>& x,
126 const interval<T, Policies>& y)
127 {
128 if (empty(x)) return true;
129 return !empty(y) && y.lower() <= x.lower() && x.upper() <= y.upper();
130 }
131
132 template<class T, class Policies1, class Policies2> inline
133 bool proper_subset(const interval<T, Policies1>& x,
134 const interval<T, Policies2>& y)
135 {
136 if (empty(y)) return false;
137 if (empty(x)) return true;
138 return y.lower() <= x.lower() && x.upper() <= y.upper() &&
139 (y.lower() != x.lower() || x.upper() != y.upper());
140 }
141
142 template<class T, class Policies1, class Policies2> inline
143 bool overlap(const interval<T, Policies1>& x,
144 const interval<T, Policies2>& y)
145 {
146 if (interval_lib::detail::test_input(x, y)) return false;
147 return (x.lower() <= y.lower() && y.lower() <= x.upper()) ||
148 (y.lower() <= x.lower() && x.lower() <= y.upper());
149 }
150
151 template<class T, class Policies> inline
152 bool singleton(const interval<T, Policies>& x)
153 {
154 return !empty(x) && x.lower() == x.upper();
155 }
156
157 template<class T, class Policies1, class Policies2> inline
158 bool equal(const interval<T, Policies1>& x, const interval<T, Policies2>& y)
159 {
160 if (empty(x)) return empty(y);
161 return !empty(y) && x.lower() == y.lower() && x.upper() == y.upper();
162 }
163
164 template<class T, class Policies> inline
165 interval<T, Policies> intersect(const interval<T, Policies>& x,
166 const interval<T, Policies>& y)
167 {
168 BOOST_USING_STD_MIN();
169 BOOST_USING_STD_MAX();
170 if (interval_lib::detail::test_input(x, y))
171 return interval<T, Policies>::empty();
172 const T& l = max BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y.lower());
173 const T& u = min BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y.upper());
174 if (l <= u) return interval<T, Policies>(l, u, true);
175 else return interval<T, Policies>::empty();
176 }
177
178 template<class T, class Policies> inline
179 interval<T, Policies> hull(const interval<T, Policies>& x,
180 const interval<T, Policies>& y)
181 {
182 BOOST_USING_STD_MIN();
183 BOOST_USING_STD_MAX();
184 bool bad_x = interval_lib::detail::test_input(x);
185 bool bad_y = interval_lib::detail::test_input(y);
186 if (bad_x)
187 if (bad_y) return interval<T, Policies>::empty();
188 else return y;
189 else
190 if (bad_y) return x;
191 return interval<T, Policies>(min BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y.lower()),
192 max BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y.upper()), true);
193 }
194
195 template<class T, class Policies> inline
196 interval<T, Policies> hull(const interval<T, Policies>& x, const T& y)
197 {
198 BOOST_USING_STD_MIN();
199 BOOST_USING_STD_MAX();
200 bool bad_x = interval_lib::detail::test_input(x);
201 bool bad_y = interval_lib::detail::test_input<T, Policies>(y);
202 if (bad_y)
203 if (bad_x) return interval<T, Policies>::empty();
204 else return x;
205 else
206 if (bad_x) return interval<T, Policies>(y, y, true);
207 return interval<T, Policies>(min BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y),
208 max BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y), true);
209 }
210
211 template<class T, class Policies> inline
212 interval<T, Policies> hull(const T& x, const interval<T, Policies>& y)
213 {
214 BOOST_USING_STD_MIN();
215 BOOST_USING_STD_MAX();
216 bool bad_x = interval_lib::detail::test_input<T, Policies>(x);
217 bool bad_y = interval_lib::detail::test_input(y);
218 if (bad_x)
219 if (bad_y) return interval<T, Policies>::empty();
220 else return y;
221 else
222 if (bad_y) return interval<T, Policies>(x, x, true);
223 return interval<T, Policies>(min BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.lower()),
224 max BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.upper()), true);
225 }
226
227 template<class T> inline
228 interval<T> hull(const T& x, const T& y)
229 {
230 return interval<T>::hull(x, y);
231 }
232
233 template<class T, class Policies> inline
234 std::pair<interval<T, Policies>, interval<T, Policies> >
235 bisect(const interval<T, Policies>& x)
236 {
237 typedef interval<T, Policies> I;
238 if (interval_lib::detail::test_input(x))
239 return std::pair<I,I>(I::empty(), I::empty());
240 const T m = median(x);
241 return std::pair<I,I>(I(x.lower(), m, true), I(m, x.upper(), true));
242 }
243
244 /*
245 * Elementary functions
246 */
247
248 template<class T, class Policies> inline
249 T norm(const interval<T, Policies>& x)
250 {
251 if (interval_lib::detail::test_input(x)) {
252 typedef typename Policies::checking checking;
253 return checking::nan();
254 }
255 BOOST_USING_STD_MAX();
256 return max BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast<T>(-x.lower()), x.upper());
257 }
258
259 template<class T, class Policies> inline
260 interval<T, Policies> abs(const interval<T, Policies>& x)
261 {
262 typedef interval<T, Policies> I;
263 if (interval_lib::detail::test_input(x))
264 return I::empty();
265 if (!interval_lib::user::is_neg(x.lower())) return x;
266 if (!interval_lib::user::is_pos(x.upper())) return -x;
267 BOOST_USING_STD_MAX();
268 return I(static_cast<T>(0), max BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast<T>(-x.lower()), x.upper()), true);
269 }
270
271 template<class T, class Policies> inline
272 interval<T, Policies> max BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x,
273 const interval<T, Policies>& y)
274 {
275 typedef interval<T, Policies> I;
276 if (interval_lib::detail::test_input(x, y))
277 return I::empty();
278 BOOST_USING_STD_MAX();
279 return I(max BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y.lower()), max BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y.upper()), true);
280 }
281
282 template<class T, class Policies> inline
283 interval<T, Policies> max BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x, const T& y)
284 {
285 typedef interval<T, Policies> I;
286 if (interval_lib::detail::test_input(x, y))
287 return I::empty();
288 BOOST_USING_STD_MAX();
289 return I(max BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y), max BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y), true);
290 }
291
292 template<class T, class Policies> inline
293 interval<T, Policies> max BOOST_PREVENT_MACRO_SUBSTITUTION (const T& x, const interval<T, Policies>& y)
294 {
295 typedef interval<T, Policies> I;
296 if (interval_lib::detail::test_input(x, y))
297 return I::empty();
298 BOOST_USING_STD_MAX();
299 return I(max BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.lower()), max BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.upper()), true);
300 }
301
302 template<class T, class Policies> inline
303 interval<T, Policies> min BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x,
304 const interval<T, Policies>& y)
305 {
306 typedef interval<T, Policies> I;
307 if (interval_lib::detail::test_input(x, y))
308 return I::empty();
309 BOOST_USING_STD_MIN();
310 return I(min BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y.lower()), min BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y.upper()), true);
311 }
312
313 template<class T, class Policies> inline
314 interval<T, Policies> min BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x, const T& y)
315 {
316 typedef interval<T, Policies> I;
317 if (interval_lib::detail::test_input(x, y))
318 return I::empty();
319 BOOST_USING_STD_MIN();
320 return I(min BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y), min BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y), true);
321 }
322
323 template<class T, class Policies> inline
324 interval<T, Policies> min BOOST_PREVENT_MACRO_SUBSTITUTION (const T& x, const interval<T, Policies>& y)
325 {
326 typedef interval<T, Policies> I;
327 if (interval_lib::detail::test_input(x, y))
328 return I::empty();
329 BOOST_USING_STD_MIN();
330 return I(min BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.lower()), min BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.upper()), true);
331 }
332
333 } // namespace numeric
334 } // namespace boost
335
336 #endif // BOOST_NUMERIC_INTERVAL_UTILITY_HPP