-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathLineRange.cs
76 lines (57 loc) · 2.39 KB
/
LineRange.cs
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
using System;
using System.Collections.Generic;
using System.Linq;
namespace CodeChicken.DiffPatch
{
public struct LineRange : IEquatable<LineRange>
{
public int start, end;
public int length {
get => end - start;
set => end = start + value;
}
public int last {
get => end - 1;
set => end = value + 1;
}
public int first {
get => start;
set => start = value;
}
public LineRange Map(Func<int, int> f) => new LineRange {start = f(start), end = f(end)};
public bool Contains(int i) => start <= i && i < end;
public bool Contains(LineRange r) => r.start >= start && r.end <= end;
public bool Intersects(LineRange r) => r.start < end || r.end > start;
public override string ToString() => "[" + start + "," + end + ")";
public static bool operator ==(LineRange r1, LineRange r2) => r1.start == r2.start && r1.end == r2.end;
public static bool operator !=(LineRange r1, LineRange r2) => r1.start != r2.start || r1.end != r2.end;
public static LineRange operator +(LineRange r, int i) => new LineRange {start = r.start + i, end = r.end + i};
public static LineRange operator -(LineRange r, int i) => new LineRange {start = r.start - i, end = r.end - i};
public static LineRange Union(LineRange r1, LineRange r2) => new LineRange {
start = Math.Min(r1.start, r2.start),
end = Math.Max(r1.end, r2.end)
};
public static LineRange Intersection(LineRange r1, LineRange r2) => new LineRange {
start = Math.Max(r1.start, r2.start),
end = Math.Min(r1.end, r2.end)
};
public IEnumerable<LineRange> Except(IEnumerable<LineRange> except, bool presorted = false) {
if (!presorted)
except = except.OrderBy(r => r.start);
int start = this.start;
foreach (var r in except) {
if (r.start - start > 0)
yield return new LineRange { start = start, end = r.start };
start = r.end;
}
if (this.end - start > 0)
yield return new LineRange { start = start, end = this.end };
}
public override bool Equals(object obj) => obj is LineRange range && Equals(range);
public bool Equals(LineRange other) => this == other;
public override int GetHashCode() => end*end + start; // elegant pairing function, seems appropriate, probably reduces hash collisions when truncating hash
#if !NETSTANDARD2_0
public static implicit operator Range(LineRange r) => new Range(Index.FromStart(r.start), Index.FromStart(r.end));
#endif
}
}