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
RevLine 
[298]1
2Namespace System
3Namespace Collections
[305]4Namespace Generic
[298]5
[579]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
[298]41Class List<T>
[592]42 Implements IList<T>
[543]43
[298]44 items As *T
[579]45 capacity As Long
[558]46 count As Long
[298]47
48 Sub Realloc( allocateSize As Long )
[519]49 items = realloc( items, allocateSize * SizeOf(T) )
[579]50 capacity = allocateSize
[298]51 End Sub
52
[579]53 Sub _Initialize( capacity As Long )
54 This.items = GC_malloc( capacity * SizeOf(T) )
55 This.capacity = capacity
56 End Sub
[387]57
[675]58 Sub SetLeastCapacity( leastCapacity As Long )
59 Dim c = This.capacity
60 While c < leastCapacity
61 c *= 2
62 Wend
63 Realloc(c)
[298]64 End Sub
[560]65Public
66 Sub List()
[579]67 _Initialize(16)
[560]68 End Sub
69
[543]70 /*!
71 @brief 予め要素数を指定してList<T>を初期化
72 @author NoWest
73 @date 2008/07/13
74 @param リストの要素数
75 */
76 Sub List( capacity As Long )
[560]77 _Initialize( capacity )
[543]78 End Sub
79
80 /*!
81 @brief 既存の配列List<T>を初期化
82 @author NoWest
83 @date 2008/07/13
[631]84 @param 基になる配列へのポインタ
85 @param 配列の長さ
[543]86 */
[558]87 Sub List( array As *T, length As Long )
[560]88 _Initialize( length )
89
[558]90 memmove( This.items, array, length * SizeOf(T) )
91 This.count = length
[543]92 End Sub
[558]93
[298]94 /*!
[675]95 @brief 既存のIEnumerable<T>を使用してListを初期化
[631]96 @author NoWest
97 @date 2008/09/22
[675]98 @param 基になるIEnumerable<T>
[631]99 */
[675]100 Sub List ( enumerable As IEnumerable<T> )
[631]101 _Initialize( 1 )
[675]102 Foreach e In enumerable
103' This.Add(e)
104 Next
[631]105 End Sub
106
107 /*!
[298]108 @brief インデクサ
109 @author Daisuke Yamamoto
110 @date 2007/08/22
111 @param インデックス
112 */
[592]113 Sub Operator[] ( index As Long, item As T )
[582]114 Item[index] = item
115 End Sub
[592]116 Function Operator[] ( index As Long ) As T
[582]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 )
[579]127 If 0 <= index And index < capacity Then
128 items[index]=item
129 Else
130 Throw New ArgumentOutOfRangeException("index")
131 End If
[543]132 End Sub
[582]133 Override Function Item( index As Long ) As T
[579]134 If 0 <= index And index < capacity Then
135 Return items[index]
136 Else
137 Throw New ArgumentOutOfRangeException("index")
138 End If
[298]139 End Function
[519]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
[298]149
[675]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
[519]160
[298]161 '----------------------------------------------------------------
162 ' パブリック プロパティ
163 '----------------------------------------------------------------
164
165 /*!
166 @brief Listに格納されている要素の数を取得する
167 @author Daisuke Yamamoto
168 @date 2007/08/22
169 */
[543]170 Override Function Count() As Long
[558]171 Return This.count
[298]172 End Function
173
[579]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
[543]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
[298]196
197 '----------------------------------------------------------------
198 ' パブリック メソッド
199 '----------------------------------------------------------------
200
201 /*!
202 @brief Listの末端に要素を追加する
203 @author Daisuke Yamamoto
204 @date 2007/08/22
205 @param 追加するオブジェクト
206 */
[543]207 Override Sub Add( item As T )
[579]208 SetLeastCapacity(This.count + 1)
[558]209 This.items[ This.count ] = item
210 This.count++
[298]211 End Sub
212
[631]213 /*!
214 @brief 読み取り専用のListのラッパーを取得
215 @author NoWest
216 @date 2008/09/22
217 */
[633]218/* Function AsReadOnly() As System.Collections.ObjectModel.ReadOnlyCollection<T>
[631]219 Return New System.Collections.ObjectModel.ReadOnlyCollection<T>(This)
[633]220 End Function*/
[543]221
[298]222 /*!
223 @brief Listからすべての要素を削除する
224 @author Daisuke Yamamoto
225 @date 2007/08/22
226 */
[543]227 Override Sub Clear()
[558]228 This.count = 0
[298]229 End Sub
230
[675]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
[543]239
[298]240 /*!
241 @brief List内から、最初に出現する値のインデックスを取得する
242 @author Daisuke Yamamoto
243 @date 2007/08/22
244 @return インデックス(見つからなかったときは-1)
245 */
[543]246 Override Function IndexOf( item As T ) As Long
[298]247 Dim i As Long
[558]248 For i = 0 To ELM( This.count )
[298]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 */
[543]261 Override Sub Insert( index As Long, item As T )
[579]262 SetLeastCapacity(This.count + 1)
[558]263 memmove( items + (index+1)*SizeOf(T), items + index*SizeOf(T), (This.count - index)*SizeOf(T) )
[298]264 items[index] = item
[558]265 This.count++
[298]266 End Sub
[340]267
268 /*!
269 @brief List内で最初に出現する値を削除する
270 @author Daisuke Yamamoto
271 @date 2007/09/28
272 @return 値が削除されたときはTrue、されなかったときはFlaseが返る
273 */
[543]274 Override Function Remove( item As T ) As Boolean
[340]275 Dim index = IndexOf( item )
276 If index = -1 Then
277 Return False
278 End If
[352]279
[579]280 removeAtImpl( index )
[352]281 Return True
282 End Function
283
284 /*!
285 @brief List内の指定したインデックスの要素を削除する
286 @author Daisuke Yamamoto
287 @date 2007/10/03
288 */
[543]289 Override Sub RemoveAt( index As Long )
[579]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 )
[558]298 memmove( items + index*SizeOf(T), items + (index+1)*SizeOf(T), (This.count - (index+1))*SizeOf(T) )
299 This.count--
[579]300 End Sub
[386]301
[579]302Public
303
[386]304 /*!
[526]305 @brief Listの要素を文字列で返す
306 @author OverTaker
307 @date 2008/6/26
308 @return 文字列
309 */
310 Override Function ToString() As String
[579]311 Dim string = New Text.StringBuilder
[531]312 Dim i As Long
[558]313 For i = 0 To ELM( This.count )
[579]314 string.Append(This[i]).Append(Ex"\r\n")
[526]315 Next
[579]316 Return string.ToString
[526]317 End Function
318
319 /*!
[558]320 @brief 実際の要素数が現在の容量の 90% 未満の場合は、容量をその数に設定します
321 @author NoWest
322 @date 2008/07/20
323 */
324 Sub TrimExcess ()
[579]325 If ( This.capacity ) * 0.9 > This.count Then
326 Realloc( This.count )
[558]327 End If
328 End Sub
329
330 /*!
[386]331 @brief IEnumeratorインターフェイスを取得する
332 @author Daisuke Yamamoto
333 @date 2007/11/19
334 @return IEnumeratorインターフェイスが返る
335 */
[543]336 Override Function GetEnumerator() As IEnumerator<T>
[587]337 Return New Detail.PointerEnumerator<T>(items, count)
[386]338 End Function
[298]339End Class
340
[543]341
[298]342End Namespace
343End Namespace
[305]344End Namespace
Note: See TracBrowser for help on using the repository browser.