1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/numeric/interval/interval.hpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,450 @@
1.4 +/* Boost interval/interval.hpp header file
1.5 + *
1.6 + * Copyright 2002-2003 Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion
1.7 + *
1.8 + * Distributed under the Boost Software License, Version 1.0.
1.9 + * (See accompanying file LICENSE_1_0.txt or
1.10 + * copy at http://www.boost.org/LICENSE_1_0.txt)
1.11 + */
1.12 +
1.13 +#ifndef BOOST_NUMERIC_INTERVAL_INTERVAL_HPP
1.14 +#define BOOST_NUMERIC_INTERVAL_INTERVAL_HPP
1.15 +
1.16 +#include <stdexcept>
1.17 +#include <string>
1.18 +#include <boost/numeric/interval/detail/interval_prototype.hpp>
1.19 +
1.20 +namespace boost {
1.21 +namespace numeric {
1.22 +
1.23 +namespace interval_lib {
1.24 +
1.25 +class comparison_error
1.26 + : public std::runtime_error
1.27 +{
1.28 +public:
1.29 + comparison_error()
1.30 + : std::runtime_error("boost::interval: uncertain comparison")
1.31 + { }
1.32 +};
1.33 +
1.34 +} // namespace interval_lib
1.35 +
1.36 +/*
1.37 + * interval class
1.38 + */
1.39 +
1.40 +template<class T, class Policies>
1.41 +class interval
1.42 +{
1.43 +private:
1.44 + struct interval_holder;
1.45 + struct number_holder;
1.46 +public:
1.47 + typedef T base_type;
1.48 + typedef Policies traits_type;
1.49 +
1.50 + T const &lower() const;
1.51 + T const &upper() const;
1.52 +
1.53 + interval();
1.54 + interval(T const &v);
1.55 + template<class T1> interval(T1 const &v);
1.56 + interval(T const &l, T const &u);
1.57 + template<class T1, class T2> interval(T1 const &l, T2 const &u);
1.58 + interval(interval<T, Policies> const &r);
1.59 + template<class Policies1> interval(interval<T, Policies1> const &r);
1.60 + template<class T1, class Policies1> interval(interval<T1, Policies1> const &r);
1.61 +
1.62 + interval &operator=(T const &v);
1.63 + template<class T1> interval &operator=(T1 const &v);
1.64 + interval &operator=(interval<T, Policies> const &r);
1.65 + template<class Policies1> interval &operator=(interval<T, Policies1> const &r);
1.66 + template<class T1, class Policies1> interval &operator=(interval<T1, Policies1> const &r);
1.67 +
1.68 + void assign(const T& l, const T& u);
1.69 +
1.70 + static interval empty();
1.71 + static interval whole();
1.72 + static interval hull(const T& x, const T& y);
1.73 +
1.74 + interval& operator+= (const T& r);
1.75 + interval& operator+= (const interval& r);
1.76 + interval& operator-= (const T& r);
1.77 + interval& operator-= (const interval& r);
1.78 + interval& operator*= (const T& r);
1.79 + interval& operator*= (const interval& r);
1.80 + interval& operator/= (const T& r);
1.81 + interval& operator/= (const interval& r);
1.82 +
1.83 + bool operator< (const interval_holder& r) const;
1.84 + bool operator> (const interval_holder& r) const;
1.85 + bool operator<= (const interval_holder& r) const;
1.86 + bool operator>= (const interval_holder& r) const;
1.87 + bool operator== (const interval_holder& r) const;
1.88 + bool operator!= (const interval_holder& r) const;
1.89 +
1.90 + bool operator< (const number_holder& r) const;
1.91 + bool operator> (const number_holder& r) const;
1.92 + bool operator<= (const number_holder& r) const;
1.93 + bool operator>= (const number_holder& r) const;
1.94 + bool operator== (const number_holder& r) const;
1.95 + bool operator!= (const number_holder& r) const;
1.96 +
1.97 + // the following is for internal use only, it is not a published interface
1.98 + // nevertheless, it's public because friends don't always work correctly.
1.99 + interval(const T& l, const T& u, bool): low(l), up(u) {}
1.100 + void set_empty();
1.101 + void set_whole();
1.102 + void set(const T& l, const T& u);
1.103 +
1.104 +private:
1.105 + struct interval_holder {
1.106 + template<class Policies2>
1.107 + interval_holder(const interval<T, Policies2>& r)
1.108 + : low(r.lower()), up(r.upper())
1.109 + {
1.110 + typedef typename Policies2::checking checking2;
1.111 + if (checking2::is_empty(low, up))
1.112 + throw interval_lib::comparison_error();
1.113 + }
1.114 +
1.115 + const T& low;
1.116 + const T& up;
1.117 + };
1.118 +
1.119 + struct number_holder {
1.120 + number_holder(const T& r) : val(r)
1.121 + {
1.122 + typedef typename Policies::checking checking;
1.123 + if (checking::is_nan(r))
1.124 + throw interval_lib::comparison_error();
1.125 + }
1.126 +
1.127 + const T& val;
1.128 + };
1.129 +
1.130 + typedef typename Policies::checking checking;
1.131 + typedef typename Policies::rounding rounding;
1.132 +
1.133 + T low;
1.134 + T up;
1.135 +};
1.136 +
1.137 +template<class T, class Policies> inline
1.138 +interval<T, Policies>::interval():
1.139 + low(static_cast<T>(0)), up(static_cast<T>(0))
1.140 +{}
1.141 +
1.142 +template<class T, class Policies> inline
1.143 +interval<T, Policies>::interval(T const &v): low(v), up(v)
1.144 +{
1.145 + if (checking::is_nan(v)) set_empty();
1.146 +}
1.147 +
1.148 +template<class T, class Policies> template<class T1> inline
1.149 +interval<T, Policies>::interval(T1 const &v)
1.150 +{
1.151 + if (checking::is_nan(v)) set_empty();
1.152 + else {
1.153 + rounding rnd;
1.154 + low = rnd.conv_down(v);
1.155 + up = rnd.conv_up (v);
1.156 + }
1.157 +}
1.158 +
1.159 +template<class T, class Policies> template<class T1, class T2> inline
1.160 +interval<T, Policies>::interval(T1 const &l, T2 const &u)
1.161 +{
1.162 + if (checking::is_nan(l) || checking::is_nan(u) || !(l <= u)) set_empty();
1.163 + else {
1.164 + rounding rnd;
1.165 + low = rnd.conv_down(l);
1.166 + up = rnd.conv_up (u);
1.167 + }
1.168 +}
1.169 +
1.170 +template<class T, class Policies> inline
1.171 +interval<T, Policies>::interval(T const &l, T const &u): low(l), up(u)
1.172 +{
1.173 + if (checking::is_nan(l) || checking::is_nan(u) || !(l <= u))
1.174 + set_empty();
1.175 +}
1.176 +
1.177 +
1.178 +template<class T, class Policies> inline
1.179 +interval<T, Policies>::interval(interval<T, Policies> const &r): low(r.lower()), up(r.upper())
1.180 +{}
1.181 +
1.182 +template<class T, class Policies> template<class Policies1> inline
1.183 +interval<T, Policies>::interval(interval<T, Policies1> const &r): low(r.lower()), up(r.upper())
1.184 +{
1.185 + typedef typename Policies1::checking checking1;
1.186 + if (checking1::is_empty(r.lower(), r.upper())) set_empty();
1.187 +}
1.188 +
1.189 +template<class T, class Policies> template<class T1, class Policies1> inline
1.190 +interval<T, Policies>::interval(interval<T1, Policies1> const &r)
1.191 +{
1.192 + typedef typename Policies1::checking checking1;
1.193 + if (checking1::is_empty(r.lower(), r.upper())) set_empty();
1.194 + else {
1.195 + rounding rnd;
1.196 + low = rnd.conv_down(r.lower());
1.197 + up = rnd.conv_up (r.upper());
1.198 + }
1.199 +}
1.200 +
1.201 +template<class T, class Policies> inline
1.202 +interval<T, Policies> &interval<T, Policies>::operator=(T const &v)
1.203 +{
1.204 + if (checking::is_nan(v)) set_empty();
1.205 + else low = up = v;
1.206 + return *this;
1.207 +}
1.208 +
1.209 +template<class T, class Policies> template<class T1> inline
1.210 +interval<T, Policies> &interval<T, Policies>::operator=(T1 const &v)
1.211 +{
1.212 + if (checking::is_nan(v)) set_empty();
1.213 + else {
1.214 + rounding rnd;
1.215 + low = rnd.conv_down(v);
1.216 + up = rnd.conv_up (v);
1.217 + }
1.218 + return *this;
1.219 +}
1.220 +
1.221 +template<class T, class Policies> inline
1.222 +interval<T, Policies> &interval<T, Policies>::operator=(interval<T, Policies> const &r)
1.223 +{
1.224 + low = r.lower();
1.225 + up = r.upper();
1.226 + return *this;
1.227 +}
1.228 +
1.229 +template<class T, class Policies> template<class Policies1> inline
1.230 +interval<T, Policies> &interval<T, Policies>::operator=(interval<T, Policies1> const &r)
1.231 +{
1.232 + typedef typename Policies1::checking checking1;
1.233 + if (checking1::is_empty(r.lower(), r.upper())) set_empty();
1.234 + else {
1.235 + low = r.lower();
1.236 + up = r.upper();
1.237 + }
1.238 + return *this;
1.239 +}
1.240 +
1.241 +template<class T, class Policies> template<class T1, class Policies1> inline
1.242 +interval<T, Policies> &interval<T, Policies>::operator=(interval<T1, Policies1> const &r)
1.243 +{
1.244 + typedef typename Policies1::checking checking1;
1.245 + if (checking1::is_empty(r.lower(), r.upper())) set_empty();
1.246 + else {
1.247 + rounding rnd;
1.248 + low = rnd.conv_down(r.lower());
1.249 + up = rnd.conv_up (r.upper());
1.250 + }
1.251 + return *this;
1.252 +}
1.253 +
1.254 +template<class T, class Policies> inline
1.255 +void interval<T, Policies>::assign(const T& l, const T& u)
1.256 +{
1.257 + if (checking::is_nan(l) || checking::is_nan(u) || !(l <= u))
1.258 + set_empty();
1.259 + else set(l, u);
1.260 +}
1.261 +
1.262 +template<class T, class Policies> inline
1.263 +void interval<T, Policies>::set(const T& l, const T& u)
1.264 +{
1.265 + low = l;
1.266 + up = u;
1.267 +}
1.268 +
1.269 +template<class T, class Policies> inline
1.270 +void interval<T, Policies>::set_empty()
1.271 +{
1.272 + low = checking::empty_lower();
1.273 + up = checking::empty_upper();
1.274 +}
1.275 +
1.276 +template<class T, class Policies> inline
1.277 +void interval<T, Policies>::set_whole()
1.278 +{
1.279 + low = checking::neg_inf();
1.280 + up = checking::pos_inf();
1.281 +}
1.282 +
1.283 +template<class T, class Policies> inline
1.284 +interval<T, Policies> interval<T, Policies>::hull(const T& x, const T& y)
1.285 +{
1.286 + bool bad_x = checking::is_nan(x);
1.287 + bool bad_y = checking::is_nan(y);
1.288 + if (bad_x)
1.289 + if (bad_y) return interval::empty();
1.290 + else return interval(y, y, true);
1.291 + else
1.292 + if (bad_y) return interval(x, x, true);
1.293 + if (x <= y) return interval(x, y, true);
1.294 + else return interval(y, x, true);
1.295 +}
1.296 +
1.297 +template<class T, class Policies> inline
1.298 +interval<T, Policies> interval<T, Policies>::empty()
1.299 +{
1.300 + return interval<T, Policies>(checking::empty_lower(),
1.301 + checking::empty_upper(), true);
1.302 +}
1.303 +
1.304 +template<class T, class Policies> inline
1.305 +interval<T, Policies> interval<T, Policies>::whole()
1.306 +{
1.307 + return interval<T, Policies>(checking::neg_inf(), checking::pos_inf(), true);
1.308 +}
1.309 +
1.310 +template<class T, class Policies> inline
1.311 +const T& interval<T, Policies>::lower() const
1.312 +{
1.313 + return low;
1.314 +}
1.315 +
1.316 +template<class T, class Policies> inline
1.317 +const T& interval<T, Policies>::upper() const
1.318 +{
1.319 + return up;
1.320 +}
1.321 +
1.322 +/*
1.323 + * interval/interval comparisons
1.324 + */
1.325 +
1.326 +template<class T, class Policies> inline
1.327 +bool interval<T, Policies>::operator< (const interval_holder& r) const
1.328 +{
1.329 + if (!checking::is_empty(low, up)) {
1.330 + if (up < r.low) return true;
1.331 + else if (low >= r.up) return false;
1.332 + }
1.333 + throw interval_lib::comparison_error();
1.334 +}
1.335 +
1.336 +template<class T, class Policies> inline
1.337 +bool interval<T, Policies>::operator> (const interval_holder& r) const
1.338 +{
1.339 + if (!checking::is_empty(low, up)) {
1.340 + if (low > r.up) return true;
1.341 + else if (up <= r.low) return false;
1.342 + }
1.343 + throw interval_lib::comparison_error();
1.344 +}
1.345 +
1.346 +template<class T, class Policies> inline
1.347 +bool interval<T, Policies>::operator<= (const interval_holder& r) const
1.348 +{
1.349 + if (!checking::is_empty(low, up)) {
1.350 + if (up <= r.low) return true;
1.351 + else if (low > r.up) return false;
1.352 + }
1.353 + throw interval_lib::comparison_error();
1.354 +}
1.355 +
1.356 +template<class T, class Policies> inline
1.357 +bool interval<T, Policies>::operator>= (const interval_holder& r) const
1.358 +{
1.359 + if (!checking::is_empty(low, up)) {
1.360 + if (low >= r.up) return true;
1.361 + else if (up < r.low) return false;
1.362 + }
1.363 + throw interval_lib::comparison_error();
1.364 +}
1.365 +
1.366 +template<class T, class Policies> inline
1.367 +bool interval<T, Policies>::operator== (const interval_holder& r) const
1.368 +{
1.369 + if (!checking::is_empty(low, up)) {
1.370 + if (up == r.low && low == r.up) return true;
1.371 + else if (up < r.low || low > r.up) return false;
1.372 + }
1.373 + throw interval_lib::comparison_error();
1.374 +}
1.375 +
1.376 +template<class T, class Policies> inline
1.377 +bool interval<T, Policies>::operator!= (const interval_holder& r) const
1.378 +{
1.379 + if (!checking::is_empty(low, up)) {
1.380 + if (up < r.low || low > r.up) return true;
1.381 + else if (up == r.low && low == r.up) return false;
1.382 + }
1.383 + throw interval_lib::comparison_error();
1.384 +}
1.385 +
1.386 +/*
1.387 + * interval/number comparisons
1.388 + */
1.389 +
1.390 +template<class T, class Policies> inline
1.391 +bool interval<T, Policies>::operator< (const number_holder& r) const
1.392 +{
1.393 + if (!checking::is_empty(low, up)) {
1.394 + if (up < r.val) return true;
1.395 + else if (low >= r.val) return false;
1.396 + }
1.397 + throw interval_lib::comparison_error();
1.398 +}
1.399 +
1.400 +template<class T, class Policies> inline
1.401 +bool interval<T, Policies>::operator> (const number_holder& r) const
1.402 +{
1.403 + if (!checking::is_empty(low, up)) {
1.404 + if (low > r.val) return true;
1.405 + else if (up <= r.val) return false;
1.406 + }
1.407 + throw interval_lib::comparison_error();
1.408 +}
1.409 +
1.410 +template<class T, class Policies> inline
1.411 +bool interval<T, Policies>::operator<= (const number_holder& r) const
1.412 +{
1.413 + if (!checking::is_empty(low, up)) {
1.414 + if (up <= r.val) return true;
1.415 + else if (low > r.val) return false;
1.416 + }
1.417 + throw interval_lib::comparison_error();
1.418 +}
1.419 +
1.420 +template<class T, class Policies> inline
1.421 +bool interval<T, Policies>::operator>= (const number_holder& r) const
1.422 +{
1.423 + if (!checking::is_empty(low, up)) {
1.424 + if (low >= r.val) return true;
1.425 + else if (up < r.val) return false;
1.426 + }
1.427 + throw interval_lib::comparison_error();
1.428 +}
1.429 +
1.430 +template<class T, class Policies> inline
1.431 +bool interval<T, Policies>::operator== (const number_holder& r) const
1.432 +{
1.433 + if (!checking::is_empty(low, up)) {
1.434 + if (up == r.val && low == r.val) return true;
1.435 + else if (up < r.val || low > r.val) return false;
1.436 + }
1.437 + throw interval_lib::comparison_error();
1.438 +}
1.439 +
1.440 +template<class T, class Policies> inline
1.441 +bool interval<T, Policies>::operator!= (const number_holder& r) const
1.442 +{
1.443 + if (!checking::is_empty(low, up)) {
1.444 + if (up < r.val || low > r.val) return true;
1.445 + else if (up == r.val && low == r.val) return false;
1.446 + }
1.447 + throw interval_lib::comparison_error();
1.448 +}
1.449 +
1.450 +} // namespace numeric
1.451 +} // namespace boost
1.452 +
1.453 +#endif // BOOST_NUMERIC_INTERVAL_INTERVAL_HPP