1
1
// class Iv - Interval
2
2
#pragma once
3
+ #ifndef _PLN_util_geo_IV_h_b6e76e5fa705cfb_
4
+ #define _PLN_util_geo_IV_h_b6e76e5fa705cfb_
3
5
4
6
#include < algorithm>
5
7
#include < cassert>
17
19
#include < memory>
18
20
#include < numeric>
19
21
#include < string>
22
+ #include < string_view>
20
23
#include < type_traits>
21
24
#include < utility>
22
25
#include < vector>
23
26
24
27
namespace pln {
25
28
29
+ constexpr uint64_t hashComb (uint64_t a, uint64_t b) noexcept {
30
+ constexpr uint64_t m = 0xc6a4a7935bd1e995 ;
31
+ return (a ^ (b * m + (a << 6 ) + (a >> 2 ))) + 0xe6546b64 ;
32
+ }
33
+
34
+ constexpr uint64_t hashComb (uint64_t a, uint64_t b, uint64_t c) noexcept {
35
+ return hashComb (a, hashComb (b, c));
36
+ }
37
+
38
+ inline constexpr int protectedAdd (int a, int b) noexcept {
39
+ int64_t c = int64_t (a) + int64_t (b);
40
+ if (c > INT_MAX) return INT_MAX;
41
+ if (c < INT_MIN) return INT_MIN;
42
+ return c;
43
+ }
44
+
45
+ inline constexpr int protectedSub (int a, int b) noexcept {
46
+ int64_t c = int64_t (a) - int64_t (b);
47
+ if (c > INT_MAX) return INT_MAX;
48
+ if (c < INT_MIN) return INT_MIN;
49
+ return c;
50
+ }
51
+
26
52
inline constexpr int64_t add64 (int a, int b) noexcept {
27
53
return int64_t (a) + int64_t (b);
28
54
}
@@ -31,6 +57,32 @@ inline constexpr int64_t sub64(int a, int b) noexcept {
31
57
return int64_t (a) - int64_t (b);
32
58
}
33
59
60
+ inline constexpr int protectedRound (double x) noexcept {
61
+ if (x >= 0 ) {
62
+ if (x >= double (INT_MAX) - 0.5 ) return INT_MAX;
63
+ return x + 0.5 ;
64
+ }
65
+ if (x <= double (INT_MIN) + 0.5 ) return INT_MIN;
66
+ return x - 0.5 ;
67
+ }
68
+
69
+ inline constexpr int inlineRound (double x) noexcept {
70
+ return x >= 0 ? x + 0.5 : x - 0.5 ;
71
+ }
72
+
73
+ inline constexpr int64_t inlineRound64 (double x) noexcept {
74
+ return x >= 0 ? int64_t (x + 0.5 ) : int64_t (x - 0.5 );
75
+ }
76
+
77
+ inline constexpr int64_t protectedRound64 (double x) noexcept {
78
+ if (x >= 0 ) {
79
+ if (x >= double (LLONG_MAX) - 0.5 ) return LLONG_MAX;
80
+ return int64_t (x + 0.5 );
81
+ }
82
+ if (x <= double (LLONG_MIN) + 0.5 ) return LLONG_MIN;
83
+ return int64_t (x - 0.5 );
84
+ }
85
+
34
86
struct Iv {
35
87
int a_ = INT_MIN, b_ = INT_MIN;
36
88
@@ -42,11 +94,13 @@ struct Iv {
42
94
a_ = a;
43
95
b_ = b;
44
96
}
45
- void setZero () noexcept {
97
+ void toZero () noexcept {
46
98
a_ = 0 ;
47
99
b_ = 0 ;
48
100
}
49
101
102
+ uint64_t hashCode () const noexcept { return hashComb (a_, b_); }
103
+
50
104
int len () const noexcept { return b_ - a_; }
51
105
bool isLen0 () const noexcept { return a_ == b_; }
52
106
bool valid () const noexcept { return b_ != INT_MIN; }
@@ -60,35 +114,153 @@ struct Iv {
60
114
void invert () noexcept { std::swap (a_, b_); }
61
115
int center () const noexcept { return add64 (a_, b_) / 2 ; }
62
116
117
+ void bloat (int lo, int hi) noexcept {
118
+ assert (valid () and normal ());
119
+ assert (lo >= 0 and hi >= 0 );
120
+ a_ -= lo;
121
+ b_ += hi;
122
+ assert (valid () and normal ());
123
+ }
124
+
125
+ void bloat (int delta) noexcept {
126
+ assert (delta >= 0 );
127
+ bloat (delta, delta);
128
+ }
129
+
130
+ void moveTo (int t) noexcept {
131
+ assert (valid () and normal ());
132
+ int l = len ();
133
+ a_ = t;
134
+ b_ = t + l;
135
+ }
136
+ void moveRel (int dt) noexcept {
137
+ assert (valid () and normal ());
138
+ a_ += dt;
139
+ b_ += dt;
140
+ }
141
+
142
+ inline void unite (Iv i) noexcept ;
143
+ inline void unite (int t) noexcept ;
144
+
145
+ bool intersects (Iv iv) const noexcept {
146
+ return intersects (a_, b_, iv.a_ , iv.b_ );
147
+ }
148
+ inline static bool intersects (int a, int b, int c, int d) noexcept ;
149
+
150
+ bool overlaps (Iv iv) const noexcept { return overlaps (a_, b_, iv.a_ , iv.b_ ); }
151
+ inline static bool overlaps (int a, int b, int c, int d) noexcept ;
152
+
153
+ inline static int ovLen (int a, int b, int c, int d, int * p1 = nullptr ,
154
+ int * p2 = nullptr ) noexcept ;
155
+ int ovLen (Iv iv, int * p1 = nullptr , int * p2 = nullptr ) const noexcept {
156
+ return ovLen (a_, b_, iv.a_ , iv.b_ , p1, p2);
157
+ }
158
+
63
159
static bool inside (int t, int a, int b) noexcept {
64
160
if (a > b) std::swap (a, b);
65
- return t >= a && t <= b;
161
+ return t >= a and t <= b;
66
162
}
67
163
static bool insideNorm (int t, int a, int b) noexcept {
68
164
assert (normal (a, b));
69
- return t >= a && t <= b;
165
+ return t >= a and t <= b;
70
166
}
71
167
72
168
static bool insideOpen (int t, int a, int b) noexcept {
73
169
if (a > b) std::swap (a, b);
74
- return t > a && t < b;
170
+ return t > a and t < b;
75
171
}
76
172
static bool insideOpenNorm (int t, int a, int b) noexcept {
77
173
assert (normal (a, b));
78
- return t > a && t < b;
174
+ return t > a and t < b;
175
+ }
176
+
177
+ bool covers (Iv iv) const noexcept {
178
+ assert (valid () and normal ());
179
+ assert (iv.valid ());
180
+ return insideNorm (iv.a_ , a_, b_) and insideNorm (iv.b_ , a_, b_);
181
+ }
182
+ bool strictlyCovers (Iv iv) const noexcept {
183
+ assert (valid () and normal ());
184
+ assert (iv.valid ());
185
+ return insideOpenNorm (iv.a_ , a_, b_) and insideOpenNorm (iv.b_ , a_, b_);
79
186
}
80
187
81
188
bool operator <(Iv i) const noexcept {
82
189
if (a_ < i.a_ ) return true ;
83
190
if (a_ > i.a_ ) return false ;
84
191
return b_ < i.b_ ;
85
192
}
86
- bool operator ==(Iv i) const noexcept { return a_ == i.a_ && b_ == i.b_ ; }
193
+ bool operator ==(Iv i) const noexcept { return a_ == i.a_ and b_ == i.b_ ; }
87
194
bool operator !=(Iv i) const noexcept { return not operator ==(i); }
88
195
};
89
196
inline std::ostream& operator <<(std::ostream& os, Iv iv) {
90
197
os << " (iv " << iv.a_ << ' ' << iv.b_ << ' )' ;
91
198
return os;
92
199
}
93
200
94
- } // namespace pln
201
+ inline bool Iv::intersects (int a, int b, int c, int d) noexcept {
202
+ assert (a < b and c < d);
203
+ if (c < a) {
204
+ std::swap (a, c);
205
+ std::swap (b, d);
206
+ }
207
+ if (d < b) return true ;
208
+ if (c > b) return false ;
209
+ return true ;
210
+ }
211
+
212
+ inline bool Iv::overlaps (int a, int b, int c, int d) noexcept {
213
+ assert (a < b and c < d);
214
+ if (c < a) {
215
+ std::swap (a, c);
216
+ std::swap (b, d);
217
+ }
218
+ if (d <= b) return true ;
219
+ if (c >= b) return false ;
220
+ return true ;
221
+ }
222
+
223
+ inline int Iv::ovLen (int a, int b, int c, int d, int * p1, int * p2) noexcept {
224
+ assert (a < b and c < d);
225
+ if (c < a) {
226
+ std::swap (a, c);
227
+ std::swap (b, d);
228
+ }
229
+ if (d <= b) {
230
+ if (p1) *p1 = c;
231
+ if (p2) *p2 = d;
232
+ return d - c;
233
+ }
234
+ if (c >= b) return 0 ;
235
+
236
+ if (p1) *p1 = c;
237
+ if (p2) *p2 = b;
238
+ return b - c;
239
+ }
240
+
241
+ inline void Iv::unite (Iv i) noexcept {
242
+ assert (i.valid ());
243
+ i.normalize ();
244
+ if (valid ()) {
245
+ assert (normal ());
246
+ if (i.a_ < a_) a_ = i.a_ ;
247
+ if (i.b_ > b_) b_ = i.b_ ;
248
+ return ;
249
+ }
250
+ set (i);
251
+ }
252
+
253
+ inline void Iv::unite (int t) noexcept {
254
+ if (valid ()) {
255
+ assert (normal ());
256
+ if (t < a_) a_ = t;
257
+ if (t > b_) b_ = t;
258
+ return ;
259
+ }
260
+ set (t, t);
261
+ }
262
+
263
+ }
264
+
265
+ #endif
266
+
0 commit comments