]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/numeric/interval/include/boost/numeric/interval/utility.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / numeric / interval / include / 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 typedef interval<T, Policies> I;
252 if (interval_lib::detail::test_input(x)) {
253 typedef typename Policies::checking checking;
254 return checking::nan();
255 }
256 BOOST_USING_STD_MAX();
257 return max BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast<T>(-x.lower()), x.upper());
258 }
259
260 template<class T, class Policies> inline
261 interval<T, Policies> abs(const interval<T, Policies>& x)
262 {
263 typedef interval<T, Policies> I;
264 if (interval_lib::detail::test_input(x))
265 return I::empty();
266 if (!interval_lib::user::is_neg(x.lower())) return x;
267 if (!interval_lib::user::is_pos(x.upper())) return -x;
268 BOOST_USING_STD_MAX();
269 return I(static_cast<T>(0), max BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast<T>(-x.lower()), x.upper()), true);
270 }
271
272 template<class T, class Policies> inline
273 interval<T, Policies> max BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x,
274 const interval<T, Policies>& y)
275 {
276 typedef interval<T, Policies> I;
277 if (interval_lib::detail::test_input(x, y))
278 return I::empty();
279 BOOST_USING_STD_MAX();
280 return I(max BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y.lower()), max BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y.upper()), true);
281 }
282
283 template<class T, class Policies> inline
284 interval<T, Policies> max BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x, const T& y)
285 {
286 typedef interval<T, Policies> I;
287 if (interval_lib::detail::test_input(x, y))
288 return I::empty();
289 BOOST_USING_STD_MAX();
290 return I(max BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y), max BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y), true);
291 }
292
293 template<class T, class Policies> inline
294 interval<T, Policies> max BOOST_PREVENT_MACRO_SUBSTITUTION (const T& x, const interval<T, Policies>& y)
295 {
296 typedef interval<T, Policies> I;
297 if (interval_lib::detail::test_input(x, y))
298 return I::empty();
299 BOOST_USING_STD_MAX();
300 return I(max BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.lower()), max BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.upper()), true);
301 }
302
303 template<class T, class Policies> inline
304 interval<T, Policies> min BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x,
305 const interval<T, Policies>& y)
306 {
307 typedef interval<T, Policies> I;
308 if (interval_lib::detail::test_input(x, y))
309 return I::empty();
310 BOOST_USING_STD_MIN();
311 return I(min BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y.lower()), min BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y.upper()), true);
312 }
313
314 template<class T, class Policies> inline
315 interval<T, Policies> min BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x, const T& y)
316 {
317 typedef interval<T, Policies> I;
318 if (interval_lib::detail::test_input(x, y))
319 return I::empty();
320 BOOST_USING_STD_MIN();
321 return I(min BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y), min BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y), true);
322 }
323
324 template<class T, class Policies> inline
325 interval<T, Policies> min BOOST_PREVENT_MACRO_SUBSTITUTION (const T& x, const interval<T, Policies>& y)
326 {
327 typedef interval<T, Policies> I;
328 if (interval_lib::detail::test_input(x, y))
329 return I::empty();
330 BOOST_USING_STD_MIN();
331 return I(min BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.lower()), min BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.upper()), true);
332 }
333
334 } // namespace numeric
335 } // namespace boost
336
337 #endif // BOOST_NUMERIC_INTERVAL_UTILITY_HPP