PPL  0.12.1
CO_Tree.inlines.hh
Go to the documentation of this file.
00001 /* CO_Tree 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_CO_Tree_inlines_hh
00025 #define PPL_CO_Tree_inlines_hh 1
00026 
00027 namespace Parma_Polyhedra_Library {
00028 
00029 inline dimension_type
00030 CO_Tree::dfs_index(const_iterator itr) const {
00031   PPL_ASSERT(itr.current_index != 0);
00032   PPL_ASSERT(itr.current_index >= indexes + 1);
00033   PPL_ASSERT(itr.current_index <= indexes + reserved_size);
00034   const ptrdiff_t index = itr.current_index - indexes;
00035   return static_cast<dimension_type>(index);
00036 }
00037 
00038 inline dimension_type
00039 CO_Tree::dfs_index(iterator itr) const {
00040   PPL_ASSERT(itr.current_index != 0);
00041   PPL_ASSERT(itr.current_index >= indexes + 1);
00042   PPL_ASSERT(itr.current_index <= indexes + reserved_size);
00043   const ptrdiff_t index = itr.current_index - indexes;
00044   return static_cast<dimension_type>(index);
00045 }
00046 
00047 inline
00048 CO_Tree::CO_Tree() {
00049   init(0);
00050   PPL_ASSERT(OK());
00051 }
00052 
00053 inline
00054 CO_Tree::CO_Tree(const CO_Tree& y) {
00055   PPL_ASSERT(y.OK());
00056   data_allocator = y.data_allocator;
00057   init(y.reserved_size);
00058   copy_data_from(y);
00059 }
00060 
00061 inline CO_Tree&
00062 CO_Tree::operator=(const CO_Tree& y) {
00063   if (this != &y) {
00064     destroy();
00065     data_allocator = y.data_allocator;
00066     init(y.reserved_size);
00067     copy_data_from(y);
00068   }
00069   return *this;
00070 }
00071 
00072 inline void
00073 CO_Tree::clear() {
00074   *this = CO_Tree();
00075 }
00076 
00077 inline
00078 CO_Tree::~CO_Tree() {
00079 
00080   PPL_ASSERT(structure_OK());
00081 
00082   destroy();
00083 }
00084 
00085 inline bool
00086 CO_Tree::empty() const {
00087   return size_ == 0;
00088 }
00089 
00090 inline dimension_type
00091 CO_Tree::size() const {
00092   return size_;
00093 }
00094 
00095 inline dimension_type
00096 CO_Tree::max_size() {
00097   return C_Integer<dimension_type>::max/100;
00098 }
00099 
00100 inline void
00101 CO_Tree::dump_tree() const {
00102   if (empty())
00103     std::cout << "(empty tree)" << std::endl;
00104   else
00105     dump_subtree(tree_iterator(*const_cast<CO_Tree*>(this)));
00106 }
00107 
00108 inline CO_Tree::iterator
00109 CO_Tree::insert(const dimension_type key) {
00110   if (empty())
00111     return insert(key, Coefficient_zero());
00112   else {
00113     tree_iterator itr(*this);
00114     itr.go_down_searching_key(key);
00115     if (itr.index() == key)
00116       return iterator(itr);
00117     else
00118       return iterator(insert_precise(key, Coefficient_zero(), itr));
00119   }
00120 }
00121 
00122 inline CO_Tree::iterator
00123 CO_Tree::insert(dimension_type key, data_type_const_reference data1) {
00124   if (empty()) {
00125     insert_in_empty_tree(key, data1);
00126     tree_iterator itr(*this);
00127     PPL_ASSERT(itr.index() != unused_index);
00128     return iterator(itr);
00129   } else {
00130     tree_iterator itr(*this);
00131     itr.go_down_searching_key(key);
00132     return iterator(insert_precise(key, data1, itr));
00133   }
00134 }
00135 
00136 inline CO_Tree::iterator
00137 CO_Tree::erase(dimension_type key) {
00138   PPL_ASSERT(key != unused_index);
00139 
00140   if (empty())
00141     return end();
00142 
00143   tree_iterator itr(*this);
00144   itr.go_down_searching_key(key);
00145 
00146   if (itr.index() == key)
00147     return erase(itr);
00148 
00149   iterator result(itr);
00150   if (result.index() < key)
00151     ++result;
00152 
00153   PPL_ASSERT(result == end() || result.index() > key);
00154 #ifndef NDEBUG
00155   iterator last = end();
00156   --last;
00157   PPL_ASSERT((result == end()) == (last.index() < key));
00158 #endif
00159 
00160   return result;
00161 }
00162 
00163 inline CO_Tree::iterator
00164 CO_Tree::erase(iterator itr) {
00165   PPL_ASSERT(itr != end());
00166   return erase(tree_iterator(itr, *this));
00167 }
00168 
00169 inline void
00170 CO_Tree::m_swap(CO_Tree& x) {
00171   using std::swap;
00172   swap(max_depth, x.max_depth);
00173   swap(indexes, x.indexes);
00174   swap(data_allocator, x.data_allocator);
00175   swap(data, x.data);
00176   swap(reserved_size, x.reserved_size);
00177   swap(size_, x.size_);
00178   // Cached iterators have been invalidated by the swap,
00179   // they must be refreshed here.
00180   refresh_cached_iterators();
00181   x.refresh_cached_iterators();
00182   PPL_ASSERT(structure_OK());
00183   PPL_ASSERT(x.structure_OK());
00184 }
00185 
00186 inline CO_Tree::iterator
00187 CO_Tree::begin() {
00188   return iterator(*this);
00189 }
00190 
00191 inline const CO_Tree::iterator&
00192 CO_Tree::end() {
00193   return cached_end;
00194 }
00195 
00196 inline CO_Tree::const_iterator
00197 CO_Tree::begin() const {
00198   return const_iterator(*this);
00199 }
00200 
00201 inline const CO_Tree::const_iterator&
00202 CO_Tree::end() const {
00203   return cached_const_end;
00204 }
00205 
00206 inline CO_Tree::const_iterator
00207 CO_Tree::cbegin() const {
00208   return const_iterator(*this);
00209 }
00210 
00211 inline const CO_Tree::const_iterator&
00212 CO_Tree::cend() const {
00213   return cached_const_end;
00214 }
00215 
00216 inline CO_Tree::iterator
00217 CO_Tree::bisect(dimension_type key) {
00218   if (empty())
00219     return end();
00220   iterator last = end();
00221   --last;
00222   return bisect_in(begin(), last, key);
00223 }
00224 
00225 inline CO_Tree::const_iterator
00226 CO_Tree::bisect(dimension_type key) const {
00227   if (empty())
00228     return end();
00229   const_iterator last = end();
00230   --last;
00231   return bisect_in(begin(), last, key);
00232 }
00233 
00234 inline CO_Tree::iterator
00235 CO_Tree::bisect_in(iterator first, iterator last, dimension_type key) {
00236   PPL_ASSERT(first != end());
00237   PPL_ASSERT(last != end());
00238   dimension_type index = bisect_in(dfs_index(first), dfs_index(last), key);
00239   return iterator(*this, index);
00240 }
00241 
00242 inline CO_Tree::const_iterator
00243 CO_Tree::bisect_in(const_iterator first, const_iterator last,
00244                    dimension_type key) const {
00245   PPL_ASSERT(first != end());
00246   PPL_ASSERT(last != end());
00247   dimension_type index = bisect_in(dfs_index(first), dfs_index(last), key);
00248   return const_iterator(*this, index);
00249 }
00250 
00251 inline CO_Tree::iterator
00252 CO_Tree::bisect_near(iterator hint, dimension_type key) {
00253   if (hint == end())
00254     return bisect(key);
00255   dimension_type index = bisect_near(dfs_index(hint), key);
00256   return iterator(*this, index);
00257 }
00258 
00259 inline CO_Tree::const_iterator
00260 CO_Tree::bisect_near(const_iterator hint, dimension_type key) const {
00261   if (hint == end())
00262     return bisect(key);
00263   dimension_type index = bisect_near(dfs_index(hint), key);
00264   return const_iterator(*this, index);
00265 }
00266 
00267 inline void
00268 CO_Tree::insert_in_empty_tree(dimension_type key,
00269                               data_type_const_reference data1) {
00270   PPL_ASSERT(empty());
00271   rebuild_bigger_tree();
00272   tree_iterator itr(*this);
00273   PPL_ASSERT(itr.index() == unused_index);
00274   itr.index() = key;
00275   new (&(*itr)) data_type(data1);
00276   size_++;
00277 
00278   PPL_ASSERT(OK());
00279 }
00280 
00281 inline bool
00282 CO_Tree::is_less_than_ratio(dimension_type numer, dimension_type denom,
00283                             dimension_type ratio) {
00284   PPL_ASSERT(ratio <= 100);
00285   // If these are true, no overflows are possible.
00286   PPL_ASSERT(denom <= (-(dimension_type)1)/100);
00287   PPL_ASSERT(numer <= (-(dimension_type)1)/100);
00288   return 100*numer < ratio*denom;
00289 }
00290 
00291 inline bool
00292 CO_Tree::is_greater_than_ratio(dimension_type numer, dimension_type denom,
00293                                dimension_type ratio) {
00294   PPL_ASSERT(ratio <= 100);
00295   // If these are true, no overflows are possible.
00296   PPL_ASSERT(denom <= (-(dimension_type)1)/100);
00297   PPL_ASSERT(numer <= (-(dimension_type)1)/100);
00298   return 100*numer > ratio*denom;
00299 }
00300 
00301 inline void
00302 CO_Tree::rebuild_smaller_tree() {
00303   PPL_ASSERT(reserved_size > 3);
00304   CO_Tree new_tree;
00305   new_tree.init(reserved_size / 2);
00306   new_tree.move_data_from(*this);
00307   m_swap(new_tree);
00308   PPL_ASSERT(new_tree.structure_OK());
00309   PPL_ASSERT(structure_OK());
00310 }
00311 
00312 inline void
00313 CO_Tree::refresh_cached_iterators() {
00314   cached_end = iterator(*this, reserved_size + 1);
00315   cached_const_end = const_iterator(*this, reserved_size + 1);
00316 }
00317 
00318 inline void
00319 CO_Tree::move_data_element(data_type& to, data_type& from) {
00320   // The following code is equivalent (but slower):
00321   //
00322   // <CODE>
00323   //   new (&to) data_type(from);
00324   //   from.~data_type();
00325   // </CODE>
00326   std::memcpy(&to, &from, sizeof(data_type));
00327 }
00328 
00329 
00330 inline
00331 CO_Tree::const_iterator::const_iterator()
00332   : current_index(0), current_data(0) {
00333 #if PPL_CO_TREE_EXTRA_DEBUG
00334   tree = 0;
00335 #endif
00336   PPL_ASSERT(OK());
00337 }
00338 
00339 inline
00340 CO_Tree::const_iterator::const_iterator(const CO_Tree& tree1)
00341   : current_index(&(tree1.indexes[1])), current_data(&(tree1.data[1])) {
00342 #if PPL_CO_TREE_EXTRA_DEBUG
00343   tree = &tree1;
00344 #endif
00345   if (!tree1.empty())
00346     while (*current_index == unused_index) {
00347       ++current_index;
00348       ++current_data;
00349     }
00350   PPL_ASSERT(OK());
00351 }
00352 
00353 inline
00354 CO_Tree::const_iterator::const_iterator(const CO_Tree& tree1,
00355                                         dimension_type i)
00356   : current_index(&(tree1.indexes[i])), current_data(&(tree1.data[i])) {
00357 #if PPL_CO_TREE_EXTRA_DEBUG
00358   tree = &tree1;
00359 #endif
00360   PPL_ASSERT(i != 0);
00361   PPL_ASSERT(i <= tree1.reserved_size + 1);
00362   PPL_ASSERT(tree1.empty() || tree1.indexes[i] != unused_index);
00363   PPL_ASSERT(OK());
00364 }
00365 
00366 inline
00367 CO_Tree::const_iterator::const_iterator(const const_iterator& itr2) {
00368   (*this) = itr2;
00369   PPL_ASSERT(OK());
00370 }
00371 
00372 inline
00373 CO_Tree::const_iterator::const_iterator(const iterator& itr2) {
00374   (*this) = itr2;
00375   PPL_ASSERT(OK());
00376 }
00377 
00378 inline void
00379 CO_Tree::const_iterator::m_swap(const_iterator& itr) {
00380   using std::swap;
00381   swap(current_data, itr.current_data);
00382   swap(current_index, itr.current_index);
00383 #if PPL_CO_TREE_EXTRA_DEBUG
00384   swap(tree, itr.tree);
00385 #endif
00386   PPL_ASSERT(OK());
00387   PPL_ASSERT(itr.OK());
00388 }
00389 
00390 inline CO_Tree::const_iterator&
00391 CO_Tree::const_iterator::operator=(const const_iterator& itr2) {
00392   current_index = itr2.current_index;
00393   current_data = itr2.current_data;
00394 #if PPL_CO_TREE_EXTRA_DEBUG
00395   tree = itr2.tree;
00396 #endif
00397   PPL_ASSERT(OK());
00398   return *this;
00399 }
00400 
00401 inline CO_Tree::const_iterator&
00402 CO_Tree::const_iterator::operator=(const iterator& itr2) {
00403   current_index = itr2.current_index;
00404   current_data = itr2.current_data;
00405 #if PPL_CO_TREE_EXTRA_DEBUG
00406   tree = itr2.tree;
00407 #endif
00408   PPL_ASSERT(OK());
00409   return *this;
00410 }
00411 
00412 inline CO_Tree::const_iterator&
00413 CO_Tree::const_iterator::operator++() {
00414   PPL_ASSERT(current_index != 0);
00415   PPL_ASSERT(current_data != 0);
00416 #if PPL_CO_TREE_EXTRA_DEBUG
00417   PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
00418 #endif
00419   ++current_index;
00420   ++current_data;
00421   while (*current_index == unused_index) {
00422     ++current_index;
00423     ++current_data;
00424   }
00425   PPL_ASSERT(OK());
00426   return *this;
00427 }
00428 
00429 inline CO_Tree::const_iterator&
00430 CO_Tree::const_iterator::operator--() {
00431   PPL_ASSERT(current_index != 0);
00432   PPL_ASSERT(current_data != 0);
00433   --current_index;
00434   --current_data;
00435   while (*current_index == unused_index) {
00436     --current_index;
00437     --current_data;
00438   }
00439   PPL_ASSERT(OK());
00440   return *this;
00441 }
00442 
00443 inline CO_Tree::const_iterator
00444 CO_Tree::const_iterator::operator++(int) {
00445   const_iterator itr(*this);
00446   ++(*this);
00447   return itr;
00448 }
00449 
00450 inline CO_Tree::const_iterator
00451 CO_Tree::const_iterator::operator--(int) {
00452   const_iterator itr(*this);
00453   --(*this);
00454   return itr;
00455 }
00456 
00457 inline Coefficient_traits::const_reference
00458 CO_Tree::const_iterator::operator*() const {
00459   PPL_ASSERT(current_index != 0);
00460   PPL_ASSERT(current_data != 0);
00461   PPL_ASSERT(OK());
00462 #if PPL_CO_TREE_EXTRA_DEBUG
00463   PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
00464 #endif
00465   return *current_data;
00466 }
00467 
00468 inline dimension_type
00469 CO_Tree::const_iterator::index() const {
00470   PPL_ASSERT(current_index != 0);
00471   PPL_ASSERT(current_data != 0);
00472   PPL_ASSERT(OK());
00473 #if PPL_CO_TREE_EXTRA_DEBUG
00474   PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
00475 #endif
00476   return *current_index;
00477 }
00478 
00479 inline bool
00480 CO_Tree::const_iterator::operator==(const const_iterator& x) const {
00481   PPL_ASSERT((current_index == x.current_index)
00482              == (current_data == x.current_data));
00483   PPL_ASSERT(OK());
00484   return (current_index == x.current_index);
00485 }
00486 
00487 inline bool
00488 CO_Tree::const_iterator::operator!=(const const_iterator& x) const {
00489   return !(*this == x);
00490 }
00491 
00492 
00493 inline
00494 CO_Tree::iterator::iterator()
00495   : current_index(0), current_data(0) {
00496 #if PPL_CO_TREE_EXTRA_DEBUG
00497   tree = 0;
00498 #endif
00499   PPL_ASSERT(OK());
00500 }
00501 
00502 inline
00503 CO_Tree::iterator::iterator(CO_Tree& tree1)
00504   : current_index(&(tree1.indexes[1])), current_data(&(tree1.data[1])) {
00505 #if PPL_CO_TREE_EXTRA_DEBUG
00506   tree = &tree1;
00507 #endif
00508   if (!tree1.empty())
00509     while (*current_index == unused_index) {
00510       ++current_index;
00511       ++current_data;
00512     }
00513   PPL_ASSERT(OK());
00514 }
00515 
00516 inline
00517 CO_Tree::iterator::iterator(CO_Tree& tree1, dimension_type i)
00518   : current_index(&(tree1.indexes[i])), current_data(&(tree1.data[i])) {
00519 #if PPL_CO_TREE_EXTRA_DEBUG
00520   tree = &tree1;
00521 #endif
00522   PPL_ASSERT(i != 0);
00523   PPL_ASSERT(i <= tree1.reserved_size + 1);
00524   PPL_ASSERT(tree1.empty() || tree1.indexes[i] != unused_index);
00525   PPL_ASSERT(OK());
00526 }
00527 
00528 inline
00529 CO_Tree::iterator::iterator(const tree_iterator& itr) {
00530   *this = itr;
00531   PPL_ASSERT(OK());
00532 }
00533 
00534 inline
00535 CO_Tree::iterator::iterator(const iterator& itr2) {
00536   (*this) = itr2;
00537   PPL_ASSERT(OK());
00538 }
00539 
00540 inline void
00541 CO_Tree::iterator::m_swap(iterator& itr) {
00542   using std::swap;
00543   swap(current_data, itr.current_data);
00544   swap(current_index, itr.current_index);
00545 #if PPL_CO_TREE_EXTRA_DEBUG
00546   swap(tree, itr.tree);
00547 #endif
00548   PPL_ASSERT(OK());
00549   PPL_ASSERT(itr.OK());
00550 }
00551 
00552 inline CO_Tree::iterator&
00553 CO_Tree::iterator::operator=(const tree_iterator& itr) {
00554   current_index = &(itr.tree.indexes[itr.dfs_index()]);
00555   current_data = &(itr.tree.data[itr.dfs_index()]);
00556 #if PPL_CO_TREE_EXTRA_DEBUG
00557   tree = &(itr.tree);
00558 #endif
00559   PPL_ASSERT(OK());
00560   return *this;
00561 }
00562 
00563 inline CO_Tree::iterator&
00564 CO_Tree::iterator::operator=(const iterator& itr2) {
00565   current_index = itr2.current_index;
00566   current_data = itr2.current_data;
00567 #if PPL_CO_TREE_EXTRA_DEBUG
00568   tree = itr2.tree;
00569 #endif
00570   PPL_ASSERT(OK());
00571   return *this;
00572 }
00573 
00574 inline CO_Tree::iterator&
00575 CO_Tree::iterator::operator++() {
00576   PPL_ASSERT(current_index != 0);
00577   PPL_ASSERT(current_data != 0);
00578 #if PPL_CO_TREE_EXTRA_DEBUG
00579   PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
00580 #endif
00581   ++current_index;
00582   ++current_data;
00583   while (*current_index == unused_index) {
00584     ++current_index;
00585     ++current_data;
00586   }
00587 
00588   PPL_ASSERT(OK());
00589   return *this;
00590 }
00591 
00592 inline CO_Tree::iterator&
00593 CO_Tree::iterator::operator--() {
00594   PPL_ASSERT(current_index != 0);
00595   PPL_ASSERT(current_data != 0);
00596   --current_index;
00597   --current_data;
00598   while (*current_index == unused_index) {
00599     --current_index;
00600     --current_data;
00601   }
00602 
00603   PPL_ASSERT(OK());
00604   return *this;
00605 }
00606 
00607 inline CO_Tree::iterator
00608 CO_Tree::iterator::operator++(int) {
00609   iterator itr(*this);
00610   ++(*this);
00611   return itr;
00612 }
00613 
00614 inline CO_Tree::iterator
00615 CO_Tree::iterator::operator--(int) {
00616   iterator itr(*this);
00617   --(*this);
00618   return itr;
00619 }
00620 
00621 inline CO_Tree::data_type&
00622 CO_Tree::iterator::operator*() {
00623   PPL_ASSERT(current_index != 0);
00624   PPL_ASSERT(current_data != 0);
00625   PPL_ASSERT(OK());
00626 #if PPL_CO_TREE_EXTRA_DEBUG
00627   PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
00628 #endif
00629   return *current_data;
00630 }
00631 
00632 inline Coefficient_traits::const_reference
00633 CO_Tree::iterator::operator*() const {
00634   PPL_ASSERT(current_index != 0);
00635   PPL_ASSERT(current_data != 0);
00636   PPL_ASSERT(OK());
00637 #if PPL_CO_TREE_EXTRA_DEBUG
00638   PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
00639 #endif
00640   return *current_data;
00641 }
00642 
00643 inline dimension_type
00644 CO_Tree::iterator::index() const {
00645   PPL_ASSERT(current_index != 0);
00646   PPL_ASSERT(current_data != 0);
00647   PPL_ASSERT(OK());
00648 #if PPL_CO_TREE_EXTRA_DEBUG
00649   PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
00650 #endif
00651   return *current_index;
00652 }
00653 
00654 inline bool
00655 CO_Tree::iterator::operator==(const iterator& x) const {
00656   PPL_ASSERT((current_index == x.current_index)
00657              == (current_data == x.current_data));
00658   PPL_ASSERT(OK());
00659   return (current_index == x.current_index);
00660 }
00661 
00662 inline bool
00663 CO_Tree::iterator::operator!=(const iterator& x) const {
00664   return !(*this == x);
00665 }
00666 
00667 
00668 inline
00669 CO_Tree::tree_iterator::tree_iterator(CO_Tree& tree1)
00670   : tree(tree1) {
00671   PPL_ASSERT(tree.reserved_size != 0);
00672   get_root();
00673   PPL_ASSERT(OK());
00674 }
00675 
00676 inline
00677 CO_Tree::tree_iterator::tree_iterator(CO_Tree& tree1, dimension_type i1)
00678   : tree(tree1) {
00679   PPL_ASSERT(tree.reserved_size != 0);
00680   PPL_ASSERT(i1 <= tree.reserved_size + 1);
00681   i = i1;
00682   offset = least_significant_one_mask(i);
00683   PPL_ASSERT(OK());
00684 }
00685 
00686 inline
00687 CO_Tree::tree_iterator::tree_iterator(const iterator& itr, CO_Tree& tree1)
00688   : tree(tree1) {
00689   PPL_ASSERT(tree.reserved_size != 0);
00690   *this = itr;
00691   PPL_ASSERT(OK());
00692 }
00693 
00694 inline CO_Tree::tree_iterator&
00695 CO_Tree::tree_iterator::operator=(const tree_iterator& itr) {
00696   PPL_ASSERT(&tree == &(itr.tree));
00697   i = itr.i;
00698   offset = itr.offset;
00699   return *this;
00700 }
00701 
00702 inline CO_Tree::tree_iterator&
00703 CO_Tree::tree_iterator::operator=(const iterator& itr) {
00704   PPL_ASSERT(itr != tree.end());
00705   i = tree.dfs_index(itr);
00706   offset = least_significant_one_mask(i);
00707   return *this;
00708 }
00709 
00710 inline bool
00711 CO_Tree::tree_iterator::operator==(const tree_iterator& itr) const {
00712   return i == itr.i;
00713 }
00714 
00715 inline bool
00716 CO_Tree::tree_iterator::operator!=(const tree_iterator& itr) const {
00717   return !(*this == itr);
00718 }
00719 
00720 inline void
00721 CO_Tree::tree_iterator::get_root() {
00722   i = tree.reserved_size / 2 + 1;
00723   offset = i;
00724   PPL_ASSERT(OK());
00725 }
00726 
00727 inline void
00728 CO_Tree::tree_iterator::get_left_child() {
00729   PPL_ASSERT(offset != 0);
00730   PPL_ASSERT(offset != 1);
00731   offset /= 2;
00732   i -= offset;
00733   PPL_ASSERT(OK());
00734 }
00735 
00736 inline void
00737 CO_Tree::tree_iterator::get_right_child() {
00738   PPL_ASSERT(offset != 0);
00739   PPL_ASSERT(offset != 1);
00740   offset /= 2;
00741   i += offset;
00742   PPL_ASSERT(OK());
00743 }
00744 
00745 inline void
00746 CO_Tree::tree_iterator::get_parent() {
00747   PPL_ASSERT(!is_root());
00748   PPL_ASSERT(offset != 0);
00749   i &= ~offset;
00750   offset *= 2;
00751   i |= offset;
00752   PPL_ASSERT(OK());
00753 }
00754 
00755 inline void
00756 CO_Tree::tree_iterator::follow_left_children_with_value() {
00757   PPL_ASSERT(index() != unused_index);
00758   dimension_type* p = tree.indexes;
00759   p += i;
00760   p -= (offset - 1);
00761   while (*p == unused_index)
00762     ++p;
00763   ptrdiff_t distance = p - tree.indexes;
00764   PPL_ASSERT(distance >= 0);
00765   i = static_cast<dimension_type>(distance);
00766   offset = least_significant_one_mask(i);
00767   PPL_ASSERT(OK());
00768 }
00769 
00770 inline void
00771 CO_Tree::tree_iterator::follow_right_children_with_value() {
00772   PPL_ASSERT(index() != unused_index);
00773   dimension_type* p = tree.indexes;
00774   p += i;
00775   p += (offset - 1);
00776   while (*p == unused_index)
00777     --p;
00778   ptrdiff_t distance = p - tree.indexes;
00779   PPL_ASSERT(distance >= 0);
00780   i = static_cast<dimension_type>(distance);
00781   offset = least_significant_one_mask(i);
00782   PPL_ASSERT(OK());
00783 }
00784 
00785 inline bool
00786 CO_Tree::tree_iterator::is_root() const {
00787   // This is implied by OK(), it is here for reference only.
00788   PPL_ASSERT(offset <= (tree.reserved_size / 2 + 1));
00789   return offset == (tree.reserved_size / 2 + 1);
00790 }
00791 
00792 inline bool
00793 CO_Tree::tree_iterator::is_right_child() const {
00794   if (is_root())
00795     return false;
00796   return (i & (2*offset)) != 0;
00797 }
00798 
00799 inline bool
00800 CO_Tree::tree_iterator::is_leaf() const {
00801   return offset == 1;
00802 }
00803 
00804 inline CO_Tree::data_type&
00805 CO_Tree::tree_iterator::operator*() {
00806   return tree.data[i];
00807 }
00808 
00809 inline Coefficient_traits::const_reference
00810 CO_Tree::tree_iterator::operator*() const {
00811   return tree.data[i];
00812 }
00813 
00814 inline dimension_type&
00815 CO_Tree::tree_iterator::index() {
00816   return tree.indexes[i];
00817 }
00818 
00819 inline dimension_type
00820 CO_Tree::tree_iterator::index() const {
00821   return tree.indexes[i];
00822 }
00823 
00824 inline dimension_type
00825 CO_Tree::tree_iterator::dfs_index() const {
00826   return i;
00827 }
00828 
00829 inline dimension_type
00830 CO_Tree::tree_iterator::get_offset() const {
00831   return offset;
00832 }
00833 
00834 inline CO_Tree::height_t
00835 CO_Tree::tree_iterator::depth() const {
00836   return integer_log2((tree.reserved_size + 1) / offset);
00837 }
00838 
00839 inline void
00840 swap(CO_Tree& x, CO_Tree& y) {
00841   x.m_swap(y);
00842 }
00843 
00844 inline void
00845 swap(CO_Tree::const_iterator& x, CO_Tree::const_iterator& y) {
00846   x.m_swap(y);
00847 }
00848 
00849 inline void
00850 swap(CO_Tree::iterator& x, CO_Tree::iterator& y) {
00851   x.m_swap(y);
00852 }
00853 
00854 } // namespace Parma_Polyhedra_Library
00855 
00856 #endif // !defined(PPL_CO_Tree_inlines_hh)