1 /* Linear_Expression 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_Linear_Expression_inlines_hh
25 #define PPL_Linear_Expression_inlines_hh 1
26 
27 #include "Expression_Adapter_defs.hh"
28 
29 namespace Parma_Polyhedra_Library {
30 
31 inline Linear_Expression&
operator =(const Linear_Expression & e)32 Linear_Expression::operator=(const Linear_Expression& e) {
33   Linear_Expression tmp = e;
34   swap(*this, tmp);
35   return *this;
36 }
37 
38 inline
~Linear_Expression()39 Linear_Expression::~Linear_Expression() {
40   delete impl;
41 }
42 
43 inline Representation
representation() const44 Linear_Expression::representation() const {
45   return impl->representation();
46 }
47 
48 inline dimension_type
space_dimension() const49 Linear_Expression::space_dimension() const {
50   return impl->space_dimension();
51 }
52 
53 inline void
set_space_dimension(dimension_type n)54 Linear_Expression::set_space_dimension(dimension_type n) {
55   impl->set_space_dimension(n);
56 }
57 
58 inline Coefficient_traits::const_reference
coefficient(Variable v) const59 Linear_Expression::coefficient(Variable v) const {
60   return impl->coefficient(v);
61 }
62 
63 inline void
64 Linear_Expression
set_coefficient(Variable v,Coefficient_traits::const_reference n)65 ::set_coefficient(Variable v, Coefficient_traits::const_reference n) {
66   impl->set_coefficient(v, n);
67 }
68 
69 inline Coefficient_traits::const_reference
inhomogeneous_term() const70 Linear_Expression::inhomogeneous_term() const {
71   return impl->inhomogeneous_term();
72 }
73 
74 inline void
75 Linear_Expression
set_inhomogeneous_term(Coefficient_traits::const_reference n)76 ::set_inhomogeneous_term(Coefficient_traits::const_reference n) {
77   impl->set_inhomogeneous_term(n);
78 }
79 
80 inline void
swap_space_dimensions(Variable v1,Variable v2)81 Linear_Expression::swap_space_dimensions(Variable v1, Variable v2) {
82   impl->swap_space_dimensions(v1, v2);
83 }
84 
85 inline void
shift_space_dimensions(Variable v,dimension_type n)86 Linear_Expression::shift_space_dimensions(Variable v, dimension_type n) {
87   impl->shift_space_dimensions(v, n);
88 }
89 
90 inline bool
is_zero() const91 Linear_Expression::is_zero() const {
92   return impl->is_zero();
93 }
94 
95 inline bool
all_homogeneous_terms_are_zero() const96 Linear_Expression::all_homogeneous_terms_are_zero() const {
97   return impl->all_homogeneous_terms_are_zero();
98 }
99 
100 inline const Linear_Expression&
zero()101 Linear_Expression::zero() {
102   PPL_ASSERT(zero_p != 0);
103   return *zero_p;
104 }
105 
106 inline memory_size_type
external_memory_in_bytes() const107 Linear_Expression::external_memory_in_bytes() const {
108   return impl->total_memory_in_bytes();
109 }
110 
111 inline memory_size_type
total_memory_in_bytes() const112 Linear_Expression::total_memory_in_bytes() const {
113   return external_memory_in_bytes() + sizeof(*this);
114 }
115 
116 /*! \relates Linear_Expression */
117 inline Linear_Expression
operator +(const Linear_Expression & e)118 operator+(const Linear_Expression& e) {
119   return e;
120 }
121 
122 /*! \relates Linear_Expression */
123 inline Linear_Expression
operator +(const Linear_Expression & e,Coefficient_traits::const_reference n)124 operator+(const Linear_Expression& e, Coefficient_traits::const_reference n) {
125   Linear_Expression x = e;
126   x += n;
127   return x;
128 }
129 
130 /*! \relates Linear_Expression */
131 inline Linear_Expression
operator +(const Linear_Expression & e,const Variable v)132 operator+(const Linear_Expression& e, const Variable v) {
133   Linear_Expression x = e;
134   x += v;
135   return x;
136 }
137 
138 /*! \relates Linear_Expression */
139 inline Linear_Expression
operator -(const Linear_Expression & e,Coefficient_traits::const_reference n)140 operator-(const Linear_Expression& e, Coefficient_traits::const_reference n) {
141   Linear_Expression x = e;
142   x -= n;
143   return x;
144 }
145 
146 /*! \relates Linear_Expression */
147 inline Linear_Expression
operator -(const Variable v,const Variable w)148 operator-(const Variable v, const Variable w) {
149   const dimension_type v_space_dim = v.space_dimension();
150   const dimension_type w_space_dim = w.space_dimension();
151   const dimension_type space_dim = std::max(v_space_dim, w_space_dim);
152   if (space_dim > Linear_Expression::max_space_dimension()) {
153     throw std::length_error("Linear_Expression "
154                             "PPL::operator+(v, w):\n"
155                             "v or w exceed the maximum allowed "
156                             "space dimension.");
157   }
158   if (v_space_dim >= w_space_dim) {
159     Linear_Expression e(v);
160     e -= w;
161     return e;
162   }
163   else {
164     Linear_Expression e(w.space_dimension(), true);
165     e -= w;
166     e += v;
167     return e;
168   }
169 }
170 
171 /*! \relates Linear_Expression */
172 inline Linear_Expression
operator *(const Linear_Expression & e,Coefficient_traits::const_reference n)173 operator*(const Linear_Expression& e, Coefficient_traits::const_reference n) {
174   Linear_Expression x = e;
175   x *= n;
176   return x;
177 }
178 
179 /*! \relates Linear_Expression */
180 inline Linear_Expression&
operator +=(Linear_Expression & e,Coefficient_traits::const_reference n)181 operator+=(Linear_Expression& e, Coefficient_traits::const_reference n) {
182   *e.impl += n;
183   return e;
184 }
185 
186 /*! \relates Linear_Expression */
187 inline Linear_Expression&
operator -=(Linear_Expression & e,Coefficient_traits::const_reference n)188 operator-=(Linear_Expression& e, Coefficient_traits::const_reference n) {
189   *e.impl -= n;
190   return e;
191 }
192 
193 inline void
m_swap(Linear_Expression & y)194 Linear_Expression::m_swap(Linear_Expression& y) {
195   using std::swap;
196   swap(impl, y.impl);
197 }
198 
199 inline void
normalize()200 Linear_Expression::normalize() {
201   impl->normalize();
202 }
203 
204 inline void
ascii_dump(std::ostream & s) const205 Linear_Expression::ascii_dump(std::ostream& s) const {
206   impl->ascii_dump(s);
207 }
208 
209 inline bool
ascii_load(std::istream & s)210 Linear_Expression::ascii_load(std::istream& s) {
211   return impl->ascii_load(s);
212 }
213 
214 inline void
remove_space_dimensions(const Variables_Set & vars)215 Linear_Expression::remove_space_dimensions(const Variables_Set& vars) {
216   impl->remove_space_dimensions(vars);
217 }
218 
219 inline void
permute_space_dimensions(const std::vector<Variable> & cycle)220 Linear_Expression::permute_space_dimensions(const std::vector<Variable>& cycle) {
221   impl->permute_space_dimensions(cycle);
222 }
223 
224 /*! \relates Parma_Polyhedra_Library::Linear_Expression */
225 inline Linear_Expression
operator +(const Linear_Expression & e1,const Linear_Expression & e2)226 operator+(const Linear_Expression& e1, const Linear_Expression& e2) {
227   if (e1.space_dimension() >= e2.space_dimension()) {
228     Linear_Expression e = e1;
229     e += e2;
230     return e;
231   }
232   else {
233     Linear_Expression e = e2;
234     e += e1;
235     return e;
236   }
237 }
238 
239 /*! \relates Linear_Expression */
240 inline Linear_Expression
operator +(const Variable v,const Linear_Expression & e)241 operator+(const Variable v, const Linear_Expression& e) {
242   return e + v;
243 }
244 
245 /*! \relates Parma_Polyhedra_Library::Linear_Expression */
246 inline Linear_Expression
operator +(Coefficient_traits::const_reference n,const Linear_Expression & e)247 operator+(Coefficient_traits::const_reference n,
248                const Linear_Expression& e) {
249   return e + n;
250 }
251 
252 /*! \relates Linear_Expression */
253 inline Linear_Expression
operator +(const Variable v,const Variable w)254 operator+(const Variable v, const Variable w) {
255   const dimension_type v_space_dim = v.space_dimension();
256   const dimension_type w_space_dim = w.space_dimension();
257   const dimension_type space_dim = std::max(v_space_dim, w_space_dim);
258   if (space_dim > Linear_Expression::max_space_dimension()) {
259     throw std::length_error("Linear_Expression "
260                             "PPL::operator+(v, w):\n"
261                             "v or w exceed the maximum allowed "
262                             "space dimension.");
263   }
264   if (v_space_dim >= w_space_dim) {
265     Linear_Expression e(v);
266     e += w;
267     return e;
268   }
269   else {
270     Linear_Expression e(w);
271     e += v;
272     return e;
273   }
274 }
275 
276 /*! \relates Parma_Polyhedra_Library::Linear_Expression */
277 inline Linear_Expression
operator -(const Linear_Expression & e)278 operator-(const Linear_Expression& e) {
279   Linear_Expression r(e);
280   neg_assign(r);
281   return r;
282 }
283 
284 /*! \relates Parma_Polyhedra_Library::Linear_Expression */
285 inline Linear_Expression
operator -(const Linear_Expression & e1,const Linear_Expression & e2)286 operator-(const Linear_Expression& e1, const Linear_Expression& e2) {
287   if (e1.space_dimension() >= e2.space_dimension()) {
288     Linear_Expression e = e1;
289     e -= e2;
290     return e;
291   }
292   else {
293     Linear_Expression e = e2;
294     neg_assign(e);
295     e += e1;
296     return e;
297   }
298 }
299 
300 /*! \relates Parma_Polyhedra_Library::Linear_Expression */
301 inline Linear_Expression
operator -(const Variable v,const Linear_Expression & e)302 operator-(const Variable v, const Linear_Expression& e) {
303   Linear_Expression result(e, std::max(v.space_dimension(), e.space_dimension()));
304   result.negate(0, e.space_dimension() + 1);
305   result += v;
306   return result;
307 }
308 
309 /*! \relates Linear_Expression */
310 inline Linear_Expression
operator -(const Linear_Expression & e,const Variable v)311 operator-(const Linear_Expression& e, const Variable v) {
312   Linear_Expression result(e, std::max(v.space_dimension(), e.space_dimension()));
313   result -= v;
314   return result;
315 }
316 
317 /*! \relates Parma_Polyhedra_Library::Linear_Expression */
318 inline Linear_Expression
operator -(Coefficient_traits::const_reference n,const Linear_Expression & e)319 operator-(Coefficient_traits::const_reference n,
320                const Linear_Expression& e) {
321   Linear_Expression result(e);
322   neg_assign(result);
323   result += n;
324   return result;
325 }
326 
327 /*! \relates Parma_Polyhedra_Library::Linear_Expression */
328 inline Linear_Expression
operator *(Coefficient_traits::const_reference n,const Linear_Expression & e)329 operator*(Coefficient_traits::const_reference n,
330                const Linear_Expression& e) {
331   return e * n;
332 }
333 
334 /*! \relates Parma_Polyhedra_Library::Linear_Expression */
335 inline Linear_Expression&
operator +=(Linear_Expression & e1,const Linear_Expression & e2)336 operator+=(Linear_Expression& e1, const Linear_Expression& e2) {
337   *e1.impl += *e2.impl;
338   return e1;
339 }
340 
341 /*! \relates Parma_Polyhedra_Library::Linear_Expression */
342 inline Linear_Expression&
operator +=(Linear_Expression & e,const Variable v)343 operator+=(Linear_Expression& e, const Variable v) {
344   *e.impl += v;
345   return e;
346 }
347 
348 /*! \relates Parma_Polyhedra_Library::Linear_Expression */
349 inline Linear_Expression&
operator -=(Linear_Expression & e1,const Linear_Expression & e2)350 operator-=(Linear_Expression& e1, const Linear_Expression& e2) {
351   *e1.impl -= *e2.impl;
352   return e1;
353 }
354 
355 /*! \relates Parma_Polyhedra_Library::Linear_Expression */
356 inline Linear_Expression&
operator -=(Linear_Expression & e,const Variable v)357 operator-=(Linear_Expression& e, const Variable v) {
358   *e.impl -= v;
359   return e;
360 }
361 
362 /*! \relates Parma_Polyhedra_Library::Linear_Expression */
363 inline Linear_Expression&
operator *=(Linear_Expression & e,Coefficient_traits::const_reference n)364 operator*=(Linear_Expression& e, Coefficient_traits::const_reference n) {
365   *e.impl *= n;
366   return e;
367 }
368 
369 /*! \relates Parma_Polyhedra_Library::Linear_Expression */
370 inline Linear_Expression&
operator /=(Linear_Expression & e,Coefficient_traits::const_reference n)371 operator/=(Linear_Expression& e, Coefficient_traits::const_reference n) {
372   *e.impl /= n;
373   return e;
374 }
375 
376 /*! \relates Parma_Polyhedra_Library::Linear_Expression */
377 inline void
neg_assign(Linear_Expression & e)378 neg_assign(Linear_Expression& e) {
379   e.impl->negate();
380 }
381 
382 /*! \relates Parma_Polyhedra_Library::Linear_Expression */
383 inline Linear_Expression&
add_mul_assign(Linear_Expression & e,Coefficient_traits::const_reference n,const Variable v)384 add_mul_assign(Linear_Expression& e,
385                Coefficient_traits::const_reference n,
386                const Variable v) {
387   e.impl->add_mul_assign(n, v);
388   return e;
389 }
390 
391 /*! \relates Parma_Polyhedra_Library::Linear_Expression */
392 inline Linear_Expression&
sub_mul_assign(Linear_Expression & e,Coefficient_traits::const_reference n,const Variable v)393 sub_mul_assign(Linear_Expression& e,
394                     Coefficient_traits::const_reference n,
395                     const Variable v) {
396   e.impl->sub_mul_assign(n, v);
397   return e;
398 }
399 
400 inline void
add_mul_assign(Linear_Expression & e1,Coefficient_traits::const_reference factor,const Linear_Expression & e2)401 add_mul_assign(Linear_Expression& e1,
402                Coefficient_traits::const_reference factor,
403                const Linear_Expression& e2) {
404   e1.impl->add_mul_assign(factor, *e2.impl);
405 }
406 
407 inline void
sub_mul_assign(Linear_Expression & e1,Coefficient_traits::const_reference factor,const Linear_Expression & e2)408 sub_mul_assign(Linear_Expression& e1,
409                     Coefficient_traits::const_reference factor,
410                     const Linear_Expression& e2) {
411   e1.impl->sub_mul_assign(factor, *e2.impl);
412 }
413 
414 inline Coefficient_traits::const_reference
get(dimension_type i) const415 Linear_Expression::get(dimension_type i) const {
416   return impl->get(i);
417 }
418 
419 inline void
set(dimension_type i,Coefficient_traits::const_reference n)420 Linear_Expression::set(dimension_type i,
421                        Coefficient_traits::const_reference n) {
422   impl->set(i, n);
423 }
424 
425 inline Coefficient_traits::const_reference
get(Variable v) const426 Linear_Expression::get(Variable v) const {
427   return impl->get(v.space_dimension());
428 }
429 
430 inline void
set(Variable v,Coefficient_traits::const_reference n)431 Linear_Expression::set(Variable v,
432                        Coefficient_traits::const_reference n) {
433   impl->set(v.space_dimension(), n);
434 }
435 
436 inline bool
all_zeroes(dimension_type start,dimension_type end) const437 Linear_Expression::all_zeroes(dimension_type start, dimension_type end) const {
438   return impl->all_zeroes(start, end);
439 }
440 
441 inline dimension_type
num_zeroes(dimension_type start,dimension_type end) const442 Linear_Expression::num_zeroes(dimension_type start, dimension_type end) const {
443   return impl->num_zeroes(start, end);
444 }
445 
446 inline Coefficient
gcd(dimension_type start,dimension_type end) const447 Linear_Expression::gcd(dimension_type start, dimension_type end) const {
448   return impl->gcd(start, end);
449 }
450 
451 inline void
452 Linear_Expression
exact_div_assign(Coefficient_traits::const_reference c,dimension_type start,dimension_type end)453 ::exact_div_assign(Coefficient_traits::const_reference c,
454                    dimension_type start, dimension_type end) {
455   impl->exact_div_assign(c, start, end);
456 }
457 
458 inline void
459 Linear_Expression
mul_assign(Coefficient_traits::const_reference c,dimension_type start,dimension_type end)460 ::mul_assign(Coefficient_traits::const_reference c,
461              dimension_type start, dimension_type end) {
462   impl->mul_assign(c, start, end);
463 }
464 
465 inline void
sign_normalize()466 Linear_Expression::sign_normalize() {
467   impl->sign_normalize();
468 }
469 
470 inline void
negate(dimension_type first,dimension_type last)471 Linear_Expression::negate(dimension_type first, dimension_type last) {
472   impl->negate(first, last);
473 }
474 
475 inline bool
all_zeroes(const Variables_Set & vars) const476 Linear_Expression::all_zeroes(const Variables_Set& vars) const {
477   return impl->all_zeroes(vars);
478 }
479 
480 inline bool
all_zeroes_except(const Variables_Set & vars,dimension_type start,dimension_type end) const481 Linear_Expression::all_zeroes_except(const Variables_Set& vars,
482                                      dimension_type start,
483                                      dimension_type end) const {
484   return impl->all_zeroes_except(vars, start, end);
485 }
486 
487 inline dimension_type
last_nonzero() const488 Linear_Expression::last_nonzero() const {
489   return impl->last_nonzero();
490 }
491 
492 inline void
493 Linear_Expression
scalar_product_assign(Coefficient & result,const Linear_Expression & y) const494 ::scalar_product_assign(Coefficient& result, const Linear_Expression& y) const {
495   scalar_product_assign(result, y, 0, space_dimension() + 1);
496 }
497 
498 inline void
499 Linear_Expression
scalar_product_assign(Coefficient & result,const Linear_Expression & y,dimension_type start,dimension_type end) const500 ::scalar_product_assign(Coefficient& result, const Linear_Expression& y,
501                         dimension_type start, dimension_type end) const {
502   impl->scalar_product_assign(result, *(y.impl), start, end);
503 }
504 
505 inline int
506 Linear_Expression
scalar_product_sign(const Linear_Expression & y) const507 ::scalar_product_sign(const Linear_Expression& y) const {
508   return scalar_product_sign(y, 0, space_dimension() + 1);
509 }
510 
511 inline int
512 Linear_Expression
scalar_product_sign(const Linear_Expression & y,dimension_type start,dimension_type end) const513 ::scalar_product_sign(const Linear_Expression& y,
514                       dimension_type start, dimension_type end) const {
515   return impl->scalar_product_sign(*(y.impl), start, end);
516 }
517 
518 inline dimension_type
519 Linear_Expression
first_nonzero(dimension_type first,dimension_type last) const520 ::first_nonzero(dimension_type first, dimension_type last) const {
521   return impl->first_nonzero(first, last);
522 }
523 
524 inline dimension_type
525 Linear_Expression
last_nonzero(dimension_type first,dimension_type last) const526 ::last_nonzero(dimension_type first, dimension_type last) const {
527   return impl->last_nonzero(first, last);
528 }
529 
530 inline void
531 Linear_Expression
has_a_free_dimension_helper(std::set<dimension_type> & x) const532 ::has_a_free_dimension_helper(std::set<dimension_type>& x) const {
533   return impl->has_a_free_dimension_helper(x);
534 }
535 
536 inline bool
537 Linear_Expression
is_equal_to(const Linear_Expression & x,dimension_type start,dimension_type end) const538 ::is_equal_to(const Linear_Expression& x,
539               dimension_type start, dimension_type end) const {
540   return impl->is_equal_to(*(x.impl), start, end);
541 }
542 
543 inline bool
544 Linear_Expression
is_equal_to(const Linear_Expression & x,Coefficient_traits::const_reference c1,Coefficient_traits::const_reference c2,dimension_type start,dimension_type end) const545 ::is_equal_to(const Linear_Expression& x,
546               Coefficient_traits::const_reference c1,
547               Coefficient_traits::const_reference c2,
548               dimension_type start, dimension_type end) const {
549   return impl->is_equal_to(*(x.impl), c1, c2, start, end);
550 }
551 
552 inline void
553 Linear_Expression
get_row(Dense_Row & r) const554 ::get_row(Dense_Row& r) const {
555   return impl->get_row(r);
556 }
557 
558 inline void
559 Linear_Expression
get_row(Sparse_Row & r) const560 ::get_row(Sparse_Row& r) const {
561   return impl->get_row(r);
562 }
563 
564 inline void
565 Linear_Expression
linear_combine(const Linear_Expression & y,dimension_type i)566 ::linear_combine(const Linear_Expression& y, dimension_type i) {
567   impl->linear_combine(*y.impl, i);
568 }
569 
570 inline void
571 Linear_Expression
linear_combine(const Linear_Expression & y,Coefficient_traits::const_reference c1,Coefficient_traits::const_reference c2)572 ::linear_combine(const Linear_Expression& y,
573                  Coefficient_traits::const_reference c1,
574                  Coefficient_traits::const_reference c2) {
575   impl->linear_combine(*y.impl, c1, c2);
576 }
577 
578 inline void
579 Linear_Expression
linear_combine_lax(const Linear_Expression & y,Coefficient_traits::const_reference c1,Coefficient_traits::const_reference c2)580 ::linear_combine_lax(const Linear_Expression& y,
581                      Coefficient_traits::const_reference c1,
582                      Coefficient_traits::const_reference c2) {
583   impl->linear_combine_lax(*y.impl, c1, c2);
584 }
585 
586 inline int
compare(const Linear_Expression & x,const Linear_Expression & y)587 compare(const Linear_Expression& x, const Linear_Expression& y) {
588   return x.impl->compare(*y.impl);
589 }
590 
591 inline bool
is_equal_to(const Linear_Expression & x) const592 Linear_Expression::is_equal_to(const Linear_Expression& x) const {
593   return impl->is_equal_to(*x.impl);
594 }
595 
596 inline void
linear_combine(const Linear_Expression & y,Coefficient_traits::const_reference c1,Coefficient_traits::const_reference c2,dimension_type start,dimension_type end)597 Linear_Expression::linear_combine(const Linear_Expression& y,
598                                   Coefficient_traits::const_reference c1,
599                                   Coefficient_traits::const_reference c2,
600                                   dimension_type start,
601                                   dimension_type end) {
602   impl->linear_combine(*y.impl, c1, c2, start, end);
603 }
604 
605 inline void
linear_combine_lax(const Linear_Expression & y,Coefficient_traits::const_reference c1,Coefficient_traits::const_reference c2,dimension_type start,dimension_type end)606 Linear_Expression::linear_combine_lax(const Linear_Expression& y,
607                                       Coefficient_traits::const_reference c1,
608                                       Coefficient_traits::const_reference c2,
609                                       dimension_type start,
610                                       dimension_type end) {
611   impl->linear_combine_lax(*y.impl, c1, c2, start, end);
612 }
613 
614 inline bool
615 Linear_Expression
have_a_common_variable(const Linear_Expression & x,Variable first,Variable last) const616 ::have_a_common_variable(const Linear_Expression& x,
617                          Variable first, Variable last) const {
618   return impl->have_a_common_variable(*(x.impl), first, last);
619 }
620 
621 inline
622 Linear_Expression::const_iterator
const_iterator()623 ::const_iterator()
624   : itr(NULL) {
625 }
626 
627 inline
628 Linear_Expression::const_iterator
const_iterator(const const_iterator & i)629 ::const_iterator(const const_iterator& i)
630   : itr(i.itr->clone()) {
631 }
632 
633 inline
634 Linear_Expression::const_iterator
~const_iterator()635 ::~const_iterator() {
636   // Note that this does nothing if itr == NULL.
637   delete itr;
638 }
639 
640 inline void
m_swap(const_iterator & i)641 Linear_Expression::const_iterator::m_swap(const_iterator& i) {
642   using std::swap;
643   swap(itr, i.itr);
644 }
645 
646 inline Linear_Expression::const_iterator&
647 Linear_Expression::const_iterator
operator =(const const_iterator & i)648 ::operator=(const const_iterator& i) {
649   const_iterator tmp = i;
650   using std::swap;
651   swap(*this, tmp);
652   return *this;
653 }
654 
655 inline Linear_Expression::const_iterator&
656 Linear_Expression::const_iterator
operator ++()657 ::operator++() {
658   PPL_ASSERT(itr != NULL);
659   ++(*itr);
660   return *this;
661 }
662 
663 inline Linear_Expression::const_iterator&
664 Linear_Expression::const_iterator
operator --()665 ::operator--() {
666   PPL_ASSERT(itr != NULL);
667   --(*itr);
668   return *this;
669 }
670 
671 inline Linear_Expression::const_iterator::reference
672 Linear_Expression::const_iterator
operator *() const673 ::operator*() const {
674   PPL_ASSERT(itr != NULL);
675   return *(*itr);
676 }
677 
678 inline Variable
679 Linear_Expression::const_iterator
variable() const680 ::variable() const {
681   PPL_ASSERT(itr != NULL);
682   return itr->variable();
683 }
684 
685 inline bool
686 Linear_Expression::const_iterator
operator ==(const const_iterator & i) const687 ::operator==(const const_iterator& i) const {
688   PPL_ASSERT(itr != NULL);
689   PPL_ASSERT(i.itr != NULL);
690   return *itr == *(i.itr);
691 }
692 
693 inline bool
694 Linear_Expression::const_iterator
operator !=(const const_iterator & i) const695 ::operator!=(const const_iterator& i) const {
696   return !(*this == i);
697 }
698 
699 inline
700 Linear_Expression::const_iterator
const_iterator(Linear_Expression_Interface::const_iterator_interface * i)701 ::const_iterator(Linear_Expression_Interface::const_iterator_interface* i)
702   : itr(i) {
703   PPL_ASSERT(i != NULL);
704 }
705 
706 inline Linear_Expression::const_iterator
707 Linear_Expression
begin() const708 ::begin() const {
709   return const_iterator(impl->begin());
710 }
711 
712 inline Linear_Expression::const_iterator
713 Linear_Expression
end() const714 ::end() const {
715   return const_iterator(impl->end());
716 }
717 
718 inline Linear_Expression::const_iterator
719 Linear_Expression
lower_bound(Variable v) const720 ::lower_bound(Variable v) const {
721   return const_iterator(impl->lower_bound(v));
722 }
723 
724 template <typename LE_Adapter>
725 inline
726 Linear_Expression
Linear_Expression(const LE_Adapter & e,typename Enable_If<Is_Same_Or_Derived<Expression_Adapter_Base,LE_Adapter>::value,void * >::type)727 ::Linear_Expression(const LE_Adapter& e,
728                     typename Enable_If<Is_Same_Or_Derived<Expression_Adapter_Base,
729                                                           LE_Adapter>::value,
730                                        void*>::type)
731   : impl(NULL) {
732   Linear_Expression tmp(e.representation());
733   tmp.set_space_dimension(e.space_dimension());
734   tmp.set_inhomogeneous_term(e.inhomogeneous_term());
735   for (typename LE_Adapter::const_iterator i = e.begin(),
736          i_end = e.end(); i != i_end; ++i) {
737     add_mul_assign(tmp, *i, i.variable());
738   }
739   using std::swap;
740   swap(impl, tmp.impl);
741 }
742 
743 template <typename LE_Adapter>
744 inline
745 Linear_Expression
Linear_Expression(const LE_Adapter & e,Representation r,typename Enable_If<Is_Same_Or_Derived<Expression_Adapter_Base,LE_Adapter>::value,void * >::type)746 ::Linear_Expression(const LE_Adapter& e,
747                     Representation r,
748                     typename Enable_If<Is_Same_Or_Derived<Expression_Adapter_Base,
749                                                           LE_Adapter>::value,
750                                        void*>::type)
751   : impl(NULL) {
752   Linear_Expression tmp(r);
753   tmp.set_space_dimension(e.space_dimension());
754   tmp.set_inhomogeneous_term(e.inhomogeneous_term());
755   for (typename LE_Adapter::const_iterator i = e.begin(),
756          i_end = e.end(); i != i_end; ++i) {
757     add_mul_assign(tmp, *i, i.variable());
758   }
759   using std::swap;
760   swap(impl, tmp.impl);
761 }
762 
763 template <typename LE_Adapter>
764 inline
765 Linear_Expression
Linear_Expression(const LE_Adapter & e,dimension_type space_dim,typename Enable_If<Is_Same_Or_Derived<Expression_Adapter_Base,LE_Adapter>::value,void * >::type)766 ::Linear_Expression(const LE_Adapter& e,
767                     dimension_type space_dim,
768                     typename Enable_If<Is_Same_Or_Derived<Expression_Adapter_Base,
769                                                           LE_Adapter>::value,
770                                        void*>::type)
771   : impl(NULL) {
772   Linear_Expression tmp(e.representation());
773   tmp.set_space_dimension(space_dim);
774   tmp.set_inhomogeneous_term(e.inhomogeneous_term());
775   typedef typename LE_Adapter::const_iterator itr_t;
776   itr_t i_end;
777   if (space_dim <= e.space_dimension()) {
778     i_end = e.lower_bound(Variable(space_dim));
779   }
780   else {
781     i_end = e.end();
782   }
783   for (itr_t i = e.begin(); i != i_end; ++i) {
784     add_mul_assign(tmp, *i, i.variable());
785   }
786   using std::swap;
787   swap(impl, tmp.impl);
788 }
789 
790 template <typename LE_Adapter>
791 inline
792 Linear_Expression
Linear_Expression(const LE_Adapter & e,dimension_type space_dim,Representation r,typename Enable_If<Is_Same_Or_Derived<Expression_Adapter_Base,LE_Adapter>::value,void * >::type)793 ::Linear_Expression(const LE_Adapter& e,
794                     dimension_type space_dim,
795                     Representation r,
796                     typename Enable_If<Is_Same_Or_Derived<Expression_Adapter_Base,
797                                                           LE_Adapter>::value,
798                                        void*>::type)
799   : impl(NULL) {
800   Linear_Expression tmp(r);
801   tmp.set_space_dimension(space_dim);
802   tmp.set_inhomogeneous_term(e.inhomogeneous_term());
803   typedef typename LE_Adapter::const_iterator itr_t;
804   itr_t i_end;
805   if (space_dim <= e.space_dimension()) {
806     i_end = e.lower_bound(Variable(space_dim));
807   }
808   else {
809     i_end = e.end();
810   }
811   for (itr_t i = e.begin(); i != i_end; ++i) {
812     add_mul_assign(tmp, *i, i.variable());
813   }
814   using std::swap;
815   swap(impl, tmp.impl);
816 }
817 
818 namespace IO_Operators {
819 
820 /*! \relates Parma_Polyhedra_Library::Linear_Expression */
821 inline std::ostream&
operator <<(std::ostream & s,const Linear_Expression & e)822 operator<<(std::ostream& s, const Linear_Expression& e) {
823   e.impl->print(s);
824   return s;
825 }
826 
827 } // namespace IO_Operators
828 
829 /*! \relates Parma_Polyhedra_Library::Linear_Expression */
830 inline void
swap(Linear_Expression & x,Linear_Expression & y)831 swap(Linear_Expression& x, Linear_Expression& y) {
832   x.m_swap(y);
833 }
834 
835 /*! \relates Linear_Expression::const_iterator */
836 inline void
swap(Linear_Expression::const_iterator & x,Linear_Expression::const_iterator & y)837 swap(Linear_Expression::const_iterator& x,
838      Linear_Expression::const_iterator& y) {
839   x.m_swap(y);
840 }
841 
842 } // namespace Parma_Polyhedra_Library
843 
844 #endif // !defined(PPL_Linear_Expression_inlines_hh)
845