PPL  0.12.1
OR_Matrix.inlines.hh
Go to the documentation of this file.
00001 /* OR_Matrix class implementation: inline functions.
00002    Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
00003    Copyright (C) 2010-2012 BUGSENG srl (http://bugseng.com)
00004 
00005 This file is part of the Parma Polyhedra Library (PPL).
00006 
00007 The PPL is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 The PPL is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with this program; if not, write to the Free Software Foundation,
00019 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
00020 
00021 For the most up-to-date information see the Parma Polyhedra Library
00022 site: http://bugseng.com/products/ppl/ . */
00023 
00024 #ifndef PPL_OR_Matrix_inlines_hh
00025 #define PPL_OR_Matrix_inlines_hh 1
00026 
00027 #include "globals.defs.hh"
00028 #include "Checked_Number.defs.hh"
00029 #include "C_Polyhedron.defs.hh"
00030 #include "distances.defs.hh"
00031 #include "assert.hh"
00032 #include "checked.defs.hh"
00033 #include <algorithm>
00034 
00035 namespace Parma_Polyhedra_Library {
00036 
00037 template <typename T>
00038 inline dimension_type
00039 OR_Matrix<T>::row_first_element_index(const dimension_type k) {
00040   return ((k + 1)*(k + 1))/2;
00041 }
00042 
00043 template <typename T>
00044 inline dimension_type
00045 OR_Matrix<T>::row_size(const dimension_type k) {
00046   return k + 2 - k % 2;
00047 }
00048 
00049 #if PPL_OR_MATRIX_EXTRA_DEBUG
00050 
00051 template <typename T>
00052 template <typename U>
00053 inline dimension_type
00054 OR_Matrix<T>::Pseudo_Row<U>::size() const {
00055   return size_;
00056 }
00057 
00058 #endif // PPL_OR_MATRIX_EXTRA_DEBUG
00059 
00060 template <typename T>
00061 template <typename U>
00062 inline
00063 OR_Matrix<T>::Pseudo_Row<U>::Pseudo_Row()
00064   : first(0)
00065 #if PPL_OR_MATRIX_EXTRA_DEBUG
00066   , size_(0)
00067 #endif
00068 {
00069 }
00070 
00071 template <typename T>
00072 template <typename U>
00073 inline
00074 OR_Matrix<T>::Pseudo_Row<U>::Pseudo_Row(U& y
00075 #if PPL_OR_MATRIX_EXTRA_DEBUG
00076                 , dimension_type s
00077 #endif
00078                 )
00079   : first(&y)
00080 #if PPL_OR_MATRIX_EXTRA_DEBUG
00081   , size_(s)
00082 #endif
00083 {
00084 }
00085 
00086 template <typename T>
00087 template <typename U>
00088 template <typename V>
00089 inline
00090 OR_Matrix<T>::Pseudo_Row<U>::Pseudo_Row(const Pseudo_Row<V>& y)
00091   : first(y.first)
00092 #if PPL_OR_MATRIX_EXTRA_DEBUG
00093     , size_(y.size_)
00094 #endif
00095 {
00096 }
00097 
00098 template <typename T>
00099 template <typename U>
00100 inline OR_Matrix<T>::Pseudo_Row<U>&
00101 OR_Matrix<T>::Pseudo_Row<U>::operator=(const Pseudo_Row& y) {
00102   first = y.first;
00103 #if PPL_OR_MATRIX_EXTRA_DEBUG
00104   size_ = y.size_;
00105 #endif
00106   return *this;
00107 }
00108 
00109 template <typename T>
00110 template <typename U>
00111 inline
00112 OR_Matrix<T>::Pseudo_Row<U>::~Pseudo_Row() {
00113 }
00114 
00115 template <typename T>
00116 template <typename U>
00117 inline U&
00118 OR_Matrix<T>::Pseudo_Row<U>::operator[](const dimension_type k) const {
00119 #if PPL_OR_MATRIX_EXTRA_DEBUG
00120   PPL_ASSERT(k < size_);
00121 #endif
00122   return *(first + k);
00123 }
00124 
00125 template <typename T>
00126 template <typename U>
00127 inline
00128 OR_Matrix<T>::any_row_iterator<U>
00129 ::any_row_iterator(const dimension_type n_rows)
00130   : value(),
00131     e(n_rows)
00132     // Field `i' is intentionally not initialized here.
00133 {
00134 #if PPL_OR_MATRIX_EXTRA_DEBUG
00135   // Turn `value' into a valid object.
00136   value.size_ = OR_Matrix::row_size(e);
00137 #endif
00138 }
00139 
00140 template <typename T>
00141 template <typename U>
00142 inline
00143 OR_Matrix<T>::any_row_iterator<U>::any_row_iterator(U& base)
00144   :  value(base
00145 #if PPL_OR_MATRIX_EXTRA_DEBUG
00146            , OR_Matrix<T>::row_size(0)
00147 #endif
00148            ),
00149      e(0),
00150      i(0) {
00151 }
00152 
00153 template <typename T>
00154 template <typename U>
00155 template <typename V>
00156 inline
00157 OR_Matrix<T>::any_row_iterator<U>
00158 ::any_row_iterator(const any_row_iterator<V>& y)
00159   : value(y.value),
00160     e(y.e),
00161     i(y.i) {
00162 }
00163 
00164 template <typename T>
00165 template <typename U>
00166 template <typename V>
00167 inline typename OR_Matrix<T>::template any_row_iterator<U>&
00168 OR_Matrix<T>::any_row_iterator<U>::operator=(const any_row_iterator<V>& y) {
00169   value = y.value;
00170   e = y.e;
00171   i = y.i;
00172   return *this;
00173 }
00174 
00175 template <typename T>
00176 template <typename U>
00177 inline typename OR_Matrix<T>::template any_row_iterator<U>::reference
00178 OR_Matrix<T>::any_row_iterator<U>::operator*() const {
00179   return value;
00180 }
00181 
00182 template <typename T>
00183 template <typename U>
00184 inline typename OR_Matrix<T>::template any_row_iterator<U>::pointer
00185 OR_Matrix<T>::any_row_iterator<U>::operator->() const {
00186   return &value;
00187 }
00188 
00189 template <typename T>
00190 template <typename U>
00191 inline typename OR_Matrix<T>::template any_row_iterator<U>&
00192 OR_Matrix<T>::any_row_iterator<U>::operator++() {
00193   ++e;
00194   dimension_type increment = e;
00195   if (e % 2 != 0)
00196     ++increment;
00197 #if PPL_OR_MATRIX_EXTRA_DEBUG
00198   else {
00199     value.size_ += 2;
00200   }
00201 #endif
00202   i += increment;
00203   value.first += increment;
00204   return *this;
00205 }
00206 
00207 template <typename T>
00208 template <typename U>
00209 inline typename OR_Matrix<T>::template any_row_iterator<U>
00210 OR_Matrix<T>::any_row_iterator<U>::operator++(int) {
00211   any_row_iterator old = *this;
00212   ++(*this);
00213   return old;
00214 }
00215 
00216 template <typename T>
00217 template <typename U>
00218 inline typename OR_Matrix<T>::template any_row_iterator<U>&
00219 OR_Matrix<T>::any_row_iterator<U>::operator--() {
00220   dimension_type decrement = e + 1;
00221   --e;
00222   if (e % 2 != 0) {
00223     ++decrement;
00224 #if PPL_OR_MATRIX_EXTRA_DEBUG
00225     value.size_ -= 2;
00226 #endif
00227   }
00228   i -= decrement;
00229   value.first -= decrement;
00230   return *this;
00231 }
00232 
00233 template <typename T>
00234 template <typename U>
00235 inline typename OR_Matrix<T>::template any_row_iterator<U>
00236 OR_Matrix<T>::any_row_iterator<U>::operator--(int) {
00237   any_row_iterator old = *this;
00238   --(*this);
00239   return old;
00240 }
00241 
00242 template <typename T>
00243 template <typename U>
00244 inline typename OR_Matrix<T>::template any_row_iterator<U>&
00245 OR_Matrix<T>::any_row_iterator<U>::operator+=(const difference_type m) {
00246   difference_type e_dt = static_cast<difference_type>(e);
00247   difference_type i_dt = static_cast<difference_type>(i);
00248   difference_type increment = m + (m * m) / 2 + m * e_dt;
00249   if (e_dt % 2 == 0 && m % 2 != 0)
00250     ++increment;
00251   e_dt += m;
00252   i_dt += increment;
00253   e = static_cast<dimension_type>(e_dt);
00254   i = static_cast<dimension_type>(i_dt);
00255   value.first += increment;
00256 #if PPL_OR_MATRIX_EXTRA_DEBUG
00257   difference_type value_size_dt = static_cast<difference_type>(value.size_);
00258   value_size_dt += (m - m % 2);
00259   value.size_ = static_cast<dimension_type>(value_size_dt);
00260 #endif
00261   return *this;
00262 }
00263 
00264 template <typename T>
00265 template <typename U>
00266 template <typename Unsigned>
00267 inline typename
00268 Enable_If<(static_cast<Unsigned>(-1) > 0),
00269             typename OR_Matrix<T>::template any_row_iterator<U>& >::type
00270 OR_Matrix<T>::any_row_iterator<U>::operator+=(Unsigned m) {
00271   dimension_type n = m;
00272   dimension_type increment = n + (n*n)/2 + n*e;
00273   if (e % 2 == 0 && n % 2 != 0)
00274     ++increment;
00275   e += n;
00276   i += increment;
00277   value.first += increment;
00278 #if PPL_OR_MATRIX_EXTRA_DEBUG
00279   value.size_ = value.size_ + n - n % 2;
00280 #endif
00281   return *this;
00282 }
00283 
00284 template <typename T>
00285 template <typename U>
00286 inline typename OR_Matrix<T>::template any_row_iterator<U>&
00287 OR_Matrix<T>::any_row_iterator<U>::operator-=(difference_type m) {
00288   return *this += -m;
00289 }
00290 
00291 template <typename T>
00292 template <typename U>
00293 inline typename OR_Matrix<T>::template any_row_iterator<U>::difference_type
00294 OR_Matrix<T>::any_row_iterator<U>::operator-(const any_row_iterator& y) const {
00295   return e - y.e;
00296 }
00297 
00298 template <typename T>
00299 template <typename U>
00300 inline typename OR_Matrix<T>::template any_row_iterator<U>
00301 OR_Matrix<T>::any_row_iterator<U>::operator+(difference_type m) const {
00302   any_row_iterator r = *this;
00303   r += m;
00304   return r;
00305 }
00306 
00307 template <typename T>
00308 template <typename U>
00309 template <typename Unsigned>
00310 inline typename
00311 Enable_If<(static_cast<Unsigned>(-1) > 0),
00312             typename OR_Matrix<T>::template any_row_iterator<U> >::type
00313 OR_Matrix<T>::any_row_iterator<U>::operator+(Unsigned m) const {
00314   any_row_iterator r = *this;
00315   r += m;
00316   return r;
00317 }
00318 
00319 template <typename T>
00320 template <typename U>
00321 inline typename OR_Matrix<T>::template any_row_iterator<U>
00322 OR_Matrix<T>::any_row_iterator<U>::operator-(const difference_type m) const {
00323   any_row_iterator r = *this;
00324   r -= m;
00325   return r;
00326 }
00327 
00328 template <typename T>
00329 template <typename U>
00330 inline bool
00331 OR_Matrix<T>::any_row_iterator<U>
00332 ::operator==(const any_row_iterator& y) const {
00333   return e == y.e;
00334 }
00335 
00336 template <typename T>
00337 template <typename U>
00338 inline bool
00339 OR_Matrix<T>::any_row_iterator<U>
00340 ::operator!=(const any_row_iterator& y) const {
00341   return e != y.e;
00342 }
00343 
00344 template <typename T>
00345 template <typename U>
00346 inline bool
00347 OR_Matrix<T>::any_row_iterator<U>::operator<(const any_row_iterator& y) const {
00348   return e < y.e;
00349 }
00350 
00351 template <typename T>
00352 template <typename U>
00353 inline bool
00354 OR_Matrix<T>::any_row_iterator<U>
00355 ::operator<=(const any_row_iterator& y) const {
00356   return e <= y.e;
00357 }
00358 
00359 template <typename T>
00360 template <typename U>
00361 inline bool
00362 OR_Matrix<T>::any_row_iterator<U>::operator>(const any_row_iterator& y) const {
00363   return e > y.e;
00364 }
00365 
00366 template <typename T>
00367 template <typename U>
00368 inline bool
00369 OR_Matrix<T>::any_row_iterator<U>
00370 ::operator>=(const any_row_iterator& y) const {
00371   return e >= y.e;
00372 }
00373 
00374 template <typename T>
00375 template <typename U>
00376 inline dimension_type
00377 OR_Matrix<T>::any_row_iterator<U>::row_size() const {
00378   return OR_Matrix::row_size(e);
00379 }
00380 
00381 template <typename T>
00382 template <typename U>
00383 inline dimension_type
00384 OR_Matrix<T>::any_row_iterator<U>::index() const {
00385   return e;
00386 }
00387 
00388 template <typename T>
00389 inline typename OR_Matrix<T>::row_iterator
00390 OR_Matrix<T>::row_begin() {
00391   return num_rows() == 0 ? row_iterator(0) : row_iterator(vec[0]);
00392 }
00393 
00394 template <typename T>
00395 inline typename OR_Matrix<T>::row_iterator
00396 OR_Matrix<T>::row_end() {
00397   return row_iterator(num_rows());
00398 }
00399 
00400 template <typename T>
00401 inline typename OR_Matrix<T>::const_row_iterator
00402 OR_Matrix<T>::row_begin() const {
00403   return num_rows() == 0 ? const_row_iterator(0) : const_row_iterator(vec[0]);
00404 }
00405 
00406 template <typename T>
00407 inline typename OR_Matrix<T>::const_row_iterator
00408 OR_Matrix<T>::row_end() const {
00409   return const_row_iterator(num_rows());
00410 }
00411 
00412 template <typename T>
00413 inline typename OR_Matrix<T>::element_iterator
00414 OR_Matrix<T>::element_begin() {
00415   return vec.begin();
00416 }
00417 
00418 template <typename T>
00419 inline typename OR_Matrix<T>::element_iterator
00420 OR_Matrix<T>::element_end() {
00421   return vec.end();
00422 }
00423 
00424 template <typename T>
00425 inline typename OR_Matrix<T>::const_element_iterator
00426 OR_Matrix<T>::element_begin() const {
00427   return vec.begin();
00428 }
00429 
00430 template <typename T>
00431 inline typename OR_Matrix<T>::const_element_iterator
00432 OR_Matrix<T>::element_end() const {
00433   return vec.end();
00434 }
00435 
00436 template <typename T>
00437 inline void
00438 OR_Matrix<T>::m_swap(OR_Matrix& y) {
00439   using std::swap;
00440   swap(vec, y.vec);
00441   swap(space_dim, y.space_dim);
00442   swap(vec_capacity, y.vec_capacity);
00443 }
00444 
00445 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00446 
00447 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00448 inline dimension_type
00449 isqrt(dimension_type x) {
00450   dimension_type r = 0;
00451   const dimension_type FIRST_BIT_MASK = 0x40000000U;
00452   for (dimension_type t = FIRST_BIT_MASK; t != 0; t >>= 2) {
00453     dimension_type s = r + t;
00454     if (s <= x) {
00455       x -= s;
00456       r = s + t;
00457     }
00458     r >>= 1;
00459   }
00460   return r;
00461 }
00462 
00463 template <typename T>
00464 inline dimension_type
00465 OR_Matrix<T>::max_num_rows() {
00466   // Compute the maximum number of rows that are contained in a DB_Row
00467   // that allocates a pseudo-triangular matrix.
00468   dimension_type k = isqrt(2*DB_Row<T>::max_size() + 1);
00469   return (k - 1) - (k - 1) % 2;
00470 }
00471 
00472 template <typename T>
00473 inline memory_size_type
00474 OR_Matrix<T>::total_memory_in_bytes() const {
00475   return sizeof(*this) + external_memory_in_bytes();
00476 }
00477 
00478 template <typename T>
00479 inline
00480 OR_Matrix<T>::OR_Matrix(const dimension_type num_dimensions)
00481   : vec(2*num_dimensions*(num_dimensions + 1)),
00482     space_dim(num_dimensions),
00483     vec_capacity(vec.size()) {
00484 }
00485 
00486 template <typename T>
00487 inline
00488 OR_Matrix<T>::~OR_Matrix() {
00489 }
00490 
00491 template <typename T>
00492 inline typename OR_Matrix<T>::row_reference_type
00493 OR_Matrix<T>::operator[](dimension_type k) {
00494   return row_reference_type(vec[row_first_element_index(k)]
00495 #if PPL_OR_MATRIX_EXTRA_DEBUG
00496                             , row_size(k)
00497 #endif
00498                             );
00499 }
00500 
00501 template <typename T>
00502 inline typename OR_Matrix<T>::const_row_reference_type
00503 OR_Matrix<T>::operator[](dimension_type k) const {
00504   return const_row_reference_type(vec[row_first_element_index(k)]
00505 #if PPL_OR_MATRIX_EXTRA_DEBUG
00506                                   , row_size(k)
00507 #endif
00508                                   );
00509 }
00510 
00511 template <typename T>
00512 inline dimension_type
00513 OR_Matrix<T>::space_dimension() const {
00514   return space_dim;
00515 }
00516 
00517 template <typename T>
00518 inline dimension_type
00519 OR_Matrix<T>::num_rows() const {
00520   return 2*space_dimension();
00521 }
00522 
00523 template <typename T>
00524 inline void
00525 OR_Matrix<T>::clear() {
00526   OR_Matrix<T>(0).m_swap(*this);
00527 }
00528 
00529 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00530 
00531 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00532 template <typename T>
00533 inline bool
00534 operator==(const OR_Matrix<T>& x, const OR_Matrix<T>& y) {
00535   return x.space_dim == y.space_dim && x.vec == y.vec;
00536 }
00537 
00538 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00539 
00540 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00541 template <typename T>
00542 inline bool
00543 operator!=(const OR_Matrix<T>& x, const OR_Matrix<T>& y) {
00544   return !(x == y);
00545 }
00546 
00547 template <typename T>
00548 inline
00549 OR_Matrix<T>::OR_Matrix(const OR_Matrix& y)
00550   : vec(y.vec),
00551     space_dim(y.space_dim),
00552     vec_capacity(compute_capacity(y.vec.size(),
00553                                   DB_Row<T>::max_size())) {
00554 }
00555 
00556 template <typename T>
00557 template <typename U>
00558 inline
00559 OR_Matrix<T>::OR_Matrix(const OR_Matrix<U>& y)
00560   : vec(),
00561     space_dim(y.space_dim),
00562     vec_capacity(compute_capacity(y.vec.size(),
00563                                   DB_Row<T>::max_size())) {
00564   vec.construct_upward_approximation(y.vec, vec_capacity);
00565   PPL_ASSERT(OK());
00566 }
00567 
00568 template <typename T>
00569 inline OR_Matrix<T>&
00570 OR_Matrix<T>::operator=(const OR_Matrix& y) {
00571   vec = y.vec;
00572   space_dim = y.space_dim;
00573   vec_capacity = compute_capacity(y.vec.size(), DB_Row<T>::max_size());
00574   return *this;
00575 }
00576 
00577 template <typename T>
00578 inline void
00579 OR_Matrix<T>::grow(const dimension_type new_dim) {
00580   PPL_ASSERT(new_dim >= space_dim);
00581   if (new_dim > space_dim) {
00582     const dimension_type new_size = 2*new_dim*(new_dim + 1);
00583     if (new_size <= vec_capacity) {
00584       // We can recycle the old vec.
00585       vec.expand_within_capacity(new_size);
00586       space_dim = new_dim;
00587     }
00588     else {
00589       // We cannot recycle the old vec.
00590       OR_Matrix<T> new_matrix(new_dim);
00591       element_iterator j = new_matrix.element_begin();
00592       for (element_iterator i = element_begin(),
00593              mend = element_end(); i != mend; ++i, ++j)
00594         assign_or_swap(*j, *i);
00595       m_swap(new_matrix);
00596     }
00597   }
00598 }
00599 
00600 template <typename T>
00601 inline void
00602 OR_Matrix<T>::shrink(const dimension_type new_dim) {
00603   PPL_ASSERT(new_dim <= space_dim);
00604   const dimension_type new_size = 2*new_dim*(new_dim + 1);
00605   vec.shrink(new_size);
00606   space_dim = new_dim;
00607 }
00608 
00609 template <typename T>
00610 inline void
00611 OR_Matrix<T>::resize_no_copy(const dimension_type new_dim) {
00612   if (new_dim > space_dim) {
00613     const dimension_type new_size = 2*new_dim*(new_dim + 1);
00614     if (new_size <= vec_capacity) {
00615       // We can recycle the old vec.
00616       vec.expand_within_capacity(new_size);
00617       space_dim = new_dim;
00618     }
00619     else {
00620       // We cannot recycle the old vec.
00621       OR_Matrix<T> new_matrix(new_dim);
00622       m_swap(new_matrix);
00623     }
00624   }
00625   else if (new_dim < space_dim)
00626     shrink(new_dim);
00627 }
00628 
00629 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00630 
00631 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00632 template <typename Specialization, typename Temp, typename To, typename T>
00633 inline bool
00634 l_m_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00635                     const OR_Matrix<T>& x,
00636                     const OR_Matrix<T>& y,
00637                     const Rounding_Dir dir,
00638                     Temp& tmp0,
00639                     Temp& tmp1,
00640                     Temp& tmp2) {
00641   if (x.num_rows() != y.num_rows())
00642     return false;
00643   assign_r(tmp0, 0, ROUND_NOT_NEEDED);
00644   for (typename OR_Matrix<T>::const_element_iterator
00645          i = x.element_begin(), j = y.element_begin(),
00646          mat_end = x.element_end(); i != mat_end; ++i, ++j) {
00647     const T& x_i = *i;
00648     const T& y_i = *j;
00649     if (is_plus_infinity(x_i)) {
00650       if (is_plus_infinity(y_i))
00651         continue;
00652       else {
00653       pinf:
00654         assign_r(r, PLUS_INFINITY, ROUND_NOT_NEEDED);
00655         return true;
00656       }
00657     }
00658     else if (is_plus_infinity(y_i))
00659       goto pinf;
00660 
00661     const Temp* tmp1p;
00662     const Temp* tmp2p;
00663     if (x_i > y_i) {
00664       maybe_assign(tmp1p, tmp1, x_i, dir);
00665       maybe_assign(tmp2p, tmp2, y_i, inverse(dir));
00666     }
00667     else {
00668       maybe_assign(tmp1p, tmp1, y_i, dir);
00669       maybe_assign(tmp2p, tmp2, x_i, inverse(dir));
00670     }
00671     sub_assign_r(tmp1, *tmp1p, *tmp2p, dir);
00672     PPL_ASSERT(sgn(tmp1) >= 0);
00673     Specialization::combine(tmp0, tmp1, dir);
00674   }
00675 
00676   Specialization::finalize(tmp0, dir);
00677   assign_r(r, tmp0, dir);
00678   return true;
00679 }
00680 
00681 
00682 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00683 
00684 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00685 template <typename Temp, typename To, typename T>
00686 inline bool
00687 rectilinear_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00688                             const OR_Matrix<T>& x,
00689                             const OR_Matrix<T>& y,
00690                             const Rounding_Dir dir,
00691                             Temp& tmp0,
00692                             Temp& tmp1,
00693                             Temp& tmp2) {
00694   return
00695     l_m_distance_assign<Rectilinear_Distance_Specialization<Temp> >(r, x, y,
00696                                                                     dir,
00697                                                                     tmp0,
00698                                                                     tmp1,
00699                                                                     tmp2);
00700 }
00701 
00702 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00703 
00704 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00705 template <typename Temp, typename To, typename T>
00706 inline bool
00707 euclidean_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00708                           const OR_Matrix<T>& x,
00709                           const OR_Matrix<T>& y,
00710                           const Rounding_Dir dir,
00711                           Temp& tmp0,
00712                           Temp& tmp1,
00713                           Temp& tmp2) {
00714   return
00715     l_m_distance_assign<Euclidean_Distance_Specialization<Temp> >(r, x, y,
00716                                                                   dir,
00717                                                                   tmp0,
00718                                                                   tmp1,
00719                                                                   tmp2);
00720 }
00721 
00722 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00723 
00724 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00725 template <typename Temp, typename To, typename T>
00726 inline bool
00727 l_infinity_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00728                            const OR_Matrix<T>& x,
00729                            const OR_Matrix<T>& y,
00730                            const Rounding_Dir dir,
00731                            Temp& tmp0,
00732                            Temp& tmp1,
00733                            Temp& tmp2) {
00734   return
00735     l_m_distance_assign<L_Infinity_Distance_Specialization<Temp> >(r, x, y,
00736                                                                    dir,
00737                                                                    tmp0,
00738                                                                    tmp1,
00739                                                                    tmp2);
00740 }
00741 
00743 template <typename T>
00744 inline void
00745 swap(OR_Matrix<T>& x, OR_Matrix<T>& y) {
00746   x.m_swap(y);
00747 }
00748 
00749 } // namespace Parma_Polyhedra_Library
00750 
00751 #endif // !defined(PPL_OR_Matrix_inlines_hh)