1 /* Inline functions for the Interval class and its constituents.
2 Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
3 Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com)
4
5 This file is part of the Parma Polyhedra Library (PPL).
6
7 The PPL is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11
12 The PPL is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
20
21 For the most up-to-date information see the Parma Polyhedra Library
22 site: http://bugseng.com/products/ppl/ . */
23
24 #ifndef PPL_Interval_inlines_hh
25 #define PPL_Interval_inlines_hh 1
26
27 namespace Parma_Polyhedra_Library {
28
29 template <typename Boundary, typename Info>
30 inline memory_size_type
external_memory_in_bytes() const31 Interval<Boundary, Info>::external_memory_in_bytes() const {
32 return Parma_Polyhedra_Library::external_memory_in_bytes(lower())
33 + Parma_Polyhedra_Library::external_memory_in_bytes(upper());
34 }
35
36 template <typename Boundary, typename Info>
37 inline memory_size_type
total_memory_in_bytes() const38 Interval<Boundary, Info>::total_memory_in_bytes() const {
39 return sizeof(*this) + external_memory_in_bytes();
40 }
41
42 template <typename Boundary, typename Info>
43 inline void
m_swap(Interval<Boundary,Info> & y)44 Interval<Boundary, Info>::m_swap(Interval<Boundary, Info>& y) {
45 using std::swap;
46 swap(lower(), y.lower());
47 swap(upper(), y.upper());
48 swap(info(), y.info());
49 }
50
51 template <typename Boundary, typename Info>
52 inline bool
f_is_empty(const Interval<Boundary,Info> & x)53 f_is_empty(const Interval<Boundary, Info>& x) {
54 return x.is_empty();
55 }
56 template <typename Boundary, typename Info>
57 inline bool
f_is_singleton(const Interval<Boundary,Info> & x)58 f_is_singleton(const Interval<Boundary, Info>& x) {
59 return x.is_singleton();
60 }
61 template <typename Boundary, typename Info>
62 inline int
infinity_sign(const Interval<Boundary,Info> & x)63 infinity_sign(const Interval<Boundary, Info>& x) {
64 return x.infinity_sign();
65 }
66
67 namespace Interval_NS {
68
69 template <typename Boundary, typename Info>
70 inline const Boundary&
f_lower(const Interval<Boundary,Info> & x)71 f_lower(const Interval<Boundary, Info>& x) {
72 return x.lower();
73 }
74 template <typename Boundary, typename Info>
75 inline const Boundary&
f_upper(const Interval<Boundary,Info> & x)76 f_upper(const Interval<Boundary, Info>& x) {
77 return x.upper();
78 }
79 template <typename Boundary, typename Info>
80 inline const Info&
f_info(const Interval<Boundary,Info> & x)81 f_info(const Interval<Boundary, Info>& x) {
82 return x.info();
83 }
84
85 struct Scalar_As_Interval_Policy {
86 const_bool_nodef(may_be_empty, true);
87 const_bool_nodef(may_contain_infinity, true);
88 const_bool_nodef(check_inexact, false);
89 };
90
91 typedef Interval_Info_Null<Scalar_As_Interval_Policy>
92 Scalar_As_Interval_Info;
93
94 const Scalar_As_Interval_Info SCALAR_INFO;
95
96 typedef Interval_Info_Null_Open<Scalar_As_Interval_Policy>
97 Scalar_As_Interval_Info_Open;
98
99 template <typename T>
100 inline typename Enable_If<Is_Singleton<T>::value, const T&>::type
f_lower(const T & x)101 f_lower(const T& x) {
102 return x;
103 }
104 template <typename T>
105 inline typename Enable_If<Is_Singleton<T>::value, const T&>::type
f_upper(const T & x)106 f_upper(const T& x) {
107 return x;
108 }
109 template <typename T>
110 inline typename Enable_If<Is_Singleton<T>::value,
111 const Scalar_As_Interval_Info&>::type
f_info(const T &)112 f_info(const T&) {
113 return SCALAR_INFO;
114 }
115 template <typename T>
116 inline typename Enable_If<Is_Singleton<T>::value,
117 Scalar_As_Interval_Info_Open>::type
f_info(const T &,bool open)118 f_info(const T&, bool open) {
119 return Scalar_As_Interval_Info_Open(open);
120 }
121
122 template <typename T>
123 inline typename Enable_If<Is_Singleton<T>::value, bool>::type
f_is_empty(const T & x)124 f_is_empty(const T& x) {
125 return is_not_a_number(x);
126 }
127
128 template <typename T>
129 inline typename Enable_If<Is_Singleton<T>::value, bool>::type
f_is_singleton(const T & x)130 f_is_singleton(const T& x) {
131 return !f_is_empty(x);
132 }
133
134 } // namespace Interval_NS
135
136 template <typename T>
137 inline typename Enable_If<Is_Singleton<T>::value
138 || Is_Interval<T>::value, bool>::type
is_singleton_integer(const T & x)139 is_singleton_integer(const T& x) {
140 return is_singleton(x) && is_integer(f_lower(x));
141 }
142
143 template <typename T>
144 inline typename Enable_If<Is_Singleton<T>::value
145 || Is_Interval<T>::value, bool>::type
check_empty_arg(const T & x)146 check_empty_arg(const T& x) {
147 if (f_info(x).may_be_empty) {
148 return f_is_empty(x);
149 }
150 else {
151 PPL_ASSERT(!f_is_empty(x));
152 return false;
153 }
154 }
155
156 template <typename T1, typename T2>
157 inline typename Enable_If<((Is_Singleton<T1>::value
158 || Is_Interval<T1>::value)
159 && (Is_Singleton<T2>::value
160 || Is_Interval<T2>::value)
161 && (Is_Interval<T1>::value
162 || Is_Interval<T2>::value)),
163 bool>::type
operator ==(const T1 & x,const T2 & y)164 operator==(const T1& x, const T2& y) {
165 PPL_ASSERT(f_OK(x));
166 PPL_ASSERT(f_OK(y));
167 if (check_empty_arg(x)) {
168 return check_empty_arg(y);
169 }
170 else if (check_empty_arg(y)) {
171 return false;
172 }
173 return eq(LOWER, f_lower(x), f_info(x), LOWER, f_lower(y), f_info(y))
174 && eq(UPPER, f_upper(x), f_info(x), UPPER, f_upper(y), f_info(y));
175 }
176
177 template <typename T1, typename T2>
178 inline typename Enable_If<((Is_Singleton<T1>::value
179 || Is_Interval<T1>::value)
180 && (Is_Singleton<T2>::value
181 || Is_Interval<T2>::value)
182 && (Is_Interval<T1>::value
183 || Is_Interval<T2>::value)),
184 bool>::type
operator !=(const T1 & x,const T2 & y)185 operator!=(const T1& x, const T2& y) {
186 return !(x == y);
187 }
188
189 template <typename Boundary, typename Info>
190 template <typename T>
191 inline typename Enable_If<Is_Singleton<T>::value
192 || Is_Interval<T>::value, bool>::type
contains(const T & y) const193 Interval<Boundary, Info>::contains(const T& y) const {
194 PPL_ASSERT(OK());
195 PPL_ASSERT(f_OK(y));
196 if (check_empty_arg(y)) {
197 return true;
198 }
199 if (check_empty_arg(*this)) {
200 return false;
201 }
202 return le(LOWER, lower(), info(), LOWER, f_lower(y), f_info(y))
203 && ge(UPPER, upper(), info(), UPPER, f_upper(y), f_info(y));
204 }
205
206 template <typename Boundary, typename Info>
207 template <typename T>
208 inline typename Enable_If<Is_Singleton<T>::value
209 || Is_Interval<T>::value, bool>::type
strictly_contains(const T & y) const210 Interval<Boundary, Info>::strictly_contains(const T& y) const {
211 PPL_ASSERT(OK());
212 PPL_ASSERT(f_OK(y));
213 if (check_empty_arg(y)) {
214 return !check_empty_arg(*this);
215 }
216 if (check_empty_arg(*this)) {
217 return false;
218 }
219 return (lt(LOWER, lower(), info(), LOWER, f_lower(y), f_info(y))
220 && ge(UPPER, upper(), info(), UPPER, f_upper(y), f_info(y)))
221 || (le(LOWER, lower(), info(), LOWER, f_lower(y), f_info(y))
222 && gt(UPPER, upper(), info(), UPPER, f_upper(y), f_info(y)));
223 }
224
225 template <typename Boundary, typename Info>
226 template <typename T>
227 inline typename Enable_If<Is_Singleton<T>::value
228 || Is_Interval<T>::value, bool>::type
is_disjoint_from(const T & y) const229 Interval<Boundary, Info>::is_disjoint_from(const T& y) const {
230 PPL_ASSERT(OK());
231 PPL_ASSERT(f_OK(y));
232 if (check_empty_arg(*this) || check_empty_arg(y)) {
233 return true;
234 }
235 return gt(LOWER, lower(), info(), UPPER, f_upper(y), f_info(y))
236 || lt(UPPER, upper(), info(), LOWER, f_lower(y), f_info(y));
237 }
238
239 template <typename To_Boundary, typename To_Info>
240 template <typename From>
241 inline typename Enable_If<Is_Singleton<From>::value
242 || Is_Interval<From>::value, I_Result>::type
assign(const From & x)243 Interval<To_Boundary, To_Info>::assign(const From& x) {
244 PPL_ASSERT(f_OK(x));
245 if (check_empty_arg(x)) {
246 return assign(EMPTY);
247 }
248 PPL_DIRTY_TEMP(To_Info, to_info);
249 to_info.clear();
250 const Result rl = Boundary_NS::assign(LOWER, lower(), to_info,
251 LOWER, f_lower(x), f_info(x));
252 const Result ru = Boundary_NS::assign(UPPER, upper(), to_info,
253 UPPER, f_upper(x), f_info(x));
254 assign_or_swap(info(), to_info);
255 PPL_ASSERT(OK());
256 return combine(rl, ru);
257 }
258
259 template <typename To_Boundary, typename To_Info>
260 template <typename From>
261 inline typename Enable_If<Is_Singleton<From>::value
262 || Is_Interval<From>::value, I_Result>::type
join_assign(const From & x)263 Interval<To_Boundary, To_Info>::join_assign(const From& x) {
264 PPL_ASSERT(f_OK(x));
265 if (check_empty_arg(*this)) {
266 return assign(x);
267 }
268 if (check_empty_arg(x)) {
269 return combine(V_EQ, V_EQ);
270 }
271 Result rl;
272 Result ru;
273 rl = min_assign(LOWER, lower(), info(), LOWER, f_lower(x), f_info(x));
274 ru = max_assign(UPPER, upper(), info(), UPPER, f_upper(x), f_info(x));
275 PPL_ASSERT(OK());
276 return combine(rl, ru);
277 }
278
279 template <typename To_Boundary, typename To_Info>
280 template <typename From1, typename From2>
281 inline typename Enable_If<((Is_Singleton<From1>::value
282 || Is_Interval<From1>::value)
283 && (Is_Singleton<From2>::value
284 || Is_Interval<From2>::value)), I_Result>::type
join_assign(const From1 & x,const From2 & y)285 Interval<To_Boundary, To_Info>::join_assign(const From1& x, const From2& y) {
286 PPL_ASSERT(f_OK(x));
287 PPL_ASSERT(f_OK(y));
288 if (check_empty_arg(x)) {
289 return assign(y);
290 }
291 if (check_empty_arg(y)) {
292 return assign(x);
293 }
294 PPL_DIRTY_TEMP(To_Info, to_info);
295 to_info.clear();
296 Result rl;
297 Result ru;
298 rl = min_assign(LOWER, lower(), to_info,
299 LOWER, f_lower(x), f_info(x),
300 LOWER, f_lower(y), f_info(y));
301 ru = max_assign(UPPER, upper(), to_info,
302 UPPER, f_upper(x), f_info(x),
303 UPPER, f_upper(y), f_info(y));
304 assign_or_swap(info(), to_info);
305 PPL_ASSERT(OK());
306 return combine(rl, ru);
307 }
308
309 template <typename Boundary, typename Info>
310 template <typename Type>
311 inline typename Enable_If<Is_Singleton<Type>::value
312 || Is_Interval<Type>::value, bool>::type
can_be_exactly_joined_to(const Type & x) const313 Interval<Boundary, Info>::can_be_exactly_joined_to(const Type& x) const {
314 PPL_DIRTY_TEMP(Boundary, b);
315 if (gt(LOWER, lower(), info(), UPPER, f_upper(x), f_info(x))) {
316 b = lower();
317 return eq(LOWER, b, info(), UPPER, f_upper(x), f_info(x));
318 }
319 else if (lt(UPPER, upper(), info(), LOWER, f_lower(x), f_info(x))) {
320 b = upper();
321 return eq(UPPER, b, info(), LOWER, f_lower(x), f_info(x));
322 }
323 return true;
324 }
325
326
327 template <typename To_Boundary, typename To_Info>
328 template <typename From>
329 inline typename Enable_If<Is_Singleton<From>::value
330 || Is_Interval<From>::value, I_Result>::type
intersect_assign(const From & x)331 Interval<To_Boundary, To_Info>::intersect_assign(const From& x) {
332 PPL_ASSERT(f_OK(x));
333 max_assign(LOWER, lower(), info(), LOWER, f_lower(x), f_info(x));
334 min_assign(UPPER, upper(), info(), UPPER, f_upper(x), f_info(x));
335 PPL_ASSERT(OK());
336 return I_ANY;
337 }
338
339 template <typename To_Boundary, typename To_Info>
340 template <typename From1, typename From2>
341 inline typename Enable_If<((Is_Singleton<From1>::value
342 || Is_Interval<From1>::value)
343 && (Is_Singleton<From2>::value
344 || Is_Interval<From2>::value)), I_Result>::type
intersect_assign(const From1 & x,const From2 & y)345 Interval<To_Boundary, To_Info>::intersect_assign(const From1& x,
346 const From2& y) {
347 PPL_ASSERT(f_OK(x));
348 PPL_ASSERT(f_OK(y));
349 PPL_DIRTY_TEMP(To_Info, to_info);
350 to_info.clear();
351 max_assign(LOWER, lower(), to_info,
352 LOWER, f_lower(x), f_info(x),
353 LOWER, f_lower(y), f_info(y));
354 min_assign(UPPER, upper(), to_info,
355 UPPER, f_upper(x), f_info(x),
356 UPPER, f_upper(y), f_info(y));
357 assign_or_swap(info(), to_info);
358 PPL_ASSERT(OK());
359 return I_NOT_EMPTY;
360 }
361
362 template <typename To_Boundary, typename To_Info>
363 template <typename From>
364 inline typename Enable_If<Is_Singleton<From>::value
365 || Is_Interval<From>::value, I_Result>::type
difference_assign(const From & x)366 Interval<To_Boundary, To_Info>::difference_assign(const From& x) {
367 PPL_ASSERT(f_OK(x));
368 if (lt(UPPER, upper(), info(), LOWER, f_lower(x), f_info(x))
369 || gt(LOWER, lower(), info(), UPPER, f_upper(x), f_info(x))) {
370 return combine(V_EQ, V_EQ);
371 }
372 bool nl = ge(LOWER, lower(), info(), LOWER, f_lower(x), f_info(x));
373 bool nu = le(UPPER, upper(), info(), UPPER, f_upper(x), f_info(x));
374 Result rl = V_EQ;
375 Result ru = V_EQ;
376 if (nl) {
377 if (nu) {
378 return assign(EMPTY);
379 }
380 else {
381 info().clear_boundary_properties(LOWER);
382 rl = complement(LOWER, lower(), info(), UPPER, f_upper(x), f_info(x));
383 }
384 }
385 else if (nu) {
386 info().clear_boundary_properties(UPPER);
387 ru = complement(UPPER, upper(), info(), LOWER, f_lower(x), f_info(x));
388 }
389 PPL_ASSERT(OK());
390 return combine(rl, ru);
391 }
392
393 template <typename To_Boundary, typename To_Info>
394 template <typename From1, typename From2>
395 inline typename Enable_If<((Is_Singleton<From1>::value
396 || Is_Interval<From1>::value)
397 && (Is_Singleton<From2>::value
398 || Is_Interval<From2>::value)), I_Result>::type
difference_assign(const From1 & x,const From2 & y)399 Interval<To_Boundary, To_Info>::difference_assign(const From1& x,
400 const From2& y) {
401 PPL_ASSERT(f_OK(x));
402 PPL_ASSERT(f_OK(y));
403 PPL_DIRTY_TEMP(To_Info, to_info);
404 to_info.clear();
405 if (lt(UPPER, f_upper(x), f_info(x), LOWER, f_lower(y), f_info(y))
406 || gt(LOWER, f_lower(x), f_info(x), UPPER, f_upper(y), f_info(y))) {
407 return assign(x);
408 }
409 bool nl = ge(LOWER, f_lower(x), f_info(x), LOWER, f_lower(y), f_info(y));
410 bool nu = le(UPPER, f_upper(x), f_info(x), UPPER, f_upper(y), f_info(y));
411 Result rl = V_EQ;
412 Result ru = V_EQ;
413 if (nl) {
414 if (nu) {
415 return assign(EMPTY);
416 }
417 else {
418 rl = complement(LOWER, lower(), info(), UPPER, f_upper(y), f_info(y));
419 ru = Boundary_NS::assign(UPPER, upper(), info(), UPPER, f_upper(x), f_info(x));
420 }
421 }
422 else if (nu) {
423 ru = complement(UPPER, upper(), info(), LOWER, f_lower(y), f_info(y));
424 rl = Boundary_NS::assign(LOWER, lower(), info(),
425 LOWER, f_lower(x), f_info(x));
426 }
427 assign_or_swap(info(), to_info);
428 PPL_ASSERT(OK());
429 return combine(rl, ru);
430 }
431
432 template <typename To_Boundary, typename To_Info>
433 template <typename From>
434 inline typename Enable_If<Is_Singleton<From>::value
435 || Is_Interval<From>::value, I_Result>::type
436 Interval<To_Boundary, To_Info>
refine_existential(Relation_Symbol rel,const From & x)437 ::refine_existential(Relation_Symbol rel, const From& x) {
438 PPL_ASSERT(OK());
439 PPL_ASSERT(f_OK(x));
440 if (check_empty_arg(x)) {
441 return assign(EMPTY);
442 }
443 switch (rel) {
444 case LESS_THAN:
445 {
446 if (lt(UPPER, upper(), info(), UPPER, f_upper(x), f_info(x))) {
447 return combine(V_EQ, V_EQ);
448 }
449 info().clear_boundary_properties(UPPER);
450 Boundary_NS::assign(UPPER, upper(), info(),
451 UPPER, f_upper(x), f_info(x), true);
452 return I_ANY;
453 }
454 case LESS_OR_EQUAL:
455 {
456 if (le(UPPER, upper(), info(), UPPER, f_upper(x), f_info(x))) {
457 return combine(V_EQ, V_EQ);
458 }
459 info().clear_boundary_properties(UPPER);
460 Boundary_NS::assign(UPPER, upper(), info(),
461 UPPER, f_upper(x), f_info(x));
462 return I_ANY;
463 }
464 case GREATER_THAN:
465 {
466 if (gt(LOWER, lower(), info(), LOWER, f_lower(x), f_info(x))) {
467 return combine(V_EQ, V_EQ);
468 }
469 info().clear_boundary_properties(LOWER);
470 Boundary_NS::assign(LOWER, lower(), info(),
471 LOWER, f_lower(x), f_info(x), true);
472 return I_ANY;
473 }
474 case GREATER_OR_EQUAL:
475 {
476 if (ge(LOWER, lower(), info(), LOWER, f_lower(x), f_info(x))) {
477 return combine(V_EQ, V_EQ);
478 }
479 info().clear_boundary_properties(LOWER);
480 Boundary_NS::assign(LOWER, lower(), info(),
481 LOWER, f_lower(x), f_info(x));
482 return I_ANY;
483 }
484 case EQUAL:
485 return intersect_assign(x);
486 case NOT_EQUAL:
487 {
488 if (!f_is_singleton(x)) {
489 return combine(V_EQ, V_EQ);
490 }
491 if (check_empty_arg(*this)) {
492 return I_EMPTY;
493 }
494 if (eq(LOWER, lower(), info(), LOWER, f_lower(x), f_info(x))) {
495 remove_inf();
496 }
497 if (eq(UPPER, upper(), info(), UPPER, f_upper(x), f_info(x))) {
498 remove_sup();
499 }
500 return I_ANY;
501 }
502 default:
503 PPL_UNREACHABLE;
504 return I_EMPTY;
505 }
506 }
507
508 template <typename To_Boundary, typename To_Info>
509 template <typename From>
510 inline typename Enable_If<Is_Singleton<From>::value
511 || Is_Interval<From>::value, I_Result>::type
refine_universal(Relation_Symbol rel,const From & x)512 Interval<To_Boundary, To_Info>::refine_universal(Relation_Symbol rel,
513 const From& x) {
514 PPL_ASSERT(OK());
515 PPL_ASSERT(f_OK(x));
516 if (check_empty_arg(x)) {
517 return combine(V_EQ, V_EQ);
518 }
519 switch (rel) {
520 case LESS_THAN:
521 {
522 if (lt(UPPER, upper(), info(), LOWER, f_lower(x), f_info(x))) {
523 return combine(V_EQ, V_EQ);
524 }
525 info().clear_boundary_properties(UPPER);
526 Result ru = Boundary_NS::assign(UPPER, upper(), info(),
527 LOWER, f_lower(x), SCALAR_INFO,
528 !is_open(LOWER, f_lower(x), f_info(x)));
529 PPL_USED(ru);
530 return I_ANY;
531 }
532 case LESS_OR_EQUAL:
533 {
534 if (le(UPPER, upper(), info(), LOWER, f_lower(x), f_info(x))) {
535 return combine(V_EQ, V_EQ);
536 }
537 info().clear_boundary_properties(UPPER);
538 Result ru = Boundary_NS::assign(UPPER, upper(), info(),
539 LOWER, f_lower(x), SCALAR_INFO);
540 PPL_USED(ru);
541 return I_ANY;
542 }
543 case GREATER_THAN:
544 {
545 if (gt(LOWER, lower(), info(), UPPER, f_upper(x), f_info(x))) {
546 return combine(V_EQ, V_EQ);
547 }
548 info().clear_boundary_properties(LOWER);
549 Result rl = Boundary_NS::assign(LOWER, lower(), info(),
550 UPPER, f_upper(x), SCALAR_INFO,
551 !is_open(UPPER, f_upper(x), f_info(x)));
552 PPL_USED(rl);
553 return I_ANY;
554 }
555 case GREATER_OR_EQUAL:
556 {
557 if (ge(LOWER, lower(), info(), UPPER, f_upper(x), f_info(x))) {
558 return combine(V_EQ, V_EQ);
559 }
560 info().clear_boundary_properties(LOWER);
561 Result rl = Boundary_NS::assign(LOWER, lower(), info(),
562 UPPER, f_upper(x), SCALAR_INFO);
563 PPL_USED(rl);
564 return I_ANY;
565 }
566 case EQUAL:
567 if (!f_is_singleton(x)) {
568 return assign(EMPTY);
569 }
570 return intersect_assign(x);
571 case NOT_EQUAL:
572 {
573 if (check_empty_arg(*this)) {
574 return I_EMPTY;
575 }
576 if (eq(LOWER, lower(), info(), LOWER, f_lower(x), f_info(x))) {
577 remove_inf();
578 }
579 if (eq(UPPER, upper(), info(), UPPER, f_upper(x), f_info(x))) {
580 remove_sup();
581 }
582 return I_ANY;
583 }
584 default:
585 PPL_UNREACHABLE;
586 return I_EMPTY;
587 }
588 }
589
590 template <typename To_Boundary, typename To_Info>
591 template <typename From>
592 inline typename Enable_If<Is_Singleton<From>::value
593 || Is_Interval<From>::value, I_Result>::type
neg_assign(const From & x)594 Interval<To_Boundary, To_Info>::neg_assign(const From& x) {
595 PPL_ASSERT(f_OK(x));
596 if (check_empty_arg(x)) {
597 return assign(EMPTY);
598 }
599 PPL_DIRTY_TEMP(To_Info, to_info);
600 to_info.clear();
601 Result rl;
602 Result ru;
603 PPL_DIRTY_TEMP(To_Boundary, to_lower);
604 rl = Boundary_NS::neg_assign(LOWER, to_lower, to_info, UPPER, f_upper(x), f_info(x));
605 ru = Boundary_NS::neg_assign(UPPER, upper(), to_info, LOWER, f_lower(x), f_info(x));
606 assign_or_swap(lower(), to_lower);
607 assign_or_swap(info(), to_info);
608 PPL_ASSERT(OK());
609 return combine(rl, ru);
610 }
611
612 template <typename To_Boundary, typename To_Info>
613 template <typename From1, typename From2>
614 inline typename Enable_If<((Is_Singleton<From1>::value
615 || Is_Interval<From1>::value)
616 && (Is_Singleton<From2>::value
617 || Is_Interval<From2>::value)), I_Result>::type
add_assign(const From1 & x,const From2 & y)618 Interval<To_Boundary, To_Info>::add_assign(const From1& x, const From2& y) {
619 PPL_ASSERT(f_OK(x));
620 PPL_ASSERT(f_OK(y));
621 if (check_empty_arg(x) || check_empty_arg(y)) {
622 return assign(EMPTY);
623 }
624 int inf_sign = Parma_Polyhedra_Library::infinity_sign(x);
625 if (inf_sign != 0) {
626 if (Parma_Polyhedra_Library::infinity_sign(y) == -inf_sign) {
627 return assign(EMPTY);
628 }
629 }
630 else {
631 inf_sign = Parma_Polyhedra_Library::infinity_sign(y);
632 }
633 if (inf_sign < 0) {
634 return assign(MINUS_INFINITY);
635 }
636 else if (inf_sign > 0) {
637 return assign(PLUS_INFINITY);
638 }
639 PPL_DIRTY_TEMP(To_Info, to_info);
640 to_info.clear();
641 Result rl = Boundary_NS::add_assign(LOWER, lower(), to_info,
642 LOWER, f_lower(x), f_info(x),
643 LOWER, f_lower(y), f_info(y));
644 Result ru = Boundary_NS::add_assign(UPPER, upper(), to_info,
645 UPPER, f_upper(x), f_info(x),
646 UPPER, f_upper(y), f_info(y));
647 assign_or_swap(info(), to_info);
648 PPL_ASSERT(OK());
649 return combine(rl, ru);
650 }
651
652 template <typename To_Boundary, typename To_Info>
653 template <typename From1, typename From2>
654 inline typename Enable_If<((Is_Singleton<From1>::value
655 || Is_Interval<From1>::value)
656 && (Is_Singleton<From2>::value
657 || Is_Interval<From2>::value)), I_Result>::type
sub_assign(const From1 & x,const From2 & y)658 Interval<To_Boundary, To_Info>::sub_assign(const From1& x, const From2& y) {
659 PPL_ASSERT(f_OK(x));
660 PPL_ASSERT(f_OK(y));
661 if (check_empty_arg(x) || check_empty_arg(y)) {
662 return assign(EMPTY);
663 }
664 int inf_sign = Parma_Polyhedra_Library::infinity_sign(x);
665 if (inf_sign != 0) {
666 if (Parma_Polyhedra_Library::infinity_sign(y) == inf_sign) {
667 return assign(EMPTY);
668 }
669 }
670 else {
671 inf_sign = -Parma_Polyhedra_Library::infinity_sign(y);
672 }
673 if (inf_sign < 0) {
674 return assign(MINUS_INFINITY);
675 }
676 else if (inf_sign > 0) {
677 return assign(PLUS_INFINITY);
678 }
679 PPL_DIRTY_TEMP(To_Info, to_info);
680 to_info.clear();
681 Result rl;
682 Result ru;
683 PPL_DIRTY_TEMP(To_Boundary, to_lower);
684 rl = Boundary_NS::sub_assign(LOWER, to_lower, to_info,
685 LOWER, f_lower(x), f_info(x),
686 UPPER, f_upper(y), f_info(y));
687 ru = Boundary_NS::sub_assign(UPPER, upper(), to_info,
688 UPPER, f_upper(x), f_info(x),
689 LOWER, f_lower(y), f_info(y));
690 assign_or_swap(lower(), to_lower);
691 assign_or_swap(info(), to_info);
692 PPL_ASSERT(OK());
693 return combine(rl, ru);
694 }
695
696 /**
697 +---------+-----------+-----------+-----------------+
698 | * | yl > 0 | yu < 0 | yl < 0, yu > 0 |
699 +---------+-----------+-----------+-----------------+
700 | xl > 0 |xl*yl,xu*yu|xu*yl,xl*yu| xu*yl,xu*yu |
701 +---------+-----------+-----------+-----------------+
702 | xu < 0 |xl*yu,xu*yl|xu*yu,xl*yl| xl*yu,xl*yl |
703 +---------+-----------+-----------+-----------------+
704 |xl<0 xu>0|xl*yu,xu*yu|xu*yl,xl*yl|min(xl*yu,xu*yl),|
705 | | | |max(xl*yl,xu*yu) |
706 +---------+-----------+-----------+-----------------+
707 **/
708 template <typename To_Boundary, typename To_Info>
709 template <typename From1, typename From2>
710 inline typename Enable_If<((Is_Singleton<From1>::value
711 || Is_Interval<From1>::value)
712 && (Is_Singleton<From2>::value
713 || Is_Interval<From2>::value)), I_Result>::type
mul_assign(const From1 & x,const From2 & y)714 Interval<To_Boundary, To_Info>::mul_assign(const From1& x, const From2& y) {
715 PPL_ASSERT(f_OK(x));
716 PPL_ASSERT(f_OK(y));
717 if (check_empty_arg(x) || check_empty_arg(y)) {
718 return assign(EMPTY);
719 }
720 int xls = sgn_b(LOWER, f_lower(x), f_info(x));
721 int xus = (xls > 0) ? 1 : sgn_b(UPPER, f_upper(x), f_info(x));
722 int yls = sgn_b(LOWER, f_lower(y), f_info(y));
723 int yus = (yls > 0) ? 1 : sgn_b(UPPER, f_upper(y), f_info(y));
724 int inf_sign = Parma_Polyhedra_Library::infinity_sign(x);
725 int ls;
726 int us;
727 if (inf_sign != 0) {
728 ls = yls;
729 us = yus;
730 goto inf;
731 }
732 else {
733 inf_sign = Parma_Polyhedra_Library::infinity_sign(y);
734 if (inf_sign != 0) {
735 ls = xls;
736 us = xus;
737 inf:
738 if (ls == 0 && us == 0) {
739 return assign(EMPTY);
740 }
741 if (ls == -us) {
742 return set_infinities();
743 }
744 if (ls < 0 || us < 0) {
745 inf_sign = -inf_sign;
746 }
747 if (inf_sign < 0) {
748 return assign(MINUS_INFINITY);
749 }
750 else {
751 return assign(PLUS_INFINITY);
752 }
753 }
754 }
755
756 PPL_DIRTY_TEMP(To_Info, to_info);
757 to_info.clear();
758 Result rl;
759 Result ru;
760 PPL_DIRTY_TEMP(To_Boundary, to_lower);
761
762 if (xls >= 0) {
763 if (yls >= 0) {
764 // 0 <= xl <= xu, 0 <= yl <= yu
765 rl = mul_assign_z(LOWER, to_lower, to_info,
766 LOWER, f_lower(x), f_info(x), xls,
767 LOWER, f_lower(y), f_info(y), yls);
768 ru = mul_assign_z(UPPER, upper(), to_info,
769 UPPER, f_upper(x), f_info(x), xus,
770 UPPER, f_upper(y), f_info(y), yus);
771 }
772 else if (yus <= 0) {
773 // 0 <= xl <= xu, yl <= yu <= 0
774 rl = mul_assign_z(LOWER, to_lower, to_info,
775 UPPER, f_upper(x), f_info(x), xus,
776 LOWER, f_lower(y), f_info(y), yls);
777 ru = mul_assign_z(UPPER, upper(), to_info,
778 LOWER, f_lower(x), f_info(x), xls,
779 UPPER, f_upper(y), f_info(y), yus);
780 }
781 else {
782 // 0 <= xl <= xu, yl < 0 < yu
783 rl = mul_assign_z(LOWER, to_lower, to_info,
784 UPPER, f_upper(x), f_info(x), xus,
785 LOWER, f_lower(y), f_info(y), yls);
786 ru = mul_assign_z(UPPER, upper(), to_info,
787 UPPER, f_upper(x), f_info(x), xus,
788 UPPER, f_upper(y), f_info(y), yus);
789 }
790 }
791 else if (xus <= 0) {
792 if (yls >= 0) {
793 // xl <= xu <= 0, 0 <= yl <= yu
794 rl = mul_assign_z(LOWER, to_lower, to_info,
795 LOWER, f_lower(x), f_info(x), xls,
796 UPPER, f_upper(y), f_info(y), yus);
797 ru = mul_assign_z(UPPER, upper(), to_info,
798 UPPER, f_upper(x), f_info(x), xus,
799 LOWER, f_lower(y), f_info(y), yls);
800 }
801 else if (yus <= 0) {
802 // xl <= xu <= 0, yl <= yu <= 0
803 rl = mul_assign_z(LOWER, to_lower, to_info,
804 UPPER, f_upper(x), f_info(x), xus,
805 UPPER, f_upper(y), f_info(y), yus);
806 ru = mul_assign_z(UPPER, upper(), to_info,
807 LOWER, f_lower(x), f_info(x), xls,
808 LOWER, f_lower(y), f_info(y), yls);
809 }
810 else {
811 // xl <= xu <= 0, yl < 0 < yu
812 rl = mul_assign_z(LOWER, to_lower, to_info,
813 LOWER, f_lower(x), f_info(x), xls,
814 UPPER, f_upper(y), f_info(y), yus);
815 ru = mul_assign_z(UPPER, upper(), to_info,
816 LOWER, f_lower(x), f_info(x), xls,
817 LOWER, f_lower(y), f_info(y), yls);
818 }
819 }
820 else if (yls >= 0) {
821 // xl < 0 < xu, 0 <= yl <= yu
822 rl = mul_assign_z(LOWER, to_lower, to_info,
823 LOWER, f_lower(x), f_info(x), xls,
824 UPPER, f_upper(y), f_info(y), yus);
825 ru = mul_assign_z(UPPER, upper(), to_info,
826 UPPER, f_upper(x), f_info(x), xus,
827 UPPER, f_upper(y), f_info(y), yus);
828 }
829 else if (yus <= 0) {
830 // xl < 0 < xu, yl <= yu <= 0
831 rl = mul_assign_z(LOWER, to_lower, to_info,
832 UPPER, f_upper(x), f_info(x), xus,
833 LOWER, f_lower(y), f_info(y), yls);
834 ru = mul_assign_z(UPPER, upper(), to_info,
835 LOWER, f_lower(x), f_info(x), xls,
836 LOWER, f_lower(y), f_info(y), yls);
837 }
838 else {
839 // xl < 0 < xu, yl < 0 < yu
840 PPL_DIRTY_TEMP(To_Boundary, tmp);
841 PPL_DIRTY_TEMP(To_Info, tmp_info);
842 tmp_info.clear();
843 Result tmp_r;
844 tmp_r = Boundary_NS::mul_assign(LOWER, tmp, tmp_info,
845 UPPER, f_upper(x), f_info(x),
846 LOWER, f_lower(y), f_info(y));
847 rl = Boundary_NS::mul_assign(LOWER, to_lower, to_info,
848 LOWER, f_lower(x), f_info(x),
849 UPPER, f_upper(y), f_info(y));
850 if (gt(LOWER, to_lower, to_info, LOWER, tmp, tmp_info)) {
851 to_lower = tmp;
852 rl = tmp_r;
853 }
854 tmp_info.clear();
855 tmp_r = Boundary_NS::mul_assign(UPPER, tmp, tmp_info,
856 UPPER, f_upper(x), f_info(x),
857 UPPER, f_upper(y), f_info(y));
858 ru = Boundary_NS::mul_assign(UPPER, upper(), to_info,
859 LOWER, f_lower(x), f_info(x),
860 LOWER, f_lower(y), f_info(y));
861 if (lt(UPPER, upper(), to_info, UPPER, tmp, tmp_info)) {
862 upper() = tmp;
863 ru = tmp_r;
864 }
865 }
866 assign_or_swap(lower(), to_lower);
867 assign_or_swap(info(), to_info);
868 PPL_ASSERT(OK());
869 return combine(rl, ru);
870 }
871
872 /**
873 +-----------+-----------+-----------+
874 | / | yu < 0 | yl > 0 |
875 +-----------+-----------+-----------+
876 | xu<=0 |xu/yl,xl/yu|xl/yl,xu/yu|
877 +-----------+-----------+-----------+
878 |xl<=0 xu>=0|xu/yu,xl/yu|xl/yl,xu/yl|
879 +-----------+-----------+-----------+
880 | xl>=0 |xu/yu,xl/yl|xl/yu,xu/yl|
881 +-----------+-----------+-----------+
882 **/
883 template <typename To_Boundary, typename To_Info>
884 template <typename From1, typename From2>
885 inline typename Enable_If<((Is_Singleton<From1>::value
886 || Is_Interval<From1>::value)
887 && (Is_Singleton<From2>::value
888 || Is_Interval<From2>::value)), I_Result>::type
div_assign(const From1 & x,const From2 & y)889 Interval<To_Boundary, To_Info>::div_assign(const From1& x, const From2& y) {
890 PPL_ASSERT(f_OK(x));
891 PPL_ASSERT(f_OK(y));
892 if (check_empty_arg(x) || check_empty_arg(y)) {
893 return assign(EMPTY);
894 }
895 int yls = sgn_b(LOWER, f_lower(y), f_info(y));
896 int yus = (yls > 0) ? 1 : sgn_b(UPPER, f_upper(y), f_info(y));
897 if (yls == 0 && yus == 0) {
898 return assign(EMPTY);
899 }
900 int inf_sign = Parma_Polyhedra_Library::infinity_sign(x);
901 if (inf_sign != 0) {
902 if (Parma_Polyhedra_Library::infinity_sign(y) != 0) {
903 return assign(EMPTY);
904 }
905 if (yls == -yus) {
906 return set_infinities();
907 }
908 if (yls < 0 || yus < 0) {
909 inf_sign = -inf_sign;
910 }
911 if (inf_sign < 0) {
912 return assign(MINUS_INFINITY);
913 }
914 else {
915 return assign(PLUS_INFINITY);
916 }
917 }
918 int xls = sgn_b(LOWER, f_lower(x), f_info(x));
919 int xus = (xls > 0) ? 1 : sgn_b(UPPER, f_upper(x), f_info(x));
920
921 PPL_DIRTY_TEMP(To_Info, to_info);
922 to_info.clear();
923 Result rl;
924 Result ru;
925 PPL_DIRTY_TEMP(To_Boundary, to_lower);
926 if (yls >= 0) {
927 if (xls >= 0) {
928 rl = div_assign_z(LOWER, to_lower, to_info,
929 LOWER, f_lower(x), f_info(x), xls,
930 UPPER, f_upper(y), f_info(y), yus);
931 ru = div_assign_z(UPPER, upper(), to_info,
932 UPPER, f_upper(x), f_info(x), xus,
933 LOWER, f_lower(y), f_info(y), yls);
934 }
935 else if (xus <= 0) {
936 rl = div_assign_z(LOWER, to_lower, to_info,
937 LOWER, f_lower(x), f_info(x), xls,
938 LOWER, f_lower(y), f_info(y), yls);
939 ru = div_assign_z(UPPER, upper(), to_info,
940 UPPER, f_upper(x), f_info(x), xus,
941 UPPER, f_upper(y), f_info(y), yus);
942 }
943 else {
944 rl = div_assign_z(LOWER, to_lower, to_info,
945 LOWER, f_lower(x), f_info(x), xls,
946 LOWER, f_lower(y), f_info(y), yls);
947 ru = div_assign_z(UPPER, upper(), to_info,
948 UPPER, f_upper(x), f_info(x), xus,
949 LOWER, f_lower(y), f_info(y), yls);
950 }
951 }
952 else if (yus <= 0) {
953 if (xls >= 0) {
954 rl = div_assign_z(LOWER, to_lower, to_info,
955 UPPER, f_upper(x), f_info(x), xus,
956 UPPER, f_upper(y), f_info(y), yus);
957 ru = div_assign_z(UPPER, upper(), to_info,
958 LOWER, f_lower(x), f_info(x), xls,
959 LOWER, f_lower(y), f_info(y), yls);
960 }
961 else if (xus <= 0) {
962 rl = div_assign_z(LOWER, to_lower, to_info,
963 UPPER, f_upper(x), f_info(x), xus,
964 LOWER, f_lower(y), f_info(y), yls);
965 ru = div_assign_z(UPPER, upper(), to_info,
966 LOWER, f_lower(x), f_info(x), xls,
967 UPPER, f_upper(y), f_info(y), yus);
968 }
969 else {
970 rl = div_assign_z(LOWER, to_lower, to_info,
971 UPPER, f_upper(x), f_info(x), xus,
972 UPPER, f_upper(y), f_info(y), yus);
973 ru = div_assign_z(UPPER, upper(), to_info,
974 LOWER, f_lower(x), f_info(x), xls,
975 UPPER, f_upper(y), f_info(y), yus);
976 }
977 }
978 else {
979 return static_cast<I_Result>(assign(UNIVERSE) | I_SINGULARITIES);
980 }
981 assign_or_swap(lower(), to_lower);
982 assign_or_swap(info(), to_info);
983 PPL_ASSERT(OK());
984 return combine(rl, ru);
985 }
986
987 template <typename B, typename Info, typename T>
988 inline typename Enable_If<Is_Singleton<T>::value, Interval<B, Info> >::type
operator +(const Interval<B,Info> & x,const T & y)989 operator+(const Interval<B, Info>& x, const T& y) {
990 Interval<B, Info> z;
991 z.add_assign(x, y);
992 return z;
993 }
994
995 template <typename B, typename Info, typename T>
996 inline typename Enable_If<Is_Singleton<T>::value, Interval<B, Info> >::type
operator +(const T & x,const Interval<B,Info> & y)997 operator+(const T& x, const Interval<B, Info>& y) {
998 Interval<B, Info> z;
999 z.add_assign(x, y);
1000 return z;
1001 }
1002
1003 template <typename B, typename Info>
1004 inline Interval<B, Info>
operator +(const Interval<B,Info> & x,const Interval<B,Info> & y)1005 operator+(const Interval<B, Info>& x, const Interval<B, Info>& y) {
1006 Interval<B, Info> z;
1007 z.add_assign(x, y);
1008 return z;
1009 }
1010
1011 template <typename B, typename Info, typename T>
1012 inline typename Enable_If<Is_Singleton<T>::value, Interval<B, Info> >::type
operator -(const Interval<B,Info> & x,const T & y)1013 operator-(const Interval<B, Info>& x, const T& y) {
1014 Interval<B, Info> z;
1015 z.sub_assign(x, y);
1016 return z;
1017 }
1018
1019 template <typename B, typename Info, typename T>
1020 inline typename Enable_If<Is_Singleton<T>::value, Interval<B, Info> >::type
operator -(const T & x,const Interval<B,Info> & y)1021 operator-(const T& x, const Interval<B, Info>& y) {
1022 Interval<B, Info> z;
1023 z.sub_assign(x, y);
1024 return z;
1025 }
1026
1027 template <typename B, typename Info>
1028 inline Interval<B, Info>
operator -(const Interval<B,Info> & x,const Interval<B,Info> & y)1029 operator-(const Interval<B, Info>& x, const Interval<B, Info>& y) {
1030 Interval<B, Info> z;
1031 z.sub_assign(x, y);
1032 return z;
1033 }
1034
1035 template <typename B, typename Info, typename T>
1036 inline typename Enable_If<Is_Singleton<T>::value, Interval<B, Info> >::type
operator *(const Interval<B,Info> & x,const T & y)1037 operator*(const Interval<B, Info>& x, const T& y) {
1038 Interval<B, Info> z;
1039 z.mul_assign(x, y);
1040 return z;
1041 }
1042
1043 template <typename B, typename Info, typename T>
1044 inline typename Enable_If<Is_Singleton<T>::value, Interval<B, Info> >::type
operator *(const T & x,const Interval<B,Info> & y)1045 operator*(const T& x, const Interval<B, Info>& y) {
1046 Interval<B, Info> z;
1047 z.mul_assign(x, y);
1048 return z;
1049 }
1050
1051 template <typename B, typename Info>
1052 inline Interval<B, Info>
operator *(const Interval<B,Info> & x,const Interval<B,Info> & y)1053 operator*(const Interval<B, Info>& x, const Interval<B, Info>& y) {
1054 Interval<B, Info> z;
1055 z.mul_assign(x, y);
1056 return z;
1057 }
1058
1059 template <typename B, typename Info, typename T>
1060 inline typename Enable_If<Is_Singleton<T>::value, Interval<B, Info> >::type
operator /(const Interval<B,Info> & x,const T & y)1061 operator/(const Interval<B, Info>& x, const T& y) {
1062 Interval<B, Info> z;
1063 z.div_assign(x, y);
1064 return z;
1065 }
1066
1067 template <typename B, typename Info, typename T>
1068 inline typename Enable_If<Is_Singleton<T>::value, Interval<B, Info> >::type
operator /(const T & x,const Interval<B,Info> & y)1069 operator/(const T& x, const Interval<B, Info>& y) {
1070 Interval<B, Info> z;
1071 z.div_assign(x, y);
1072 return z;
1073 }
1074
1075 template <typename B, typename Info>
1076 inline Interval<B, Info>
operator /(const Interval<B,Info> & x,const Interval<B,Info> & y)1077 operator/(const Interval<B, Info>& x, const Interval<B, Info>& y) {
1078 Interval<B, Info> z;
1079 z.div_assign(x, y);
1080 return z;
1081 }
1082
1083 template <typename Boundary, typename Info>
1084 inline std::ostream&
operator <<(std::ostream & os,const Interval<Boundary,Info> & x)1085 operator<<(std::ostream& os, const Interval<Boundary, Info>& x) {
1086 if (check_empty_arg(x)) {
1087 return os << "[]";
1088 }
1089 if (x.is_singleton()) {
1090 output(os, x.lower(), Numeric_Format(), ROUND_NOT_NEEDED);
1091 return os;
1092 }
1093 os << (x.lower_is_open() ? "(" : "[");
1094 if (x.info().get_boundary_property(LOWER, SPECIAL)) {
1095 os << "-inf";
1096 }
1097 else {
1098 output(os, x.lower(), Numeric_Format(), ROUND_NOT_NEEDED);
1099 }
1100 os << ", ";
1101 if (x.info().get_boundary_property(UPPER, SPECIAL)) {
1102 os << "+inf";
1103 }
1104 else {
1105 output(os, x.upper(), Numeric_Format(), ROUND_NOT_NEEDED);
1106 }
1107 os << (x.upper_is_open() ? ")" : "]");
1108 return os;
1109 }
1110
1111 template <typename Boundary, typename Info>
1112 inline void
ascii_dump(std::ostream & s) const1113 Interval<Boundary, Info>::ascii_dump(std::ostream& s) const {
1114 using Parma_Polyhedra_Library::ascii_dump;
1115 s << "info ";
1116 info().ascii_dump(s);
1117 s << " lower ";
1118 ascii_dump(s, lower());
1119 s << " upper ";
1120 ascii_dump(s, upper());
1121 s << '\n';
1122 }
1123
1124 template <typename Boundary, typename Info>
1125 inline bool
ascii_load(std::istream & s)1126 Interval<Boundary, Info>::ascii_load(std::istream& s) {
1127 using Parma_Polyhedra_Library::ascii_load;
1128 std::string str;
1129 if (!(s >> str) || str != "info") {
1130 return false;
1131 }
1132 if (!info().ascii_load(s)) {
1133 return false;
1134 }
1135 if (!(s >> str) || str != "lower") {
1136 return false;
1137 }
1138 if (!ascii_load(s, lower())) {
1139 return false;
1140 }
1141 if (!(s >> str) || str != "upper") {
1142 return false;
1143 }
1144 if (!ascii_load(s, upper())) {
1145 return false;
1146 }
1147 PPL_ASSERT(OK());
1148 return true;
1149 }
1150
1151 /*! \brief
1152 Helper class to select the appropriate numerical type to perform
1153 boundary computations so as to reduce the chances of overflow without
1154 incurring too much overhead.
1155 */
1156 template <typename Interval_Boundary_Type> struct Select_Temp_Boundary_Type;
1157
1158 template <typename Interval_Boundary_Type>
1159 struct Select_Temp_Boundary_Type {
1160 typedef Interval_Boundary_Type type;
1161 };
1162
1163 #if PPL_SUPPORTED_DOUBLE
1164 template <>
1165 struct Select_Temp_Boundary_Type<float> {
1166 typedef double type;
1167 };
1168 #endif
1169
1170 template <>
1171 struct Select_Temp_Boundary_Type<char> {
1172 typedef signed long long type;
1173 };
1174
1175 template <>
1176 struct Select_Temp_Boundary_Type<signed char> {
1177 typedef signed long long type;
1178 };
1179
1180 template <>
1181 struct Select_Temp_Boundary_Type<unsigned char> {
1182 typedef signed long long type;
1183 };
1184
1185 template <>
1186 struct Select_Temp_Boundary_Type<signed short> {
1187 typedef signed long long type;
1188 };
1189
1190 template <>
1191 struct Select_Temp_Boundary_Type<unsigned short> {
1192 typedef signed long long type;
1193 };
1194
1195 template <>
1196 struct Select_Temp_Boundary_Type<signed int> {
1197 typedef signed long long type;
1198 };
1199
1200 template <>
1201 struct Select_Temp_Boundary_Type<unsigned int> {
1202 typedef signed long long type;
1203 };
1204
1205 template <>
1206 struct Select_Temp_Boundary_Type<signed long> {
1207 typedef signed long long type;
1208 };
1209
1210 template <>
1211 struct Select_Temp_Boundary_Type<unsigned long> {
1212 typedef signed long long type;
1213 };
1214
1215 template <>
1216 struct Select_Temp_Boundary_Type<unsigned long long> {
1217 typedef signed long long type;
1218 };
1219
1220 /*! \relates Interval */
1221 template <typename Boundary, typename Info>
1222 inline void
swap(Interval<Boundary,Info> & x,Interval<Boundary,Info> & y)1223 swap(Interval<Boundary, Info>& x, Interval<Boundary, Info>& y) {
1224 x.m_swap(y);
1225 }
1226
1227 } // namespace Parma_Polyhedra_Library
1228
1229 #endif // !defined(PPL_Interval_inlines_hh)
1230