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

Last change on this file since 675 was 675, checked in by イグトランス (egtra), 15 years ago

List<T>のCapacityの増加量を2倍に修正。内部のポインタの取得用のDataプロパティの追加。Containsの実装。

File size: 7.1 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 Implements 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( leastCapacity As Long )
59 Dim c = This.capacity
60 While c < leastCapacity
61 c *= 2
62 Wend
63 Realloc(c)
64 End Sub
65Public
66 Sub List()
67 _Initialize(16)
68 End Sub
69
70 /*!
71 @brief 予め要素数を指定してList<T>を初期化
72 @author NoWest
73 @date 2008/07/13
74 @param リストの要素数
75 */
76 Sub List( capacity As Long )
77 _Initialize( capacity )
78 End Sub
79
80 /*!
81 @brief 既存の配列List<T>を初期化
82 @author NoWest
83 @date 2008/07/13
84 @param 基になる配列へのポインタ
85 @param 配列の長さ
86 */
87 Sub List( array As *T, length As Long )
88 _Initialize( length )
89
90 memmove( This.items, array, length * SizeOf(T) )
91 This.count = length
92 End Sub
93
94 /*!
95 @brief 既存のIEnumerable<T>を使用してListを初期化
96 @author NoWest
97 @date 2008/09/22
98 @param 基になるIEnumerable<T>
99 */
100 Sub List ( enumerable As IEnumerable<T> )
101 _Initialize( 1 )
102 Foreach e In enumerable
103' This.Add(e)
104 Next
105 End Sub
106
107 /*!
108 @brief インデクサ
109 @author Daisuke Yamamoto
110 @date 2007/08/22
111 @param インデックス
112 */
113 Sub Operator[] ( index As Long, item As T )
114 Item[index] = item
115 End Sub
116 Function Operator[] ( index As Long ) As T
117 Return Item[index]
118 End Function
119
120 /*!
121 @brief インデクサ
122 @author Egtra
123 @date 2008/08/04
124 @param インデックス
125 */
126 Override Sub Item( index As Long, item As T )
127 If 0 <= index And index < capacity Then
128 items[index]=item
129 Else
130 Throw New ArgumentOutOfRangeException("index")
131 End If
132 End Sub
133 Override Function Item( index As Long ) As T
134 If 0 <= index And index < capacity Then
135 Return items[index]
136 Else
137 Throw New ArgumentOutOfRangeException("index")
138 End If
139 End Function
140 /*!
141 @brief ポインタ型へのキャスト
142 @author Daisuke Yamamoto
143 @date 2007/08/22
144 @param インデックス
145 */
146 Function Operator() As *T
147 Return items
148 End Function
149
150 /*!
151 @brief 内部の配列へのポインタを取得する
152 @auther Egtra
153 @date 2009/01/13
154 @retrun 内部の配列へのポインタ
155 @pre Count <> 0
156 */
157 Function Data() As *T
158 Return items
159 End Function
160
161 '----------------------------------------------------------------
162 ' パブリック プロパティ
163 '----------------------------------------------------------------
164
165 /*!
166 @brief Listに格納されている要素の数を取得する
167 @author Daisuke Yamamoto
168 @date 2007/08/22
169 */
170 Override Function Count() As Long
171 Return This.count
172 End Function
173
174 Const Function Capacity() As Long
175 Return This.capacity
176 End Function
177
178 Sub Capacity(c As Long)
179 If c <> capacity Then
180 If c < capacity Then
181 Throw New ArgumentOutOfRangeException("capacity")
182 Else
183 Realloc(c)
184 End If
185 End If
186 End Sub
187
188 /*!
189 @brief Listが読み込み専用かどうかを取得する
190 @author NoWest
191 @date 2008/07/12
192 */
193 Override Function IsReadOnly() As Boolean
194 Return False
195 End Function
196
197 '----------------------------------------------------------------
198 ' パブリック メソッド
199 '----------------------------------------------------------------
200
201 /*!
202 @brief Listの末端に要素を追加する
203 @author Daisuke Yamamoto
204 @date 2007/08/22
205 @param 追加するオブジェクト
206 */
207 Override Sub Add( item As T )
208 SetLeastCapacity(This.count + 1)
209 This.items[ This.count ] = item
210 This.count++
211 End Sub
212
213 /*!
214 @brief 読み取り専用のListのラッパーを取得
215 @author NoWest
216 @date 2008/09/22
217 */
218/* Function AsReadOnly() As System.Collections.ObjectModel.ReadOnlyCollection<T>
219 Return New System.Collections.ObjectModel.ReadOnlyCollection<T>(This)
220 End Function*/
221
222 /*!
223 @brief Listからすべての要素を削除する
224 @author Daisuke Yamamoto
225 @date 2007/08/22
226 */
227 Override Sub Clear()
228 This.count = 0
229 End Sub
230
231 /*!
232 @brief Listに指定された要素が含まれるか調べる
233 @author Egtra
234 @date 2009/01/13
235 */
236 Function Contains ( item As T ) As Boolean
237 Return IndexOf(item) >= 0
238 End Function
239
240 /*!
241 @brief List内から、最初に出現する値のインデックスを取得する
242 @author Daisuke Yamamoto
243 @date 2007/08/22
244 @return インデックス(見つからなかったときは-1)
245 */
246 Override Function IndexOf( item As T ) As Long
247 Dim i As Long
248 For i = 0 To ELM( This.count )
249 If items[i].Equals(item) Then
250 Return i
251 End If
252 Next
253 Return -1
254 End Function
255
256 /*!
257 @brief List内の指定したインデックスの位置に要素を挿入する
258 @author Daisuke Yamamoto
259 @date 2007/08/22
260 */
261 Override Sub Insert( index As Long, item As T )
262 SetLeastCapacity(This.count + 1)
263 memmove( items + (index+1)*SizeOf(T), items + index*SizeOf(T), (This.count - index)*SizeOf(T) )
264 items[index] = item
265 This.count++
266 End Sub
267
268 /*!
269 @brief List内で最初に出現する値を削除する
270 @author Daisuke Yamamoto
271 @date 2007/09/28
272 @return 値が削除されたときはTrue、されなかったときはFlaseが返る
273 */
274 Override Function Remove( item As T ) As Boolean
275 Dim index = IndexOf( item )
276 If index = -1 Then
277 Return False
278 End If
279
280 removeAtImpl( index )
281 Return True
282 End Function
283
284 /*!
285 @brief List内の指定したインデックスの要素を削除する
286 @author Daisuke Yamamoto
287 @date 2007/10/03
288 */
289 Override Sub RemoveAt( index As Long )
290 If 0 <= index And index < capacity Then
291 removeAtImpl( index )
292 Else
293 Throw New ArgumentOutOfRangeException("index")
294 End If
295 End Sub
296Private
297 Sub removeAtImpl( index As Long )
298 memmove( items + index*SizeOf(T), items + (index+1)*SizeOf(T), (This.count - (index+1))*SizeOf(T) )
299 This.count--
300 End Sub
301
302Public
303
304 /*!
305 @brief Listの要素を文字列で返す
306 @author OverTaker
307 @date 2008/6/26
308 @return 文字列
309 */
310 Override Function ToString() As String
311 Dim string = New Text.StringBuilder
312 Dim i As Long
313 For i = 0 To ELM( This.count )
314 string.Append(This[i]).Append(Ex"\r\n")
315 Next
316 Return string.ToString
317 End Function
318
319 /*!
320 @brief 実際の要素数が現在の容量の 90% 未満の場合は、容量をその数に設定します
321 @author NoWest
322 @date 2008/07/20
323 */
324 Sub TrimExcess ()
325 If ( This.capacity ) * 0.9 > This.count Then
326 Realloc( This.count )
327 End If
328 End Sub
329
330 /*!
331 @brief IEnumeratorインターフェイスを取得する
332 @author Daisuke Yamamoto
333 @date 2007/11/19
334 @return IEnumeratorインターフェイスが返る
335 */
336 Override Function GetEnumerator() As IEnumerator<T>
337 Return New Detail.PointerEnumerator<T>(items, count)
338 End Function
339End Class
340
341
342End Namespace
343End Namespace
344End Namespace
Note: See TracBrowser for help on using the repository browser.