Skip to content

Commit a661ab1

Browse files
authored
Merge pull request #33 from 5cript/feat/more-erase-tests
Feat/more erase tests
2 parents 639401d + 0478ae2 commit a661ab1

File tree

5 files changed

+145
-16
lines changed

5 files changed

+145
-16
lines changed

include/interval-tree/draw.hpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ namespace lib_interval_tree
2121
{};
2222

2323
template <>
24-
struct NumericalPointerEquivalent <sizeof(unsigned long)>
24+
struct NumericalPointerEquivalent <sizeof(std::uint32_t)>
2525
{
26-
using type = unsigned long;
26+
using type = uint32_t;
2727
};
2828

2929
template <>
30-
struct NumericalPointerEquivalent <sizeof(unsigned long long)>
30+
struct NumericalPointerEquivalent <sizeof(std::uint64_t)>
3131
{
32-
using type = unsigned long long;
32+
using type = uint64_t;
3333
};
3434

3535
template <typename... List>

include/interval-tree/interval_tree.hpp

+19-11
Original file line numberDiff line numberDiff line change
@@ -886,19 +886,27 @@ namespace lib_interval_tree
886886
throw std::out_of_range("cannot erase end iterator");
887887

888888
auto next = iter;
889-
++next;
890889

891-
node_type* y;
892-
if (!iter.node_->left_ || !iter.node_->right_)
893-
y = iter.node_;
894-
else
895-
y = successor(iter.node_);
890+
node_type* y = [&next, &iter, this]() {
891+
if (!iter.node_->left_ || !iter.node_->right_)
892+
{
893+
++next;
894+
return iter.node_;
895+
}
896+
else
897+
{
898+
const auto y = successor(iter.node_);
899+
next = iterator{iter.node_, this};
900+
return y;
901+
}
902+
}();
896903

897-
node_type* x;
898-
if (y->left_)
899-
x = y->left_;
900-
else
901-
x = y->right_;
904+
node_type* x = [y](){
905+
if (y->left_)
906+
return y->left_;
907+
else
908+
return y->right_;
909+
}();
902910

903911
if (x)
904912
x->parent_ = y->parent_;

tests/CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ target_compile_options(tree-tests PUBLIC "$<$<CONFIG:DEBUG>:${DEBUG_OPTIONS}>")
2828
set(RELEASE_OPTIONS -fexceptions -O3 -Wall -pedantic)
2929
target_compile_options(tree-tests PUBLIC "$<$<CONFIG:RELEASE>:${RELEASE_OPTIONS}>")
3030

31+
if (INT_TREE_DRAW_EXAMPLES)
32+
target_link_libraries(tree-tests PRIVATE cairo cairo-wrap)
33+
endif()
34+
3135
# If msys2, copy dynamic libraries to executable directory, visual studio does this automatically.
3236
# And there is no need on linux.
3337
if (DEFINED ENV{MSYSTEM})

tests/erase_tests.hpp

+102-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#pragma once
22

3+
#include "interval_io.hpp"
4+
#include "test_utility.hpp"
5+
36
#include <ctime>
47
#include <random>
58
#include <cmath>
@@ -48,7 +51,7 @@ class OracleInterval : public lib_interval_tree::interval<numerical_type, interv
4851
other.oracle_ = nullptr;
4952
return *this;
5053
}
51-
~OracleInterval()
54+
~OracleInterval()
5255
{
5356
if (oracle_ != nullptr)
5457
--oracle_->livingInstances;
@@ -73,6 +76,23 @@ class EraseTests
7376
public:
7477
using interval_type = OracleInterval<int>;
7578

79+
public:
80+
auto makeTree()
81+
{
82+
lib_interval_tree::interval_tree_t <int> regularTree;
83+
regularTree.insert({16, 21});
84+
regularTree.insert({8, 9});
85+
regularTree.insert({25, 30});
86+
regularTree.insert({5, 8});
87+
regularTree.insert({15, 23});
88+
regularTree.insert({17, 19});
89+
regularTree.insert({26, 26});
90+
regularTree.insert({0, 3});
91+
regularTree.insert({6, 10});
92+
regularTree.insert({19, 20});
93+
return regularTree;
94+
}
95+
7696
protected:
7797
Oracle oracle;
7898
lib_interval_tree::interval_tree <OracleInterval<int>> tree;
@@ -162,3 +182,84 @@ TEST_F(EraseTests, RandomEraseTest)
162182
testMaxProperty(tree);
163183
testTreeHeightHealth(tree);
164184
}
185+
186+
187+
188+
TEST_F(EraseTests, MassiveDeleteEntireTreeWithEraseReturnIterator)
189+
{
190+
constexpr int amount = 1000;
191+
192+
for (int i = 0; i != amount; ++i)
193+
tree.insert(makeSafeOracleInterval(&oracle, distSmall(gen), distSmall(gen)));
194+
195+
for(auto iter = tree.begin(); !tree.empty();)
196+
{
197+
iter = tree.erase(iter);
198+
}
199+
200+
EXPECT_EQ(oracle.livingInstances, 0);
201+
testMaxProperty(tree);
202+
testTreeHeightHealth(tree);
203+
}
204+
205+
TEST_F(EraseTests, ReturnedIteratorPointsToNextInOrderNode)
206+
{
207+
auto regularTree = makeTree();
208+
auto iter = regularTree.erase(regularTree.find({16, 21}));
209+
EXPECT_EQ(*iter, (decltype(regularTree)::interval_type{17, 19})) << *iter;
210+
211+
regularTree = makeTree();
212+
iter = regularTree.erase(regularTree.find({8, 9}));
213+
EXPECT_EQ(*iter, (decltype(regularTree)::interval_type{15, 23})) << *iter;
214+
215+
regularTree = makeTree();
216+
iter = regularTree.erase(regularTree.find({25, 30}));
217+
EXPECT_EQ(*iter, (decltype(regularTree)::interval_type{26, 26})) << *iter;
218+
219+
regularTree = makeTree();
220+
iter = regularTree.erase(regularTree.find({5, 8}));
221+
EXPECT_EQ(*iter, (decltype(regularTree)::interval_type{6, 10})) << *iter;
222+
223+
regularTree = makeTree();
224+
iter = regularTree.erase(regularTree.find({15, 23}));
225+
EXPECT_EQ(*iter, (decltype(regularTree)::interval_type{16, 21})) << *iter;
226+
227+
regularTree = makeTree();
228+
iter = regularTree.erase(regularTree.find({17, 19}));
229+
EXPECT_EQ(*iter, (decltype(regularTree)::interval_type{19, 20})) << *iter;
230+
231+
regularTree = makeTree();
232+
iter = regularTree.erase(regularTree.find({26, 26}));
233+
EXPECT_EQ(iter, regularTree.end());
234+
235+
regularTree = makeTree();
236+
iter = regularTree.erase(regularTree.find({0, 3}));
237+
EXPECT_EQ(*iter, (decltype(regularTree)::interval_type{5, 8})) << *iter;
238+
239+
regularTree = makeTree();
240+
iter = regularTree.erase(regularTree.find({6, 10}));
241+
EXPECT_EQ(*iter, (decltype(regularTree)::interval_type{8, 9})) << *iter;
242+
243+
regularTree = makeTree();
244+
iter = regularTree.erase(regularTree.find({19, 20}));
245+
EXPECT_EQ(*iter, (decltype(regularTree)::interval_type{25, 30})) << *iter;
246+
}
247+
248+
TEST_F(EraseTests, CanEraseEntireTreeUsingReturnedIterator)
249+
{
250+
auto tree = makeTree();
251+
for (auto iter = tree.begin(); iter != tree.end();)
252+
iter = tree.erase(iter);
253+
EXPECT_EQ(tree.empty(), true);
254+
}
255+
256+
TEST_F(EraseTests, FromNuiTest)
257+
{
258+
lib_interval_tree::interval_tree_t <int> tree;
259+
tree.insert({0, 0});
260+
tree.insert({4, 4});
261+
tree.insert({13, 13});
262+
263+
auto iter = tree.erase(tree.find({4, 4}));
264+
EXPECT_EQ(*iter, (decltype(tree)::interval_type{13, 13})) << *iter;
265+
}

tests/interval_io.hpp

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#pragma once
2+
3+
#include <interval-tree/interval_tree.hpp>
4+
5+
#include <iostream>
6+
7+
namespace lib_interval_tree
8+
{
9+
template <typename... IntervalArgs>
10+
std::ostream&
11+
operator<<(std::ostream& os, lib_interval_tree::interval<IntervalArgs...> const& interval)
12+
{
13+
os << '[' << interval.low() << ", " << interval.high() << ']';
14+
return os;
15+
}
16+
}

0 commit comments

Comments
 (0)