00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef PPL_Interval_defs_hh
00024 #define PPL_Interval_defs_hh 1
00025
00026 #include "globals.defs.hh"
00027 #include "meta_programming.hh"
00028 #include "assign_or_swap.hh"
00029 #include "Interval.types.hh"
00030 #include "Interval_Info.defs.hh"
00031 #include <iosfwd>
00032
00033
00034 #include <iostream>
00035
00036 namespace Parma_Polyhedra_Library {
00037
00038 enum I_Result {
00039 I_EMPTY = 0,
00040
00041
00042
00043
00044
00045
00046
00047
00048 I_MAYBE_EMPTY = 1 << 12,
00049 I_SINGULARITIES = 1 << 13
00050 };
00051
00052 enum Ternary { T_YES, T_NO, T_MAYBE };
00053
00054 inline I_Result
00055 combine(Result l, Result u) {
00056 return static_cast<I_Result>(l | (u << 6));
00057 }
00058
00059 inline Result
00060 lower(I_Result r) {
00061 return static_cast<Result>(r & 63);
00062 }
00063
00064 inline Result
00065 upper(I_Result r) {
00066 return static_cast<Result>((r >> 6) & 63);
00067 }
00068
00069 template <typename Info>
00070 inline bool
00071 unrepresentability_error(I_Result r, const Info&) {
00072 return !Info::store_special
00073 && (is_special(lower(r)) || is_special(upper(r)));
00074 }
00075
00076 using namespace Boundary_NS;
00077 using namespace Interval_NS;
00078
00079 struct Interval_Base {};
00080
00081 template <typename T, typename Enable = void>
00082 struct Is_Singleton : public Is_Native_Or_Checked<T> {};
00083
00084 template <typename T>
00085 struct Is_Interval : public Is_Same_Or_Derived<Interval_Base, T> {};
00086
00088
00091 template <typename Boundary, typename Info>
00092 class Interval : public Interval_Base, private Info {
00093 private:
00094 COMPILE_TIME_CHECK(!Info::store_special
00095 || !std::numeric_limits<Boundary>::has_infinity,
00096 "store_special is meaningless"
00097 " when boundary type may contains infinity");
00098 Info& w_info() const {
00099 return const_cast<Interval&>(*this);
00100 }
00101 bool is_empty_nocache() const {
00102 return lt(UPPER, upper(), info(), LOWER, lower(), info());
00103 }
00104 bool is_singleton_nocache() const {
00105 return eq(LOWER, lower(), info(), UPPER, upper(), info());
00106 }
00107 Result lower_normalize() const {
00108 Result r;
00109 if (info().get_boundary_property(LOWER, NORMALIZED)
00110 || info().get_boundary_property(LOWER, SPECIAL))
00111 r = V_EQ;
00112 else {
00113 if (info().get_boundary_property(LOWER, OPEN)) {
00114 r = info().restrict(lower(), V_GT);
00115 if (r != V_GT)
00116 w_info().set_boundary_property(LOWER, OPEN, false);
00117 }
00118 else {
00119 r = info().restrict(lower(), V_GE);
00120 if (r == V_GT)
00121 w_info().set_boundary_property(LOWER, OPEN);
00122 }
00123 w_info().set_boundary_property(LOWER, NORMALIZED);
00124 }
00125 return r;
00126 }
00127 Result upper_normalize() const {
00128 Result r;
00129 if (info().get_boundary_property(UPPER, NORMALIZED)
00130 || info().get_boundary_property(UPPER, SPECIAL))
00131 r = V_EQ;
00132 else {
00133 if (info().get_boundary_property(UPPER, OPEN)) {
00134 r = info().restrict(upper(), V_LT);
00135 if (r != V_LT)
00136 w_info().set_boundary_property(UPPER, OPEN, false);
00137 }
00138 else {
00139 r = info().restrict(upper(), V_LE);
00140 if (r == V_LT)
00141 w_info().set_boundary_property(UPPER, OPEN);
00142 }
00143 w_info().set_boundary_property(UPPER, NORMALIZED);
00144 }
00145 return r;
00146 }
00147
00148
00149 public:
00150 typedef Boundary boundary_type;
00151 typedef Info info_type;
00152
00153 typedef Interval_NS::Property Property;
00154
00155 void lower_load() {
00156 #ifdef PPL_ABI_BREAKING_EXTRA_DEBUG
00157 lower_loaded = 1;
00158 #endif
00159 }
00160
00161 void upper_load() {
00162 #ifdef PPL_ABI_BREAKING_EXTRA_DEBUG
00163 upper_loaded = 1;
00164 #endif
00165 }
00166
00167 void complete_init() {
00168 #ifdef PPL_ABI_BREAKING_EXTRA_DEBUG
00169 assert(lower_loaded);
00170 assert(upper_loaded);
00171 completed = 1;
00172 #endif
00173 }
00174
00175 void complete_init_internal() {
00176 #ifdef PPL_ABI_BREAKING_EXTRA_DEBUG
00177 lower_loaded = 1;
00178 upper_loaded = 1;
00179 completed = 1;
00180 #endif
00181 }
00182
00183 template <typename T>
00184 typename Enable_If<Is_Singleton<T>::value || Is_Interval<T>::value, Interval&>::type
00185 operator=(const T& x) {
00186 assign(x);
00187 return *this;
00188 }
00189
00190 template <typename T>
00191 typename Enable_If<Is_Singleton<T>::value || Is_Interval<T>::value, Interval&>::type
00192 operator+=(const T& x) {
00193 add_assign(*this, x);
00194 return *this;
00195 }
00196 template <typename T>
00197 typename Enable_If<Is_Singleton<T>::value || Is_Interval<T>::value, Interval&>::type
00198 operator-=(const T& x) {
00199 sub_assign(*this, x);
00200 return *this;
00201 }
00202 template <typename T>
00203 typename Enable_If<Is_Singleton<T>::value || Is_Interval<T>::value, Interval&>::type
00204 operator*=(const T& x) {
00205 mul_assign(*this, x);
00206 return *this;
00207 }
00208 template <typename T>
00209 typename Enable_If<Is_Singleton<T>::value || Is_Interval<T>::value, Interval&>::type
00210 operator/=(const T& x) {
00211 div_assign(*this, x);
00212 return *this;
00213 }
00214
00216 void swap(Interval& y);
00217
00218 Info& info() {
00219 return *this;
00220 }
00221
00222 const Info& info() const {
00223 return *this;
00224 }
00225
00226 Boundary& lower() {
00227 return lower_;
00228 }
00229
00230 const Boundary& lower() const {
00231 return lower_;
00232 }
00233
00234 Boundary& upper() {
00235 return upper_;
00236 }
00237
00238 const Boundary& upper() const {
00239 return upper_;
00240 }
00241
00242 Ternary is_empty_cached() const {
00243 if (info().get_interval_property(CARDINALITY_0))
00244 return info().get_interval_property(CARDINALITY_IS) ? T_YES : T_NO;
00245 else if (info().get_interval_property(CARDINALITY_IS))
00246 return T_NO;
00247 else
00248 return T_MAYBE;
00249 }
00250
00251 Ternary is_singleton_cached() const {
00252 if (info().get_interval_property(CARDINALITY_1))
00253 return info().get_interval_property(CARDINALITY_IS) ? T_YES : T_NO;
00254 else if (info().get_interval_property(CARDINALITY_IS))
00255 return T_NO;
00256 else
00257 return T_MAYBE;
00258 }
00259
00260 bool is_empty() const {
00261 switch (is_empty_cached()) {
00262 case T_NO:
00263 return false;
00264 case T_YES:
00265 return true;
00266 case T_MAYBE:
00267 bool r = is_empty_nocache();
00268 if (r) {
00269 w_info().set_interval_property(CARDINALITY_IS, r);
00270 w_info().set_interval_property(CARDINALITY_1, false);
00271 }
00272 w_info().set_interval_property(CARDINALITY_0);
00273 return r;
00274 }
00275 assert(false);
00276 return false;
00277 }
00278
00279 bool is_singleton() const {
00280 switch (is_singleton_cached()) {
00281 case T_NO:
00282 return false;
00283 case T_YES:
00284 return true;
00285 case T_MAYBE:
00286 bool r = is_singleton_nocache();
00287 if (r) {
00288 w_info().set_interval_property(CARDINALITY_IS, r);
00289 w_info().set_interval_property(CARDINALITY_0, false);
00290 }
00291 w_info().set_interval_property(CARDINALITY_1);
00292 return r;
00293 }
00294 assert(false);
00295 return false;
00296 }
00297
00298 bool has_restriction() const {
00299 return info().has_restriction();
00300 }
00301
00302 I_Result normalize() const {
00303 assert(OK());
00304 if (has_restriction()) {
00305 Result rl = lower_normalize();
00306 Result ru = upper_normalize();
00307
00308 invalidate_cardinality_cache();
00309 info().normalize();
00310 assert(OK());
00311 return combine(rl, ru);
00312 }
00313 else
00314 return combine(V_EQ, V_EQ);
00315 }
00316
00317 bool lower_is_open() const {
00318 assert(OK());
00319 return is_open(LOWER, lower(), info());
00320 }
00321
00322 bool upper_is_open() const {
00323 assert(OK());
00324 return is_open(UPPER, upper(), info());
00325 }
00326
00327 Result lower_shrink() {
00328 assert(OK());
00329 return shrink(LOWER, lower(), info());
00330 }
00331
00332 Result upper_shrink() {
00333 assert(OK());
00334 return shrink(UPPER, upper(), info());
00335 }
00336
00337 bool lower_is_unbounded() const {
00338 assert(OK());
00339 return Boundary_NS::is_unbounded(LOWER, lower(), info());
00340 }
00341
00342 bool upper_is_unbounded() const {
00343 assert(OK());
00344 return Boundary_NS::is_unbounded(UPPER, upper(), info());
00345 }
00346
00347 bool is_unbounded() const {
00348 assert(OK());
00349 return lower_is_unbounded() || upper_is_unbounded();
00350 }
00351
00352 bool is_universe() const {
00353 assert(OK());
00354 return lower_is_unbounded() && upper_is_unbounded()
00355 && !has_restriction();
00356 }
00357
00358 void invalidate_cardinality_cache() const {
00359 w_info().set_interval_property(CARDINALITY_IS, false);
00360 w_info().set_interval_property(CARDINALITY_0, false);
00361 w_info().set_interval_property(CARDINALITY_1, false);
00362 }
00363
00364 template <typename T>
00365 Result lower_set_uninit(const T& x, bool open = false) {
00366 info().clear_boundary_properties(LOWER);
00367 Result rl = Boundary_NS::assign(LOWER, lower(), info(), LOWER, x, f_info(x, open));
00368 lower_load();
00369 return rl;
00370 }
00371
00372 Result lower_set_uninit(const Unbounded&) {
00373 info().clear_boundary_properties(LOWER);
00374 Result rl = set_unbounded(LOWER, lower(), info());
00375 lower_load();
00376 return rl;
00377 }
00378
00379 template <typename T>
00380 Result lower_set(const T& x, bool open = false) {
00381 assert(OK());
00382 info().clear_boundary_properties(LOWER);
00383 Result rl = Boundary_NS::assign(LOWER, lower(), info(), LOWER, x, f_info(x, open));
00384 invalidate_cardinality_cache();
00385 assert(OK());
00386 return rl;
00387 }
00388
00389 Result lower_set(const Unbounded&) {
00390 assert(OK());
00391 info().clear_boundary_properties(LOWER);
00392 Result rl = set_unbounded(LOWER, lower(), info());
00393 invalidate_cardinality_cache();
00394 assert(OK());
00395 return rl;
00396 }
00397
00398 template <typename T>
00399 Result lower_narrow(const T& x, bool open = false) {
00400 assert(OK());
00401 if (ge(LOWER, lower(), info(), LOWER, x, f_info(x, open)))
00402 return V_EQ;
00403 return lower_set(x, open);
00404 }
00405
00406 template <typename T>
00407 Result lower_widen(const T& x, bool open = false) {
00408 assert(OK());
00409 if (le(LOWER, lower(), info(), LOWER, x, f_info(x, open)))
00410 return V_EQ;
00411 return lower_set(x, open);
00412 }
00413
00414 Result lower_widen(const Unbounded&) {
00415 assert(OK());
00416 if (lower_is_unbounded())
00417 return V_EQ;
00418 info().clear_boundary_properties(LOWER);
00419 Result rl = set_unbounded(LOWER, lower(), info());
00420 invalidate_cardinality_cache();
00421 assert(OK());
00422 return V_EQ;
00423 }
00424
00425 template <typename T>
00426 Result upper_set_uninit(const T& x, bool open = false) {
00427 info().clear_boundary_properties(UPPER);
00428 Result rl = Boundary_NS::assign(UPPER, upper(), info(), UPPER, x, f_info(x, open));
00429 upper_load();
00430 return rl;
00431 }
00432 Result upper_set_uninit(const Unbounded&) {
00433 info().clear_boundary_properties(UPPER);
00434 Result rl = set_unbounded(UPPER, upper(), info());
00435 upper_load();
00436 return rl;
00437 }
00438
00439 template <typename T>
00440 Result upper_set(const T& x, bool open = false) {
00441 assert(OK());
00442 info().clear_boundary_properties(UPPER);
00443 Result rl = Boundary_NS::assign(UPPER, upper(), info(), UPPER, x, f_info(x, open));
00444 invalidate_cardinality_cache();
00445 assert(OK());
00446 return rl;
00447 }
00448
00449 Result upper_set(const Unbounded&) {
00450 assert(OK());
00451 info().clear_boundary_properties(UPPER);
00452 Result rl = set_unbounded(UPPER, upper(), info());
00453 invalidate_cardinality_cache();
00454 assert(OK());
00455 return rl;
00456 }
00457
00458 template <typename T>
00459 Result upper_narrow(const T& x, bool open = false) {
00460 assert(OK());
00461 if (le(UPPER, upper(), info(), UPPER, x, f_info(x, open)))
00462 return V_EQ;
00463 return upper_set(x, open);
00464 }
00465
00466 template <typename T>
00467 Result upper_widen(const T& x, bool open = false) {
00468 assert(OK());
00469 if (ge(UPPER, upper(), info(), UPPER, x, f_info(x, open)))
00470 return V_EQ;
00471 return upper_set(x, open);
00472 }
00473
00474 Result upper_widen(const Unbounded&) {
00475 assert(OK());
00476 if (upper_is_unbounded())
00477 return V_EQ;
00478 info().clear_boundary_properties(UPPER);
00479 Result rl = set_unbounded(UPPER, upper(), info());
00480 invalidate_cardinality_cache();
00481 assert(OK());
00482 return rl;
00483 }
00484
00485 I_Result assign(Degenerate_Element e) {
00486 I_Result r;
00487 Result rl, ru;
00488 info().clear();
00489 switch (e) {
00490 case EMPTY:
00491 info().set_interval_property(CARDINALITY_IS);
00492 info().set_interval_property(CARDINALITY_0);
00493 lower_set_uninit(1);
00494 upper_set_uninit(0);
00495 r = I_EMPTY;
00496 break;
00497 case UNIVERSE:
00498 info().set_interval_property(CARDINALITY_0, true);
00499 info().set_interval_property(CARDINALITY_1, true);
00500 rl = lower_set_uninit(UNBOUNDED);
00501 ru = upper_set_uninit(UNBOUNDED);
00502 r = combine(rl, ru);
00503 break;
00504 default:
00505 assert(0);
00506 r = I_EMPTY;
00507 break;
00508 }
00509 complete_init();
00510 assert(OK());
00511 return r;
00512 }
00513
00514 template <typename From>
00515 typename Enable_If<Is_Special<From>::value, I_Result>::type assign(const From&) {
00516 info().clear();
00517 info().set_interval_property(CARDINALITY_0, true);
00518 info().set_interval_property(CARDINALITY_1, true);
00519 Result rl, ru;
00520 switch (From::code) {
00521 case VC_MINUS_INFINITY:
00522 rl = Boundary_NS::set_minus_infinity(LOWER, lower(), info());
00523 ru = Boundary_NS::set_minus_infinity(UPPER, upper(), info());
00524 break;
00525 case VC_PLUS_INFINITY:
00526 rl = Boundary_NS::set_plus_infinity(LOWER, lower(), info());
00527 ru = Boundary_NS::set_plus_infinity(UPPER, upper(), info());
00528 break;
00529 default:
00530 assert(0);
00531 rl = VC_NAN;
00532 ru = VC_NAN;
00533 }
00534 complete_init_internal();
00535 assert(OK());
00536 return combine(rl, ru);
00537 }
00538
00539 I_Result set_infinities() {
00540 info().clear();
00541 info().set_interval_property(CARDINALITY_0, true);
00542 info().set_interval_property(CARDINALITY_1, true);
00543
00544 Result rl = Boundary_NS::set_minus_infinity(LOWER, lower(), info());
00545 Result ru = Boundary_NS::set_plus_infinity(UPPER, upper(), info());
00546 complete_init_internal();
00547 assert(OK());
00548 return combine(rl, ru);
00549 }
00550
00551 bool is_topologically_closed() const {
00552 assert(OK());
00553 return !Info::store_open
00554 || is_empty()
00555 || ((lower_is_unbounded() || !lower_is_open())
00556 && (upper_is_unbounded() || !upper_is_open()));
00557 }
00558
00560 void topological_closure_assign() {
00561 if (!Info::store_open || is_empty())
00562 return;
00563
00564 if (!lower_is_unbounded())
00565 info().set_boundary_property(LOWER, OPEN, false);
00566
00567 if (!upper_is_unbounded())
00568 info().set_boundary_property(UPPER, OPEN, false);
00569 }
00570
00571 bool is_infinity() const {
00572 assert(OK());
00573 if (is_reverse_infinity(LOWER, lower(), info()))
00574 return 1;
00575 else if (is_reverse_infinity(UPPER, upper(), info()))
00576 return -1;
00577 else
00578 return 0;
00579 }
00580
00581 bool contains_integer_point() const {
00582 assert(OK());
00583 if (is_empty())
00584 return false;
00585 if (is_unbounded())
00586 return true;
00587 Boundary l;
00588 if (lower_is_open()) {
00589 add_assign_r(l, lower(), Boundary(1), ROUND_DOWN);
00590 floor_assign_r(l, l, ROUND_DOWN);
00591 }
00592 else
00593 ceil_assign_r(l, lower(), ROUND_DOWN);
00594 Boundary u;
00595 if (upper_is_open()) {
00596 sub_assign_r(u, upper(), Boundary(1), ROUND_UP);
00597 ceil_assign_r(u, u, ROUND_UP);
00598 }
00599 else
00600 floor_assign_r(u, upper(), ROUND_UP);
00601 return u >= l;
00602 }
00603
00605 memory_size_type total_memory_in_bytes() const;
00606
00608 memory_size_type external_memory_in_bytes() const;
00609
00610 void ascii_dump(std::ostream& s) const;
00611 bool ascii_load(std::istream& s);
00612
00613 bool OK() const {
00614 #ifdef PPL_ABI_BREAKING_EXTRA_DEBUG
00615 if (!completed) {
00616 std::cerr << "The interval initialization has not been completed."
00617 << std::endl;
00618 return false;
00619 }
00620 #endif
00621 #if 0
00622 if (!Info::may_be_empty && is_empty()) {
00623 #ifndef NDEBUG
00624 std::cerr << "The interval is unexpectedly empty.\n";
00625 #endif
00626 return false;
00627 }
00628 #endif
00629
00630 if (is_open(LOWER, lower(), info())) {
00631 if (is_plus_infinity(LOWER, lower(), info())) {
00632 #ifndef NDEBUG
00633 std::cerr << "The lower boundary is +inf open.\n";
00634 #endif
00635 }
00636 }
00637 else if (!Info::may_contain_infinity
00638 && (is_minus_infinity(LOWER, lower(), info())
00639 || is_plus_infinity(LOWER, lower(), info()))) {
00640 #ifndef NDEBUG
00641 std::cerr << "The lower boundary is unexpectedly infinity.\n";
00642 #endif
00643 return false;
00644 }
00645 if (!info().get_boundary_property(LOWER, SPECIAL)) {
00646 if (is_not_a_number(lower())) {
00647 #ifndef NDEBUG
00648 std::cerr << "The lower boundary is not a number.\n";
00649 #endif
00650 return false;
00651 }
00652 #if 0
00653 if (info().get_boundary_property(LOWER, NORMALIZED)
00654 && !info().is_restricted(lower())) {
00655 #ifndef NDEBUG
00656 std::cerr << "The lower boundary is marked to be normalized, "
00657 << "but it is not.\n";
00658 #endif
00659 return false;
00660 }
00661 #endif
00662 }
00663
00664 if (is_open(UPPER, upper(), info())) {
00665 if (is_minus_infinity(UPPER, upper(), info())) {
00666 #ifndef NDEBUG
00667 std::cerr << "The upper boundary is -inf open.\n";
00668 #endif
00669 }
00670 }
00671 else if (!Info::may_contain_infinity
00672 && (is_minus_infinity(UPPER, upper(), info())
00673 || is_plus_infinity(UPPER, upper(), info()))) {
00674 #ifndef NDEBUG
00675 std::cerr << "The upper boundary is unexpectedly infinity."
00676 << std::endl;
00677 #endif
00678 return false;
00679 }
00680 if (!info().get_boundary_property(UPPER, SPECIAL)) {
00681 if (is_not_a_number(upper())) {
00682 #ifndef NDEBUG
00683 std::cerr << "The upper boundary is not a number.\n";
00684 #endif
00685 return false;
00686 }
00687 #if 0
00688 if (info().get_boundary_property(UPPER, NORMALIZED)
00689 && !info().is_restricted(upper())) {
00690 #ifndef NDEBUG
00691 std::cerr << "The upper boundary is marked to be normalized, "
00692 << "but it is not.\n";
00693 #endif
00694 return false;
00695 }
00696 #endif
00697 }
00698
00699 Ternary t;
00700
00701 t = is_empty_cached();
00702 if (t == T_YES) {
00703 if (!is_empty_nocache()) {
00704 #ifndef NDEBUG
00705 std::cerr << "The interval is marked to be empty, "
00706 << "but actually it is not empty.\n";
00707 #endif
00708 return false;
00709 }
00710 }
00711 else if (t == T_NO) {
00712 if (is_empty_nocache()) {
00713 #ifndef NDEBUG
00714 std::cerr << "The interval is marked to be not empty, "
00715 << "but actually it is empty.\n";
00716 #endif
00717 return false;
00718 }
00719 }
00720
00721 t = is_singleton_cached();
00722 if (t == T_YES) {
00723 if (!is_singleton_nocache()) {
00724 #ifndef NDEBUG
00725 std::cerr << "The interval is marked to be singleton, "
00726 << "but actually it is not singleton.\n";
00727 #endif
00728 return false;
00729 }
00730 }
00731 else if (t == T_NO) {
00732 if (is_singleton_nocache()) {
00733 #ifndef NDEBUG
00734 std::cerr << "The interval is marked to be not singleton, "
00735 << "but actually it is singleton.\n";
00736 #endif
00737 return false;
00738 }
00739 }
00740
00741 if (info().get_interval_property(CARDINALITY_IS) &&
00742 info().get_interval_property(CARDINALITY_0)
00743 == info().get_interval_property(CARDINALITY_1)) {
00744 #ifndef NDEBUG
00745 std::cerr << "The interval is marked to know its cardinality, "
00746 << "but this is unspecified or ambiguous.\n";
00747 #endif
00748 return false;
00749 }
00750
00751
00752 return true;
00753 }
00754
00755 Interval()
00756 #ifdef PPL_ABI_BREAKING_EXTRA_DEBUG
00757 : lower_loaded(0), upper_loaded(0), completed(0)
00758 #endif
00759 {
00760 }
00761
00762 template <typename T>
00763 explicit Interval(const T& x)
00764 #ifdef PPL_ABI_BREAKING_EXTRA_DEBUG
00765 : lower_loaded(0), upper_loaded(0), completed(0)
00766 #endif
00767 {
00768 assign(x);
00769 }
00770
00771 template <typename T>
00772 typename Enable_If<Is_Singleton<T>::value || Is_Interval<T>::value, bool>::type
00773 contains(const T& y) const;
00774
00775 template <typename T>
00776 typename Enable_If<Is_Singleton<T>::value || Is_Interval<T>::value, bool>::type
00777 strictly_contains(const T& y) const;
00778
00779 template <typename T>
00780 typename Enable_If<Is_Singleton<T>::value
00781 || Is_Interval<T>::value, bool>::type
00782 is_disjoint_from(const T& y) const;
00783
00784 template <typename From1, typename From2>
00785 I_Result assign(const From1& l, const From2& u);
00786
00787 template <typename From>
00788 typename Enable_If<Is_Singleton<From>::value
00789 || Is_Interval<From>::value, I_Result>::type
00790 assign(const From& x);
00791
00792 template <typename From>
00793 typename Enable_If<Is_Singleton<From>::value
00794 || Is_Interval<From>::value, I_Result>::type
00795 join_assign(const From& x);
00796
00797 template <typename From1, typename From2>
00798 typename Enable_If<((Is_Singleton<From1>::value
00799 || Is_Interval<From1>::value)
00800 && (Is_Singleton<From2>::value
00801 || Is_Interval<From2>::value)), I_Result>::type
00802 join_assign(const From1& x, const From2& y);
00803
00804 template <typename From>
00805 typename Enable_If<Is_Singleton<From>::value
00806 || Is_Interval<From>::value, I_Result>::type
00807 intersect_assign(const From& x);
00808
00809 template <typename From1, typename From2>
00810 typename Enable_If<((Is_Singleton<From1>::value
00811 || Is_Interval<From1>::value)
00812 && (Is_Singleton<From2>::value
00813 || Is_Interval<From2>::value)), I_Result>::type
00814 intersect_assign(const From1& x, const From2& y);
00815
00820 template <typename From>
00821 typename Enable_If<Is_Singleton<From>::value
00822 || Is_Interval<From>::value, I_Result>::type
00823 difference_assign(const From& x);
00824
00829 template <typename From1, typename From2>
00830 typename Enable_If<((Is_Singleton<From1>::value
00831 || Is_Interval<From1>::value)
00832 && (Is_Singleton<From2>::value
00833 || Is_Interval<From2>::value)), I_Result>::type
00834 difference_assign(const From1& x, const From2& y);
00835
00851 template <typename From>
00852 typename Enable_If<Is_Singleton<From>::value || Is_Interval<From>::value, I_Result>::type
00853 refine_existential(Relation_Symbol rel, const From& x);
00854
00870 template <typename From>
00871 typename Enable_If<Is_Singleton<From>::value || Is_Interval<From>::value, I_Result>::type
00872 refine_universal(Relation_Symbol rel, const From& x);
00873
00874 template <typename From>
00875 typename Enable_If<Is_Singleton<From>::value || Is_Interval<From>::value, I_Result>::type
00876 neg_assign(const From& x);
00877
00878 template <typename From1, typename From2>
00879 typename Enable_If<((Is_Singleton<From1>::value || Is_Interval<From1>::value)
00880 && (Is_Singleton<From2>::value || Is_Interval<From2>::value)), I_Result>::type
00881 add_assign(const From1& x, const From2& y);
00882
00883 template <typename From1, typename From2>
00884 typename Enable_If<((Is_Singleton<From1>::value || Is_Interval<From1>::value)
00885 && (Is_Singleton<From2>::value || Is_Interval<From2>::value)), I_Result>::type
00886 sub_assign(const From1& x, const From2& y);
00887
00888 template <typename From1, typename From2>
00889 typename Enable_If<((Is_Singleton<From1>::value || Is_Interval<From1>::value)
00890 && (Is_Singleton<From2>::value || Is_Interval<From2>::value)), I_Result>::type
00891 mul_assign(const From1& x, const From2& y);
00892
00893 template <typename From1, typename From2>
00894 typename Enable_If<((Is_Singleton<From1>::value || Is_Interval<From1>::value)
00895 && (Is_Singleton<From2>::value || Is_Interval<From2>::value)), I_Result>::type
00896 div_assign(const From1& x, const From2& y);
00897
00898 template <typename From, typename Iterator>
00899 typename Enable_If<Is_Interval<From>::value, void>::type
00900 CC76_widening_assign(const From& y, Iterator first, Iterator last);
00901
00902 private:
00903 Boundary lower_;
00904 Boundary upper_;
00905 #ifdef PPL_ABI_BREAKING_EXTRA_DEBUG
00906 unsigned int lower_loaded:1;
00907 unsigned int upper_loaded:1;
00908 unsigned int completed:1;
00909 #endif
00910 };
00911
00912 }
00913
00914 #include "Interval.inlines.hh"
00915 #include "Interval.templates.hh"
00916
00917 #endif // !defined(PPL_Interval_defs_hh)