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