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
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>
[543]42 Inherits IList<T>
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
82 @param インデックス
83 */
[558]84 Sub List( array As *T, length As Long )
[560]85 _Initialize( length )
86
[558]87 memmove( This.items, array, length * SizeOf(T) )
88 This.count = length
[543]89 End Sub
[558]90
[298]91 /*!
92 @brief インデクサ
93 @author Daisuke Yamamoto
94 @date 2007/08/22
95 @param インデックス
96 */
[543]97 Override Sub Operator[] ( index As Long, item As T )
[579]98 If 0 <= index And index < capacity Then
99 items[index]=item
100 Else
101 Throw New ArgumentOutOfRangeException("index")
102 End If
[543]103 End Sub
104 Override Function Operator[] ( index As Long ) As T
[579]105 If 0 <= index And index < capacity Then
106 Return items[index]
107 Else
108 Throw New ArgumentOutOfRangeException("index")
109 End If
[298]110 End Function
111
[519]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
[298]121
[519]122
[298]123 '----------------------------------------------------------------
124 ' パブリック プロパティ
125 '----------------------------------------------------------------
126
127 /*!
128 @brief Listに格納されている要素の数を取得する
129 @author Daisuke Yamamoto
130 @date 2007/08/22
131 */
[543]132 Override Function Count() As Long
[558]133 Return This.count
[298]134 End Function
135
[579]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
[543]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
[298]158
159 '----------------------------------------------------------------
160 ' パブリック メソッド
161 '----------------------------------------------------------------
162
163 /*!
164 @brief Listの末端に要素を追加する
165 @author Daisuke Yamamoto
166 @date 2007/08/22
167 @param 追加するオブジェクト
168 */
[543]169 Override Sub Add( item As T )
[579]170 SetLeastCapacity(This.count + 1)
[558]171 This.items[ This.count ] = item
172 This.count++
[298]173 End Sub
174
[543]175' Function AsReadOnly() As ReadOnlyCollection
176
[298]177 /*!
178 @brief Listからすべての要素を削除する
179 @author Daisuke Yamamoto
180 @date 2007/08/22
181 */
[543]182 Override Sub Clear()
[558]183 This.count = 0
[298]184 End Sub
185
[543]186/* Override Function Contains ( item As T ) As Boolean
187 TODO
188 End Function*/
189
[298]190 /*!
191 @brief List内から、最初に出現する値のインデックスを取得する
192 @author Daisuke Yamamoto
193 @date 2007/08/22
194 @return インデックス(見つからなかったときは-1)
195 */
[543]196 Override Function IndexOf( item As T ) As Long
[298]197 Dim i As Long
[558]198 For i = 0 To ELM( This.count )
[298]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 */
[543]211 Override Sub Insert( index As Long, item As T )
[579]212 SetLeastCapacity(This.count + 1)
[558]213 memmove( items + (index+1)*SizeOf(T), items + index*SizeOf(T), (This.count - index)*SizeOf(T) )
[298]214 items[index] = item
[558]215 This.count++
[298]216 End Sub
[340]217
218 /*!
219 @brief List内で最初に出現する値を削除する
220 @author Daisuke Yamamoto
221 @date 2007/09/28
222 @return 値が削除されたときはTrue、されなかったときはFlaseが返る
223 */
[543]224 Override Function Remove( item As T ) As Boolean
[340]225 Dim index = IndexOf( item )
226 If index = -1 Then
227 Return False
228 End If
[352]229
[579]230 removeAtImpl( index )
[352]231 Return True
232 End Function
233
234 /*!
235 @brief List内の指定したインデックスの要素を削除する
236 @author Daisuke Yamamoto
237 @date 2007/10/03
238 */
[543]239 Override Sub RemoveAt( index As Long )
[579]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 )
[558]248 memmove( items + index*SizeOf(T), items + (index+1)*SizeOf(T), (This.count - (index+1))*SizeOf(T) )
249 This.count--
[579]250 End Sub
[386]251
[579]252Public
253
[386]254 /*!
[526]255 @brief Listの要素を文字列で返す
256 @author OverTaker
257 @date 2008/6/26
258 @return 文字列
259 */
260 Override Function ToString() As String
[579]261 Dim string = New Text.StringBuilder
[531]262 Dim i As Long
[558]263 For i = 0 To ELM( This.count )
[579]264 string.Append(This[i]).Append(Ex"\r\n")
[526]265 Next
[579]266 Return string.ToString
[526]267 End Function
268
269 /*!
[558]270 @brief 実際の要素数が現在の容量の 90% 未満の場合は、容量をその数に設定します
271 @author NoWest
272 @date 2008/07/20
273 */
274 Sub TrimExcess ()
[579]275 If ( This.capacity ) * 0.9 > This.count Then
276 Realloc( This.count )
[558]277 End If
278 End Sub
279
280 /*!
[386]281 @brief IEnumeratorインターフェイスを取得する
282 @author Daisuke Yamamoto
283 @date 2007/11/19
284 @return IEnumeratorインターフェイスが返る
285 */
[543]286 Override Function GetEnumerator() As IEnumerator<T>
[579]287 Return New Detail.PointerEnumerator(items, count)
[386]288 End Function
[298]289End Class
290
[543]291
[298]292End Namespace
293End Namespace
[305]294End Namespace
Note: See TracBrowser for help on using the repository browser.