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