|
PPL
0.12.1
|
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)