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_inlines_hh
00024 #define PPL_Interval_inlines_hh 1
00025
00026 namespace Parma_Polyhedra_Library {
00027
00028 template <typename Boundary, typename Info>
00029 inline memory_size_type
00030 Interval<Boundary, Info>::external_memory_in_bytes() const {
00031 return Parma_Polyhedra_Library::external_memory_in_bytes(lower())
00032 + Parma_Polyhedra_Library::external_memory_in_bytes(upper());
00033 }
00034
00035 template <typename Boundary, typename Info>
00036 inline memory_size_type
00037 Interval<Boundary, Info>::total_memory_in_bytes() const {
00038 return sizeof(*this) + external_memory_in_bytes();
00039 }
00040
00041 template <typename Boundary, typename Info>
00042 inline void
00043 Interval<Boundary, Info>::swap(Interval<Boundary, Info>& y) {
00044 std::swap(lower(), y.lower());
00045 std::swap(upper(), y.upper());
00046 std::swap(info(), y.info());
00047 }
00048
00049 template <typename Boundary, typename Info>
00050 inline bool
00051 f_is_empty(const Interval<Boundary, Info>& x) {
00052 return x.is_empty();
00053 }
00054 template <typename Boundary, typename Info>
00055 inline bool
00056 f_is_singleton(const Interval<Boundary, Info>& x) {
00057 return x.is_singleton();
00058 }
00059 template <typename Boundary, typename Info>
00060 inline int
00061 is_infinity(const Interval<Boundary, Info>& x) {
00062 return x.is_infinity();
00063 }
00064
00065 namespace Interval_NS {
00066
00067 template <typename Boundary, typename Info>
00068 inline const Boundary&
00069 f_lower(const Interval<Boundary, Info>& x) {
00070 return x.lower();
00071 }
00072 template <typename Boundary, typename Info>
00073 inline const Boundary&
00074 f_upper(const Interval<Boundary, Info>& x) {
00075 return x.upper();
00076 }
00077 template <typename Boundary, typename Info>
00078 inline const Info&
00079 f_info(const Interval<Boundary, Info>& x) {
00080 return x.info();
00081 }
00082
00083 struct Scalar_As_Interval_Policy {
00084 const_bool_nodef(may_be_empty, true);
00085 const_bool_nodef(may_contain_infinity, true);
00086 const_bool_nodef(check_empty_result, false);
00087 const_bool_nodef(check_inexact, false);
00088 };
00089
00090 typedef Interval_Restriction_None<Interval_Info_Null<Scalar_As_Interval_Policy> > Scalar_As_Interval_Info;
00091
00092 const Scalar_As_Interval_Info SCALAR_INFO;
00093
00094 typedef Interval_Restriction_None<Interval_Info_Null_Open<Scalar_As_Interval_Policy> > Scalar_As_Interval_Info_Open;
00095
00096 template <typename T>
00097 inline typename Enable_If<Is_Singleton<T>::value, const T&>::type
00098 f_lower(const T& x) {
00099 return x;
00100 }
00101 template <typename T>
00102 inline typename Enable_If<Is_Singleton<T>::value, const T&>::type
00103 f_upper(const T& x) {
00104 return x;
00105 }
00106 template <typename T>
00107 inline typename Enable_If<Is_Singleton<T>::value, const Scalar_As_Interval_Info&>::type
00108 f_info(const T&) {
00109 return SCALAR_INFO;
00110 }
00111 template <typename T>
00112 inline typename Enable_If<Is_Singleton<T>::value, Scalar_As_Interval_Info_Open>::type
00113 f_info(const T&, bool open) {
00114 return Scalar_As_Interval_Info_Open(open);
00115 }
00116
00117 template <typename T>
00118 inline typename Enable_If<Is_Singleton<T>::value, bool>::type
00119 f_is_empty(const T& x) {
00120 return is_not_a_number(x);
00121 }
00122
00123 template <typename T>
00124 inline typename Enable_If<Is_Singleton<T>::value, bool>::type
00125 f_is_singleton(const T& x) {
00126 return !f_is_empty(x);
00127 }
00128
00129 template <typename T>
00130 inline typename Enable_If<Is_Singleton<T>::value || Is_Interval<T>::value, Ternary>::type
00131 f_is_empty_lazy(const T& x) {
00132 if (f_info(x).get_interval_property(CARDINALITY_0))
00133 return f_info(x).get_interval_property(CARDINALITY_IS) ? T_YES : T_NO;
00134 else
00135 return T_MAYBE;
00136 }
00137
00138 }
00139
00140 inline bool
00141 is_integer(const char*) {
00142
00143 return false;
00144 }
00145
00146 inline bool
00147 is_not_a_number(const char*) {
00148
00149 return false;
00150 }
00151
00152 template <typename T>
00153 inline typename Enable_If<Is_Singleton<T>::value || Is_Interval<T>::value, bool>::type
00154 is_singleton_integer(const T& x) {
00155 return is_singleton(x) && is_integer(f_lower(x));
00156 }
00157
00158 template <typename T1, typename T2>
00159 inline bool
00160 same_object(const T1&, const T2&) {
00161 return false;
00162 }
00163
00164 template <typename T>
00165 inline bool
00166 same_object(const T& x, const T& y) {
00167 return &x == &y;
00168 }
00169
00170 template <typename T>
00171 inline typename Enable_If<Is_Singleton<T>::value || Is_Interval<T>::value, bool>::type
00172 check_empty_arg(const T& x) {
00173 if (f_info(x).may_be_empty)
00174 return f_is_empty(x);
00175 else {
00176 assert(!f_is_empty(x));
00177 return false;
00178 }
00179 }
00180
00181 template <typename Boundary, typename Info>
00182 inline I_Result
00183 check_empty_result(const Interval<Boundary, Info>& x, I_Result r) {
00184 if (Info::check_empty_result && f_is_empty(x))
00185 return I_EMPTY;
00186 else
00187 return static_cast<I_Result>(r | I_MAYBE_EMPTY);
00188 }
00189
00190 template <typename T1, typename T2>
00191 inline typename Enable_If<((Is_Singleton<T1>::value || Is_Interval<T1>::value)
00192 && (Is_Singleton<T2>::value || Is_Interval<T2>::value)
00193 && (Is_Interval<T1>::value || Is_Interval<T2>::value)),
00194 bool>::type
00195 operator==(const T1& x, const T2& y) {
00196 assert(f_OK(x));
00197 assert(f_OK(y));
00198 if (check_empty_arg(x))
00199 return check_empty_arg(y);
00200 else if (check_empty_arg(y))
00201 return false;
00202 return eq_restriction(f_info(x), f_info(y))
00203 && eq(LOWER, f_lower(x), f_info(x), LOWER, f_lower(y), f_info(y))
00204 && eq(UPPER, f_upper(x), f_info(x), UPPER, f_upper(y), f_info(y));
00205 }
00206
00207 template <typename T1, typename T2>
00208 inline typename Enable_If<((Is_Singleton<T1>::value || Is_Interval<T1>::value)
00209 && (Is_Singleton<T2>::value || Is_Interval<T2>::value)
00210 && (Is_Interval<T1>::value || Is_Interval<T2>::value)),
00211 bool>::type
00212 operator!=(const T1& x, const T2& y) {
00213 return !(x == y);
00214 }
00215
00216 template <typename Boundary, typename Info>
00217 template <typename T>
00218 inline typename Enable_If<Is_Singleton<T>::value || Is_Interval<T>::value, bool>::type
00219 Interval<Boundary, Info>::contains(const T& y) const {
00220 assert(OK());
00221 assert(f_OK(y));
00222 if (check_empty_arg(y))
00223 return true;
00224 if (check_empty_arg(*this))
00225 return false;
00226 if (!contains_restriction(info(), f_info(y)))
00227 return false;
00228 return le(LOWER, lower(), info(), LOWER, f_lower(y), f_info(y))
00229 && ge(UPPER, upper(), info(), UPPER, f_upper(y), f_info(y));
00230 }
00231
00232 template <typename Boundary, typename Info>
00233 template <typename T>
00234 inline typename Enable_If<Is_Singleton<T>::value || Is_Interval<T>::value, bool>::type
00235 Interval<Boundary, Info>::strictly_contains(const T& y) const {
00236 assert(OK());
00237 assert(f_OK(y));
00238 if (check_empty_arg(y))
00239 return !check_empty_arg(*this);
00240 if (check_empty_arg(*this))
00241 return false;
00242 if (!contains_restriction(info(), f_info(y)))
00243 return false;
00244 else if (!eq_restriction(*this, y))
00245 return le(LOWER, lower(), info(), LOWER, f_lower(y), f_info(y))
00246 && ge(UPPER, upper(), info(), UPPER, f_upper(y), f_info(y));
00247 return (lt(LOWER, lower(), info(), LOWER, f_lower(y), f_info(y))
00248 && ge(UPPER, upper(), info(), UPPER, f_upper(y), f_info(y)))
00249 || (le(LOWER, lower(), info(), LOWER, f_lower(y), f_info(y))
00250 && gt(UPPER, upper(), info(), UPPER, f_upper(y), f_info(y)));
00251 }
00252
00253 template <typename Boundary, typename Info>
00254 template <typename T>
00255 inline typename Enable_If<Is_Singleton<T>::value
00256 || Is_Interval<T>::value, bool>::type
00257 Interval<Boundary, Info>::is_disjoint_from(const T& y) const {
00258 assert(OK());
00259 assert(f_OK(y));
00260 if (check_empty_arg(*this) || check_empty_arg(y))
00261 return true;
00262
00263
00264
00265 return gt(LOWER, lower(), info(), UPPER, f_upper(y), f_info(y))
00266 || lt(UPPER, upper(), info(), LOWER, f_lower(y), f_info(y));
00267 }
00268
00269 template <typename To_Boundary, typename To_Info>
00270 template <typename From1, typename From2>
00271 inline I_Result
00272 Interval<To_Boundary, To_Info>::assign(const From1& l, const From2& u) {
00273 info().clear();
00274 Result rl = Boundary_NS::assign(LOWER, lower(), info(), LOWER, l, f_info(l));
00275 Result ru = Boundary_NS::assign(UPPER, upper(), info(), UPPER, u, f_info(u));
00276 complete_init_internal();
00277 assert(OK());
00278
00279
00280 return Parma_Polyhedra_Library::check_empty_result(*this, combine(rl, ru));
00281 }
00282
00283 template <typename To_Boundary, typename To_Info>
00284 template <typename From>
00285 inline typename Enable_If<Is_Singleton<From>::value
00286 || Is_Interval<From>::value, I_Result>::type
00287 Interval<To_Boundary, To_Info>::assign(const From& x) {
00288 assert(f_OK(x));
00289 if (check_empty_arg(x))
00290 return assign(EMPTY);
00291 DIRTY_TEMP(To_Info, to_info);
00292 to_info.clear();
00293 if (!assign_restriction(to_info, x))
00294 return assign(EMPTY);
00295 Result rl = Boundary_NS::assign(LOWER, lower(), to_info,
00296 LOWER, f_lower(x), f_info(x));
00297 Result ru = Boundary_NS::assign(UPPER, upper(), to_info,
00298 UPPER, f_upper(x), f_info(x));
00299 assign_or_swap(info(), to_info);
00300 complete_init_internal();
00301 assert(OK());
00302 return combine(rl, ru);
00303 }
00304
00305 template <typename To_Boundary, typename To_Info>
00306 template <typename From>
00307 inline typename Enable_If<Is_Singleton<From>::value
00308 || Is_Interval<From>::value, I_Result>::type
00309 Interval<To_Boundary, To_Info>::join_assign(const From& x) {
00310 assert(f_OK(x));
00311 if (check_empty_arg(*this))
00312 return assign(x);
00313 if (check_empty_arg(x))
00314 return combine(V_EQ, V_EQ);
00315 if (!join_restriction(info(), *this, x))
00316 return assign(EMPTY);
00317 info().set_interval_property(CARDINALITY_IS, false);
00318 info().set_interval_property(CARDINALITY_0);
00319 info().set_interval_property(CARDINALITY_1, false);
00320 Result rl, ru;
00321 rl = min_assign(LOWER, lower(), info(), LOWER, f_lower(x), f_info(x));
00322 ru = max_assign(UPPER, upper(), info(), UPPER, f_upper(x), f_info(x));
00323 assert(OK());
00324 return combine(rl, ru);
00325 }
00326
00327 template <typename To_Boundary, typename To_Info>
00328 template <typename From1, typename From2>
00329 inline typename Enable_If<((Is_Singleton<From1>::value
00330 || Is_Interval<From1>::value)
00331 && (Is_Singleton<From2>::value
00332 || Is_Interval<From2>::value)), I_Result>::type
00333 Interval<To_Boundary, To_Info>::join_assign(const From1& x, const From2& y) {
00334 assert(f_OK(x));
00335 assert(f_OK(y));
00336 if (check_empty_arg(x))
00337 return assign(y);
00338 if (check_empty_arg(y))
00339 return assign(x);
00340 DIRTY_TEMP(To_Info, to_info);
00341 to_info.clear();
00342 if (!join_restriction(to_info, x, y))
00343 return assign(EMPTY);
00344 to_info.set_interval_property(CARDINALITY_0);
00345 Result rl, ru;
00346 rl = min_assign(LOWER, lower(), to_info,
00347 LOWER, f_lower(x), f_info(x),
00348 LOWER, f_lower(y), f_info(y));
00349 ru = max_assign(UPPER, upper(), to_info,
00350 UPPER, f_upper(x), f_info(x),
00351 UPPER, f_upper(y), f_info(y));
00352 assign_or_swap(info(), to_info);
00353 complete_init_internal();
00354 assert(OK());
00355 return combine(rl, ru);
00356 }
00357
00358 template <typename To_Boundary, typename To_Info>
00359 template <typename From>
00360 inline typename Enable_If<Is_Singleton<From>::value
00361 || Is_Interval<From>::value, I_Result>::type
00362 Interval<To_Boundary, To_Info>::intersect_assign(const From& x) {
00363 assert(f_OK(x));
00364 if (!intersect_restriction(info(), *this, x))
00365 return assign(EMPTY);
00366
00367 invalidate_cardinality_cache();
00368 Result rl, ru;
00369 rl = max_assign(LOWER, lower(), info(), LOWER, f_lower(x), f_info(x));
00370 ru = min_assign(UPPER, upper(), info(), UPPER, f_upper(x), f_info(x));
00371 assert(OK());
00372
00373
00374 return Parma_Polyhedra_Library::check_empty_result(*this, combine(rl, ru));
00375 }
00376
00377 template <typename To_Boundary, typename To_Info>
00378 template <typename From1, typename From2>
00379 inline typename Enable_If<((Is_Singleton<From1>::value
00380 || Is_Interval<From1>::value)
00381 && (Is_Singleton<From2>::value
00382 || Is_Interval<From2>::value)), I_Result>::type
00383 Interval<To_Boundary, To_Info>::intersect_assign(const From1& x,
00384 const From2& y) {
00385 assert(f_OK(x));
00386 assert(f_OK(y));
00387 DIRTY_TEMP(To_Info, to_info);
00388 to_info.clear();
00389 if (!intersect_restriction(to_info, x, y))
00390 return assign(EMPTY);
00391 Result rl, ru;
00392 rl = max_assign(LOWER, lower(), to_info,
00393 LOWER, f_lower(x), f_info(x),
00394 LOWER, f_lower(y), f_info(y));
00395 ru = min_assign(UPPER, upper(), to_info,
00396 UPPER, f_upper(x), f_info(x),
00397 UPPER, f_upper(y), f_info(y));
00398 assign_or_swap(info(), to_info);
00399 complete_init_internal();
00400 assert(OK());
00401
00402
00403 return Parma_Polyhedra_Library::check_empty_result(*this, combine(rl, ru));
00404 }
00405
00406 template <typename To_Boundary, typename To_Info>
00407 template <typename From>
00408 inline typename Enable_If<Is_Singleton<From>::value
00409 || Is_Interval<From>::value, I_Result>::type
00410 Interval<To_Boundary, To_Info>::difference_assign(const From& x) {
00411 assert(f_OK(x));
00412
00413 if (lt(UPPER, upper(), info(), LOWER, f_lower(x), f_info(x)) ||
00414 gt(LOWER, lower(), info(), UPPER, f_upper(x), f_info(x)))
00415 return combine(V_EQ, V_EQ);
00416 bool nl = ge(LOWER, lower(), info(), LOWER, f_lower(x), f_info(x));
00417 bool nu = le(UPPER, upper(), info(), UPPER, f_upper(x), f_info(x));
00418 Result rl = V_EQ, ru = V_EQ;
00419 if (nl) {
00420 if (nu)
00421 return assign(EMPTY);
00422 else {
00423 invalidate_cardinality_cache();
00424 info().clear_boundary_properties(LOWER);
00425 rl = complement(LOWER, lower(), info(), UPPER, f_upper(x), f_info(x));
00426 }
00427 }
00428 else if (nu) {
00429 invalidate_cardinality_cache();
00430 info().clear_boundary_properties(UPPER);
00431 ru = complement(UPPER, upper(), info(), LOWER, f_lower(x), f_info(x));
00432 }
00433 assert(OK());
00434 return combine(rl, ru);
00435 }
00436
00437 template <typename To_Boundary, typename To_Info>
00438 template <typename From1, typename From2>
00439 inline typename Enable_If<((Is_Singleton<From1>::value
00440 || Is_Interval<From1>::value)
00441 && (Is_Singleton<From2>::value
00442 || Is_Interval<From2>::value)), I_Result>::type
00443 Interval<To_Boundary, To_Info>::difference_assign(const From1& x,
00444 const From2& y) {
00445 assert(f_OK(x));
00446 assert(f_OK(y));
00447 DIRTY_TEMP(To_Info, to_info);
00448 to_info.clear();
00449
00450 if (lt(UPPER, f_upper(x), f_info(x), LOWER, f_lower(y), f_info(y)) ||
00451 gt(LOWER, f_lower(x), f_info(x), UPPER, f_upper(y), f_info(y)))
00452 return assign(x);
00453 bool nl = ge(LOWER, f_lower(x), f_info(x), LOWER, f_lower(y), f_info(y));
00454 bool nu = le(UPPER, f_upper(x), f_info(x), UPPER, f_upper(y), f_info(y));
00455 Result rl = V_EQ, ru = V_EQ;
00456 if (nl) {
00457 if (nu)
00458 return assign(EMPTY);
00459 else {
00460 rl = complement(LOWER, lower(), info(), UPPER, f_upper(y), f_info(y));
00461 ru = Boundary_NS::assign(UPPER, upper(), info(), UPPER, f_upper(x), f_info(x));
00462 }
00463 }
00464 else if (nu) {
00465 ru = complement(UPPER, upper(), info(), LOWER, f_lower(y), f_info(y));
00466 rl = Boundary_NS::assign(LOWER, lower(), info(), LOWER, f_lower(x), f_info(x));
00467 }
00468 assign_or_swap(info(), to_info);
00469 complete_init_internal();
00470 assert(OK());
00471 return combine(rl, ru);
00472 }
00473
00474 template <typename To_Boundary, typename To_Info>
00475 template <typename From>
00476 inline typename Enable_If<Is_Singleton<From>::value
00477 || Is_Interval<From>::value, I_Result>::type
00478 Interval<To_Boundary, To_Info>
00479 ::refine_existential(Relation_Symbol rel, const From& x) {
00480 assert(OK());
00481 assert(f_OK(x));
00482 if (check_empty_arg(x))
00483 return assign(EMPTY);
00484 switch (rel) {
00485 case LESS_THAN:
00486 {
00487 if (lt(UPPER, upper(), info(), UPPER, f_upper(x), f_info(x)))
00488 return combine(V_EQ, V_EQ);
00489 info().clear_boundary_properties(UPPER);
00490 Result ru = Boundary_NS::assign(UPPER, upper(), info(),
00491 UPPER, f_upper(x), f_info(x), true);
00492 invalidate_cardinality_cache();
00493 normalize();
00494
00495
00496 return Parma_Polyhedra_Library::check_empty_result(*this,
00497 combine(V_EQ, ru));
00498 }
00499 case LESS_OR_EQUAL:
00500 {
00501 if (le(UPPER, upper(), info(), UPPER, f_upper(x), f_info(x)))
00502 return combine(V_EQ, V_EQ);
00503 info().clear_boundary_properties(UPPER);
00504 Result ru = Boundary_NS::assign(UPPER, upper(), info(),
00505 UPPER, f_upper(x), f_info(x));
00506 invalidate_cardinality_cache();
00507 normalize();
00508
00509
00510 return Parma_Polyhedra_Library::check_empty_result(*this,
00511 combine(V_EQ, ru));
00512 }
00513 case GREATER_THAN:
00514 {
00515 if (gt(LOWER, lower(), info(), LOWER, f_lower(x), f_info(x)))
00516 return combine(V_EQ, V_EQ);
00517 info().clear_boundary_properties(LOWER);
00518 Result rl = Boundary_NS::assign(LOWER, lower(), info(),
00519 LOWER, f_lower(x), f_info(x), true);
00520 invalidate_cardinality_cache();
00521 normalize();
00522
00523
00524 return Parma_Polyhedra_Library::check_empty_result(*this,
00525 combine(rl, V_EQ));
00526 }
00527 case GREATER_OR_EQUAL:
00528 {
00529 if (ge(LOWER, lower(), info(), LOWER, f_lower(x), f_info(x)))
00530 return combine(V_EQ, V_EQ);
00531 info().clear_boundary_properties(LOWER);
00532 Result rl = Boundary_NS::assign(LOWER, lower(), info(),
00533 LOWER, f_lower(x), f_info(x));
00534 invalidate_cardinality_cache();
00535 normalize();
00536
00537
00538 return Parma_Polyhedra_Library::check_empty_result(*this,
00539 combine(rl, V_EQ));
00540 }
00541 case EQUAL:
00542 return intersect_assign(x);
00543 case NOT_EQUAL:
00544 {
00545 if (!f_is_singleton(x))
00546 return combine(V_EQ, V_EQ);
00547 if (check_empty_arg(*this))
00548 return I_EMPTY;
00549 if (eq(LOWER, lower(), info(), LOWER, f_lower(x), f_info(x)))
00550 lower_shrink();
00551 if (eq(UPPER, upper(), info(), UPPER, f_upper(x), f_info(x)))
00552 upper_shrink();
00553 invalidate_cardinality_cache();
00554 normalize();
00555
00556
00557 return Parma_Polyhedra_Library::check_empty_result(*this,
00558 combine(V_EQ, V_EQ));
00559 }
00560 default:
00561 assert(false);
00562 return I_EMPTY;
00563 }
00564 }
00565
00566 template <typename To_Boundary, typename To_Info>
00567 template <typename From>
00568 inline typename Enable_If<Is_Singleton<From>::value
00569 || Is_Interval<From>::value, I_Result>::type
00570 Interval<To_Boundary, To_Info>::refine_universal(Relation_Symbol rel,
00571 const From& x) {
00572 assert(OK());
00573 assert(f_OK(x));
00574 if (check_empty_arg(x))
00575 return combine(V_EQ, V_EQ);
00576 switch (rel) {
00577 case LESS_THAN:
00578 {
00579 if (lt(UPPER, upper(), info(), LOWER, f_lower(x), f_info(x)))
00580 return combine(V_EQ, V_EQ);
00581 info().clear_boundary_properties(UPPER);
00582 Result ru = Boundary_NS::assign(UPPER, upper(), info(),
00583 LOWER, f_lower(x), SCALAR_INFO, !is_open(LOWER, f_lower(x), f_info(x)));
00584 invalidate_cardinality_cache();
00585 normalize();
00586
00587
00588 return Parma_Polyhedra_Library::check_empty_result(*this,
00589 combine(V_EQ, ru));
00590 }
00591 case LESS_OR_EQUAL:
00592 {
00593 if (le(UPPER, upper(), info(), LOWER, f_lower(x), f_info(x)))
00594 return combine(V_EQ, V_EQ);
00595 info().clear_boundary_properties(UPPER);
00596 Result ru = Boundary_NS::assign(UPPER, upper(), info(),
00597 LOWER, f_lower(x), SCALAR_INFO);
00598 invalidate_cardinality_cache();
00599 normalize();
00600
00601
00602 return Parma_Polyhedra_Library::check_empty_result(*this,
00603 combine(V_EQ, ru));
00604 }
00605 case GREATER_THAN:
00606 {
00607 if (gt(LOWER, lower(), info(), UPPER, f_upper(x), f_info(x)))
00608 return combine(V_EQ, V_EQ);
00609 info().clear_boundary_properties(LOWER);
00610 Result rl = Boundary_NS::assign(LOWER, lower(), info(),
00611 UPPER, f_upper(x), SCALAR_INFO, !is_open(UPPER, f_upper(x), f_info(x)));
00612 invalidate_cardinality_cache();
00613 normalize();
00614
00615
00616 return Parma_Polyhedra_Library::check_empty_result(*this,
00617 combine(rl, V_EQ));
00618 }
00619 case GREATER_OR_EQUAL:
00620 {
00621 if (ge(LOWER, lower(), info(), UPPER, f_upper(x), f_info(x)))
00622 return combine(V_EQ, V_EQ);
00623 info().clear_boundary_properties(LOWER);
00624 Result rl = Boundary_NS::assign(LOWER, lower(), info(),
00625 UPPER, f_upper(x), SCALAR_INFO);
00626 invalidate_cardinality_cache();
00627 normalize();
00628
00629
00630 return Parma_Polyhedra_Library::check_empty_result(*this,
00631 combine(rl, V_EQ));
00632 }
00633 case EQUAL:
00634 if (!f_is_singleton(x))
00635 return assign(EMPTY);
00636 return intersect_assign(x);
00637 case NOT_EQUAL:
00638 {
00639 if (check_empty_arg(*this))
00640 return I_EMPTY;
00641 if (eq(LOWER, lower(), info(), LOWER, f_lower(x), f_info(x)))
00642 lower_shrink();
00643 if (eq(UPPER, upper(), info(), UPPER, f_upper(x), f_info(x)))
00644 upper_shrink();
00645 invalidate_cardinality_cache();
00646 normalize();
00647
00648
00649 return Parma_Polyhedra_Library::check_empty_result(*this,
00650 combine(V_EQ, V_EQ));
00651 }
00652 default:
00653 assert(false);
00654 return I_EMPTY;
00655 }
00656 }
00657
00658 template <typename To_Boundary, typename To_Info>
00659 template <typename From>
00660 inline typename Enable_If<Is_Singleton<From>::value
00661 || Is_Interval<From>::value, I_Result>::type
00662 Interval<To_Boundary, To_Info>::neg_assign(const From& x) {
00663 assert(f_OK(x));
00664 if (check_empty_arg(x))
00665 return assign(EMPTY);
00666 DIRTY_TEMP(To_Info, to_info);
00667 to_info.clear();
00668 if (!neg_restriction(to_info, x))
00669 return assign(EMPTY);
00670 Result rl, ru;
00671 DIRTY_TEMP(To_Boundary, to_lower);
00672 rl = Boundary_NS::neg_assign(LOWER, to_lower, to_info, UPPER, f_upper(x), f_info(x));
00673 ru = Boundary_NS::neg_assign(UPPER, upper(), to_info, LOWER, f_lower(x), f_info(x));
00674 assign_or_swap(lower(), to_lower);
00675 assign_or_swap(info(), to_info);
00676 complete_init_internal();
00677 assert(OK());
00678 return combine(rl, ru);
00679 }
00680
00681 template <typename To_Boundary, typename To_Info>
00682 template <typename From1, typename From2>
00683 inline typename Enable_If<((Is_Singleton<From1>::value
00684 || Is_Interval<From1>::value)
00685 && (Is_Singleton<From2>::value
00686 || Is_Interval<From2>::value)), I_Result>::type
00687 Interval<To_Boundary, To_Info>::add_assign(const From1& x, const From2& y) {
00688 assert(f_OK(x));
00689 assert(f_OK(y));
00690 if (check_empty_arg(x) || check_empty_arg(y))
00691 return assign(EMPTY);
00692 int inf = Parma_Polyhedra_Library::is_infinity(x);
00693 if (inf) {
00694 if (Parma_Polyhedra_Library::is_infinity(y) == -inf)
00695 return assign(EMPTY);
00696 }
00697 else
00698 inf = Parma_Polyhedra_Library::is_infinity(y);
00699 if (inf < 0)
00700 return assign(MINUS_INFINITY);
00701 else if (inf > 0)
00702 return assign(PLUS_INFINITY);
00703 DIRTY_TEMP(To_Info, to_info);
00704 to_info.clear();
00705 if (!add_restriction(to_info, x, y))
00706 return assign(EMPTY);
00707 Result rl = Boundary_NS::add_assign(LOWER, lower(), to_info,
00708 LOWER, f_lower(x), f_info(x),
00709 LOWER, f_lower(y), f_info(y));
00710 Result ru = Boundary_NS::add_assign(UPPER, upper(), to_info,
00711 UPPER, f_upper(x), f_info(x),
00712 UPPER, f_upper(y), f_info(y));
00713 assign_or_swap(info(), to_info);
00714 complete_init_internal();
00715 assert(OK());
00716 return combine(rl, ru);
00717 }
00718
00719 template <typename To_Boundary, typename To_Info>
00720 template <typename From1, typename From2>
00721 inline typename Enable_If<((Is_Singleton<From1>::value
00722 || Is_Interval<From1>::value)
00723 && (Is_Singleton<From2>::value
00724 || Is_Interval<From2>::value)), I_Result>::type
00725 Interval<To_Boundary, To_Info>::sub_assign(const From1& x, const From2& y) {
00726 assert(f_OK(x));
00727 assert(f_OK(y));
00728 if (check_empty_arg(x) || check_empty_arg(y))
00729 return assign(EMPTY);
00730 int inf = Parma_Polyhedra_Library::is_infinity(x);
00731 if (inf) {
00732 if (Parma_Polyhedra_Library::is_infinity(y) == inf)
00733 return assign(EMPTY);
00734 }
00735 else
00736 inf = -Parma_Polyhedra_Library::is_infinity(y);
00737 if (inf < 0)
00738 return assign(MINUS_INFINITY);
00739 else if (inf > 0)
00740 return assign(PLUS_INFINITY);
00741
00742 DIRTY_TEMP(To_Info, to_info);
00743 to_info.clear();
00744 if (!sub_restriction(to_info, x, y))
00745 return assign(EMPTY);
00746 Result rl, ru;
00747 DIRTY_TEMP(To_Boundary, to_lower);
00748 rl = Boundary_NS::sub_assign(LOWER, to_lower, to_info,
00749 LOWER, f_lower(x), f_info(x),
00750 UPPER, f_upper(y), f_info(y));
00751 ru = Boundary_NS::sub_assign(UPPER, upper(), to_info,
00752 UPPER, f_upper(x), f_info(x),
00753 LOWER, f_lower(y), f_info(y));
00754 assign_or_swap(lower(), to_lower);
00755 assign_or_swap(info(), to_info);
00756 complete_init_internal();
00757 assert(OK());
00758 return combine(rl, ru);
00759 }
00760
00773 template <typename To_Boundary, typename To_Info>
00774 template <typename From1, typename From2>
00775 inline typename Enable_If<((Is_Singleton<From1>::value
00776 || Is_Interval<From1>::value)
00777 && (Is_Singleton<From2>::value
00778 || Is_Interval<From2>::value)), I_Result>::type
00779 Interval<To_Boundary, To_Info>::mul_assign(const From1& x, const From2& y) {
00780 assert(f_OK(x));
00781 assert(f_OK(y));
00782 if (check_empty_arg(x) || check_empty_arg(y))
00783 return assign(EMPTY);
00784 int xls = sgn_b(LOWER, f_lower(x), f_info(x));
00785 int xus = xls > 0 ? 1 : sgn_b(UPPER, f_upper(x), f_info(x));
00786 int yls = sgn_b(LOWER, f_lower(y), f_info(y));
00787 int yus = yls > 0 ? 1 : sgn_b(UPPER, f_upper(y), f_info(y));
00788 int inf = Parma_Polyhedra_Library::is_infinity(x);
00789 int ls, us;
00790 if (inf) {
00791 ls = yls;
00792 us = yus;
00793 goto inf;
00794 }
00795 else {
00796 inf = Parma_Polyhedra_Library::is_infinity(y);
00797 if (inf) {
00798 ls = xls;
00799 us = xus;
00800 inf:
00801 if (ls == 0 && us == 0)
00802 return assign(EMPTY);
00803 if (ls == -us)
00804 return set_infinities();
00805 if (ls < 0 || us < 0)
00806 inf = -inf;
00807 if (inf < 0)
00808 return assign(MINUS_INFINITY);
00809 else
00810 return assign(PLUS_INFINITY);
00811 }
00812 }
00813
00814 DIRTY_TEMP(To_Info, to_info);
00815 to_info.clear();
00816 if (!mul_restriction(to_info, x, y))
00817 return assign(EMPTY);
00818 Result rl, ru;
00819 DIRTY_TEMP(To_Boundary, to_lower);
00820
00821 if (xls >= 0) {
00822 if (yls >= 0) {
00823
00824 rl = mul_assign_z(LOWER, to_lower, to_info,
00825 LOWER, f_lower(x), f_info(x), xls,
00826 LOWER, f_lower(y), f_info(y), yls);
00827 ru = mul_assign_z(UPPER, upper(), to_info,
00828 UPPER, f_upper(x), f_info(x), xus,
00829 UPPER, f_upper(y), f_info(y), yus);
00830 }
00831 else if (yus <= 0) {
00832
00833 rl = mul_assign_z(LOWER, to_lower, to_info,
00834 UPPER, f_upper(x), f_info(x), xus,
00835 LOWER, f_lower(y), f_info(y), yls);
00836 ru = mul_assign_z(UPPER, upper(), to_info,
00837 LOWER, f_lower(x), f_info(x), xls,
00838 UPPER, f_upper(y), f_info(y), yus);
00839 }
00840 else {
00841
00842 rl = mul_assign_z(LOWER, to_lower, to_info,
00843 UPPER, f_upper(x), f_info(x), xus,
00844 LOWER, f_lower(y), f_info(y), yls);
00845 ru = mul_assign_z(UPPER, upper(), to_info,
00846 UPPER, f_upper(x), f_info(x), xus,
00847 UPPER, f_upper(y), f_info(y), yus);
00848 }
00849 }
00850 else if (xus <= 0) {
00851 if (yls >= 0) {
00852
00853 rl = mul_assign_z(LOWER, to_lower, to_info,
00854 LOWER, f_lower(x), f_info(x), xls,
00855 UPPER, f_upper(y), f_info(y), yus);
00856 ru = mul_assign_z(UPPER, upper(), to_info,
00857 UPPER, f_upper(x), f_info(x), xus,
00858 LOWER, f_lower(y), f_info(y), yls);
00859 }
00860 else if (yus <= 0) {
00861
00862 rl = mul_assign_z(LOWER, to_lower, to_info,
00863 UPPER, f_upper(x), f_info(x), xus,
00864 UPPER, f_upper(y), f_info(y), yus);
00865 ru = mul_assign_z(UPPER, upper(), to_info,
00866 LOWER, f_lower(x), f_info(x), xls,
00867 LOWER, f_lower(y), f_info(y), yls);
00868 }
00869 else {
00870
00871 rl = mul_assign_z(LOWER, to_lower, to_info,
00872 LOWER, f_lower(x), f_info(x), xls,
00873 UPPER, f_upper(y), f_info(y), yus);
00874 ru = mul_assign_z(UPPER, upper(), to_info,
00875 LOWER, f_lower(x), f_info(x), xls,
00876 LOWER, f_lower(y), f_info(y), yls);
00877 }
00878 }
00879 else if (yls >= 0) {
00880
00881 rl = mul_assign_z(LOWER, to_lower, to_info,
00882 LOWER, f_lower(x), f_info(x), xls,
00883 UPPER, f_upper(y), f_info(y), yus);
00884 ru = mul_assign_z(UPPER, upper(), to_info,
00885 UPPER, f_upper(x), f_info(x), xus,
00886 UPPER, f_upper(y), f_info(y), yus);
00887 }
00888 else if (yus <= 0) {
00889
00890 rl = mul_assign_z(LOWER, to_lower, to_info,
00891 UPPER, f_upper(x), f_info(x), xus,
00892 LOWER, f_lower(y), f_info(y), yls);
00893 ru = mul_assign_z(UPPER, upper(), to_info,
00894 LOWER, f_lower(x), f_info(x), xls,
00895 LOWER, f_lower(y), f_info(y), yls);
00896 }
00897 else {
00898
00899 DIRTY_TEMP(To_Boundary, tmp);
00900 DIRTY_TEMP(To_Info, tmp_info);
00901 tmp_info.clear();
00902 Result tmp_r;
00903 tmp_r = Boundary_NS::mul_assign(LOWER, tmp, tmp_info,
00904 UPPER, f_upper(x), f_info(x),
00905 LOWER, f_lower(y), f_info(y));
00906 rl = Boundary_NS::mul_assign(LOWER, to_lower, to_info,
00907 LOWER, f_lower(x), f_info(x),
00908 UPPER, f_upper(y), f_info(y));
00909 if (gt(LOWER, to_lower, to_info, LOWER, tmp, tmp_info)) {
00910 to_lower = tmp;
00911 rl = tmp_r;
00912 }
00913 tmp_info.clear();
00914 tmp_r = Boundary_NS::mul_assign(UPPER, tmp, tmp_info,
00915 UPPER, f_upper(x), f_info(x),
00916 UPPER, f_upper(y), f_info(y));
00917 ru = Boundary_NS::mul_assign(UPPER, upper(), to_info,
00918 LOWER, f_lower(x), f_info(x),
00919 LOWER, f_lower(y), f_info(y));
00920 if (lt(UPPER, upper(), to_info, UPPER, tmp, tmp_info)) {
00921 upper() = tmp;
00922 ru = tmp_r;
00923 }
00924 }
00925 assign_or_swap(lower(), to_lower);
00926 assign_or_swap(info(), to_info);
00927 complete_init_internal();
00928 assert(OK());
00929 return combine(rl, ru);
00930 }
00931
00943 template <typename To_Boundary, typename To_Info>
00944 template <typename From1, typename From2>
00945 inline typename Enable_If<((Is_Singleton<From1>::value
00946 || Is_Interval<From1>::value)
00947 && (Is_Singleton<From2>::value
00948 || Is_Interval<From2>::value)), I_Result>::type
00949 Interval<To_Boundary, To_Info>::div_assign(const From1& x, const From2& y) {
00950 assert(f_OK(x));
00951 assert(f_OK(y));
00952 if (check_empty_arg(x) || check_empty_arg(y))
00953 return assign(EMPTY);
00954 int yls = sgn_b(LOWER, f_lower(y), f_info(y));
00955 int yus = yls > 0 ? 1 : sgn_b(UPPER, f_upper(y), f_info(y));
00956 if (yls == 0 && yus == 0)
00957 return assign(EMPTY);
00958 int inf = Parma_Polyhedra_Library::is_infinity(x);
00959 if (inf) {
00960 if (Parma_Polyhedra_Library::is_infinity(y))
00961 return assign(EMPTY);
00962 if (yls == -yus)
00963 return set_infinities();
00964 if (yls < 0 || yus < 0)
00965 inf = -inf;
00966 if (inf < 0)
00967 return assign(MINUS_INFINITY);
00968 else
00969 return assign(PLUS_INFINITY);
00970 }
00971 int xls = sgn_b(LOWER, f_lower(x), f_info(x));
00972 int xus = xls > 0 ? 1 : sgn_b(UPPER, f_upper(x), f_info(x));
00973
00974 DIRTY_TEMP(To_Info, to_info);
00975 to_info.clear();
00976 if (!div_restriction(to_info, x, y))
00977 return assign(EMPTY);
00978 Result rl, ru;
00979 DIRTY_TEMP(To_Boundary, to_lower);
00980 if (yls >= 0) {
00981 if (xls >= 0) {
00982 rl = div_assign_z(LOWER, to_lower, to_info,
00983 LOWER, f_lower(x), f_info(x), xls,
00984 UPPER, f_upper(y), f_info(y), yus);
00985 ru = div_assign_z(UPPER, upper(), to_info,
00986 UPPER, f_upper(x), f_info(x), xus,
00987 LOWER, f_lower(y), f_info(y), yls);
00988 }
00989 else if (xus <= 0) {
00990 rl = div_assign_z(LOWER, to_lower, to_info,
00991 LOWER, f_lower(x), f_info(x), xls,
00992 LOWER, f_lower(y), f_info(y), yls);
00993 ru = div_assign_z(UPPER, upper(), to_info,
00994 UPPER, f_upper(x), f_info(x), xus,
00995 UPPER, f_upper(y), f_info(y), yus);
00996 }
00997 else {
00998 rl = div_assign_z(LOWER, to_lower, to_info,
00999 LOWER, f_lower(x), f_info(x), xls,
01000 LOWER, f_lower(y), f_info(y), yls);
01001 ru = div_assign_z(UPPER, upper(), to_info,
01002 UPPER, f_upper(x), f_info(x), xus,
01003 LOWER, f_lower(y), f_info(y), yls);
01004 }
01005 }
01006 else if (yus <= 0) {
01007 if (xls >= 0) {
01008 rl = div_assign_z(LOWER, to_lower, to_info,
01009 UPPER, f_upper(x), f_info(x), xus,
01010 UPPER, f_upper(y), f_info(y), yus);
01011 ru = div_assign_z(UPPER, upper(), to_info,
01012 LOWER, f_lower(x), f_info(x), xls,
01013 LOWER, f_lower(y), f_info(y), yls);
01014 }
01015 else if (xus <= 0) {
01016 rl = div_assign_z(LOWER, to_lower, to_info,
01017 UPPER, f_upper(x), f_info(x), xus,
01018 LOWER, f_lower(y), f_info(y), yls);
01019 ru = div_assign_z(UPPER, upper(), to_info,
01020 LOWER, f_lower(x), f_info(x), xls,
01021 UPPER, f_upper(y), f_info(y), yus);
01022 }
01023 else {
01024 rl = div_assign_z(LOWER, to_lower, to_info,
01025 UPPER, f_upper(x), f_info(x), xus,
01026 UPPER, f_upper(y), f_info(y), yus);
01027 ru = div_assign_z(UPPER, upper(), to_info,
01028 LOWER, f_lower(x), f_info(x), xls,
01029 UPPER, f_upper(y), f_info(y), yus);
01030 }
01031 }
01032 else {
01033
01034 return static_cast<I_Result>(assign(UNIVERSE) | I_SINGULARITIES);
01035 }
01036 assign_or_swap(lower(), to_lower);
01037 assign_or_swap(info(), to_info);
01038 complete_init_internal();
01039 assert(OK());
01040 return combine(rl, ru);
01041 }
01042
01043 template <typename B, typename Info, typename T>
01044 inline typename Enable_If<Is_Singleton<T>::value, Interval<B, Info> >::type
01045 operator+(const Interval<B, Info>& x, const T& y) {
01046 Interval<B, Info> z;
01047 z.add_assign(x, y);
01048 return z;
01049 }
01050
01051 template <typename B, typename Info, typename T>
01052 inline typename Enable_If<Is_Singleton<T>::value, Interval<B, Info> >::type
01053 operator+(const T& x, const Interval<B, Info>& y) {
01054 Interval<B, Info> z;
01055 z.add_assign(x, y);
01056 return z;
01057 }
01058
01059 template <typename B, typename Info>
01060 inline Interval<B, Info>
01061 operator+(const Interval<B, Info>& x, const Interval<B, Info>& y) {
01062 Interval<B, Info> z;
01063 z.add_assign(x, y);
01064 return z;
01065 }
01066
01067 template <typename B, typename Info, typename T>
01068 inline typename Enable_If<Is_Singleton<T>::value, Interval<B, Info> >::type
01069 operator-(const Interval<B, Info>& x, const T& y) {
01070 Interval<B, Info> z;
01071 z.sub_assign(x, y);
01072 return z;
01073 }
01074
01075 template <typename B, typename Info, typename T>
01076 inline typename Enable_If<Is_Singleton<T>::value, Interval<B, Info> >::type
01077 operator-(const T& x, const Interval<B, Info>& y) {
01078 Interval<B, Info> z;
01079 z.sub_assign(x, y);
01080 return z;
01081 }
01082
01083 template <typename B, typename Info>
01084 inline Interval<B, Info>
01085 operator-(const Interval<B, Info>& x, const Interval<B, Info>& y) {
01086 Interval<B, Info> z;
01087 z.sub_assign(x, y);
01088 return z;
01089 }
01090
01091 template <typename B, typename Info, typename T>
01092 inline typename Enable_If<Is_Singleton<T>::value, Interval<B, Info> >::type
01093 operator*(const Interval<B, Info>& x, const T& y) {
01094 Interval<B, Info> z;
01095 z.mul_assign(x, y);
01096 return z;
01097 }
01098
01099 template <typename B, typename Info, typename T>
01100 inline typename Enable_If<Is_Singleton<T>::value, Interval<B, Info> >::type
01101 operator*(const T& x, const Interval<B, Info>& y) {
01102 Interval<B, Info> z;
01103 z.mul_assign(x, y);
01104 return z;
01105 }
01106
01107 template <typename B, typename Info>
01108 inline Interval<B, Info>
01109 operator*(const Interval<B, Info>& x, const Interval<B, Info>& y) {
01110 Interval<B, Info> z;
01111 z.mul_assign(x, y);
01112 return z;
01113 }
01114
01115 template <typename B, typename Info, typename T>
01116 inline typename Enable_If<Is_Singleton<T>::value, Interval<B, Info> >::type
01117 operator/(const Interval<B, Info>& x, const T& y) {
01118 Interval<B, Info> z;
01119 z.div_assign(x, y);
01120 return z;
01121 }
01122
01123 template <typename B, typename Info, typename T>
01124 inline typename Enable_If<Is_Singleton<T>::value, Interval<B, Info> >::type
01125 operator/(const T& x, const Interval<B, Info>& y) {
01126 Interval<B, Info> z;
01127 z.div_assign(x, y);
01128 return z;
01129 }
01130
01131 template <typename B, typename Info>
01132 inline Interval<B, Info>
01133 operator/(const Interval<B, Info>& x, const Interval<B, Info>& y) {
01134 Interval<B, Info> z;
01135 z.div_assign(x, y);
01136 return z;
01137 }
01138
01139 template <typename Boundary, typename Info>
01140 inline std::ostream&
01141 operator<<(std::ostream& os, const Interval<Boundary, Info>& x) {
01142
01143 if (check_empty_arg(x))
01144 return os << "[]";
01145 if (x.is_singleton()) {
01146 output(os, x.lower(), Numeric_Format(), ROUND_NOT_NEEDED);
01147 return os;
01148 }
01149 os << (x.lower_is_open() ? "(" : "[");
01150 if (x.info().get_boundary_property(LOWER, SPECIAL))
01151 os << "-inf";
01152 else
01153 output(os, x.lower(), Numeric_Format(), ROUND_NOT_NEEDED);
01154 os << ", ";
01155 if (x.info().get_boundary_property(UPPER, SPECIAL))
01156 os << "+inf";
01157 else
01158 output(os, x.upper(), Numeric_Format(), ROUND_NOT_NEEDED);
01159 os << (x.upper_is_open() ? ")" : "]");
01160 output_restriction(os, x.info());
01161 return os;
01162 }
01163
01164 template <typename Boundary, typename Info>
01165 inline void
01166 Interval<Boundary, Info>::ascii_dump(std::ostream& s) const {
01167 using Parma_Polyhedra_Library::ascii_dump;
01168 s << "info ";
01169 info().ascii_dump(s);
01170 s << " lower ";
01171 ascii_dump(s, lower());
01172 s << " upper ";
01173 ascii_dump(s, upper());
01174 s << '\n';
01175 }
01176
01177 template <typename Boundary, typename Info>
01178 inline bool
01179 Interval<Boundary, Info>::ascii_load(std::istream& s) {
01180 using Parma_Polyhedra_Library::ascii_load;
01181 std::string str;
01182 if (!(s >> str) || str != "info")
01183 return false;
01184 if (!info().ascii_load(s))
01185 return false;
01186 if (!(s >> str) || str != "lower")
01187 return false;
01188 if (!ascii_load(s, lower()))
01189 return false;
01190 if (!(s >> str) || str != "upper")
01191 return false;
01192 if (!ascii_load(s, upper()))
01193 return false;
01194 #ifdef PPL_ABI_BREAKING_EXTRA_DEBUG
01195 complete_init_internal();
01196 #endif
01197 assert(OK());
01198 return true;
01199 }
01200
01206 template <typename Interval_Boundary_Type> struct Select_Temp_Boundary_Type;
01207
01208 template <typename Interval_Boundary_Type>
01209 struct Select_Temp_Boundary_Type {
01210 typedef Interval_Boundary_Type type;
01211 };
01212
01213 template <>
01214 struct Select_Temp_Boundary_Type<float> {
01215 typedef double type;
01216 };
01217
01218 template <>
01219 struct Select_Temp_Boundary_Type<signed char> {
01220 typedef signed long long type;
01221 };
01222
01223 template <>
01224 struct Select_Temp_Boundary_Type<unsigned char> {
01225 typedef signed long long type;
01226 };
01227
01228 template <>
01229 struct Select_Temp_Boundary_Type<signed short> {
01230 typedef signed long long type;
01231 };
01232
01233 template <>
01234 struct Select_Temp_Boundary_Type<unsigned short> {
01235 typedef signed long long type;
01236 };
01237
01238 template <>
01239 struct Select_Temp_Boundary_Type<signed int> {
01240 typedef signed long long type;
01241 };
01242
01243 template <>
01244 struct Select_Temp_Boundary_Type<unsigned int> {
01245 typedef signed long long type;
01246 };
01247
01248 template <>
01249 struct Select_Temp_Boundary_Type<signed long> {
01250 typedef signed long long type;
01251 };
01252
01253 template <>
01254 struct Select_Temp_Boundary_Type<unsigned long> {
01255 typedef signed long long type;
01256 };
01257
01258 template <>
01259 struct Select_Temp_Boundary_Type<unsigned long long> {
01260 typedef signed long long type;
01261 };
01262
01263 }
01264
01265 namespace std {
01266
01268 template <typename Boundary, typename Info>
01269 inline void
01270 swap(Parma_Polyhedra_Library::Interval<Boundary, Info>& x,
01271 Parma_Polyhedra_Library::Interval<Boundary, Info>& y) {
01272 x.swap(y);
01273 }
01274
01275 }
01276
01277 #endif // !defined(PPL_Interval_inlines_hh)