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

Last change on this file since 633 was 633, checked in by NoWest, 15 years ago

AsReadOnlyCollectionを実装するとうまくコンパイルできない問題ですが、
それ以前の問題として、Listクラス内でAdd()メソッドでIEnumeratorのCurrentプロパティの値を設定できないエラーがあります。

症状としてはCurrentの結果がT型であるのにListのAddはByte型とに認識され
TからByte型にキャストできないとエラーがでます。

File size: 6.8 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( 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 @param 配列の長さ
84 */
85 Sub List( array As *T, length As Long )
86 _Initialize( length )
87
88 memmove( This.items, array, length * SizeOf(T) )
89 This.count = length
90 End Sub
91
92 /*!
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 'ここでTをByetに変換できないというエラーになる This.Add(enumerator.Current())
102 Wend
103 End Sub
104
105 /*!
106 @brief インデクサ
107 @author Daisuke Yamamoto
108 @date 2007/08/22
109 @param インデックス
110 */
111 Sub Operator[] ( index As Long, item As T )
112 Item[index] = item
113 End Sub
114 Function Operator[] ( index As Long ) As T
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 )
125 If 0 <= index And index < capacity Then
126 items[index]=item
127 Else
128 Throw New ArgumentOutOfRangeException("index")
129 End If
130 End Sub
131 Override Function Item( index As Long ) As T
132 If 0 <= index And index < capacity Then
133 Return items[index]
134 Else
135 Throw New ArgumentOutOfRangeException("index")
136 End If
137 End Function
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
147
148
149 '----------------------------------------------------------------
150 ' パブリック プロパティ
151 '----------------------------------------------------------------
152
153 /*!
154 @brief Listに格納されている要素の数を取得する
155 @author Daisuke Yamamoto
156 @date 2007/08/22
157 */
158 Override Function Count() As Long
159 Return This.count
160 End Function
161
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
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
184
185 '----------------------------------------------------------------
186 ' パブリック メソッド
187 '----------------------------------------------------------------
188
189 /*!
190 @brief Listの末端に要素を追加する
191 @author Daisuke Yamamoto
192 @date 2007/08/22
193 @param 追加するオブジェクト
194 */
195 Override Sub Add( item As T )
196 SetLeastCapacity(This.count + 1)
197 This.items[ This.count ] = item
198 This.count++
199 End Sub
200
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*/
209
210 /*!
211 @brief Listからすべての要素を削除する
212 @author Daisuke Yamamoto
213 @date 2007/08/22
214 */
215 Override Sub Clear()
216 This.count = 0
217 End Sub
218
219/* Override Function Contains ( item As T ) As Boolean
220 TODO
221 End Function*/
222
223 /*!
224 @brief List内から、最初に出現する値のインデックスを取得する
225 @author Daisuke Yamamoto
226 @date 2007/08/22
227 @return インデックス(見つからなかったときは-1)
228 */
229 Override Function IndexOf( item As T ) As Long
230 Dim i As Long
231 For i = 0 To ELM( This.count )
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 */
244 Override Sub Insert( index As Long, item As T )
245 SetLeastCapacity(This.count + 1)
246 memmove( items + (index+1)*SizeOf(T), items + index*SizeOf(T), (This.count - index)*SizeOf(T) )
247 items[index] = item
248 This.count++
249 End Sub
250
251 /*!
252 @brief List内で最初に出現する値を削除する
253 @author Daisuke Yamamoto
254 @date 2007/09/28
255 @return 値が削除されたときはTrue、されなかったときはFlaseが返る
256 */
257 Override Function Remove( item As T ) As Boolean
258 Dim index = IndexOf( item )
259 If index = -1 Then
260 Return False
261 End If
262
263 removeAtImpl( index )
264 Return True
265 End Function
266
267 /*!
268 @brief List内の指定したインデックスの要素を削除する
269 @author Daisuke Yamamoto
270 @date 2007/10/03
271 */
272 Override Sub RemoveAt( index As Long )
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 )
281 memmove( items + index*SizeOf(T), items + (index+1)*SizeOf(T), (This.count - (index+1))*SizeOf(T) )
282 This.count--
283 End Sub
284
285Public
286
287 /*!
288 @brief Listの要素を文字列で返す
289 @author OverTaker
290 @date 2008/6/26
291 @return 文字列
292 */
293 Override Function ToString() As String
294 Dim string = New Text.StringBuilder
295 Dim i As Long
296 For i = 0 To ELM( This.count )
297 string.Append(This[i]).Append(Ex"\r\n")
298 Next
299 Return string.ToString
300 End Function
301
302 /*!
303 @brief 実際の要素数が現在の容量の 90% 未満の場合は、容量をその数に設定します
304 @author NoWest
305 @date 2008/07/20
306 */
307 Sub TrimExcess ()
308 If ( This.capacity ) * 0.9 > This.count Then
309 Realloc( This.count )
310 End If
311 End Sub
312
313 /*!
314 @brief IEnumeratorインターフェイスを取得する
315 @author Daisuke Yamamoto
316 @date 2007/11/19
317 @return IEnumeratorインターフェイスが返る
318 */
319 Override Function GetEnumerator() As IEnumerator<T>
320 Return New Detail.PointerEnumerator<T>(items, count)
321 End Function
322End Class
323
324
325End Namespace
326End Namespace
327End Namespace
Note: See TracBrowser for help on using the repository browser.