33#include " interval_tree_fwd.hpp"
44#include " interval_types.hpp"
55#include " tree_hooks.hpp"
6+ #include " feature_test.hpp"
67
78#include < string>
89#include < memory>
@@ -26,8 +27,8 @@ namespace lib_interval_tree
2627 // ############################################################################################################
2728 using default_interval_value_type = int ;
2829 // ############################################################################################################
29- template <typename numerical_type, typename interval_kind_ = closed >
30- struct interval
30+ template <typename numerical_type, typename interval_kind_>
31+ struct interval_base
3132 {
3233 public:
3334 using value_type = numerical_type;
@@ -40,7 +41,7 @@ namespace lib_interval_tree
4041# if __cplusplus >= 201703L
4142 constexpr
4243# endif
43- interval (value_type low, value_type high)
44+ interval_base (value_type low, value_type high)
4445 : low_{low}
4546 , high_{high}
4647 {
@@ -51,52 +52,86 @@ namespace lib_interval_tree
5152# if __cplusplus >= 201703L
5253 constexpr
5354# endif
54- interval (value_type low, value_type high)
55+ interval_base (value_type low, value_type high)
5556 : low_{std::min (low, high)}
5657 , high_{std::max (low, high)}
5758 {}
5859#endif
59- virtual ~interval () = default ;
60+ virtual ~interval_base () = default ;
6061
6162 /* *
62- * Returns if both intervals equal.
63+ * Returns the lower bound of the interval
6364 */
64- friend bool operator ==(interval const & lhs, interval const & other)
65+ value_type low () const
6566 {
66- return lhs. low_ == other. low_ && lhs. high_ == other. high_ ;
67+ return low_;
6768 }
6869
6970 /* *
70- * Returns if both intervals are different.
71+ * Returns the upper bound of the interval
7172 */
72- friend bool operator !=(interval const & lhs, interval const & other)
73+ value_type high () const
7374 {
74- return lhs. low_ != other. low_ || lhs. high_ != other. high_ ;
75+ return high_;
7576 }
7677
78+ protected:
79+ value_type low_;
80+ value_type high_;
81+ };
82+ // ############################################################################################################
83+ template <typename numerical_type, typename interval_kind_ = closed>
84+ struct interval : public interval_base <numerical_type, interval_kind_>
85+ {
86+ public:
87+ using value_type = typename interval_base<numerical_type, interval_kind_>::value_type;
88+ using interval_kind = typename interval_base<numerical_type, interval_kind_>::interval_kind;
89+
90+ using interval_base<numerical_type, interval_kind_>::low;
91+ using interval_base<numerical_type, interval_kind_>::high;
92+
93+ using interval_base<numerical_type, interval_kind_>::low_;
94+ using interval_base<numerical_type, interval_kind_>::high_;
95+
7796 /* *
78- * Returns the lower bound of the interval
97+ * Constructs an interval. low MUST be smaller than high.
7998 */
80- value_type low () const
99+ #if __cplusplus >= 201703L
100+ constexpr
101+ #endif
102+ interval (value_type low, value_type high)
103+ : interval_base<numerical_type, interval_kind_>{low, high}
104+ {}
105+
106+ /* *
107+ * Returns true if both intervals equal.
108+ */
109+ friend bool operator ==(
110+ interval<numerical_type, interval_kind_> const & lhs,
111+ interval<numerical_type, interval_kind_> const & rhs
112+ )
81113 {
82- return low_;
114+ return lhs. low_ == rhs. low_ && lhs. high_ == rhs. high_ ;
83115 }
84116
85117 /* *
86- * Returns the upper bound of the interval
118+ * Returns true if both intervals are different.
87119 */
88- value_type high () const
120+ friend bool operator !=(
121+ interval<numerical_type, interval_kind_> const & lhs,
122+ interval<numerical_type, interval_kind_> const & rhs
123+ )
89124 {
90- return high_;
125+ return lhs. low_ != rhs. low_ || lhs. high_ != rhs. high_ ;
91126 }
92127
93128 /* *
94129 * Returns whether the intervals overlap.
95130 * For when both intervals are closed.
96131 */
97- bool overlaps (value_type l, value_type h) const
132+ LIB_INTERVAL_TREE_DEPRECATED bool overlaps (value_type l, value_type h) const
98133 {
99- return low_ <= h && l <= high_ ;
134+ return interval_kind::overlaps ( low_, high_, l, h) ;
100135 }
101136
102137 /* *
@@ -113,7 +148,7 @@ namespace lib_interval_tree
113148 */
114149 bool overlaps (interval const & other) const
115150 {
116- return overlaps (other.low_ , other.high_ );
151+ return interval_kind:: overlaps (low_, high_, other.low_ , other.high_ );
117152 }
118153
119154 /* *
@@ -137,7 +172,7 @@ namespace lib_interval_tree
137172 */
138173 bool within (interval const & other) const
139174 {
140- return low_ <= other.low_ && high_ >= other.high_ ;
175+ return within ( other.low_ ) && within ( other.high_ ) ;
141176 }
142177
143178 /* *
@@ -148,18 +183,113 @@ namespace lib_interval_tree
148183 {
149184 if (overlaps (other))
150185 return 0 ;
151- if (high_ < other.low_ )
186+ if (high_ <= other.low_ )
152187 return other.low_ - high_;
153188 else
154189 return low_ - other.high_ ;
155190 }
156191
192+ /* *
193+ * Creates a new interval from this and other, that contains both intervals and whatever
194+ * is between.
195+ */
196+ interval join (interval const & other) const
197+ {
198+ return {std::min (low_, other.low_ ), std::max (high_, other.high_ )};
199+ }
200+
157201 /* *
158202 * Returns the size of the interval.
159203 */
160204 value_type size () const
161205 {
162- return high_ - low_;
206+ return interval_kind::size (low_, high_);
207+ }
208+ };
209+
210+ template <typename numerical_type>
211+ struct interval <numerical_type, dynamic> : public interval_base<numerical_type, dynamic>
212+ {
213+ public:
214+ using value_type = typename interval_base<numerical_type, dynamic>::value_type;
215+ using interval_kind = dynamic;
216+
217+ /* *
218+ * Constructs an interval. low MUST be smaller than high.
219+ */
220+ #if __cplusplus >= 201703L
221+ constexpr
222+ #endif
223+ interval (value_type low, value_type high, interval_border leftBorder, interval_border rightBorder)
224+ : interval_base<numerical_type, interval_kind>{low, high}
225+ , left_border_{leftBorder}
226+ , right_border_{rightBorder}
227+ {}
228+
229+ /* *
230+ * Returns true if both intervals equal.
231+ */
232+ friend bool
233+ operator ==(interval<numerical_type, dynamic> const & lhs, interval<numerical_type, dynamic> const & other)
234+ {
235+ return lhs.low_ == other.low_ && lhs.high_ == other.high_ && lhs.left_border_ == other.left_border_ &&
236+ lhs.right_border_ == other.right_border_ ;
237+ }
238+
239+ /* *
240+ * Returns true if both intervals are different.
241+ */
242+ friend bool
243+ operator !=(interval<numerical_type, dynamic> const & lhs, interval<numerical_type, dynamic> const & other)
244+ {
245+ return lhs.low_ != other.low_ || lhs.high_ != other.high_ || lhs.left_border_ != other.left_border_ ||
246+ lhs.right_border_ != other.right_border_ ;
247+ }
248+
249+ using interval_base<numerical_type, interval_kind>::low;
250+ using interval_base<numerical_type, interval_kind>::high;
251+ using interval_base<numerical_type, interval_kind>::low_;
252+ using interval_base<numerical_type, interval_kind>::high_;
253+
254+ /* *
255+ * Returns whether the intervals overlap
256+ */
257+ bool overlaps (interval const & other) const
258+ {
259+ return interval_kind::overlaps (*this , other);
260+ }
261+
262+ /* *
263+ * Returns whether the intervals overlap exclusively, independent of border.
264+ */
265+ bool overlaps_exclusive (interval const & other) const
266+ {
267+ return low_ < other.high_ && other.low_ < high_;
268+ }
269+
270+ /* *
271+ * Returns whether the given value is in this.
272+ */
273+ bool within (value_type value) const
274+ {
275+ return interval_kind::within (*this , value);
276+ }
277+
278+ /* *
279+ * Returns whether the given interval is in this.
280+ */
281+ bool within (interval const & other) const
282+ {
283+ return within (other.low_ ) && within (other.high_ );
284+ }
285+
286+ /* *
287+ * Calculates the distance between the two intervals.
288+ * Overlapping intervals have 0 distance.
289+ */
290+ value_type operator -(interval const & other) const
291+ {
292+ interval_kind::distance (*this , other);
163293 }
164294
165295 /* *
@@ -168,13 +298,40 @@ namespace lib_interval_tree
168298 */
169299 interval join (interval const & other) const
170300 {
171- return {std::min (low_, other.low_ ), std::max (high_, other.high_ )};
301+ return interval_kind::join (*this , other);
302+ }
303+
304+ /* *
305+ * Returns the size of the interval.
306+ */
307+ value_type size () const
308+ {
309+ return interval_kind::size (*this );
310+ }
311+
312+ /* *
313+ * @brief Returns the left border type of the interval.
314+ *
315+ */
316+ interval_border left_border () const
317+ {
318+ return left_border_;
319+ }
320+
321+ /* *
322+ * @brief Returns the right border type of the interval.
323+ *
324+ */
325+ interval_border right_border () const
326+ {
327+ return right_border_;
172328 }
173329
174330 protected:
175- value_type low_ ;
176- value_type high_ ;
331+ interval_border left_border_ ;
332+ interval_border right_border_ ;
177333 };
334+
178335 // ############################################################################################################
179336 /* *
180337 * Creates a safe interval that puts the lower bound left automatically.
0 commit comments