OSDN Git Service

コア部分を共通プロジェクト化した
[fooeditengine/FooEditEngine.git] / Core / RangeCollection.cs
similarity index 96%
rename from Common/RangeCollection.cs
rename to Core/RangeCollection.cs
index e0ac121..9ac4a17 100644 (file)
-/* https://github.com/mbuchetics/RangeTree よりコピペ。このファイルのみMITライセンスに従います */\r
-using System;\r
-using System.Collections.Generic;\r
-using System.Linq;\r
-using System.Text;\r
-using System.Threading.Tasks;\r
-\r
-namespace FooEditEngine\r
-{\r
-    /// <summary>\r
-    /// マーカーを表す\r
-    /// </summary>\r
-    internal interface IRange\r
-    {\r
-        /// <summary>\r
-        /// マーカーの開始位置。-1を設定した場合、そのマーカーはレタリングされません\r
-        /// </summary>\r
-        int start { get; set; }\r
-        /// <summary>\r
-        /// マーカーの長さ。0を設定した場合、そのマーカーはレタリングされません\r
-        /// </summary>\r
-        int length { get; set; }\r
-    }\r
-\r
-    internal sealed class RangeCollection<T> : IEnumerable<T>\r
-        where T : IRange\r
-    {\r
-        List<T> collection;\r
-\r
-        public RangeCollection()\r
-            : this(null)\r
-        {\r
-        }\r
-\r
-        public RangeCollection(IEnumerable<T> collection)\r
-        {\r
-            if (collection == null)\r
-                this.collection = new List<T>();\r
-            else\r
-                this.collection = new List<T>(collection);\r
-        }\r
-\r
-        public T this[int i]\r
-        {\r
-            get\r
-            {\r
-                return this.collection[i];\r
-            }\r
-            set\r
-            {\r
-                this.collection[i] = value;\r
-            }\r
-        }\r
-\r
-        public int Count\r
-        {\r
-            get\r
-            {\r
-                return this.collection.Count;\r
-            }\r
-        }\r
-\r
-        public void Add(T item)\r
-        {\r
-            this.collection.Add(item);\r
-            for (int i = this.collection.Count - 1; i >= 0; i--)\r
-            {\r
-                if (i > 0 && this.collection[i].start < this.collection[i - 1].start)\r
-                {\r
-                    T temp = this.collection[i];\r
-                    this.collection[i] = this.collection[i - 1];\r
-                    this.collection[i - 1] = temp;\r
-                }\r
-                else\r
-                {\r
-                    break;\r
-                }\r
-            }\r
-        }\r
-\r
-        public void Remove(int start, int length)\r
-        {\r
-            if (this.collection.Count == 0)\r
-                return;\r
-\r
-            int at = this.IndexOf(start);\r
-\r
-            int endAt = this.IndexOf(start + length - 1);\r
-\r
-            if(at != -1 && endAt != -1)\r
-            {\r
-                for (int i = endAt; i >= at; i--)\r
-                {\r
-                    this.collection.RemoveAt(i);\r
-                }\r
-            }\r
-            else if (at != -1)\r
-            {\r
-                this.collection.RemoveAt(at);\r
-            }\r
-            else if(endAt != -1)\r
-            {\r
-                this.collection.RemoveAt(endAt);\r
-            }\r
-        }\r
-\r
-        public void RemoveNearest(int start, int length)\r
-        {\r
-            if (this.collection.Count == 0)\r
-                return;\r
-            \r
-            int nearAt;\r
-            int at = this.IndexOfNearest(start, out nearAt);\r
-            if (at == -1)\r
-                at = nearAt;\r
-            \r
-            int nearEndAt;\r
-            int endAt = this.IndexOfNearest(start + length - 1, out nearEndAt);\r
-            if (endAt == -1)\r
-                endAt = nearEndAt;\r
-            \r
-            int end = start + length - 1; \r
-            for (int i = endAt; i >= at; i--)\r
-            {\r
-                int markerEnd = this.collection[i].start + this.collection[i].length - 1;\r
-                if (this.collection[i].start >= start && markerEnd <= end ||\r
-                    markerEnd >= start && markerEnd <= end ||\r
-                    this.collection[i].start >= start && this.collection[i].start <= end ||\r
-                    this.collection[i].start < start && markerEnd > end)\r
-                    this.collection.RemoveAt(i);\r
-            }\r
-        }\r
-\r
-        public void RemoveAt(int index)\r
-        {\r
-            this.collection.RemoveAt(index);\r
-        }\r
-\r
-        public int IndexOf(int start)\r
-        {\r
-            int dummy;\r
-            return this.IndexOfNearest(start, out dummy);\r
-        }\r
-\r
-        int IndexOfNearest(int start,out int nearIndex)\r
-        {\r
-            nearIndex = -1;\r
-            int left = 0, right = this.collection.Count - 1, mid;\r
-            while (left <= right)\r
-            {\r
-                mid = (left + right) / 2;\r
-                T item = this.collection[mid];\r
-                if (start >= item.start && start < item.start + item.length)\r
-                {\r
-                    return mid;\r
-                }\r
-                if (start < item.start)\r
-                {\r
-                    right = mid - 1;\r
-                }\r
-                else\r
-                {\r
-                    left = mid + 1;\r
-                }\r
-            }\r
-            System.Diagnostics.Debug.Assert(left >= 0 || right >= 0);\r
-            nearIndex = left >= 0 ? left : right;\r
-            if (nearIndex > this.collection.Count - 1)\r
-                nearIndex = right;\r
-            return -1;\r
-        }\r
-\r
-        public IEnumerable<T> Get(int index)\r
-        {\r
-            int at = this.IndexOf(index);\r
-            if (at == -1)\r
-                yield break;\r
-            yield return this.collection[at];\r
-        }\r
-\r
-        public IEnumerable<T> Get(int start, int length)\r
-        {\r
-            int nearAt;\r
-            int at = this.IndexOfNearest(start,out nearAt);\r
-            if (at == -1)\r
-                at = nearAt;\r
-\r
-            if (at == -1)\r
-                yield break;\r
-\r
-            int end = start + length - 1;\r
-            for (int i = at; i < this.collection.Count; i++)\r
-            {\r
-                int markerEnd = this.collection[i].start + this.collection[i].length - 1;\r
-                if (this.collection[i].start >= start && markerEnd <= end ||\r
-                    markerEnd >= start && markerEnd <= end ||\r
-                    this.collection[i].start >= start && this.collection[i].start <= end ||\r
-                    this.collection[i].start < start && markerEnd > end)\r
-                    yield return this.collection[i];\r
-                else if (this.collection[i].start > start + length)\r
-                    yield break;\r
-            }\r
-        }\r
-\r
-        public void Clear()\r
-        {\r
-            this.collection.Clear();\r
-        }\r
-\r
-        public IEnumerator<T> GetEnumerator()\r
-        {\r
-            foreach (T item in this.collection)\r
-                yield return item;\r
-        }\r
-\r
-        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\r
-        {\r
-            throw new NotImplementedException();\r
-        }\r
-    }\r
-\r
-}\r
+/* https://github.com/mbuchetics/RangeTree よりコピペ。このファイルのみMITライセンスに従います */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FooEditEngine
+{
+    /// <summary>
+    /// マーカーを表す
+    /// </summary>
+    internal interface IRange
+    {
+        /// <summary>
+        /// マーカーの開始位置。-1を設定した場合、そのマーカーはレタリングされません
+        /// </summary>
+        int start { get; set; }
+        /// <summary>
+        /// マーカーの長さ。0を設定した場合、そのマーカーはレタリングされません
+        /// </summary>
+        int length { get; set; }
+    }
+
+    internal sealed class RangeCollection<T> : IEnumerable<T>
+        where T : IRange
+    {
+        List<T> collection;
+
+        public RangeCollection()
+            : this(null)
+        {
+        }
+
+        public RangeCollection(IEnumerable<T> collection)
+        {
+            if (collection == null)
+                this.collection = new List<T>();
+            else
+                this.collection = new List<T>(collection);
+        }
+
+        public T this[int i]
+        {
+            get
+            {
+                return this.collection[i];
+            }
+            set
+            {
+                this.collection[i] = value;
+            }
+        }
+
+        public int Count
+        {
+            get
+            {
+                return this.collection.Count;
+            }
+        }
+
+        public void Add(T item)
+        {
+            this.collection.Add(item);
+            for (int i = this.collection.Count - 1; i >= 0; i--)
+            {
+                if (i > 0 && this.collection[i].start < this.collection[i - 1].start)
+                {
+                    T temp = this.collection[i];
+                    this.collection[i] = this.collection[i - 1];
+                    this.collection[i - 1] = temp;
+                }
+                else
+                {
+                    break;
+                }
+            }
+        }
+
+        public void Remove(int start, int length)
+        {
+            if (this.collection.Count == 0)
+                return;
+
+            int at = this.IndexOf(start);
+
+            int endAt = this.IndexOf(start + length - 1);
+
+            if(at != -1 && endAt != -1)
+            {
+                for (int i = endAt; i >= at; i--)
+                {
+                    this.collection.RemoveAt(i);
+                }
+            }
+            else if (at != -1)
+            {
+                this.collection.RemoveAt(at);
+            }
+            else if(endAt != -1)
+            {
+                this.collection.RemoveAt(endAt);
+            }
+        }
+
+        public void RemoveNearest(int start, int length)
+        {
+            if (this.collection.Count == 0)
+                return;
+            
+            int nearAt;
+            int at = this.IndexOfNearest(start, out nearAt);
+            if (at == -1)
+                at = nearAt;
+            
+            int nearEndAt;
+            int endAt = this.IndexOfNearest(start + length - 1, out nearEndAt);
+            if (endAt == -1)
+                endAt = nearEndAt;
+            
+            int end = start + length - 1; 
+            for (int i = endAt; i >= at; i--)
+            {
+                int markerEnd = this.collection[i].start + this.collection[i].length - 1;
+                if (this.collection[i].start >= start && markerEnd <= end ||
+                    markerEnd >= start && markerEnd <= end ||
+                    this.collection[i].start >= start && this.collection[i].start <= end ||
+                    this.collection[i].start < start && markerEnd > end)
+                    this.collection.RemoveAt(i);
+            }
+        }
+
+        public void RemoveAt(int index)
+        {
+            this.collection.RemoveAt(index);
+        }
+
+        public int IndexOf(int start)
+        {
+            int dummy;
+            return this.IndexOfNearest(start, out dummy);
+        }
+
+        int IndexOfNearest(int start,out int nearIndex)
+        {
+            nearIndex = -1;
+            int left = 0, right = this.collection.Count - 1, mid;
+            while (left <= right)
+            {
+                mid = (left + right) / 2;
+                T item = this.collection[mid];
+                if (start >= item.start && start < item.start + item.length)
+                {
+                    return mid;
+                }
+                if (start < item.start)
+                {
+                    right = mid - 1;
+                }
+                else
+                {
+                    left = mid + 1;
+                }
+            }
+            System.Diagnostics.Debug.Assert(left >= 0 || right >= 0);
+            nearIndex = left >= 0 ? left : right;
+            if (nearIndex > this.collection.Count - 1)
+                nearIndex = right;
+            return -1;
+        }
+
+        public IEnumerable<T> Get(int index)
+        {
+            int at = this.IndexOf(index);
+            if (at == -1)
+                yield break;
+            yield return this.collection[at];
+        }
+
+        public IEnumerable<T> Get(int start, int length)
+        {
+            int nearAt;
+            int at = this.IndexOfNearest(start,out nearAt);
+            if (at == -1)
+                at = nearAt;
+
+            if (at == -1)
+                yield break;
+
+            int end = start + length - 1;
+            for (int i = at; i < this.collection.Count; i++)
+            {
+                int markerEnd = this.collection[i].start + this.collection[i].length - 1;
+                if (this.collection[i].start >= start && markerEnd <= end ||
+                    markerEnd >= start && markerEnd <= end ||
+                    this.collection[i].start >= start && this.collection[i].start <= end ||
+                    this.collection[i].start < start && markerEnd > end)
+                    yield return this.collection[i];
+                else if (this.collection[i].start > start + length)
+                    yield break;
+            }
+        }
+
+        public void Clear()
+        {
+            this.collection.Clear();
+        }
+
+        public IEnumerator<T> GetEnumerator()
+        {
+            foreach (T item in this.collection)
+                yield return item;
+        }
+
+        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+        {
+            throw new NotImplementedException();
+        }
+    }
+
+}