1 /* https://github.com/mbuchetics/RangeTree よりコピペ。このファイルのみMITライセンスに従います */
\r
3 using System.Collections.Generic;
\r
6 using System.Threading.Tasks;
\r
8 namespace FooEditEngine
\r
13 internal interface IRange
\r
16 /// マーカーの開始位置。-1を設定した場合、そのマーカーはレタリングされません
\r
18 int start { get; set; }
\r
20 /// マーカーの長さ。0を設定した場合、そのマーカーはレタリングされません
\r
22 int length { get; set; }
\r
25 internal sealed class RangeCollection<T> : IEnumerable<T>
\r
30 public RangeCollection()
\r
35 public RangeCollection(IEnumerable<T> collection)
\r
37 if (collection == null)
\r
38 this.collection = new List<T>();
\r
40 this.collection = new List<T>(collection);
\r
43 public T this[int i]
\r
47 return this.collection[i];
\r
51 this.collection[i] = value;
\r
59 return this.collection.Count;
\r
63 public void Add(T item)
\r
65 this.collection.Add(item);
\r
66 for (int i = this.collection.Count - 1; i >= 0; i--)
\r
68 if (i > 0 && this.collection[i].start < this.collection[i - 1].start)
\r
70 T temp = this.collection[i];
\r
71 this.collection[i] = this.collection[i - 1];
\r
72 this.collection[i - 1] = temp;
\r
81 public void Remove(int start, int length)
\r
84 int at = this.IndexOfNearest(start, out nearAt);
\r
88 int end = start + length - 1;
\r
89 for (int i = at; i < this.collection.Count; i++)
\r
91 int markerEnd = this.collection[i].start + this.collection[i].length - 1;
\r
92 if (this.collection[i].start >= start && markerEnd <= end ||
\r
93 markerEnd >= start && markerEnd <= end ||
\r
94 this.collection[i].start >= start && this.collection[i].start <= end ||
\r
95 this.collection[i].start < start && markerEnd > end)
\r
96 this.collection.RemoveAt(i);
\r
97 else if (this.collection[i].start > start + length)
\r
102 public void RemoveAt(int index)
\r
104 this.collection.RemoveAt(index);
\r
107 public int IndexOf(int start)
\r
110 return this.IndexOfNearest(start, out dummy);
\r
113 int IndexOfNearest(int start,out int nearIndex)
\r
116 int left = 0, right = this.collection.Count - 1, mid;
\r
117 while (left <= right)
\r
119 mid = (left + right) / 2;
\r
120 T item = this.collection[mid];
\r
121 if (start >= item.start && start < item.start + item.length)
\r
125 if (start < item.start)
\r
134 System.Diagnostics.Debug.Assert(left >= 0 || right >= 0);
\r
135 nearIndex = left >= 0 ? left : right;
\r
139 public IEnumerable<T> Get(int index)
\r
141 int at = this.IndexOf(index);
\r
144 yield return this.collection[at];
\r
147 public IEnumerable<T> Get(int start, int length)
\r
150 int at = this.IndexOfNearest(start,out nearAt);
\r
154 int end = start + length - 1;
\r
155 for (int i = at; i < this.collection.Count; i++)
\r
157 int markerEnd = this.collection[i].start + this.collection[i].length - 1;
\r
158 if (this.collection[i].start >= start && markerEnd <= end ||
\r
159 markerEnd >= start && markerEnd <= end ||
\r
160 this.collection[i].start >= start && this.collection[i].start <= end ||
\r
161 this.collection[i].start < start && markerEnd > end)
\r
162 yield return this.collection[i];
\r
163 else if (this.collection[i].start > start + length)
\r
168 public void Clear()
\r
170 this.collection.Clear();
\r
173 public IEnumerator<T> GetEnumerator()
\r
175 foreach (T item in this.collection)
\r
179 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
\r
181 throw new NotImplementedException();
\r