feat(util/rb_tree): add for_each_greater
This commit is contained in:
parent
2a4b3b75bd
commit
82fb38b440
3 changed files with 46 additions and 1 deletions
|
@ -235,6 +235,21 @@ static void tst6() {
|
|||
#endif
|
||||
}
|
||||
|
||||
static void tst7() {
|
||||
int_rb_tree t;
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
t.insert(i);
|
||||
}
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
int c = 0;
|
||||
t.for_each_greater(i, [&](int v) {
|
||||
lean_assert(v > i);
|
||||
c++;
|
||||
});
|
||||
lean_assert(c == 1000 - i - 1, c, i);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
tst1();
|
||||
tst2();
|
||||
|
@ -242,6 +257,6 @@ int main() {
|
|||
tst4();
|
||||
tst5();
|
||||
tst6();
|
||||
tst7();
|
||||
return has_violations() ? 1 : 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -82,6 +82,12 @@ public:
|
|||
return optional<T>();
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void for_each_greater(K const & k, F && f) const {
|
||||
auto f_prime = [&](entry const & e) { f(e.first, e.second); };
|
||||
m_map.for_each_greater(mk_pair(k, T()), f_prime);
|
||||
}
|
||||
|
||||
/** \brief (For debugging) Display the content of this splay map. */
|
||||
friend std::ostream & operator<<(std::ostream & out, rb_map const & m) {
|
||||
out << "{";
|
||||
|
|
|
@ -248,6 +248,25 @@ class rb_tree : public CMP {
|
|||
return optional<T>();
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void for_each_greater(T const & v, F && f, node_cell const * n) const {
|
||||
if (n) {
|
||||
int c = cmp(v, n->m_value);
|
||||
if (c == 0) {
|
||||
for_each(f, n->m_right.m_ptr);
|
||||
} else if (c > 0) {
|
||||
// v > n->m_value
|
||||
for_each_greater(v, f, n->m_right.m_ptr);
|
||||
} else {
|
||||
// v < n->m_value
|
||||
lean_assert(c < 0);
|
||||
for_each_greater(v, f, n->m_left.m_ptr);
|
||||
f(n->m_value);
|
||||
for_each(f, n->m_right.m_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void display(std::ostream & out, node_cell const * n) {
|
||||
if (n) {
|
||||
out << "(";
|
||||
|
@ -371,6 +390,11 @@ public:
|
|||
template<typename F>
|
||||
optional<T> find_if(F && f) const { return find_if(f, m_root.m_ptr); }
|
||||
|
||||
template<typename F>
|
||||
void for_each_greater(T const & v, F && f) const {
|
||||
for_each_greater(v, f, m_root.m_ptr);
|
||||
}
|
||||
|
||||
// For debugging purposes
|
||||
void display(std::ostream & out) const { display(out, m_root.m_ptr); }
|
||||
|
||||
|
|
Loading…
Reference in a new issue