PPL  1.2
CO_Tree_inlines.hh
Go to the documentation of this file.
1 /* CO_Tree 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_CO_Tree_inlines_hh
25 #define PPL_CO_Tree_inlines_hh 1
26 
27 #include <cstddef>
28 
29 namespace Parma_Polyhedra_Library {
30 
31 inline dimension_type
33  PPL_ASSERT(itr.current_index != 0);
34  PPL_ASSERT(itr.current_index >= indexes + 1);
35  PPL_ASSERT(itr.current_index <= indexes + reserved_size);
36  const std::ptrdiff_t index = itr.current_index - indexes;
37  return static_cast<dimension_type>(index);
38 }
39 
40 inline dimension_type
42  PPL_ASSERT(itr.current_index != 0);
43  PPL_ASSERT(itr.current_index >= indexes + 1);
44  PPL_ASSERT(itr.current_index <= indexes + reserved_size);
45  const std::ptrdiff_t index = itr.current_index - indexes;
46  return static_cast<dimension_type>(index);
47 }
48 
49 inline
51  init(0);
52  PPL_ASSERT(OK());
53 }
54 
55 inline
57  PPL_ASSERT(y.OK());
60  copy_data_from(y);
61 }
62 
63 inline CO_Tree&
65  if (this != &y) {
66  destroy();
69  copy_data_from(y);
70  }
71  return *this;
72 }
73 
74 inline void
76  *this = CO_Tree();
77 }
78 
79 inline
81 
82  destroy();
83 }
84 
85 inline bool
86 CO_Tree::empty() const {
87  return size_ == 0;
88 }
89 
90 inline dimension_type
91 CO_Tree::size() const {
92  return size_;
93 }
94 
95 inline dimension_type
98 }
99 
100 inline void
102  if (empty()) {
103  std::cout << "(empty tree)" << std::endl;
104  }
105  else {
106  dump_subtree(tree_iterator(*const_cast<CO_Tree*>(this)));
107  }
108 }
109 
110 inline CO_Tree::iterator
112  if (empty()) {
113  return insert(key, Coefficient_zero());
114  }
115  else {
116  tree_iterator itr(*this);
117  itr.go_down_searching_key(key);
118  if (itr.index() == key) {
119  return iterator(itr);
120  }
121  else {
122  return iterator(insert_precise(key, Coefficient_zero(), itr));
123  }
124  }
125 }
126 
127 inline CO_Tree::iterator
129  if (empty()) {
130  insert_in_empty_tree(key, data1);
131  tree_iterator itr(*this);
132  PPL_ASSERT(itr.index() != unused_index);
133  return iterator(itr);
134  }
135  else {
136  tree_iterator itr(*this);
137  itr.go_down_searching_key(key);
138  return iterator(insert_precise(key, data1, itr));
139  }
140 }
141 
142 inline CO_Tree::iterator
144  PPL_ASSERT(key != unused_index);
145 
146  if (empty()) {
147  return end();
148  }
149 
150  tree_iterator itr(*this);
151  itr.go_down_searching_key(key);
152 
153  if (itr.index() == key) {
154  return erase(itr);
155  }
156 
157  iterator result(itr);
158  if (result.index() < key) {
159  ++result;
160  }
161 
162  PPL_ASSERT(result == end() || result.index() > key);
163 #ifndef NDEBUG
164  iterator last = end();
165  --last;
166  PPL_ASSERT((result == end()) == (last.index() < key));
167 #endif
168 
169  return result;
170 }
171 
172 inline CO_Tree::iterator
174  PPL_ASSERT(itr != end());
175  return erase(tree_iterator(itr, *this));
176 }
177 
178 inline void
180  using std::swap;
182  swap(indexes, x.indexes);
184  swap(data, x.data);
186  swap(size_, x.size_);
187  // Cached iterators have been invalidated by the swap,
188  // they must be refreshed here.
191  PPL_ASSERT(structure_OK());
192  PPL_ASSERT(x.structure_OK());
193 }
194 
195 inline CO_Tree::iterator
197  return iterator(*this);
198 }
199 
200 inline const CO_Tree::iterator&
202  return cached_end;
203 }
204 
206 CO_Tree::begin() const {
207  return const_iterator(*this);
208 }
209 
210 inline const CO_Tree::const_iterator&
211 CO_Tree::end() const {
212  return cached_const_end;
213 }
214 
217  return const_iterator(*this);
218 }
219 
220 inline const CO_Tree::const_iterator&
221 CO_Tree::cend() const {
222  return cached_const_end;
223 }
224 
225 inline CO_Tree::iterator
227  if (empty()) {
228  return end();
229  }
230  iterator last = end();
231  --last;
232  return bisect_in(begin(), last, key);
233 }
234 
237  if (empty()) {
238  return end();
239  }
240  const_iterator last = end();
241  --last;
242  return bisect_in(begin(), last, key);
243 }
244 
245 inline CO_Tree::iterator
247  PPL_ASSERT(first != end());
248  PPL_ASSERT(last != end());
249  const dimension_type index
250  = bisect_in(dfs_index(first), dfs_index(last), key);
251  return iterator(*this, index);
252 }
253 
256  dimension_type key) const {
257  PPL_ASSERT(first != end());
258  PPL_ASSERT(last != end());
259  const dimension_type index
260  = bisect_in(dfs_index(first), dfs_index(last), key);
261  return const_iterator(*this, index);
262 }
263 
264 inline CO_Tree::iterator
266  if (hint == end()) {
267  return bisect(key);
268  }
269  const dimension_type index
270  = bisect_near(dfs_index(hint), key);
271  return iterator(*this, index);
272 }
273 
276  if (hint == end()) {
277  return bisect(key);
278  }
279  const dimension_type index = bisect_near(dfs_index(hint), key);
280  return const_iterator(*this, index);
281 }
282 
283 inline void
285  PPL_ASSERT(itr != end());
286  PPL_ASSERT(i <= itr.index());
287  indexes[dfs_index(itr)] = i;
288  PPL_ASSERT(OK());
289 }
290 
291 inline void
294  PPL_ASSERT(empty());
296  tree_iterator itr(*this);
297  PPL_ASSERT(itr.index() == unused_index);
298  new(&(*itr)) data_type(data1);
299  // Set the index afterwards, so that if the constructor above throws
300  // the tree's structure is consistent.
301  itr.index() = key;
302  ++size_;
303 
304  PPL_ASSERT(OK());
305 }
306 
307 inline bool
309  dimension_type ratio) {
310  PPL_ASSERT(ratio <= 100);
311  // If these are true, no overflows are possible.
312  PPL_ASSERT(denom <= unused_index/100);
313  PPL_ASSERT(numer <= unused_index/100);
314  return 100*numer < ratio*denom;
315 }
316 
317 inline bool
319  dimension_type ratio) {
320  PPL_ASSERT(ratio <= 100);
321  // If these are true, no overflows are possible.
322  PPL_ASSERT(denom <= unused_index/100);
323  PPL_ASSERT(numer <= unused_index/100);
324  return 100*numer > ratio*denom;
325 }
326 
327 inline void
329  PPL_ASSERT(reserved_size > 3);
330  CO_Tree new_tree;
331  new_tree.init(reserved_size / 2);
332  new_tree.move_data_from(*this);
333  m_swap(new_tree);
334  PPL_ASSERT(new_tree.structure_OK());
335  PPL_ASSERT(structure_OK());
336 }
337 
338 inline void
340  cached_end = iterator(*this, reserved_size + 1);
342 }
343 
344 inline void
346  /*
347  The following code is equivalent (but slower):
348 
349  <CODE>
350  new(&to) data_type(from);
351  from.~data_type();
352  </CODE>
353  */
354  std::memcpy(&to, &from, sizeof(data_type));
355 }
356 
357 
358 inline
360  : current_index(0), current_data(0) {
361 #if PPL_CO_TREE_EXTRA_DEBUG
362  tree = 0;
363 #endif
364  PPL_ASSERT(OK());
365 }
366 
367 inline
369  : current_index(&(tree1.indexes[1])), current_data(&(tree1.data[1])) {
370 #if PPL_CO_TREE_EXTRA_DEBUG
371  tree = &tree1;
372 #endif
373  if (!tree1.empty()) {
374  while (*current_index == unused_index) {
375  ++current_index;
376  ++current_data;
377  }
378  }
379  PPL_ASSERT(OK());
380 }
381 
382 inline
384  dimension_type i)
385  : current_index(&(tree1.indexes[i])), current_data(&(tree1.data[i])) {
386 #if PPL_CO_TREE_EXTRA_DEBUG
387  tree = &tree1;
388 #endif
389  PPL_ASSERT(i != 0);
390  PPL_ASSERT(i <= tree1.reserved_size + 1);
391  PPL_ASSERT(tree1.empty() || tree1.indexes[i] != unused_index);
392  PPL_ASSERT(OK());
393 }
394 
395 inline
397  (*this) = itr2;
398  PPL_ASSERT(OK());
399 }
400 
401 inline
403  (*this) = itr2;
404  PPL_ASSERT(OK());
405 }
406 
407 inline void
409  using std::swap;
410  swap(current_data, itr.current_data);
411  swap(current_index, itr.current_index);
412 #if PPL_CO_TREE_EXTRA_DEBUG
413  swap(tree, itr.tree);
414 #endif
415  PPL_ASSERT(OK());
416  PPL_ASSERT(itr.OK());
417 }
418 
421  current_index = itr2.current_index;
422  current_data = itr2.current_data;
423 #if PPL_CO_TREE_EXTRA_DEBUG
424  tree = itr2.tree;
425 #endif
426  PPL_ASSERT(OK());
427  return *this;
428 }
429 
432  current_index = itr2.current_index;
433  current_data = itr2.current_data;
434 #if PPL_CO_TREE_EXTRA_DEBUG
435  tree = itr2.tree;
436 #endif
437  PPL_ASSERT(OK());
438  return *this;
439 }
440 
443  PPL_ASSERT(current_index != 0);
444  PPL_ASSERT(current_data != 0);
445 #if PPL_CO_TREE_EXTRA_DEBUG
446  PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
447 #endif
448  ++current_index;
449  ++current_data;
450  while (*current_index == unused_index) {
451  ++current_index;
452  ++current_data;
453  }
454  PPL_ASSERT(OK());
455  return *this;
456 }
457 
460  PPL_ASSERT(current_index != 0);
461  PPL_ASSERT(current_data != 0);
462  --current_index;
463  --current_data;
464  while (*current_index == unused_index) {
465  --current_index;
466  --current_data;
467  }
468  PPL_ASSERT(OK());
469  return *this;
470 }
471 
474  const_iterator itr(*this);
475  ++(*this);
476  return itr;
477 }
478 
481  const_iterator itr(*this);
482  --(*this);
483  return itr;
484 }
485 
486 inline Coefficient_traits::const_reference
488  PPL_ASSERT(current_index != 0);
489  PPL_ASSERT(current_data != 0);
490  PPL_ASSERT(OK());
491 #if PPL_CO_TREE_EXTRA_DEBUG
492  PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
493 #endif
494  return *current_data;
495 }
496 
497 inline dimension_type
499  PPL_ASSERT(current_index != 0);
500  PPL_ASSERT(current_data != 0);
501  PPL_ASSERT(OK());
502 #if PPL_CO_TREE_EXTRA_DEBUG
503  PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
504 #endif
505  return *current_index;
506 }
507 
508 inline bool
510  PPL_ASSERT((current_index == x.current_index)
511  == (current_data == x.current_data));
512  PPL_ASSERT(OK());
513  return (current_index == x.current_index);
514 }
515 
516 inline bool
518  return !(*this == x);
519 }
520 
521 
522 inline
524  : current_index(0), current_data(0) {
525 #if PPL_CO_TREE_EXTRA_DEBUG
526  tree = 0;
527 #endif
528  PPL_ASSERT(OK());
529 }
530 
531 inline
533  : current_index(&(tree1.indexes[1])), current_data(&(tree1.data[1])) {
534 #if PPL_CO_TREE_EXTRA_DEBUG
535  tree = &tree1;
536 #endif
537  if (!tree1.empty()) {
538  while (*current_index == unused_index) {
539  ++current_index;
540  ++current_data;
541  }
542  }
543  PPL_ASSERT(OK());
544 }
545 
546 inline
548  : current_index(&(tree1.indexes[i])), current_data(&(tree1.data[i])) {
549 #if PPL_CO_TREE_EXTRA_DEBUG
550  tree = &tree1;
551 #endif
552  PPL_ASSERT(i != 0);
553  PPL_ASSERT(i <= tree1.reserved_size + 1);
554  PPL_ASSERT(tree1.empty() || tree1.indexes[i] != unused_index);
555  PPL_ASSERT(OK());
556 }
557 
558 inline
560  *this = itr;
561  PPL_ASSERT(OK());
562 }
563 
564 inline
566  (*this) = itr2;
567  PPL_ASSERT(OK());
568 }
569 
570 inline void
572  using std::swap;
573  swap(current_data, itr.current_data);
574  swap(current_index, itr.current_index);
575 #if PPL_CO_TREE_EXTRA_DEBUG
576  swap(tree, itr.tree);
577 #endif
578  PPL_ASSERT(OK());
579  PPL_ASSERT(itr.OK());
580 }
581 
582 inline CO_Tree::iterator&
584  current_index = &(itr.tree.indexes[itr.dfs_index()]);
585  current_data = &(itr.tree.data[itr.dfs_index()]);
586 #if PPL_CO_TREE_EXTRA_DEBUG
587  tree = &(itr.tree);
588 #endif
589  PPL_ASSERT(OK());
590  return *this;
591 }
592 
593 inline CO_Tree::iterator&
595  current_index = itr2.current_index;
596  current_data = itr2.current_data;
597 #if PPL_CO_TREE_EXTRA_DEBUG
598  tree = itr2.tree;
599 #endif
600  PPL_ASSERT(OK());
601  return *this;
602 }
603 
604 inline CO_Tree::iterator&
606  PPL_ASSERT(current_index != 0);
607  PPL_ASSERT(current_data != 0);
608 #if PPL_CO_TREE_EXTRA_DEBUG
609  PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
610 #endif
611  ++current_index;
612  ++current_data;
613  while (*current_index == unused_index) {
614  ++current_index;
615  ++current_data;
616  }
617 
618  PPL_ASSERT(OK());
619  return *this;
620 }
621 
622 inline CO_Tree::iterator&
624  PPL_ASSERT(current_index != 0);
625  PPL_ASSERT(current_data != 0);
626  --current_index;
627  --current_data;
628  while (*current_index == unused_index) {
629  --current_index;
630  --current_data;
631  }
632 
633  PPL_ASSERT(OK());
634  return *this;
635 }
636 
637 inline CO_Tree::iterator
639  iterator itr(*this);
640  ++(*this);
641  return itr;
642 }
643 
644 inline CO_Tree::iterator
646  iterator itr(*this);
647  --(*this);
648  return itr;
649 }
650 
651 inline CO_Tree::data_type&
653  PPL_ASSERT(current_index != 0);
654  PPL_ASSERT(current_data != 0);
655  PPL_ASSERT(OK());
656 #if PPL_CO_TREE_EXTRA_DEBUG
657  PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
658 #endif
659  return *current_data;
660 }
661 
662 inline Coefficient_traits::const_reference
664  PPL_ASSERT(current_index != 0);
665  PPL_ASSERT(current_data != 0);
666  PPL_ASSERT(OK());
667 #if PPL_CO_TREE_EXTRA_DEBUG
668  PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
669 #endif
670  return *current_data;
671 }
672 
673 inline dimension_type
675  PPL_ASSERT(current_index != 0);
676  PPL_ASSERT(current_data != 0);
677  PPL_ASSERT(OK());
678 #if PPL_CO_TREE_EXTRA_DEBUG
679  PPL_ASSERT(current_index != &(tree->indexes[tree->reserved_size + 1]));
680 #endif
681  return *current_index;
682 }
683 
684 inline bool
686  PPL_ASSERT((current_index == x.current_index)
687  == (current_data == x.current_data));
688  PPL_ASSERT(OK());
689  return (current_index == x.current_index);
690 }
691 
692 inline bool
694  return !(*this == x);
695 }
696 
697 
698 inline
700  : tree(tree1) {
701  PPL_ASSERT(tree.reserved_size != 0);
702  get_root();
703  PPL_ASSERT(OK());
704 }
705 
706 inline
708  : tree(tree1) {
709  PPL_ASSERT(tree.reserved_size != 0);
710  PPL_ASSERT(i1 <= tree.reserved_size + 1);
711  i = i1;
713  PPL_ASSERT(OK());
714 }
715 
716 inline
718  : tree(tree1) {
719  PPL_ASSERT(tree.reserved_size != 0);
720  *this = itr;
721  PPL_ASSERT(OK());
722 }
723 
726  PPL_ASSERT(&tree == &(itr.tree));
727  i = itr.i;
728  offset = itr.offset;
729  return *this;
730 }
731 
734  PPL_ASSERT(itr != tree.end());
735  i = tree.dfs_index(itr);
736  offset = least_significant_one_mask(i);
737  return *this;
738 }
739 
740 inline bool
742  return i == itr.i;
743 }
744 
745 inline bool
747  return !(*this == itr);
748 }
749 
750 inline void
752  i = tree.reserved_size / 2 + 1;
753  offset = i;
754  PPL_ASSERT(OK());
755 }
756 
757 inline void
759  PPL_ASSERT(offset != 0);
760  PPL_ASSERT(offset != 1);
761  offset /= 2;
762  i -= offset;
763  PPL_ASSERT(OK());
764 }
765 
766 inline void
768  PPL_ASSERT(offset != 0);
769  PPL_ASSERT(offset != 1);
770  offset /= 2;
771  i += offset;
772  PPL_ASSERT(OK());
773 }
774 
775 inline void
777  PPL_ASSERT(!is_root());
778  PPL_ASSERT(offset != 0);
779  i &= ~offset;
780  offset *= 2;
781  i |= offset;
782  PPL_ASSERT(OK());
783 }
784 
785 inline void
787  PPL_ASSERT(index() != unused_index);
788  const dimension_type* p = tree.indexes;
789  p += i;
790  p -= (offset - 1);
791  while (*p == unused_index) {
792  ++p;
793  }
794  const std::ptrdiff_t distance = p - tree.indexes;
795  PPL_ASSERT(distance >= 0);
796  i = static_cast<dimension_type>(distance);
797  offset = least_significant_one_mask(i);
798  PPL_ASSERT(OK());
799 }
800 
801 inline void
803  PPL_ASSERT(index() != unused_index);
804  const dimension_type* p = tree.indexes;
805  p += i;
806  p += (offset - 1);
807  while (*p == unused_index) {
808  --p;
809  }
810  const std::ptrdiff_t distance = p - tree.indexes;
811  PPL_ASSERT(distance >= 0);
812  i = static_cast<dimension_type>(distance);
813  offset = least_significant_one_mask(i);
814  PPL_ASSERT(OK());
815 }
816 
817 inline bool
819  // This is implied by OK(), it is here for reference only.
820  PPL_ASSERT(offset <= (tree.reserved_size / 2 + 1));
821  return offset == (tree.reserved_size / 2 + 1);
822 }
823 
824 inline bool
826  if (is_root()) {
827  return false;
828  }
829  return (i & (2*offset)) != 0;
830 }
831 
832 inline bool
834  return offset == 1;
835 }
836 
837 inline CO_Tree::data_type&
839  return tree.data[i];
840 }
841 
842 inline Coefficient_traits::const_reference
844  return tree.data[i];
845 }
846 
847 inline dimension_type&
849  return tree.indexes[i];
850 }
851 
852 inline dimension_type
854  return tree.indexes[i];
855 }
856 
857 inline dimension_type
859  return i;
860 }
861 
862 inline dimension_type
864  return offset;
865 }
866 
867 inline CO_Tree::height_t
869  return integer_log2((tree.reserved_size + 1) / offset);
870 }
871 
872 inline void
874  x.m_swap(y);
875 }
876 
877 inline void
879  x.m_swap(y);
880 }
881 
882 inline void
884  x.m_swap(y);
885 }
886 
887 } // namespace Parma_Polyhedra_Library
888 
889 #endif // !defined(PPL_CO_Tree_inlines_hh)
dimension_type index() const
Returns the index of the element pointed to by *this.
bool is_root() const
Returns true if the pointed node is the root node.
void dump_tree() const
Dumps the tree to stdout, for debugging purposes.
bool operator!=(const iterator &x) const
Compares *this with x .
data_type & operator*()
Returns the key and value of the current node.
void m_swap(iterator &itr)
Swaps itr with *this.
Coefficient data_type
The type of the data elements associated with keys.
void init(dimension_type n)
Initializes a tree with reserved size at least n .
Definition: CO_Tree.cc:607
size_t dimension_type
An unsigned integral type for representing space dimensions.
bool OK() const
Checks the internal invariants.
Definition: CO_Tree.cc:752
static void dump_subtree(tree_iterator itr)
Dumps the subtree rooted at itr to stdout, for debugging purposes.
Definition: CO_Tree.cc:798
static unsigned integer_log2(dimension_type n)
Returns the floor of the base-2 logarithm of n .
Definition: CO_Tree.cc:787
static bool is_greater_than_ratio(dimension_type numer, dimension_type denom, dimension_type ratio)
Compares the fractions numer/denom with ratio/100.
void destroy()
Deallocates the tree's dynamic arrays.
Definition: CO_Tree.cc:649
bool OK() const
Checks the internal invariant.
Definition: CO_Tree.cc:1401
dimension_type get_offset() const
Returns 2^h, with h the height of the current node in the tree, counting from 0.
void swap(CO_Tree::iterator &x, CO_Tree::iterator &y)
dimension_type dfs_index() const
Returns the index of the current node in the DFS layout of the complete tree.
void get_parent()
Makes the iterator point to the parent of the current node.
iterator begin()
Returns an iterator that points at the first element.
data_type * data
The vector that contains the data of the keys in the tree.
bool operator==(const iterator &x) const
Compares *this with x .
bool is_right_child() const
Returns true if the pointed node has a parent and is its right child.
const dimension_type * current_index
A pointer to the corresponding element of the tree's indexes[] array.
bool is_leaf() const
Returns true if the pointed node is a leaf of the complete tree.
An iterator on the tree elements, ordered by key.
dimension_type * indexes
The vector that contains the keys in the tree.
static dimension_type max_size()
Returns the size() of the largest possible CO_Tree.
const_iterator & operator++()
Navigates to the next element.
const data_type * current_data
A pointer to the corresponding element of the tree's data[] array.
void m_swap(const_iterator &itr)
Swaps itr with *this.
unsigned height_t
This is used for node heights and depths in the tree.
std::allocator< data_type > data_allocator
The allocator used to allocate/deallocate data.
dimension_type size() const
Returns the number of elements stored in the tree.
void m_swap(CO_Tree &x)
Swaps x with *this.
iterator & operator=(const iterator &itr)
Assigns itr to *this .
const iterator & end()
Returns an iterator that points after the last element.
const_iterator & operator--()
Navigates to the previous element.
const_iterator()
Constructs an invalid const_iterator.
iterator bisect_in(iterator first, iterator last, dimension_type key)
Searches an element with key key in [first, last] using bisection.
void get_left_child()
Makes the iterator point to the left child of the current node.
CO_Tree & operator=(const CO_Tree &y)
The assignment operator.
bool empty() const
Returns true if the tree has no elements.
iterator insert(dimension_type key)
Inserts an element in the tree.
dimension_type reserved_size
The number of nodes in the complete tree.
const_iterator cbegin() const
Returns a const_iterator that points at the first element.
bool operator==(const const_iterator &x) const
Compares *this with x .
data_type & operator*()
Returns the current element.
tree_iterator & operator=(const tree_iterator &itr)
The assignment operator.
iterator cached_end
The iterator returned by end().
A cache-oblivious binary search tree of pairs.
bool operator==(const tree_iterator &itr) const
Compares *this with itr.
dimension_type offset
This is 2^h, with h the height of the current node in the tree, counting from 0.
iterator bisect(dimension_type key)
Searches an element with key key using bisection.
const_iterator cached_const_end
The iterator returned by the const version of end().
void follow_left_children_with_value()
Follows left children with a value, until it arrives at a leaf or at a node with no value...
tree_iterator(CO_Tree &tree)
Constructs a tree_iterator pointing at the root node of the specified tree.
bool OK() const
Checks the internal invariants, in debug mode only.
Definition: CO_Tree.cc:1359
const const_iterator & cend() const
Returns a const_iterator that points after the last element.
dimension_type dfs_index(const_iterator itr) const
static bool is_less_than_ratio(dimension_type numer, dimension_type denom, dimension_type ratio)
Compares the fractions numer/denom with ratio/100.
bool OK() const
Checks the internal invariants, in debug mode only.
Definition: CO_Tree.cc:1317
iterator & operator++()
Navigates to the next element in the tree.
CO_Tree & tree
The tree containing the element pointed to by this iterator.
bool operator!=(const const_iterator &x) const
Compares *this with x .
dimension_type & index()
Returns a reference to the index of the element pointed to by *this.
bool operator!=(const tree_iterator &itr) const
Compares *this with itr.
tree_iterator insert_precise(dimension_type key, data_type_const_reference data, tree_iterator itr)
Inserts an element in the tree.
Definition: CO_Tree.cc:401
Coefficient_traits::const_reference data_type_const_reference
Coefficient_traits::const_reference Coefficient_zero()
Returns a const reference to a Coefficient with value 0.
The entire library is confined to this namespace.
Definition: version.hh:61
A const iterator on the tree elements, ordered by key.
iterator()
Constructs an invalid iterator.
height_t depth() const
Returns the depth of the current node in the complete tree.
void rebuild_bigger_tree()
Increases the tree's reserved size.
Definition: CO_Tree.cc:819
data_type_const_reference operator*() const
Returns the current element.
void clear()
Removes all elements from the tree.
void swap(CO_Tree &x, CO_Tree &y)
Swaps x with y.
static void move_data_element(data_type &to, data_type &from)
Moves the value of from in to .
void get_root()
Makes the iterator point to the root of tree.
void refresh_cached_iterators()
Re-initializes the cached iterators.
dimension_type size_
The number of values stored in the tree.
void insert_in_empty_tree(dimension_type key, data_type_const_reference data)
Inserts an element in the tree.
bool structure_OK() const
Checks the internal invariants, but not the densities.
Definition: CO_Tree.cc:664
void follow_right_children_with_value()
Follows right children with a value, until it arrives at a leaf or at a node with no value...
const_iterator & operator=(const const_iterator &itr)
Assigns itr to *this .
iterator erase(dimension_type key)
Erases the element with key key from the tree.
const dimension_type * current_index
A pointer to the corresponding element of the tree's indexes[] array.
iterator bisect_near(iterator hint, dimension_type key)
Searches an element with key key near hint.
dimension_type index() const
Returns the index of the element pointed to by *this.
void move_data_from(CO_Tree &tree)
Moves all data in the tree tree into *this.
Definition: CO_Tree.cc:1133
height_t max_depth
The depth of the leaves in the complete tree.
void fast_shift(dimension_type i, iterator itr)
dimension_type least_significant_one_mask(dimension_type i)
static const dimension_type unused_index
An index used as a marker for unused nodes in the tree.
iterator & operator--()
Navigates to the previous element in the tree.
void rebuild_smaller_tree()
Decreases the tree's reserved size.
void get_right_child()
Makes the iterator point to the right child of the current node.
void copy_data_from(const CO_Tree &tree)
Copies all data in the tree tree into *this.
Definition: CO_Tree.cc:1246
dimension_type i
The index of the current node in the DFS layout of the complete tree.
CO_Tree()
Constructs an empty tree.
data_type * current_data
A pointer to the corresponding element of the tree's data[] array.
void go_down_searching_key(dimension_type key)
Searches for an element with key key in the subtree rooted at *this.
Definition: CO_Tree.cc:1417