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