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

Last change on this file since 631 was 631, checked in by NoWest, 16 years ago

List<T>、Stack<T>、Queue<T>を相互にIEnumerator<T>を使って変換できるようにしました。

List<T>クラスからReadOnlyCollectionの呼び出しがコンパイルできません。
どうしても問題を再現できなかったので、皆さんの所でも問題が発生するか確認のためにupしておきます。
やっぱり問題がおきたら、RevertするかListのAsReadOnlyメソッドをコメントアウトしてください。

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