1 /* Generator 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_Generator_inlines_hh
25 #define PPL_Generator_inlines_hh 1
26
27 namespace Parma_Polyhedra_Library {
28
29 inline bool
is_necessarily_closed() const30 Generator::is_necessarily_closed() const {
31 return (topology() == NECESSARILY_CLOSED);
32 }
33
34 inline bool
is_not_necessarily_closed() const35 Generator::is_not_necessarily_closed() const {
36 return (topology() == NOT_NECESSARILY_CLOSED);
37 }
38
39 inline Generator::expr_type
expression() const40 Generator::expression() const {
41 return expr_type(expr, is_not_necessarily_closed());
42 }
43
44 inline dimension_type
space_dimension() const45 Generator::space_dimension() const {
46 return expression().space_dimension();
47 }
48
49 inline bool
is_line_or_equality() const50 Generator::is_line_or_equality() const {
51 return (kind_ == LINE_OR_EQUALITY);
52 }
53
54 inline bool
is_ray_or_point_or_inequality() const55 Generator::is_ray_or_point_or_inequality() const {
56 return (kind_ == RAY_OR_POINT_OR_INEQUALITY);
57 }
58
59 inline Topology
topology() const60 Generator::topology() const {
61 return topology_;
62 }
63
64 inline void
set_is_line_or_equality()65 Generator::set_is_line_or_equality() {
66 kind_ = LINE_OR_EQUALITY;
67 }
68
69 inline void
set_is_ray_or_point_or_inequality()70 Generator::set_is_ray_or_point_or_inequality() {
71 kind_ = RAY_OR_POINT_OR_INEQUALITY;
72 }
73
74 inline void
set_topology(Topology x)75 Generator::set_topology(Topology x) {
76 if (topology() == x) {
77 return;
78 }
79 if (topology() == NECESSARILY_CLOSED) {
80 // Add a column for the epsilon dimension.
81 expr.set_space_dimension(expr.space_dimension() + 1);
82 }
83 else {
84 PPL_ASSERT(expr.space_dimension() > 0);
85 expr.set_space_dimension(expr.space_dimension() - 1);
86 }
87 topology_ = x;
88 }
89
90 inline void
mark_as_necessarily_closed()91 Generator::mark_as_necessarily_closed() {
92 PPL_ASSERT(is_not_necessarily_closed());
93 topology_ = NECESSARILY_CLOSED;
94 }
95
96 inline void
mark_as_not_necessarily_closed()97 Generator::mark_as_not_necessarily_closed() {
98 PPL_ASSERT(is_necessarily_closed());
99 topology_ = NOT_NECESSARILY_CLOSED;
100 }
101
102 inline void
set_necessarily_closed()103 Generator::set_necessarily_closed() {
104 set_topology(NECESSARILY_CLOSED);
105 }
106
107 inline void
set_not_necessarily_closed()108 Generator::set_not_necessarily_closed() {
109 set_topology(NOT_NECESSARILY_CLOSED);
110 }
111
112 inline
Generator(Representation r)113 Generator::Generator(Representation r)
114 : expr(r),
115 kind_(RAY_OR_POINT_OR_INEQUALITY),
116 topology_(NECESSARILY_CLOSED) {
117 expr.set_inhomogeneous_term(Coefficient_one());
118 PPL_ASSERT(space_dimension() == 0);
119 PPL_ASSERT(OK());
120 }
121
122 inline
Generator(dimension_type space_dim,Kind kind,Topology topology,Representation r)123 Generator::Generator(dimension_type space_dim, Kind kind, Topology topology,
124 Representation r)
125 : expr(r),
126 kind_(kind),
127 topology_(topology) {
128 if (is_necessarily_closed()) {
129 expr.set_space_dimension(space_dim);
130 }
131 else {
132 expr.set_space_dimension(space_dim + 1);
133 }
134 PPL_ASSERT(space_dimension() == space_dim);
135 PPL_ASSERT(OK());
136 }
137
138 inline
Generator(Linear_Expression & e,Type type,Topology topology)139 Generator::Generator(Linear_Expression& e, Type type, Topology topology)
140 : topology_(topology) {
141 PPL_ASSERT(type != CLOSURE_POINT || topology == NOT_NECESSARILY_CLOSED);
142 swap(expr, e);
143 if (topology == NOT_NECESSARILY_CLOSED) {
144 expr.set_space_dimension(expr.space_dimension() + 1);
145 }
146 if (type == LINE) {
147 kind_ = LINE_OR_EQUALITY;
148 }
149 else {
150 kind_ = RAY_OR_POINT_OR_INEQUALITY;
151 }
152 strong_normalize();
153 }
154
155 inline
Generator(Linear_Expression & e,Kind kind,Topology topology)156 Generator::Generator(Linear_Expression& e, Kind kind, Topology topology)
157 : kind_(kind),
158 topology_(topology) {
159 swap(expr, e);
160 if (topology == NOT_NECESSARILY_CLOSED) {
161 expr.set_space_dimension(expr.space_dimension() + 1);
162 }
163 strong_normalize();
164 }
165
166 inline
Generator(const Generator & g)167 Generator::Generator(const Generator& g)
168 : expr(g.expr),
169 kind_(g.kind_),
170 topology_(g.topology_) {
171 }
172
173 inline
Generator(const Generator & g,Representation r)174 Generator::Generator(const Generator& g, Representation r)
175 : expr(g.expr, r),
176 kind_(g.kind_),
177 topology_(g.topology_) {
178 // This does not assert OK() because it's called by OK().
179 PPL_ASSERT(OK());
180 }
181
182 inline
Generator(const Generator & g,dimension_type space_dim)183 Generator::Generator(const Generator& g, dimension_type space_dim)
184 : expr(g.expr, g.is_necessarily_closed() ? space_dim : (space_dim + 1)),
185 kind_(g.kind_),
186 topology_(g.topology_) {
187 PPL_ASSERT(OK());
188 PPL_ASSERT(space_dimension() == space_dim);
189 }
190
191 inline
Generator(const Generator & g,dimension_type space_dim,Representation r)192 Generator::Generator(const Generator& g, dimension_type space_dim,
193 Representation r)
194 : expr(g.expr, g.is_necessarily_closed() ? space_dim : (space_dim + 1), r),
195 kind_(g.kind_),
196 topology_(g.topology_) {
197 PPL_ASSERT(OK());
198 PPL_ASSERT(space_dimension() == space_dim);
199 }
200
201 inline
~Generator()202 Generator::~Generator() {
203 }
204
205 inline Generator&
operator =(const Generator & g)206 Generator::operator=(const Generator& g) {
207 Generator tmp = g;
208 swap(*this, tmp);
209
210 return *this;
211 }
212
213 inline Representation
representation() const214 Generator::representation() const {
215 return expr.representation();
216 }
217
218 inline void
set_representation(Representation r)219 Generator::set_representation(Representation r) {
220 expr.set_representation(r);
221 }
222
223 inline dimension_type
max_space_dimension()224 Generator::max_space_dimension() {
225 return Linear_Expression::max_space_dimension();
226 }
227
228 inline void
set_space_dimension_no_ok(dimension_type space_dim)229 Generator::set_space_dimension_no_ok(dimension_type space_dim) {
230 const dimension_type old_expr_space_dim = expr.space_dimension();
231 if (topology() == NECESSARILY_CLOSED) {
232 expr.set_space_dimension(space_dim);
233 }
234 else {
235 const dimension_type old_space_dim = space_dimension();
236 if (space_dim > old_space_dim) {
237 expr.set_space_dimension(space_dim + 1);
238 expr.swap_space_dimensions(Variable(space_dim), Variable(old_space_dim));
239 }
240 else {
241 expr.swap_space_dimensions(Variable(space_dim), Variable(old_space_dim));
242 expr.set_space_dimension(space_dim + 1);
243 }
244 }
245 PPL_ASSERT(space_dimension() == space_dim);
246 if (expr.space_dimension() < old_expr_space_dim) {
247 strong_normalize();
248 }
249 }
250
251 inline void
set_space_dimension(dimension_type space_dim)252 Generator::set_space_dimension(dimension_type space_dim) {
253 set_space_dimension_no_ok(space_dim);
254 PPL_ASSERT(OK());
255 }
256
257 inline void
shift_space_dimensions(Variable v,dimension_type n)258 Generator::shift_space_dimensions(Variable v, dimension_type n) {
259 expr.shift_space_dimensions(v, n);
260 }
261
262 inline bool
is_line() const263 Generator::is_line() const {
264 return is_line_or_equality();
265 }
266
267 inline bool
is_ray_or_point() const268 Generator::is_ray_or_point() const {
269 return is_ray_or_point_or_inequality();
270 }
271
272 inline bool
is_line_or_ray() const273 Generator::is_line_or_ray() const {
274 return expr.inhomogeneous_term() == 0;
275 }
276
277 inline bool
is_ray() const278 Generator::is_ray() const {
279 return is_ray_or_point() && is_line_or_ray();
280 }
281
282 inline Generator::Type
type() const283 Generator::type() const {
284 if (is_line()) {
285 return LINE;
286 }
287 if (is_line_or_ray()) {
288 return RAY;
289 }
290 if (is_necessarily_closed()) {
291 return POINT;
292 }
293 else {
294 // Checking the value of the epsilon coefficient.
295 if (epsilon_coefficient() == 0) {
296 return CLOSURE_POINT;
297 }
298 else {
299 return POINT;
300 }
301 }
302 }
303
304 inline bool
is_point() const305 Generator::is_point() const {
306 return type() == POINT;
307 }
308
309 inline bool
is_closure_point() const310 Generator::is_closure_point() const {
311 return type() == CLOSURE_POINT;
312 }
313
314 inline void
set_is_line()315 Generator::set_is_line() {
316 set_is_line_or_equality();
317 }
318
319 inline void
set_is_ray_or_point()320 Generator::set_is_ray_or_point() {
321 set_is_ray_or_point_or_inequality();
322 }
323
324 inline Coefficient_traits::const_reference
coefficient(const Variable v) const325 Generator::coefficient(const Variable v) const {
326 if (v.space_dimension() > space_dimension()) {
327 throw_dimension_incompatible("coefficient(v)", "v", v);
328 }
329 return expr.coefficient(v);
330 }
331
332 inline Coefficient_traits::const_reference
divisor() const333 Generator::divisor() const {
334 Coefficient_traits::const_reference d = expr.inhomogeneous_term();
335 if (!is_ray_or_point() || d == 0) {
336 throw_invalid_argument("divisor()",
337 "*this is neither a point nor a closure point");
338 }
339 return d;
340 }
341
342 inline Coefficient_traits::const_reference
epsilon_coefficient() const343 Generator::epsilon_coefficient() const {
344 PPL_ASSERT(is_not_necessarily_closed());
345 return expr.coefficient(Variable(expr.space_dimension() - 1));
346 }
347
348
349 inline void
set_epsilon_coefficient(Coefficient_traits::const_reference n)350 Generator::set_epsilon_coefficient(Coefficient_traits::const_reference n) {
351 PPL_ASSERT(is_not_necessarily_closed());
352 expr.set_coefficient(Variable(expr.space_dimension() - 1), n);
353 }
354
355
356 inline memory_size_type
external_memory_in_bytes() const357 Generator::external_memory_in_bytes() const {
358 return expr.external_memory_in_bytes();
359 }
360
361 inline memory_size_type
total_memory_in_bytes() const362 Generator::total_memory_in_bytes() const {
363 return sizeof(*this) + external_memory_in_bytes();
364 }
365
366 inline void
strong_normalize()367 Generator::strong_normalize() {
368 expr.normalize();
369 sign_normalize();
370 }
371
372 inline const Generator&
zero_dim_point()373 Generator::zero_dim_point() {
374 PPL_ASSERT(zero_dim_point_p != 0);
375 return *zero_dim_point_p;
376 }
377
378 inline const Generator&
zero_dim_closure_point()379 Generator::zero_dim_closure_point() {
380 PPL_ASSERT(zero_dim_closure_point_p != 0);
381 return *zero_dim_closure_point_p;
382 }
383
384 /*! \relates Generator */
385 inline Generator
line(const Linear_Expression & e,Representation r)386 line(const Linear_Expression& e, Representation r) {
387 return Generator::line(e, r);
388 }
389
390 /*! \relates Generator */
391 inline Generator
ray(const Linear_Expression & e,Representation r)392 ray(const Linear_Expression& e, Representation r) {
393 return Generator::ray(e, r);
394 }
395
396 /*! \relates Generator */
397 inline Generator
point(const Linear_Expression & e,Coefficient_traits::const_reference d,Representation r)398 point(const Linear_Expression& e, Coefficient_traits::const_reference d,
399 Representation r) {
400 return Generator::point(e, d, r);
401 }
402
403 /*! \relates Generator */
404 inline Generator
point(Representation r)405 point(Representation r) {
406 return Generator::point(r);
407 }
408
409 /*! \relates Generator */
410 inline Generator
point(const Linear_Expression & e,Representation r)411 point(const Linear_Expression& e, Representation r) {
412 return Generator::point(e, r);
413 }
414
415 /*! \relates Generator */
416 inline Generator
closure_point(const Linear_Expression & e,Coefficient_traits::const_reference d,Representation r)417 closure_point(const Linear_Expression& e,
418 Coefficient_traits::const_reference d,
419 Representation r) {
420 return Generator::closure_point(e, d, r);
421 }
422
423 /*! \relates Generator */
424 inline Generator
closure_point(Representation r)425 closure_point(Representation r) {
426 return Generator::closure_point(r);
427 }
428
429 /*! \relates Generator */
430 inline Generator
closure_point(const Linear_Expression & e,Representation r)431 closure_point(const Linear_Expression& e,
432 Representation r) {
433 return Generator::closure_point(e, r);
434 }
435
436 /*! \relates Generator */
437 inline bool
operator ==(const Generator & x,const Generator & y)438 operator==(const Generator& x, const Generator& y) {
439 return x.is_equivalent_to(y);
440 }
441
442 /*! \relates Generator */
443 inline bool
operator !=(const Generator & x,const Generator & y)444 operator!=(const Generator& x, const Generator& y) {
445 return !x.is_equivalent_to(y);
446 }
447
448 inline void
ascii_dump(std::ostream & s) const449 Generator::ascii_dump(std::ostream& s) const {
450
451 expr.ascii_dump(s);
452
453 s << " ";
454
455 switch (type()) {
456 case Generator::LINE:
457 s << "L ";
458 break;
459 case Generator::RAY:
460 s << "R ";
461 break;
462 case Generator::POINT:
463 s << "P ";
464 break;
465 case Generator::CLOSURE_POINT:
466 s << "C ";
467 break;
468 }
469 if (is_necessarily_closed()) {
470 s << "(C)";
471 }
472 else {
473 s << "(NNC)";
474 }
475 s << "\n";
476 }
477
478 inline bool
ascii_load(std::istream & s)479 Generator::ascii_load(std::istream& s) {
480 std::string str;
481
482 expr.ascii_load(s);
483
484 if (!(s >> str)) {
485 return false;
486 }
487 if (str == "L") {
488 set_is_line();
489 }
490 else if (str == "R" || str == "P" || str == "C") {
491 set_is_ray_or_point();
492 }
493 else {
494 return false;
495 }
496
497 std::string str2;
498
499 if (!(s >> str2)) {
500 return false;
501 }
502 if (str2 == "(C)") {
503 if (is_not_necessarily_closed()) {
504 // TODO: Avoid using the mark_as_*() methods if possible.
505 mark_as_necessarily_closed();
506 }
507 }
508 else {
509 if (str2 == "(NNC)") {
510 if (is_necessarily_closed()) {
511 // TODO: Avoid using the mark_as_*() methods if possible.
512 mark_as_not_necessarily_closed();
513 }
514 }
515 else {
516 return false;
517 }
518 }
519
520 // Checking for equality of actual and declared types.
521 switch (type()) {
522 case Generator::LINE:
523 if (str != "L") {
524 return false;
525 }
526 break;
527 case Generator::RAY:
528 if (str != "R") {
529 return false;
530 }
531 break;
532 case Generator::POINT:
533 if (str != "P") {
534 return false;
535 }
536 break;
537 case Generator::CLOSURE_POINT:
538 if (str != "C") {
539 return false;
540 }
541 break;
542 }
543
544 return true;
545 }
546
547 inline void
m_swap(Generator & y)548 Generator::m_swap(Generator& y) {
549 using std::swap;
550 swap(expr, y.expr);
551 swap(kind_, y.kind_);
552 swap(topology_, y.topology_);
553 }
554
555 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
556 /*! \relates Generator */
557 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
558 template <typename Specialization, typename Temp, typename To>
559 inline bool
l_m_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const Generator & x,const Generator & y,const Rounding_Dir dir,Temp & tmp0,Temp & tmp1,Temp & tmp2)560 l_m_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
561 const Generator& x,
562 const Generator& y,
563 const Rounding_Dir dir,
564 Temp& tmp0,
565 Temp& tmp1,
566 Temp& tmp2) {
567 // Generator kind compatibility check: we only compute distances
568 // between (closure) points.
569 if (x.is_line_or_ray() || y.is_line_or_ray()) {
570 return false;
571 }
572 const dimension_type x_space_dim = x.space_dimension();
573 // Dimension-compatibility check.
574 if (x_space_dim != y.space_dimension()) {
575 return false;
576 }
577
578 // All zero-dim generators have distance zero.
579 if (x_space_dim == 0) {
580 assign_r(r, 0, ROUND_NOT_NEEDED);
581 return true;
582 }
583
584 PPL_DIRTY_TEMP(mpq_class, x_coord);
585 PPL_DIRTY_TEMP(mpq_class, y_coord);
586 PPL_DIRTY_TEMP(mpq_class, x_div);
587 PPL_DIRTY_TEMP(mpq_class, y_div);
588 assign_r(x_div, x.divisor(), ROUND_NOT_NEEDED);
589 assign_r(y_div, y.divisor(), ROUND_NOT_NEEDED);
590
591 assign_r(tmp0, 0, ROUND_NOT_NEEDED);
592 // TODO: This loop can be optimized more, if needed.
593 for (dimension_type i = x_space_dim; i-- > 0; ) {
594 assign_r(x_coord, x.coefficient(Variable(i)), ROUND_NOT_NEEDED);
595 div_assign_r(x_coord, x_coord, x_div, ROUND_NOT_NEEDED);
596 assign_r(y_coord, y.coefficient(Variable(i)), ROUND_NOT_NEEDED);
597 div_assign_r(y_coord, y_coord, y_div, ROUND_NOT_NEEDED);
598 const Temp* tmp1p;
599 const Temp* tmp2p;
600
601 if (x_coord > y_coord) {
602 maybe_assign(tmp1p, tmp1, x_coord, dir);
603 maybe_assign(tmp2p, tmp2, y_coord, inverse(dir));
604 }
605 else {
606 maybe_assign(tmp1p, tmp1, y_coord, dir);
607 maybe_assign(tmp2p, tmp2, x_coord, inverse(dir));
608 }
609 sub_assign_r(tmp1, *tmp1p, *tmp2p, dir);
610 PPL_ASSERT(sgn(tmp1) >= 0);
611 Specialization::combine(tmp0, tmp1, dir);
612 }
613 Specialization::finalize(tmp0, dir);
614 assign_r(r, tmp0, dir);
615 return true;
616 }
617
618 /*! \relates Generator */
619 template <typename Temp, typename To>
620 inline bool
rectilinear_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const Generator & x,const Generator & y,const Rounding_Dir dir,Temp & tmp0,Temp & tmp1,Temp & tmp2)621 rectilinear_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
622 const Generator& x,
623 const Generator& y,
624 const Rounding_Dir dir,
625 Temp& tmp0,
626 Temp& tmp1,
627 Temp& tmp2) {
628 return l_m_distance_assign<Rectilinear_Distance_Specialization<Temp> >
629 (r, x, y, dir, tmp0, tmp1, tmp2);
630 }
631
632 /*! \relates Generator */
633 template <typename Temp, typename To>
634 inline bool
rectilinear_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const Generator & x,const Generator & y,const Rounding_Dir dir)635 rectilinear_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
636 const Generator& x,
637 const Generator& y,
638 const Rounding_Dir dir) {
639 typedef Checked_Number<Temp, Extended_Number_Policy> Checked_Temp;
640 PPL_DIRTY_TEMP(Checked_Temp, tmp0);
641 PPL_DIRTY_TEMP(Checked_Temp, tmp1);
642 PPL_DIRTY_TEMP(Checked_Temp, tmp2);
643 return rectilinear_distance_assign(r, x, y, dir, tmp0, tmp1, tmp2);
644 }
645
646 /*! \relates Generator */
647 template <typename To>
648 inline bool
rectilinear_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const Generator & x,const Generator & y,const Rounding_Dir dir)649 rectilinear_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
650 const Generator& x,
651 const Generator& y,
652 const Rounding_Dir dir) {
653 return rectilinear_distance_assign<To, To>(r, x, y, dir);
654 }
655
656 /*! \relates Generator */
657 template <typename Temp, typename To>
658 inline bool
euclidean_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const Generator & x,const Generator & y,const Rounding_Dir dir,Temp & tmp0,Temp & tmp1,Temp & tmp2)659 euclidean_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
660 const Generator& x,
661 const Generator& y,
662 const Rounding_Dir dir,
663 Temp& tmp0,
664 Temp& tmp1,
665 Temp& tmp2) {
666 return l_m_distance_assign<Euclidean_Distance_Specialization<Temp> >
667 (r, x, y, dir, tmp0, tmp1, tmp2);
668 }
669
670 /*! \relates Generator */
671 template <typename Temp, typename To>
672 inline bool
euclidean_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const Generator & x,const Generator & y,const Rounding_Dir dir)673 euclidean_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
674 const Generator& x,
675 const Generator& y,
676 const Rounding_Dir dir) {
677 typedef Checked_Number<Temp, Extended_Number_Policy> Checked_Temp;
678 PPL_DIRTY_TEMP(Checked_Temp, tmp0);
679 PPL_DIRTY_TEMP(Checked_Temp, tmp1);
680 PPL_DIRTY_TEMP(Checked_Temp, tmp2);
681 return euclidean_distance_assign(r, x, y, dir, tmp0, tmp1, tmp2);
682 }
683
684 /*! \relates Generator */
685 template <typename To>
686 inline bool
euclidean_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const Generator & x,const Generator & y,const Rounding_Dir dir)687 euclidean_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
688 const Generator& x,
689 const Generator& y,
690 const Rounding_Dir dir) {
691 return euclidean_distance_assign<To, To>(r, x, y, dir);
692 }
693
694 /*! \relates Generator */
695 template <typename Temp, typename To>
696 inline bool
l_infinity_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const Generator & x,const Generator & y,const Rounding_Dir dir,Temp & tmp0,Temp & tmp1,Temp & tmp2)697 l_infinity_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
698 const Generator& x,
699 const Generator& y,
700 const Rounding_Dir dir,
701 Temp& tmp0,
702 Temp& tmp1,
703 Temp& tmp2) {
704 return l_m_distance_assign<L_Infinity_Distance_Specialization<Temp> >
705 (r, x, y, dir, tmp0, tmp1, tmp2);
706 }
707
708 /*! \relates Generator */
709 template <typename Temp, typename To>
710 inline bool
l_infinity_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const Generator & x,const Generator & y,const Rounding_Dir dir)711 l_infinity_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
712 const Generator& x,
713 const Generator& y,
714 const Rounding_Dir dir) {
715 typedef Checked_Number<Temp, Extended_Number_Policy> Checked_Temp;
716 PPL_DIRTY_TEMP(Checked_Temp, tmp0);
717 PPL_DIRTY_TEMP(Checked_Temp, tmp1);
718 PPL_DIRTY_TEMP(Checked_Temp, tmp2);
719 return l_infinity_distance_assign(r, x, y, dir, tmp0, tmp1, tmp2);
720 }
721
722 /*! \relates Generator */
723 template <typename To>
724 inline bool
l_infinity_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const Generator & x,const Generator & y,const Rounding_Dir dir)725 l_infinity_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
726 const Generator& x,
727 const Generator& y,
728 const Rounding_Dir dir) {
729 return l_infinity_distance_assign<To, To>(r, x, y, dir);
730 }
731
732 /*! \relates Generator */
733 inline void
swap(Generator & x,Generator & y)734 swap(Generator& x, Generator& y) {
735 x.m_swap(y);
736 }
737
738 } // namespace Parma_Polyhedra_Library
739
740 #endif // !defined(PPL_Generator_inlines_hh)
741