OSDN Git Service

Bヘッダのない形式への部分的対応
[karinto/karinto.git] / Karinto / Range.cs
1 /*\r
2  *      Karinto Library Project\r
3  *\r
4  *      This software is distributed under a zlib-style license.\r
5  *      See license.txt for more information.\r
6  */\r
7 \r
8 using System;\r
9 using System.Collections.Generic;\r
10 \r
11 namespace Karinto\r
12 {\r
13     /// <summary>\r
14     ///     範囲を示す\r
15     /// </summary>\r
16     public class Range\r
17     {\r
18         #region constructors\r
19         /// <summary>\r
20         ///     終端を含む範囲\r
21         /// </summary>\r
22         /// <param name="first">最初の要素</param>\r
23         /// <param name="last">最後の要素</param>\r
24         public Range(IComparable first, IComparable last)\r
25             : this(first, last, false)\r
26         {\r
27         }\r
28 \r
29         /// <summary>\r
30         ///     範囲\r
31         /// </summary>\r
32         /// <param name="first">最初の要素</param>\r
33         /// <param name="last">最後の要素</param>\r
34         /// <param name="isExcludeEnd">終端を含むか否か(含まないときtrue)</param>\r
35         public Range(IComparable first, IComparable last, bool excludeEnd)\r
36         {\r
37             if (first.GetType() != last.GetType())\r
38             {\r
39                 throw new ArgumentException("The boundary elements must be same type.");\r
40             }\r
41             First = first;\r
42             Last = last;\r
43             ExcludesEnd = excludeEnd;\r
44         }\r
45         #endregion\r
46 \r
47         #region properties\r
48         public IComparable First { get; private set; }\r
49         public IComparable Last { get; private set; }\r
50         public bool ExcludesEnd { get; private set; }\r
51         #endregion\r
52 \r
53         #region public methods\r
54         /// <summary>\r
55         ///     対象が範囲内か調べる\r
56         /// </summary>\r
57         /// <param name="other">対象</param>\r
58         /// <returns>範囲内か否か(範囲内ならtrue)</returns>\r
59         public bool Includes(IComparable other)\r
60         {\r
61             if (other.CompareTo(First) < 0) return false;\r
62             if (other.CompareTo(Last) > 0) return false;\r
63             if (other.CompareTo(Last) == 0) return !ExcludesEnd;\r
64             return true;\r
65         }\r
66 \r
67         /// <summary>\r
68         ///     両端に値を加算することで範囲を移動させる\r
69         /// </summary>\r
70         /// <param name="delta">変化量</param>\r
71         public void Shift(double delta)\r
72         {\r
73             First = (double)First + delta;\r
74             Last = (double)Last + delta;\r
75         }\r
76 \r
77         /// <summary>\r
78         ///     両端に値を加算することで範囲を移動させる\r
79         /// </summary>\r
80         /// <param name="delta">変化量</param>\r
81         public void Shift(int delta)\r
82         {\r
83             First = (int)First + delta;\r
84             Last = (int)Last + delta;\r
85         }\r
86 \r
87         public IEnumerator<Int32> GetEnumerator()\r
88         {\r
89             Int32 cursor = Convert.ToInt32(First);\r
90             Int32 last = Convert.ToInt32(Last);\r
91             while (cursor < last)\r
92             {\r
93                 yield return cursor;\r
94                 cursor++;\r
95             }\r
96             if (cursor == last)\r
97             {\r
98                 if (!ExcludesEnd) yield return cursor;\r
99             }\r
100         }\r
101 \r
102         /// <summary>\r
103         ///     イテレータブロック\r
104         /// </summary>\r
105         /// <param name="step">刻み</param>\r
106         /// <returns>step刻みの範囲内の要素</returns>\r
107         public IEnumerable<Int32> Step(Int32 step)\r
108         {\r
109             Int32 cursor = Convert.ToInt32(First);\r
110             Int32 last = Convert.ToInt32(Last);\r
111             while (cursor < last)\r
112             {\r
113                 yield return cursor;\r
114                 cursor += step;\r
115             }\r
116             if (cursor == last)\r
117             {\r
118                 if (!ExcludesEnd) yield return cursor;\r
119             }\r
120         }\r
121 \r
122         /// <summary>\r
123         ///     イテレータブロック\r
124         /// </summary>\r
125         /// <param name="stepWidth">刻み</param>\r
126         /// <returns>step刻みの範囲内の要素</returns>\r
127         public IEnumerable<double> Step(double stepWidth)\r
128         {\r
129             int i = 0;\r
130             double first = Convert.ToDouble(First);\r
131             double last = Convert.ToDouble(Last);\r
132             double cursor = first;\r
133             while (cursor < last)\r
134             {\r
135                 yield return cursor;\r
136                 i++;\r
137                 cursor = first + stepWidth * i;//単純に加算していくと誤差が蓄積する\r
138             }\r
139             if (cursor == last)\r
140             {\r
141                 if (!ExcludesEnd) yield return cursor;\r
142             }\r
143         }\r
144         #endregion\r
145 \r
146     }\r
147 }\r