this repo has no description
1/* Boost interval/interval.hpp header file 2 * 3 * Copyright 2002-2003 Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion 4 * 5 * Distributed under the Boost Software License, Version 1.0. 6 * (See accompanying file LICENSE_1_0.txt or 7 * copy at http://www.boost.org/LICENSE_1_0.txt) 8 */ 9 10#ifndef GECODE_BOOST_NUMERIC_INTERVAL_INTERVAL_HPP 11#define GECODE_BOOST_NUMERIC_INTERVAL_INTERVAL_HPP 12 13#include <stdexcept> 14#include <string> 15#include <gecode/third-party/boost/numeric/interval/detail/interval_prototype.hpp> 16 17namespace gecode_boost { 18namespace numeric { 19 20namespace interval_lib { 21 22class comparison_error 23 : public std::runtime_error 24{ 25public: 26 comparison_error() 27 : std::runtime_error("gecode_boost::interval: uncertain comparison") 28 { } 29}; 30 31} // namespace interval_lib 32 33/* 34 * interval class 35 */ 36 37template<class T, class Policies> 38class interval 39{ 40private: 41 struct interval_holder; 42 struct number_holder; 43public: 44 typedef T base_type; 45 typedef Policies traits_type; 46 47 T const &lower() const; 48 T const &upper() const; 49 50 interval(); 51 interval(T const &v); 52 template<class T1> interval(T1 const &v); 53 interval(T const &l, T const &u); 54 template<class T1, class T2> interval(T1 const &l, T2 const &u); 55 interval(interval<T, Policies> const &r); 56 template<class Policies1> interval(interval<T, Policies1> const &r); 57 template<class T1, class Policies1> interval(interval<T1, Policies1> const &r); 58 59 interval &operator=(T const &v); 60 template<class T1> interval &operator=(T1 const &v); 61 interval &operator=(interval<T, Policies> const &r); 62 template<class Policies1> interval &operator=(interval<T, Policies1> const &r); 63 template<class T1, class Policies1> interval &operator=(interval<T1, Policies1> const &r); 64 65 void assign(const T& l, const T& u); 66 67 static interval empty(); 68 static interval whole(); 69 static interval hull(const T& x, const T& y); 70 71 interval& operator+= (const T& r); 72 interval& operator+= (const interval& r); 73 interval& operator-= (const T& r); 74 interval& operator-= (const interval& r); 75 interval& operator*= (const T& r); 76 interval& operator*= (const interval& r); 77 interval& operator/= (const T& r); 78 interval& operator/= (const interval& r); 79 80 bool operator< (const interval_holder& r) const; 81 bool operator> (const interval_holder& r) const; 82 bool operator<= (const interval_holder& r) const; 83 bool operator>= (const interval_holder& r) const; 84 bool operator== (const interval_holder& r) const; 85 bool operator!= (const interval_holder& r) const; 86 87 bool operator< (const number_holder& r) const; 88 bool operator> (const number_holder& r) const; 89 bool operator<= (const number_holder& r) const; 90 bool operator>= (const number_holder& r) const; 91 bool operator== (const number_holder& r) const; 92 bool operator!= (const number_holder& r) const; 93 94 // the following is for internal use only, it is not a published interface 95 // nevertheless, it's public because friends don't always work correctly. 96 interval(const T& l, const T& u, bool): low(l), up(u) {} 97 void set_empty(); 98 void set_whole(); 99 void set(const T& l, const T& u); 100 101private: 102 struct interval_holder { 103 template<class Policies2> 104 interval_holder(const interval<T, Policies2>& r) 105 : low(r.lower()), up(r.upper()) 106 { 107 typedef typename Policies2::checking checking2; 108 if (checking2::is_empty(low, up)) 109 throw interval_lib::comparison_error(); 110 } 111 112 const T& low; 113 const T& up; 114 }; 115 116 struct number_holder { 117 number_holder(const T& r) : val(r) 118 { 119 typedef typename Policies::checking checking; 120 if (checking::is_nan(r)) 121 throw interval_lib::comparison_error(); 122 } 123 124 const T& val; 125 }; 126 127 typedef typename Policies::checking checking; 128 typedef typename Policies::rounding rounding; 129 130 T low; 131 T up; 132}; 133 134template<class T, class Policies> inline 135interval<T, Policies>::interval(): 136 low(static_cast<T>(0)), up(static_cast<T>(0)) 137{} 138 139template<class T, class Policies> inline 140interval<T, Policies>::interval(T const &v): low(v), up(v) 141{ 142 if (checking::is_nan(v)) set_empty(); 143} 144 145template<class T, class Policies> template<class T1> inline 146interval<T, Policies>::interval(T1 const &v) 147{ 148 if (checking::is_nan(v)) set_empty(); 149 else { 150 rounding rnd; 151 low = rnd.conv_down(v); 152 up = rnd.conv_up (v); 153 } 154} 155 156template<class T, class Policies> template<class T1, class T2> inline 157interval<T, Policies>::interval(T1 const &l, T2 const &u) 158{ 159 if (checking::is_nan(l) || checking::is_nan(u) || !(l <= u)) set_empty(); 160 else { 161 rounding rnd; 162 low = rnd.conv_down(l); 163 up = rnd.conv_up (u); 164 } 165} 166 167template<class T, class Policies> inline 168interval<T, Policies>::interval(T const &l, T const &u): low(l), up(u) 169{ 170 if (checking::is_nan(l) || checking::is_nan(u) || !(l <= u)) 171 set_empty(); 172} 173 174 175template<class T, class Policies> inline 176interval<T, Policies>::interval(interval<T, Policies> const &r): low(r.lower()), up(r.upper()) 177{} 178 179template<class T, class Policies> template<class Policies1> inline 180interval<T, Policies>::interval(interval<T, Policies1> const &r): low(r.lower()), up(r.upper()) 181{ 182 typedef typename Policies1::checking checking1; 183 if (checking1::is_empty(r.lower(), r.upper())) set_empty(); 184} 185 186template<class T, class Policies> template<class T1, class Policies1> inline 187interval<T, Policies>::interval(interval<T1, Policies1> const &r) 188{ 189 typedef typename Policies1::checking checking1; 190 if (checking1::is_empty(r.lower(), r.upper())) set_empty(); 191 else { 192 rounding rnd; 193 low = rnd.conv_down(r.lower()); 194 up = rnd.conv_up (r.upper()); 195 } 196} 197 198template<class T, class Policies> inline 199interval<T, Policies> &interval<T, Policies>::operator=(T const &v) 200{ 201 if (checking::is_nan(v)) set_empty(); 202 else low = up = v; 203 return *this; 204} 205 206template<class T, class Policies> template<class T1> inline 207interval<T, Policies> &interval<T, Policies>::operator=(T1 const &v) 208{ 209 if (checking::is_nan(v)) set_empty(); 210 else { 211 rounding rnd; 212 low = rnd.conv_down(v); 213 up = rnd.conv_up (v); 214 } 215 return *this; 216} 217 218template<class T, class Policies> inline 219interval<T, Policies> &interval<T, Policies>::operator=(interval<T, Policies> const &r) 220{ 221 low = r.lower(); 222 up = r.upper(); 223 return *this; 224} 225 226template<class T, class Policies> template<class Policies1> inline 227interval<T, Policies> &interval<T, Policies>::operator=(interval<T, Policies1> const &r) 228{ 229 typedef typename Policies1::checking checking1; 230 if (checking1::is_empty(r.lower(), r.upper())) set_empty(); 231 else { 232 low = r.lower(); 233 up = r.upper(); 234 } 235 return *this; 236} 237 238template<class T, class Policies> template<class T1, class Policies1> inline 239interval<T, Policies> &interval<T, Policies>::operator=(interval<T1, Policies1> const &r) 240{ 241 typedef typename Policies1::checking checking1; 242 if (checking1::is_empty(r.lower(), r.upper())) set_empty(); 243 else { 244 rounding rnd; 245 low = rnd.conv_down(r.lower()); 246 up = rnd.conv_up (r.upper()); 247 } 248 return *this; 249} 250 251template<class T, class Policies> inline 252void interval<T, Policies>::assign(const T& l, const T& u) 253{ 254 if (checking::is_nan(l) || checking::is_nan(u) || !(l <= u)) 255 set_empty(); 256 else set(l, u); 257} 258 259template<class T, class Policies> inline 260void interval<T, Policies>::set(const T& l, const T& u) 261{ 262 low = l; 263 up = u; 264} 265 266template<class T, class Policies> inline 267void interval<T, Policies>::set_empty() 268{ 269 low = checking::empty_lower(); 270 up = checking::empty_upper(); 271} 272 273template<class T, class Policies> inline 274void interval<T, Policies>::set_whole() 275{ 276 low = checking::neg_inf(); 277 up = checking::pos_inf(); 278} 279 280template<class T, class Policies> inline 281interval<T, Policies> interval<T, Policies>::hull(const T& x, const T& y) 282{ 283 bool bad_x = checking::is_nan(x); 284 bool bad_y = checking::is_nan(y); 285 if (bad_x) 286 if (bad_y) return interval::empty(); 287 else return interval(y, y, true); 288 else 289 if (bad_y) return interval(x, x, true); 290 if (x <= y) return interval(x, y, true); 291 else return interval(y, x, true); 292} 293 294template<class T, class Policies> inline 295interval<T, Policies> interval<T, Policies>::empty() 296{ 297 return interval<T, Policies>(checking::empty_lower(), 298 checking::empty_upper(), true); 299} 300 301template<class T, class Policies> inline 302interval<T, Policies> interval<T, Policies>::whole() 303{ 304 return interval<T, Policies>(checking::neg_inf(), checking::pos_inf(), true); 305} 306 307template<class T, class Policies> inline 308const T& interval<T, Policies>::lower() const 309{ 310 return low; 311} 312 313template<class T, class Policies> inline 314const T& interval<T, Policies>::upper() const 315{ 316 return up; 317} 318 319/* 320 * interval/interval comparisons 321 */ 322 323template<class T, class Policies> inline 324bool interval<T, Policies>::operator< (const interval_holder& r) const 325{ 326 if (!checking::is_empty(low, up)) { 327 if (up < r.low) return true; 328 else if (low >= r.up) return false; 329 } 330 throw interval_lib::comparison_error(); 331} 332 333template<class T, class Policies> inline 334bool interval<T, Policies>::operator> (const interval_holder& r) const 335{ 336 if (!checking::is_empty(low, up)) { 337 if (low > r.up) return true; 338 else if (up <= r.low) return false; 339 } 340 throw interval_lib::comparison_error(); 341} 342 343template<class T, class Policies> inline 344bool interval<T, Policies>::operator<= (const interval_holder& r) const 345{ 346 if (!checking::is_empty(low, up)) { 347 if (up <= r.low) return true; 348 else if (low > r.up) return false; 349 } 350 throw interval_lib::comparison_error(); 351} 352 353template<class T, class Policies> inline 354bool interval<T, Policies>::operator>= (const interval_holder& r) const 355{ 356 if (!checking::is_empty(low, up)) { 357 if (low >= r.up) return true; 358 else if (up < r.low) return false; 359 } 360 throw interval_lib::comparison_error(); 361} 362 363template<class T, class Policies> inline 364bool interval<T, Policies>::operator== (const interval_holder& r) const 365{ 366 if (!checking::is_empty(low, up)) { 367//Boost bug ? if (up == r.low && low == r.up) return true; 368 if (up == r.up && low == r.low) return true; 369 else if (up < r.low || low > r.up) return false; 370 } 371 throw interval_lib::comparison_error(); 372} 373 374template<class T, class Policies> inline 375bool interval<T, Policies>::operator!= (const interval_holder& r) const 376{ 377 if (!checking::is_empty(low, up)) { 378 if (up < r.low || low > r.up) return true; 379 else if (up == r.low && low == r.up) return false; 380 } 381 throw interval_lib::comparison_error(); 382} 383 384/* 385 * interval/number comparisons 386 */ 387 388template<class T, class Policies> inline 389bool interval<T, Policies>::operator< (const number_holder& r) const 390{ 391 if (!checking::is_empty(low, up)) { 392 if (up < r.val) return true; 393 else if (low >= r.val) return false; 394 } 395 throw interval_lib::comparison_error(); 396} 397 398template<class T, class Policies> inline 399bool interval<T, Policies>::operator> (const number_holder& r) const 400{ 401 if (!checking::is_empty(low, up)) { 402 if (low > r.val) return true; 403 else if (up <= r.val) return false; 404 } 405 throw interval_lib::comparison_error(); 406} 407 408template<class T, class Policies> inline 409bool interval<T, Policies>::operator<= (const number_holder& r) const 410{ 411 if (!checking::is_empty(low, up)) { 412 if (up <= r.val) return true; 413 else if (low > r.val) return false; 414 } 415 throw interval_lib::comparison_error(); 416} 417 418template<class T, class Policies> inline 419bool interval<T, Policies>::operator>= (const number_holder& r) const 420{ 421 if (!checking::is_empty(low, up)) { 422 if (low >= r.val) return true; 423 else if (up < r.val) return false; 424 } 425 throw interval_lib::comparison_error(); 426} 427 428template<class T, class Policies> inline 429bool interval<T, Policies>::operator== (const number_holder& r) const 430{ 431 if (!checking::is_empty(low, up)) { 432 if (up == r.val && low == r.val) return true; 433 else if (up < r.val || low > r.val) return false; 434 } 435 throw interval_lib::comparison_error(); 436} 437 438template<class T, class Policies> inline 439bool interval<T, Policies>::operator!= (const number_holder& r) const 440{ 441 if (!checking::is_empty(low, up)) { 442 if (up < r.val || low > r.val) return true; 443 else if (up == r.val && low == r.val) return false; 444 } 445 throw interval_lib::comparison_error(); 446} 447 448} // namespace numeric 449} // namespace gecode_boost 450 451#endif // GECODE_BOOST_NUMERIC_INTERVAL_INTERVAL_HPP