37# include <gtest/gtest.h>
43# include <type_traits>
46using namespace testing;
48static_assert(
not std::is_copy_constructible_v<Interval_Tree<int>>);
49static_assert(
not std::is_copy_assignable_v<Interval_Tree<int>>);
50static_assert(
not std::is_move_constructible_v<Interval_Tree<int>>);
51static_assert(
not std::is_move_assignable_v<Interval_Tree<int>>);
184 EXPECT_EQ(tree.search(Key(0, 0)),
nullptr);
185 EXPECT_EQ(tree.overlap_search(Key(0, 10)),
nullptr);
190 auto * p = make_node(1, 5);
194 EXPECT_NE(tree.search(Key(1, 5)),
nullptr);
199 tree.insert(make_node(15, 20));
200 tree.insert(make_node(10, 30));
201 tree.insert(make_node(17, 19));
202 tree.insert(make_node(5, 20));
203 tree.insert(make_node(12, 15));
204 tree.insert(make_node(30, 40));
212 auto * p1 = make_node(1, 5);
213 auto * p2 = make_node(1, 5);
223 auto * p1 = make_node(1, 5);
224 auto * p2 = make_node(1, 5);
233 tree.insert(make_node(1, 5));
234 tree.insert(make_node(10, 20));
235 tree.insert(make_node(3, 7));
240 auto *
removed = tree.remove(Key(10, 20));
249 tree.insert(make_node(1, 5));
250 auto *
removed = tree.remove(Key(99, 100));
258 tree.insert(make_node(15, 20));
259 tree.insert(make_node(10, 30));
260 tree.insert(make_node(17, 19));
261 tree.insert(make_node(5, 20));
262 tree.insert(make_node(12, 15));
263 tree.insert(make_node(30, 40));
265 auto * result = tree.overlap_search(Key(14, 16));
272 tree.insert(make_node(1, 5));
273 tree.insert(make_node(10, 15));
274 tree.insert(make_node(20, 25));
276 auto * result = tree.overlap_search(Key(6, 9));
282 tree.insert(make_node(1, 5));
283 tree.insert(make_node(3, 8));
284 tree.insert(make_node(7, 10));
285 tree.insert(make_node(15, 20));
288 tree.all_overlaps(Key(4, 7), [&
results](
const Key &
iv) {
301 tree.insert(make_node(1, 5));
302 tree.insert(make_node(3, 8));
303 tree.insert(make_node(7, 10));
304 tree.insert(make_node(15, 20));
306 auto results = tree.find_stab(4);
316 tree.insert(make_node(5, 5));
317 tree.insert(make_node(3, 7));
319 auto * result = tree.overlap_search(Key(5, 5));
326 tree.insert(make_node(1, 10));
329 tree.insert(make_node(5, 20));
332 tree.insert(make_node(15, 25));
335 auto *
r1 = tree.remove(Key(5, 20));
339 auto * r2 = tree.remove(Key(1, 10));
346 tree.insert(make_node(10, 20));
347 tree.insert(make_node(5, 15));
348 tree.insert(make_node(1, 3));
349 tree.insert(make_node(20, 30));
354 for (IvTree::Iterator it(tree); it.has_curr(); it.next())
356 Key
k =
KEY(it.get_curr());
367 tree.insert(make_node(0, 3));
368 tree.insert(make_node(5, 8));
369 tree.insert(make_node(6, 10));
370 tree.insert(make_node(8, 9));
371 tree.insert(make_node(15, 23));
372 tree.insert(make_node(16, 21));
373 tree.insert(make_node(17, 19));
374 tree.insert(make_node(19, 20));
375 tree.insert(make_node(25, 30));
376 tree.insert(make_node(26, 26));
382 auto overlaps = tree.find_all_overlaps(Key(22, 25));
384 overlaps.for_each([](
const Key &
iv) {
389 auto * result = tree.overlap_search(Key(11, 14));
395 std::mt19937
gen(12345);
396 std::uniform_int_distribution<int> dist(0, 10000);
398 const size_t N = 5000;
402 for (
size_t i = 0; i <
N; ++i)
404 int a = dist(
gen), b = dist(
gen);
405 if (a > b) std::swap(a, b);
406 tree.insert_dup(make_node(a, b));
414 for (
int q = 0; q < 100; ++q)
416 int a = dist(
gen), b = dist(
gen);
417 if (a > b) std::swap(a, b);
420 auto * found = tree.overlap_search(query);
423 if (
iv.overlaps(query))
430 EXPECT_NE(found,
nullptr) <<
"BF found overlap for ["
431 << a <<
"," << b <<
"] but tree didn't";
433 EXPECT_EQ(found,
nullptr) <<
"BF found no overlap for ["
434 << a <<
"," << b <<
"] but tree did";
459 tree.insert(Key(1, 5));
460 tree.insert(Key(10, 20));
464 auto * found = tree.search(Key(1, 5));
469 EXPECT_EQ(tree.search(Key(2, 3)),
nullptr);
482 tree.insert(Key(1, 5));
483 tree.insert(Key(10, 20));
484 tree.insert(Key(3, 7));
489 EXPECT_EQ(tree.search(Key(10, 20)),
nullptr);
501 tree.insert(Key(1, 5));
508 EXPECT_THROW(tree.insert(Key(5, 1)), std::domain_error);
514 tree.insert(Key(1, 5));
515 tree.insert(Key(10, 15));
516 tree.insert(Key(20, 25));
518 auto * result = tree.overlap_search(Key(4, 11));
522 EXPECT_EQ(tree.overlap_search(Key(6, 9)),
nullptr);
527 tree.insert(Key(1, 5));
528 auto * result = tree.overlap_search(3, 4);
534 tree.insert(Key(1, 5));
535 tree.insert(Key(3, 8));
536 tree.insert(Key(7, 10));
537 tree.insert(Key(15, 20));
539 auto results = tree.find_all_overlaps(Key(4, 7));
549 tree.insert(Key(1, 5));
550 tree.insert(Key(3, 8));
551 auto results = tree.find_all_overlaps(2, 4);
557 tree.insert(Key(1, 5));
558 tree.insert(Key(3, 8));
559 tree.insert(Key(7, 10));
562 tree.stab(4, [&
count](
const Key &) { ++
count; });
568 tree.insert(Key(1, 10));
569 tree.insert(Key(5, 15));
570 tree.insert(Key(20, 25));
572 auto results = tree.find_stab(7);
584 tree.insert(Key(1, 5));
585 tree.insert(Key(10, 20));
586 tree.insert(Key(3, 7));
598 tree.insert(Key(1, 5));
599 tree.insert(Key(10, 20));
609 tree.insert(Key(1, 5));
610 tree.insert(Key(10, 20));
622 tree.insert(Key(1, 5));
623 tree.insert(Key(10, 20));
626 other = std::move(tree);
656 tree.insert(Key(1, 5));
657 tree.insert(Key(10, 20));
658 tree.insert(Key(3, 7));
661 tree.for_each([&
count](
const Key &) { ++
count; });
667 tree.insert(Key(1, 5));
668 tree.insert(Key(10, 20));
670 EXPECT_TRUE(tree.exists([](
const Key &
iv) { return iv.low == 10; }));
671 EXPECT_FALSE(tree.exists([](
const Key &
iv) { return iv.low == 99; }));
676 tree.insert(Key(1, 5));
677 tree.insert(Key(10, 20));
678 tree.insert(Key(3, 7));
680 auto wide = tree.filter([](
const Key &
iv) {
681 return (
iv.high -
iv.low) >= 5;
695 tree.insert(Key(1, 5));
696 tree.insert(Key(10, 20));
697 tree.insert(Key(3, 7));
698 tree.insert(Key(25, 30));
699 tree.insert(Key(0, 2));
706 tree.insert(Key(1, 5));
707 tree.insert(Key(10, 20));
708 tree.insert(Key(3, 7));
711 for (
const auto &
iv : tree)
773 std::mt19937
gen(54321);
774 std::uniform_int_distribution<int> dist(0, 1000);
779 for (
int i = 0; i < 1000; ++i)
781 int a = dist(
gen), b = dist(
gen);
782 if (a > b) std::swap(a, b);
810 <<
"Lost interval [" <<
iv.
low <<
"," <<
iv.high <<
"]";
816 std::mt19937
gen(99999);
817 std::uniform_int_distribution<int> dist(0, 100);
822 for (
int i = 0; i < 200; ++i)
824 int a = dist(
gen), b = dist(
gen);
825 if (a > b) std::swap(a, b);
834 for (
int q = 0; q < 50; ++q)
836 int a = dist(
gen), b = dist(
gen);
837 if (a > b) std::swap(a, b);
844 if (
iv.overlaps(query))
848 <<
"Mismatch for query [" << a <<
"," << b <<
"]";
High-level interval tree with automatic memory management.
DynList< Key > find_all_overlaps(const Key &query) const
Find all overlapping intervals.
Key & insert_dup(const Key &iv)
Insert interval, allowing duplicates.
Key & insert(const Key &iv)
Insert an interval (unique).
const Key * overlap_search(const Key &query) const
Find any interval overlapping query.
bool verify() const
Verify all tree invariants (BST, Treap, MaxEndpoint).
size_t size() const noexcept
Return the number of intervals in the tree.
bool remove(const Key &iv)
Remove an interval from the tree.
const Key * search(const Key &iv) const noexcept
Search for an exact interval.
Dynamic singly linked list with functional programming support.
T & append(const T &item)
void set_seed(const unsigned long seed) noexcept
Set the random number generator seed.
Node *& getRoot() noexcept
Return the tree's root.
DynIntervalTree< int > tree
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
Node * make_node(int lo, int hi)
int cmp(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
void destroyRec(Node *&root) noexcept
Free recursively all the memory occupied by the tree root
TEST_F(IntervalTypeTest, Construction)
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
Itor2 copy(Itor1 sourceBeg, const Itor1 &sourceEnd, Itor2 destBeg)
Copy elements from one range to another.
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
BST comparator for intervals: order by (low, then high).
Closed interval [low, high].
static Interval point(const T &p) noexcept(std::is_nothrow_copy_constructible_v< T >)
Construct a point interval [p, p].
bool contains(const T &p, const Compare &cmp=Compare()) const noexcept(std::is_nothrow_invocable_v< const Compare &, const T &, const T & >)
Return true if this interval contains the point p.
bool is_valid(const Compare &cmp=Compare()) const noexcept(std::is_nothrow_invocable_v< const Compare &, const T &, const T & >)
Return true if low <= high.
bool overlaps(const Interval &other, const Compare &cmp=Compare()) const noexcept(std::is_nothrow_invocable_v< const Compare &, const T &, const T & >)
Return true if this interval overlaps with other.
CountingLess(int *c=nullptr) noexcept
bool operator()(const int &a, const int &b) const noexcept
Interval tree: augmented BST for overlap/stabbing queries.