-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathmulti_join_interval.hpp
103 lines (99 loc) · 2.78 KB
/
multi_join_interval.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#pragma once
#include <interval-tree/interval_types.hpp>
#include <algorithm>
#include <vector>
template <typename numerical_type, typename interval_kind_ = lib_interval_tree::closed>
struct multi_join_interval
{
public:
using value_type = numerical_type;
using interval_kind = interval_kind_;
#ifndef INTERVAL_TREE_SAFE_INTERVALS
#if __cplusplus >= 201703L
constexpr
#endif
multi_join_interval(value_type low, value_type high)
: low_{low}
, high_{high}
{
if (low > high)
throw std::invalid_argument("Low border is not lower or equal to high border.");
}
#else
#if __cplusplus >= 201703L
constexpr
#endif
multi_join_interval(value_type low, value_type high)
: low_{std::min(low, high)}
, high_{std::max(low, high)}
{
}
#endif
virtual ~multi_join_interval() = default;
friend bool operator==(multi_join_interval const& lhs, multi_join_interval const& other)
{
return lhs.low_ == other.low_ && lhs.high_ == other.high_;
}
friend bool operator!=(multi_join_interval const& lhs, multi_join_interval const& other)
{
return lhs.low_ != other.low_ || lhs.high_ != other.high_;
}
value_type low() const
{
return low_;
}
value_type high() const
{
return high_;
}
bool overlaps(value_type l, value_type h) const
{
return low_ <= h && l <= high_;
}
bool overlaps_exclusive(value_type l, value_type h) const
{
return low_ < h && l < high_;
}
bool overlaps(multi_join_interval const& other) const
{
return overlaps(other.low_, other.high_);
}
bool overlaps_exclusive(multi_join_interval const& other) const
{
return overlaps_exclusive(other.low_, other.high_);
}
bool within(value_type value) const
{
return interval_kind::within(low_, high_, value);
}
bool within(multi_join_interval const& other) const
{
return low_ <= other.low_ && high_ >= other.high_;
}
value_type operator-(multi_join_interval const& other) const
{
if (overlaps(other))
return 0;
if (high_ < other.low_)
return other.low_ - high_;
else
return low_ - other.high_;
}
value_type size() const
{
return high_ - low_;
}
std::vector<multi_join_interval> join(multi_join_interval const& other) const
{
const auto min = std::min(low_, other.low_);
const auto max = std::max(high_, other.high_);
const auto avg = (min + max) / 2;
return {
{min, avg},
{avg, max},
};
}
protected:
value_type low_;
value_type high_;
};