1 /* Box class implementation: inline functions.
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_Box_inlines_hh
25 #define PPL_Box_inlines_hh 1
26
27 #include "Boundary_defs.hh"
28 #include "Constraint_System_defs.hh"
29 #include "Constraint_System_inlines.hh"
30 #include "Congruence_System_defs.hh"
31 #include "Congruence_System_inlines.hh"
32 #include "distances_defs.hh"
33
34 namespace Parma_Polyhedra_Library {
35
36 template <typename ITV>
37 inline bool
marked_empty() const38 Box<ITV>::marked_empty() const {
39 return status.test_empty_up_to_date() && status.test_empty();
40 }
41
42 template <typename ITV>
43 inline void
set_empty()44 Box<ITV>::set_empty() {
45 status.set_empty();
46 status.set_empty_up_to_date();
47 }
48
49 template <typename ITV>
50 inline void
set_nonempty()51 Box<ITV>::set_nonempty() {
52 status.reset_empty();
53 status.set_empty_up_to_date();
54 }
55
56 template <typename ITV>
57 inline void
set_empty_up_to_date()58 Box<ITV>::set_empty_up_to_date() {
59 status.set_empty_up_to_date();
60 }
61
62 template <typename ITV>
63 inline void
reset_empty_up_to_date()64 Box<ITV>::reset_empty_up_to_date() {
65 return status.reset_empty_up_to_date();
66 }
67
68 template <typename ITV>
69 inline
Box(const Box & y,Complexity_Class)70 Box<ITV>::Box(const Box& y, Complexity_Class)
71 : seq(y.seq), status(y.status) {
72 }
73
74 template <typename ITV>
75 inline Box<ITV>&
operator =(const Box & y)76 Box<ITV>::operator=(const Box& y) {
77 seq = y.seq;
78 status = y.status;
79 return *this;
80 }
81
82 template <typename ITV>
83 inline void
m_swap(Box & y)84 Box<ITV>::m_swap(Box& y) {
85 Box& x = *this;
86 using std::swap;
87 swap(x.seq, y.seq);
88 swap(x.status, y.status);
89 }
90
91 template <typename ITV>
92 inline
Box(const Constraint_System & cs,Recycle_Input)93 Box<ITV>::Box(const Constraint_System& cs, Recycle_Input) {
94 // Recycling is useless: just delegate.
95 Box<ITV> tmp(cs);
96 this->m_swap(tmp);
97 }
98
99 template <typename ITV>
100 inline
Box(const Generator_System & gs,Recycle_Input)101 Box<ITV>::Box(const Generator_System& gs, Recycle_Input) {
102 // Recycling is useless: just delegate.
103 Box<ITV> tmp(gs);
104 this->m_swap(tmp);
105 }
106
107 template <typename ITV>
108 inline
Box(const Congruence_System & cgs,Recycle_Input)109 Box<ITV>::Box(const Congruence_System& cgs, Recycle_Input) {
110 // Recycling is useless: just delegate.
111 Box<ITV> tmp(cgs);
112 this->m_swap(tmp);
113 }
114
115 template <typename ITV>
116 inline memory_size_type
total_memory_in_bytes() const117 Box<ITV>::total_memory_in_bytes() const {
118 return sizeof(*this) + external_memory_in_bytes();
119 }
120
121 template <typename ITV>
122 inline dimension_type
space_dimension() const123 Box<ITV>::space_dimension() const {
124 return seq.size();
125 }
126
127 template <typename ITV>
128 inline dimension_type
max_space_dimension()129 Box<ITV>::max_space_dimension() {
130 // One dimension is reserved to have a value of type dimension_type
131 // that does not represent a legal dimension.
132 return Sequence().max_size() - 1;
133 }
134
135 template <typename ITV>
136 inline int32_t
hash_code() const137 Box<ITV>::hash_code() const {
138 return hash_code_from_dimension(space_dimension());
139 }
140
141 template <typename ITV>
142 inline const ITV&
operator [](const dimension_type k) const143 Box<ITV>::operator[](const dimension_type k) const {
144 PPL_ASSERT(k < seq.size());
145 return seq[k];
146 }
147
148 template <typename ITV>
149 inline const ITV&
get_interval(const Variable var) const150 Box<ITV>::get_interval(const Variable var) const {
151 if (space_dimension() < var.space_dimension()) {
152 throw_dimension_incompatible("get_interval(v)", "v", var);
153 }
154 if (is_empty()) {
155 static ITV empty_interval(EMPTY);
156 return empty_interval;
157 }
158
159 return seq[var.id()];
160 }
161
162 template <typename ITV>
163 inline void
set_interval(const Variable var,const ITV & i)164 Box<ITV>::set_interval(const Variable var, const ITV& i) {
165 const dimension_type space_dim = space_dimension();
166 if (space_dim < var.space_dimension()) {
167 throw_dimension_incompatible("set_interval(v, i)", "v", var);
168 }
169
170 if (is_empty() && space_dim >= 2) {
171 // If the box is empty, and has dimension >= 2, setting only one
172 // interval will not make it non-empty.
173 return;
174 }
175 seq[var.id()] = i;
176 reset_empty_up_to_date();
177
178 PPL_ASSERT(OK());
179 }
180
181 template <typename ITV>
182 inline bool
is_empty() const183 Box<ITV>::is_empty() const {
184 return marked_empty() || check_empty();
185 }
186
187 template <typename ITV>
188 inline bool
bounds_from_above(const Linear_Expression & expr) const189 Box<ITV>::bounds_from_above(const Linear_Expression& expr) const {
190 return bounds(expr, true);
191 }
192
193 template <typename ITV>
194 inline bool
bounds_from_below(const Linear_Expression & expr) const195 Box<ITV>::bounds_from_below(const Linear_Expression& expr) const {
196 return bounds(expr, false);
197 }
198
199 template <typename ITV>
200 inline bool
maximize(const Linear_Expression & expr,Coefficient & sup_n,Coefficient & sup_d,bool & maximum) const201 Box<ITV>::maximize(const Linear_Expression& expr,
202 Coefficient& sup_n, Coefficient& sup_d,
203 bool& maximum) const {
204 return max_min(expr, true, sup_n, sup_d, maximum);
205 }
206
207 template <typename ITV>
208 inline bool
maximize(const Linear_Expression & expr,Coefficient & sup_n,Coefficient & sup_d,bool & maximum,Generator & g) const209 Box<ITV>::maximize(const Linear_Expression& expr,
210 Coefficient& sup_n, Coefficient& sup_d, bool& maximum,
211 Generator& g) const {
212 return max_min(expr, true, sup_n, sup_d, maximum, g);
213 }
214
215 template <typename ITV>
216 inline bool
minimize(const Linear_Expression & expr,Coefficient & inf_n,Coefficient & inf_d,bool & minimum) const217 Box<ITV>::minimize(const Linear_Expression& expr,
218 Coefficient& inf_n, Coefficient& inf_d,
219 bool& minimum) const {
220 return max_min(expr, false, inf_n, inf_d, minimum);
221 }
222
223 template <typename ITV>
224 inline bool
minimize(const Linear_Expression & expr,Coefficient & inf_n,Coefficient & inf_d,bool & minimum,Generator & g) const225 Box<ITV>::minimize(const Linear_Expression& expr,
226 Coefficient& inf_n, Coefficient& inf_d, bool& minimum,
227 Generator& g) const {
228 return max_min(expr, false, inf_n, inf_d, minimum, g);
229 }
230
231 template <typename ITV>
232 inline bool
strictly_contains(const Box & y) const233 Box<ITV>::strictly_contains(const Box& y) const {
234 const Box& x = *this;
235 return x.contains(y) && !y.contains(x);
236 }
237
238 template <typename ITV>
239 inline void
expand_space_dimension(const Variable var,const dimension_type m)240 Box<ITV>::expand_space_dimension(const Variable var,
241 const dimension_type m) {
242 const dimension_type space_dim = space_dimension();
243 // `var' should be one of the dimensions of the vector space.
244 if (var.space_dimension() > space_dim) {
245 throw_dimension_incompatible("expand_space_dimension(v, m)", "v", var);
246 }
247
248 // The space dimension of the resulting Box should not
249 // overflow the maximum allowed space dimension.
250 if (m > max_space_dimension() - space_dim) {
251 throw_invalid_argument("expand_dimension(v, m)",
252 "adding m new space dimensions exceeds "
253 "the maximum allowed space dimension");
254 }
255
256 // To expand the space dimension corresponding to variable `var',
257 // we append to the box `m' copies of the corresponding interval.
258 seq.insert(seq.end(), m, seq[var.id()]);
259 PPL_ASSERT(OK());
260 }
261
262 template <typename ITV>
263 inline bool
operator !=(const Box<ITV> & x,const Box<ITV> & y)264 operator!=(const Box<ITV>& x, const Box<ITV>& y) {
265 return !(x == y);
266 }
267
268 template <typename ITV>
269 inline bool
has_lower_bound(const Variable var,Coefficient & n,Coefficient & d,bool & closed) const270 Box<ITV>::has_lower_bound(const Variable var,
271 Coefficient& n, Coefficient& d, bool& closed) const {
272 // NOTE: assertion !is_empty() would be wrong;
273 // see the calls in method Box<ITV>::constraints().
274 PPL_ASSERT(!marked_empty());
275 const dimension_type k = var.id();
276 PPL_ASSERT(k < seq.size());
277 const ITV& seq_k = seq[k];
278
279 if (seq_k.lower_is_boundary_infinity()) {
280 return false;
281 }
282 closed = !seq_k.lower_is_open();
283
284 PPL_DIRTY_TEMP(mpq_class, lr);
285 assign_r(lr, seq_k.lower(), ROUND_NOT_NEEDED);
286 n = lr.get_num();
287 d = lr.get_den();
288
289 return true;
290 }
291
292 template <typename ITV>
293 inline bool
has_upper_bound(const Variable var,Coefficient & n,Coefficient & d,bool & closed) const294 Box<ITV>::has_upper_bound(const Variable var,
295 Coefficient& n, Coefficient& d, bool& closed) const {
296 // NOTE: assertion !is_empty() would be wrong;
297 // see the calls in method Box<ITV>::constraints().
298 PPL_ASSERT(!marked_empty());
299 const dimension_type k = var.id();
300 PPL_ASSERT(k < seq.size());
301 const ITV& seq_k = seq[k];
302
303 if (seq_k.upper_is_boundary_infinity()) {
304 return false;
305 }
306
307 closed = !seq_k.upper_is_open();
308
309 PPL_DIRTY_TEMP(mpq_class, ur);
310 assign_r(ur, seq_k.upper(), ROUND_NOT_NEEDED);
311 n = ur.get_num();
312 d = ur.get_den();
313
314 return true;
315 }
316
317 template <typename ITV>
318 inline void
add_constraint(const Constraint & c)319 Box<ITV>::add_constraint(const Constraint& c) {
320 const dimension_type c_space_dim = c.space_dimension();
321 // Dimension-compatibility check.
322 if (c_space_dim > space_dimension()) {
323 throw_dimension_incompatible("add_constraint(c)", c);
324 }
325
326 add_constraint_no_check(c);
327 }
328
329 template <typename ITV>
330 inline void
add_constraints(const Constraint_System & cs)331 Box<ITV>::add_constraints(const Constraint_System& cs) {
332 // Dimension-compatibility check.
333 if (cs.space_dimension() > space_dimension()) {
334 throw_dimension_incompatible("add_constraints(cs)", cs);
335 }
336
337 add_constraints_no_check(cs);
338 }
339
340 template <typename T>
341 inline void
add_recycled_constraints(Constraint_System & cs)342 Box<T>::add_recycled_constraints(Constraint_System& cs) {
343 add_constraints(cs);
344 }
345
346 template <typename ITV>
347 inline void
add_congruence(const Congruence & cg)348 Box<ITV>::add_congruence(const Congruence& cg) {
349 const dimension_type cg_space_dim = cg.space_dimension();
350 // Dimension-compatibility check.
351 if (cg_space_dim > space_dimension()) {
352 throw_dimension_incompatible("add_congruence(cg)", cg);
353 }
354
355 add_congruence_no_check(cg);
356 }
357
358 template <typename ITV>
359 inline void
add_congruences(const Congruence_System & cgs)360 Box<ITV>::add_congruences(const Congruence_System& cgs) {
361 if (cgs.space_dimension() > space_dimension()) {
362 throw_dimension_incompatible("add_congruences(cgs)", cgs);
363 }
364 add_congruences_no_check(cgs);
365 }
366
367 template <typename T>
368 inline void
add_recycled_congruences(Congruence_System & cgs)369 Box<T>::add_recycled_congruences(Congruence_System& cgs) {
370 add_congruences(cgs);
371 }
372
373 template <typename T>
374 inline bool
can_recycle_constraint_systems()375 Box<T>::can_recycle_constraint_systems() {
376 return false;
377 }
378
379 template <typename T>
380 inline bool
can_recycle_congruence_systems()381 Box<T>::can_recycle_congruence_systems() {
382 return false;
383 }
384
385 template <typename T>
386 inline void
widening_assign(const Box & y,unsigned * tp)387 Box<T>::widening_assign(const Box& y, unsigned* tp) {
388 CC76_widening_assign(y, tp);
389 }
390
391 template <typename ITV>
392 inline Congruence_System
minimized_congruences() const393 Box<ITV>::minimized_congruences() const {
394 // Only equalities can be congruences and these are already minimized.
395 return congruences();
396 }
397
398 template <typename ITV>
399 inline I_Result
400 Box<ITV>
refine_interval_no_check(ITV & itv,const Constraint::Type type,Coefficient_traits::const_reference numer,Coefficient_traits::const_reference denom)401 ::refine_interval_no_check(ITV& itv,
402 const Constraint::Type type,
403 Coefficient_traits::const_reference numer,
404 Coefficient_traits::const_reference denom) {
405 PPL_ASSERT(denom != 0);
406 // The interval constraint is of the form
407 // `var + numer / denom rel 0',
408 // where `rel' is either the relation `==', `>=', or `>'.
409 // For the purpose of refining the interval, this is
410 // (morally) turned into `var rel -numer/denom'.
411 PPL_DIRTY_TEMP(mpq_class, q);
412 assign_r(q.get_num(), numer, ROUND_NOT_NEEDED);
413 assign_r(q.get_den(), denom, ROUND_NOT_NEEDED);
414 q.canonicalize();
415 // Turn `numer/denom' into `-numer/denom'.
416 q = -q;
417
418 Relation_Symbol rel_sym;
419 switch (type) {
420 case Constraint::EQUALITY:
421 rel_sym = EQUAL;
422 break;
423 case Constraint::NONSTRICT_INEQUALITY:
424 rel_sym = (denom > 0) ? GREATER_OR_EQUAL : LESS_OR_EQUAL;
425 break;
426 case Constraint::STRICT_INEQUALITY:
427 rel_sym = (denom > 0) ? GREATER_THAN : LESS_THAN;
428 break;
429 default:
430 // Silence compiler warning.
431 PPL_UNREACHABLE;
432 return I_ANY;
433 }
434 I_Result res = itv.add_constraint(i_constraint(rel_sym, q));
435 PPL_ASSERT(itv.OK());
436 return res;
437 }
438
439 template <typename ITV>
440 inline void
441 Box<ITV>
add_interval_constraint_no_check(const dimension_type var_id,const Constraint::Type type,Coefficient_traits::const_reference numer,Coefficient_traits::const_reference denom)442 ::add_interval_constraint_no_check(const dimension_type var_id,
443 const Constraint::Type type,
444 Coefficient_traits::const_reference numer,
445 Coefficient_traits::const_reference denom) {
446 PPL_ASSERT(!marked_empty());
447 PPL_ASSERT(var_id < space_dimension());
448 PPL_ASSERT(denom != 0);
449 refine_interval_no_check(seq[var_id], type, numer, denom);
450 // FIXME: do check the value returned and set `empty' and
451 // `empty_up_to_date' as appropriate.
452 // This has to be done after reimplementation of intervals.
453 reset_empty_up_to_date();
454 PPL_ASSERT(OK());
455 }
456
457 template <typename ITV>
458 inline void
refine_with_constraint(const Constraint & c)459 Box<ITV>::refine_with_constraint(const Constraint& c) {
460 const dimension_type c_space_dim = c.space_dimension();
461 // Dimension-compatibility check.
462 if (c_space_dim > space_dimension()) {
463 throw_dimension_incompatible("refine_with_constraint(c)", c);
464 }
465
466 // If the box is already empty, there is nothing left to do.
467 if (marked_empty()) {
468 return;
469 }
470
471 refine_no_check(c);
472 }
473
474 template <typename ITV>
475 inline void
refine_with_constraints(const Constraint_System & cs)476 Box<ITV>::refine_with_constraints(const Constraint_System& cs) {
477 // Dimension-compatibility check.
478 if (cs.space_dimension() > space_dimension()) {
479 throw_dimension_incompatible("refine_with_constraints(cs)", cs);
480 }
481
482 // If the box is already empty, there is nothing left to do.
483 if (marked_empty()) {
484 return;
485 }
486 refine_no_check(cs);
487 }
488
489 template <typename ITV>
490 inline void
refine_with_congruence(const Congruence & cg)491 Box<ITV>::refine_with_congruence(const Congruence& cg) {
492 const dimension_type cg_space_dim = cg.space_dimension();
493 // Dimension-compatibility check.
494 if (cg_space_dim > space_dimension()) {
495 throw_dimension_incompatible("refine_with_congruence(cg)", cg);
496 }
497 // If the box is already empty, there is nothing left to do.
498 if (marked_empty()) {
499 return;
500 }
501 refine_no_check(cg);
502 }
503
504 template <typename ITV>
505 inline void
refine_with_congruences(const Congruence_System & cgs)506 Box<ITV>::refine_with_congruences(const Congruence_System& cgs) {
507 // Dimension-compatibility check.
508 if (cgs.space_dimension() > space_dimension()) {
509 throw_dimension_incompatible("refine_with_congruences(cgs)", cgs);
510 }
511
512 // If the box is already empty, there is nothing left to do.
513 if (marked_empty()) {
514 return;
515 }
516
517 refine_no_check(cgs);
518 }
519
520 template <typename ITV>
521 inline void
propagate_constraint(const Constraint & c)522 Box<ITV>::propagate_constraint(const Constraint& c) {
523 const dimension_type c_space_dim = c.space_dimension();
524 // Dimension-compatibility check.
525 if (c_space_dim > space_dimension()) {
526 throw_dimension_incompatible("propagate_constraint(c)", c);
527 }
528
529 // If the box is already empty, there is nothing left to do.
530 if (marked_empty()) {
531 return;
532 }
533 propagate_constraint_no_check(c);
534 }
535
536 template <typename ITV>
537 inline void
propagate_constraints(const Constraint_System & cs,const dimension_type max_iterations)538 Box<ITV>::propagate_constraints(const Constraint_System& cs,
539 const dimension_type max_iterations) {
540 // Dimension-compatibility check.
541 if (cs.space_dimension() > space_dimension()) {
542 throw_dimension_incompatible("propagate_constraints(cs)", cs);
543 }
544
545 // If the box is already empty, there is nothing left to do.
546 if (marked_empty()) {
547 return;
548 }
549
550 propagate_constraints_no_check(cs, max_iterations);
551 }
552
553 template <typename ITV>
554 inline void
unconstrain(const Variable var)555 Box<ITV>::unconstrain(const Variable var) {
556 const dimension_type var_id = var.id();
557 // Dimension-compatibility check.
558 if (space_dimension() < var_id + 1) {
559 throw_dimension_incompatible("unconstrain(var)", var_id + 1);
560 }
561
562 // If the box is already empty, there is nothing left to do.
563 if (marked_empty()) {
564 return;
565 }
566
567 // Here the box might still be empty (but we haven't detected it yet):
568 // check emptiness of the interval for `var' before cylindrification.
569 ITV& seq_var = seq[var_id];
570 if (seq_var.is_empty()) {
571 set_empty();
572 }
573 else {
574 seq_var.assign(UNIVERSE);
575 }
576
577 PPL_ASSERT(OK());
578 }
579
580 /*! \relates Box */
581 template <typename Temp, typename To, typename ITV>
582 inline bool
rectilinear_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const Box<ITV> & x,const Box<ITV> & y,const Rounding_Dir dir,Temp & tmp0,Temp & tmp1,Temp & tmp2)583 rectilinear_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
584 const Box<ITV>& x,
585 const Box<ITV>& y,
586 const Rounding_Dir dir,
587 Temp& tmp0,
588 Temp& tmp1,
589 Temp& tmp2) {
590 return l_m_distance_assign<Rectilinear_Distance_Specialization<Temp> >
591 (r, x, y, dir, tmp0, tmp1, tmp2);
592 }
593
594 /*! \relates Box */
595 template <typename Temp, typename To, typename ITV>
596 inline bool
rectilinear_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const Box<ITV> & x,const Box<ITV> & y,const Rounding_Dir dir)597 rectilinear_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
598 const Box<ITV>& x,
599 const Box<ITV>& y,
600 const Rounding_Dir dir) {
601 typedef Checked_Number<Temp, Extended_Number_Policy> Checked_Temp;
602 PPL_DIRTY_TEMP(Checked_Temp, tmp0);
603 PPL_DIRTY_TEMP(Checked_Temp, tmp1);
604 PPL_DIRTY_TEMP(Checked_Temp, tmp2);
605 return rectilinear_distance_assign(r, x, y, dir, tmp0, tmp1, tmp2);
606 }
607
608 /*! \relates Box */
609 template <typename To, typename ITV>
610 inline bool
rectilinear_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const Box<ITV> & x,const Box<ITV> & y,const Rounding_Dir dir)611 rectilinear_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
612 const Box<ITV>& x,
613 const Box<ITV>& y,
614 const Rounding_Dir dir) {
615 // FIXME: the following qualification is only to work around a bug
616 // in the Intel C/C++ compiler version 10.1.x.
617 return Parma_Polyhedra_Library
618 ::rectilinear_distance_assign<To, To, ITV>(r, x, y, dir);
619 }
620
621 /*! \relates Box */
622 template <typename Temp, typename To, typename ITV>
623 inline bool
euclidean_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const Box<ITV> & x,const Box<ITV> & y,const Rounding_Dir dir,Temp & tmp0,Temp & tmp1,Temp & tmp2)624 euclidean_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
625 const Box<ITV>& x,
626 const Box<ITV>& y,
627 const Rounding_Dir dir,
628 Temp& tmp0,
629 Temp& tmp1,
630 Temp& tmp2) {
631 return l_m_distance_assign<Euclidean_Distance_Specialization<Temp> >
632 (r, x, y, dir, tmp0, tmp1, tmp2);
633 }
634
635 /*! \relates Box */
636 template <typename Temp, typename To, typename ITV>
637 inline bool
euclidean_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const Box<ITV> & x,const Box<ITV> & y,const Rounding_Dir dir)638 euclidean_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
639 const Box<ITV>& x,
640 const Box<ITV>& y,
641 const Rounding_Dir dir) {
642 typedef Checked_Number<Temp, Extended_Number_Policy> Checked_Temp;
643 PPL_DIRTY_TEMP(Checked_Temp, tmp0);
644 PPL_DIRTY_TEMP(Checked_Temp, tmp1);
645 PPL_DIRTY_TEMP(Checked_Temp, tmp2);
646 return euclidean_distance_assign(r, x, y, dir, tmp0, tmp1, tmp2);
647 }
648
649 /*! \relates Box */
650 template <typename To, typename ITV>
651 inline bool
euclidean_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const Box<ITV> & x,const Box<ITV> & y,const Rounding_Dir dir)652 euclidean_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
653 const Box<ITV>& x,
654 const Box<ITV>& y,
655 const Rounding_Dir dir) {
656 // FIXME: the following qualification is only to work around a bug
657 // in the Intel C/C++ compiler version 10.1.x.
658 return Parma_Polyhedra_Library
659 ::euclidean_distance_assign<To, To, ITV>(r, x, y, dir);
660 }
661
662 /*! \relates Box */
663 template <typename Temp, typename To, typename ITV>
664 inline bool
l_infinity_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const Box<ITV> & x,const Box<ITV> & y,const Rounding_Dir dir,Temp & tmp0,Temp & tmp1,Temp & tmp2)665 l_infinity_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
666 const Box<ITV>& x,
667 const Box<ITV>& y,
668 const Rounding_Dir dir,
669 Temp& tmp0,
670 Temp& tmp1,
671 Temp& tmp2) {
672 return l_m_distance_assign<L_Infinity_Distance_Specialization<Temp> >
673 (r, x, y, dir, tmp0, tmp1, tmp2);
674 }
675
676 /*! \relates Box */
677 template <typename Temp, typename To, typename ITV>
678 inline bool
l_infinity_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const Box<ITV> & x,const Box<ITV> & y,const Rounding_Dir dir)679 l_infinity_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
680 const Box<ITV>& x,
681 const Box<ITV>& y,
682 const Rounding_Dir dir) {
683 typedef Checked_Number<Temp, Extended_Number_Policy> Checked_Temp;
684 PPL_DIRTY_TEMP(Checked_Temp, tmp0);
685 PPL_DIRTY_TEMP(Checked_Temp, tmp1);
686 PPL_DIRTY_TEMP(Checked_Temp, tmp2);
687 return l_infinity_distance_assign(r, x, y, dir, tmp0, tmp1, tmp2);
688 }
689
690 /*! \relates Box */
691 template <typename To, typename ITV>
692 inline bool
l_infinity_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const Box<ITV> & x,const Box<ITV> & y,const Rounding_Dir dir)693 l_infinity_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
694 const Box<ITV>& x,
695 const Box<ITV>& y,
696 const Rounding_Dir dir) {
697 // FIXME: the following qualification is only to work around a bug
698 // in the Intel C/C++ compiler version 10.1.x.
699 return Parma_Polyhedra_Library
700 ::l_infinity_distance_assign<To, To, ITV>(r, x, y, dir);
701 }
702
703 /*! \relates Box */
704 template <typename ITV>
705 inline void
swap(Box<ITV> & x,Box<ITV> & y)706 swap(Box<ITV>& x, Box<ITV>& y) {
707 x.m_swap(y);
708 }
709
710 } // namespace Parma_Polyhedra_Library
711
712 #endif // !defined(PPL_Box_inlines_hh)
713