source: trunk/ab5.0/ablib/src/Classes/System/Collections/Generic/List.ab@ 579

Last change on this file since 579 was 579, checked in by dai, 16 years ago
  • ForeachがIDisposableを実装したIEnumerator<T>を取り扱うように変更
  • #120(列挙体のUnicode対応)の修正
File size: 6.0 KB
Line 
1
2Namespace System
3Namespace Collections
4Namespace Generic
5
6Namespace Detail
7 Class PointerEnumerator<T>
8 Implements IEnumerator<T>
9 Public
10 Sub PointerEnumerator(ptr As *T, count As Long)
11 p = ptr
12 n = count
13 cur = -1
14 End Sub
15
16 Function MoveNext() As Boolean
17 cur++
18 MoveNext = (cur <> n)
19 End Function
20
21 Sub Reset()
22 n = -1
23 End Sub
24
25 Function Current() As T
26 Current = p[cur]
27 End Function
28
29 Virtual Sub Dispose()
30 p = NULL
31 n = 0
32 cur = -1
33 End Sub
34 Private
35 p As *T
36 n As Long
37 cur As Long
38 End Class
39End Namespace
40
41Class List<T>
42 Inherits IList<T>
43
44 items As *T
45 capacity As Long
46 count As Long
47
48 Sub Realloc( allocateSize As Long )
49 items = realloc( items, allocateSize * SizeOf(T) )
50 capacity = allocateSize
51 End Sub
52
53 Sub _Initialize( capacity As Long )
54 This.items = GC_malloc( capacity * SizeOf(T) )
55 This.capacity = capacity
56 End Sub
57
58 Sub SetLeastCapacity( capacity As Long )
59 If This.capacity < capacity Then
60 Realloc(capacity)
61 End If
62 End Sub
63Public
64 Sub List()
65 _Initialize(16)
66 End Sub
67
68 /*!
69 @brief 予め要素数を指定してList<T>を初期化
70 @author NoWest
71 @date 2008/07/13
72 @param リストの要素数
73 */
74 Sub List( capacity As Long )
75 _Initialize( capacity )
76 End Sub
77
78 /*!
79 @brief 既存の配列List<T>を初期化
80 @author NoWest
81 @date 2008/07/13
82 @param インデックス
83 */
84 Sub List( array As *T, length As Long )
85 _Initialize( length )
86
87 memmove( This.items, array, length * SizeOf(T) )
88 This.count = length
89 End Sub
90
91 /*!
92 @brief インデクサ
93 @author Daisuke Yamamoto
94 @date 2007/08/22
95 @param インデックス
96 */
97 Override Sub Operator[] ( index As Long, item As T )
98 If 0 <= index And index < capacity Then
99 items[index]=item
100 Else
101 Throw New ArgumentOutOfRangeException("index")
102 End If
103 End Sub
104 Override Function Operator[] ( index As Long ) As T
105 If 0 <= index And index < capacity Then
106 Return items[index]
107 Else
108 Throw New ArgumentOutOfRangeException("index")
109 End If
110 End Function
111
112 /*!
113 @brief ポインタ型へのキャスト
114 @author Daisuke Yamamoto
115 @date 2007/08/22
116 @param インデックス
117 */
118 Function Operator() As *T
119 Return items
120 End Function
121
122
123 '----------------------------------------------------------------
124 ' パブリック プロパティ
125 '----------------------------------------------------------------
126
127 /*!
128 @brief Listに格納されている要素の数を取得する
129 @author Daisuke Yamamoto
130 @date 2007/08/22
131 */
132 Override Function Count() As Long
133 Return This.count
134 End Function
135
136 Const Function Capacity() As Long
137 Return This.capacity
138 End Function
139
140 Sub Capacity(c As Long)
141 If c <> capacity Then
142 If c < capacity Then
143 Throw New ArgumentOutOfRangeException("capacity")
144 Else
145 Realloc(c)
146 End If
147 End If
148 End Sub
149
150 /*!
151 @brief Listが読み込み専用かどうかを取得する
152 @author NoWest
153 @date 2008/07/12
154 */
155 Override Function IsReadOnly() As Boolean
156 Return False
157 End Function
158
159 '----------------------------------------------------------------
160 ' パブリック メソッド
161 '----------------------------------------------------------------
162
163 /*!
164 @brief Listの末端に要素を追加する
165 @author Daisuke Yamamoto
166 @date 2007/08/22
167 @param 追加するオブジェクト
168 */
169 Override Sub Add( item As T )
170 SetLeastCapacity(This.count + 1)
171 This.items[ This.count ] = item
172 This.count++
173 End Sub
174
175' Function AsReadOnly() As ReadOnlyCollection
176
177 /*!
178 @brief Listからすべての要素を削除する
179 @author Daisuke Yamamoto
180 @date 2007/08/22
181 */
182 Override Sub Clear()
183 This.count = 0
184 End Sub
185
186/* Override Function Contains ( item As T ) As Boolean
187 TODO
188 End Function*/
189
190 /*!
191 @brief List内から、最初に出現する値のインデックスを取得する
192 @author Daisuke Yamamoto
193 @date 2007/08/22
194 @return インデックス(見つからなかったときは-1)
195 */
196 Override Function IndexOf( item As T ) As Long
197 Dim i As Long
198 For i = 0 To ELM( This.count )
199 If items[i].Equals(item) Then
200 Return i
201 End If
202 Next
203 Return -1
204 End Function
205
206 /*!
207 @brief List内の指定したインデックスの位置に要素を挿入する
208 @author Daisuke Yamamoto
209 @date 2007/08/22
210 */
211 Override Sub Insert( index As Long, item As T )
212 SetLeastCapacity(This.count + 1)
213 memmove( items + (index+1)*SizeOf(T), items + index*SizeOf(T), (This.count - index)*SizeOf(T) )
214 items[index] = item
215 This.count++
216 End Sub
217
218 /*!
219 @brief List内で最初に出現する値を削除する
220 @author Daisuke Yamamoto
221 @date 2007/09/28
222 @return 値が削除されたときはTrue、されなかったときはFlaseが返る
223 */
224 Override Function Remove( item As T ) As Boolean
225 Dim index = IndexOf( item )
226 If index = -1 Then
227 Return False
228 End If
229
230 removeAtImpl( index )
231 Return True
232 End Function
233
234 /*!
235 @brief List内の指定したインデックスの要素を削除する
236 @author Daisuke Yamamoto
237 @date 2007/10/03
238 */
239 Override Sub RemoveAt( index As Long )
240 If 0 <= index And index < capacity Then
241 removeAtImpl( index )
242 Else
243 Throw New ArgumentOutOfRangeException("index")
244 End If
245 End Sub
246Private
247 Sub removeAtImpl( index As Long )
248 memmove( items + index*SizeOf(T), items + (index+1)*SizeOf(T), (This.count - (index+1))*SizeOf(T) )
249 This.count--
250 End Sub
251
252Public
253
254 /*!
255 @brief Listの要素を文字列で返す
256 @author OverTaker
257 @date 2008/6/26
258 @return 文字列
259 */
260 Override Function ToString() As String
261 Dim string = New Text.StringBuilder
262 Dim i As Long
263 For i = 0 To ELM( This.count )
264 string.Append(This[i]).Append(Ex"\r\n")
265 Next
266 Return string.ToString
267 End Function
268
269 /*!
270 @brief 実際の要素数が現在の容量の 90% 未満の場合は、容量をその数に設定します
271 @author NoWest
272 @date 2008/07/20
273 */
274 Sub TrimExcess ()
275 If ( This.capacity ) * 0.9 > This.count Then
276 Realloc( This.count )
277 End If
278 End Sub
279
280 /*!
281 @brief IEnumeratorインターフェイスを取得する
282 @author Daisuke Yamamoto
283 @date 2007/11/19
284 @return IEnumeratorインターフェイスが返る
285 */
286 Override Function GetEnumerator() As IEnumerator<T>
287 Return New Detail.PointerEnumerator(items, count)
288 End Function
289End Class
290
291
292End Namespace
293End Namespace
294End Namespace
Note: See TracBrowser for help on using the repository browser.