From 255c7b8f996201cd24ecda955a3e03dc19392e08 Mon Sep 17 00:00:00 2001 From: "Tim.Ebbeke" Date: Wed, 31 Jul 2024 15:25:56 +0200 Subject: [PATCH 1/6] Fixed pointer to number converter for some systems. --- include/interval-tree/draw.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/interval-tree/draw.hpp b/include/interval-tree/draw.hpp index f6768ce..6665975 100644 --- a/include/interval-tree/draw.hpp +++ b/include/interval-tree/draw.hpp @@ -21,15 +21,15 @@ namespace lib_interval_tree {}; template <> - struct NumericalPointerEquivalent + struct NumericalPointerEquivalent { - using type = unsigned long; + using type = uint32_t; }; template <> - struct NumericalPointerEquivalent + struct NumericalPointerEquivalent { - using type = unsigned long long; + using type = uint64_t; }; template From ad4a95fe4213445bd1be3d8f0877fa1aafc81f74 Mon Sep 17 00:00:00 2001 From: "Tim.Ebbeke" Date: Wed, 31 Jul 2024 15:26:30 +0200 Subject: [PATCH 2/6] Added drawing capabilities to tests when enabled. --- tests/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a0cfc23..32b946c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -28,6 +28,10 @@ target_compile_options(tree-tests PUBLIC "$<$:${DEBUG_OPTIONS}>") set(RELEASE_OPTIONS -fexceptions -O3 -Wall -pedantic) target_compile_options(tree-tests PUBLIC "$<$:${RELEASE_OPTIONS}>") +if (INT_TREE_DRAW_EXAMPLES) + target_link_libraries(tree-tests PRIVATE cairo cairo-wrap) +endif() + # If msys2, copy dynamic libraries to executable directory, visual studio does this automatically. # And there is no need on linux. if (DEFINED ENV{MSYSTEM}) From e5bfe7a43f9ba9d35d405c9f268379cdf53952e9 Mon Sep 17 00:00:00 2001 From: "Tim.Ebbeke" Date: Wed, 31 Jul 2024 15:26:45 +0200 Subject: [PATCH 3/6] Added more erase tests. --- tests/erase_tests.hpp | 74 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/tests/erase_tests.hpp b/tests/erase_tests.hpp index a5ecbdb..a35a064 100644 --- a/tests/erase_tests.hpp +++ b/tests/erase_tests.hpp @@ -1,5 +1,9 @@ #pragma once +#include +#include "interval_io.hpp" +#include "test_utility.hpp" + #include #include #include @@ -48,7 +52,7 @@ class OracleInterval : public lib_interval_tree::intervallivingInstances; @@ -73,6 +77,23 @@ class EraseTests public: using interval_type = OracleInterval; +public: + auto makeTree() + { + lib_interval_tree::interval_tree_t regularTree; + regularTree.insert({16, 21}); + regularTree.insert({8, 9}); + regularTree.insert({25, 30}); + regularTree.insert({5, 8}); + regularTree.insert({15, 23}); + regularTree.insert({17, 19}); + regularTree.insert({26, 26}); + regularTree.insert({0, 3}); + regularTree.insert({6, 10}); + regularTree.insert({19, 20}); + return regularTree; + } + protected: Oracle oracle; lib_interval_tree::interval_tree > tree; @@ -162,3 +183,54 @@ TEST_F(EraseTests, RandomEraseTest) testMaxProperty(tree); testTreeHeightHealth(tree); } + +TEST_F(EraseTests, ReturnedIteratorPointsToNextInOrderNode) +{ + auto regularTree = makeTree(); + auto iter = regularTree.erase(regularTree.find({16, 21})); + EXPECT_EQ(*iter, (decltype(regularTree)::interval_type{17, 19})) << *iter; + + regularTree = makeTree(); + iter = regularTree.erase(regularTree.find({8, 9})); + EXPECT_EQ(*iter, (decltype(regularTree)::interval_type{15, 23})) << *iter; + + regularTree = makeTree(); + iter = regularTree.erase(regularTree.find({25, 30})); + EXPECT_EQ(*iter, (decltype(regularTree)::interval_type{26, 26})) << *iter; + + regularTree = makeTree(); + iter = regularTree.erase(regularTree.find({5, 8})); + EXPECT_EQ(*iter, (decltype(regularTree)::interval_type{6, 10})) << *iter; + + regularTree = makeTree(); + iter = regularTree.erase(regularTree.find({15, 23})); + EXPECT_EQ(*iter, (decltype(regularTree)::interval_type{16, 21})) << *iter; + + regularTree = makeTree(); + iter = regularTree.erase(regularTree.find({17, 19})); + EXPECT_EQ(*iter, (decltype(regularTree)::interval_type{19, 20})) << *iter; + + regularTree = makeTree(); + iter = regularTree.erase(regularTree.find({26, 26})); + EXPECT_EQ(iter, regularTree.end()); + + regularTree = makeTree(); + iter = regularTree.erase(regularTree.find({0, 3})); + EXPECT_EQ(*iter, (decltype(regularTree)::interval_type{5, 8})) << *iter; + + regularTree = makeTree(); + iter = regularTree.erase(regularTree.find({6, 10})); + EXPECT_EQ(*iter, (decltype(regularTree)::interval_type{8, 9})) << *iter; + + regularTree = makeTree(); + iter = regularTree.erase(regularTree.find({19, 20})); + EXPECT_EQ(*iter, (decltype(regularTree)::interval_type{25, 30})) << *iter; +} + +TEST_F(EraseTests, CanEraseEntireTreeUsingReturnedIterator) +{ + auto tree = makeTree(); + for (auto iter = tree.begin(); iter != tree.end();) + iter = tree.erase(iter); + EXPECT_EQ(tree.empty(), true); +} From 0f2830ac6ad38e22553ce967633b00faddcc9b8b Mon Sep 17 00:00:00 2001 From: "Tim.Ebbeke" Date: Wed, 31 Jul 2024 15:27:05 +0200 Subject: [PATCH 4/6] Added interval stream operator for tests. --- tests/interval_io.hpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 tests/interval_io.hpp diff --git a/tests/interval_io.hpp b/tests/interval_io.hpp new file mode 100644 index 0000000..520c4be --- /dev/null +++ b/tests/interval_io.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include + +#include + +namespace lib_interval_tree +{ + template + std::ostream& + operator<<(std::ostream& os, lib_interval_tree::interval const& interval) + { + os << '[' << interval.low() << ", " << interval.high() << ']'; + return os; + } +} \ No newline at end of file From 3936adab3521afdfb35c330a278e1d44eaee5a9e Mon Sep 17 00:00:00 2001 From: "Tim.Ebbeke" Date: Wed, 31 Jul 2024 16:53:50 +0200 Subject: [PATCH 5/6] Fixed erase return iterator. --- include/interval-tree/interval_tree.hpp | 30 ++++++++++++++--------- tests/erase_tests.hpp | 32 +++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/include/interval-tree/interval_tree.hpp b/include/interval-tree/interval_tree.hpp index 513a555..88990c7 100644 --- a/include/interval-tree/interval_tree.hpp +++ b/include/interval-tree/interval_tree.hpp @@ -886,19 +886,27 @@ namespace lib_interval_tree throw std::out_of_range("cannot erase end iterator"); auto next = iter; - ++next; - node_type* y; - if (!iter.node_->left_ || !iter.node_->right_) - y = iter.node_; - else - y = successor(iter.node_); + node_type* y = [&next, &iter, this]() { + if (!iter.node_->left_ || !iter.node_->right_) + { + ++next; + return iter.node_; + } + else + { + const auto y = successor(iter.node_); + next = iterator{iter.node_, this}; + return y; + } + }(); - node_type* x; - if (y->left_) - x = y->left_; - else - x = y->right_; + node_type* x = [y](){ + if (y->left_) + return y->left_; + else + return y->right_; + }(); if (x) x->parent_ = y->parent_; diff --git a/tests/erase_tests.hpp b/tests/erase_tests.hpp index a35a064..414c0f6 100644 --- a/tests/erase_tests.hpp +++ b/tests/erase_tests.hpp @@ -184,6 +184,25 @@ TEST_F(EraseTests, RandomEraseTest) testTreeHeightHealth(tree); } + + +TEST_F(EraseTests, MassiveDeleteEntireTreeWithEraseReturnIterator) +{ + constexpr int amount = 1000; + + for (int i = 0; i != amount; ++i) + tree.insert(makeSafeOracleInterval(&oracle, distSmall(gen), distSmall(gen))); + + for(auto iter = tree.begin(); !tree.empty();) + { + iter = tree.erase(iter); + } + + EXPECT_EQ(oracle.livingInstances, 0); + testMaxProperty(tree); + testTreeHeightHealth(tree); +} + TEST_F(EraseTests, ReturnedIteratorPointsToNextInOrderNode) { auto regularTree = makeTree(); @@ -234,3 +253,16 @@ TEST_F(EraseTests, CanEraseEntireTreeUsingReturnedIterator) iter = tree.erase(iter); EXPECT_EQ(tree.empty(), true); } + +TEST_F(EraseTests, FromNuiTest) +{ + lib_interval_tree::interval_tree_t tree; + tree.insert({0, 0}); + tree.insert({4, 4}); + tree.insert({13, 13}); + + drawTree("erase_tests_from_nui", tree); + + auto iter = tree.erase(tree.find({4, 4})); + EXPECT_EQ(*iter, (decltype(tree)::interval_type{13, 13})) << *iter; +} From 0478ae2fad56cd4ec7467bd30fb45d196be1b284 Mon Sep 17 00:00:00 2001 From: "Tim.Ebbeke" Date: Wed, 31 Jul 2024 17:01:48 +0200 Subject: [PATCH 6/6] Removed draw calls. --- tests/erase_tests.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/erase_tests.hpp b/tests/erase_tests.hpp index 414c0f6..e0cce41 100644 --- a/tests/erase_tests.hpp +++ b/tests/erase_tests.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include "interval_io.hpp" #include "test_utility.hpp" @@ -261,8 +260,6 @@ TEST_F(EraseTests, FromNuiTest) tree.insert({4, 4}); tree.insert({13, 13}); - drawTree("erase_tests_from_nui", tree); - auto iter = tree.erase(tree.find({4, 4})); EXPECT_EQ(*iter, (decltype(tree)::interval_type{13, 13})) << *iter; }