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

Last change on this file since 558 was 558, checked in by NoWest, 13 years ago

Queueジェネリッククラスを追加
Listジェネリッククラスの内部でメモリの再確保が頻繁に行われないように改良

File size: 5.8 KB
Line 
1
2Namespace System
3Namespace Collections
4Namespace Generic
5
6Class List<T>
7    Inherits IList<T>
8
9    items As *T
10    size As Long
11    count As Long
12
13    currentIndexForEnumerator As Long
14
15    Sub Realloc( allocateSize As Long )
16        items = realloc( items, allocateSize * SizeOf(T) )
17    End Sub
18
19Public
20    Sub List()
21        items = GC_malloc( 1 )
22
23        ' 列挙子の位置を初期化
24        Reset()
25    End Sub
26
27    /*!
28    @brief  予め要素数を指定してList<T>を初期化
29    @author NoWest
30    @date   2008/07/13
31    @param  リストの要素数
32    */
33    Sub List( capacity As Long )
34        This.List()
35        If capacity > 0 Then
36            This.size = capacity
37            Realloc(capacity)
38        End If
39    End Sub
40
41    /*!
42    @brief  既存の配列List<T>を初期化
43    @author NoWest
44    @date   2008/07/13
45    @param  インデックス
46    */
47    Sub List( array As *T, length As Long )
48        This.List( length )
49        memmove( This.items, array, length * SizeOf(T) )
50        This.count = length
51    End Sub
52
53    Sub ~List()
54    End Sub
55
56    /*!
57    @brief  インデクサ
58    @author Daisuke Yamamoto
59    @date   2007/08/22
60    @param  インデックス
61    */
62    Override Sub Operator[] ( index As Long, item As T )
63        items[index]=item
64    End Sub
65    Override Function Operator[] ( index As Long ) As T
66        Return items[index]
67    End Function
68
69    /*!
70    @brief  ポインタ型へのキャスト
71    @author Daisuke Yamamoto
72    @date   2007/08/22
73    @param  インデックス
74    */
75    Function Operator() As *T
76        Return items
77    End Function
78
79
80    '----------------------------------------------------------------
81    ' パブリック プロパティ
82    '----------------------------------------------------------------
83
84    /*!
85    @brief  Listに格納されている要素の数を取得する
86    @author Daisuke Yamamoto
87    @date   2007/08/22
88    */
89    Override Function Count() As Long
90        Return This.count
91    End Function
92
93    /*!
94    @brief  Listが読み込み専用かどうかを取得する
95    @author NoWest
96    @date   2008/07/12
97    */
98    Override Function IsReadOnly() As Boolean
99        Return False
100    End Function
101
102    '----------------------------------------------------------------
103    ' パブリック メソッド
104    '----------------------------------------------------------------
105
106    /*!
107    @brief  Listの末端に要素を追加する
108    @author Daisuke Yamamoto
109    @date   2007/08/22
110    @param  追加するオブジェクト
111    */
112    Override Sub Add( item As T )
113        If This.size < (This.count + 1) Then
114            This.size++
115            Realloc( This.size )
116        End If
117        This.items[ This.count ] = item
118        This.count++
119    End Sub
120
121'   Function AsReadOnly() As ReadOnlyCollection
122
123    /*!
124    @brief  Listからすべての要素を削除する
125    @author Daisuke Yamamoto
126    @date   2007/08/22
127    */
128    Override Sub Clear()
129        This.count = 0
130    End Sub
131
132/*  Override Function Contains ( item As T ) As Boolean
133        TODO
134    End Function*/
135
136    /*!
137    @brief  List内から、最初に出現する値のインデックスを取得する
138    @author Daisuke Yamamoto
139    @date   2007/08/22
140    @return インデックス(見つからなかったときは-1)
141    */
142    Override Function IndexOf( item As T ) As Long
143        Dim i As Long
144        For i = 0 To ELM( This.count )
145            If items[i].Equals(item) Then
146                Return i
147            End If
148        Next
149        Return -1
150    End Function
151
152    /*!
153    @brief  List内の指定したインデックスの位置に要素を挿入する
154    @author Daisuke Yamamoto
155    @date   2007/08/22
156    */
157    Override Sub Insert( index As Long, item As T )
158        If This.size < (This.count + 1) Then
159            This.size++
160            Realloc( This.size )
161        End If
162        memmove( items + (index+1)*SizeOf(T), items + index*SizeOf(T), (This.count - index)*SizeOf(T) )
163        items[index] = item
164        This.count++
165    End Sub
166
167    /*!
168    @brief  List内で最初に出現する値を削除する
169    @author Daisuke Yamamoto
170    @date   2007/09/28
171    @return 値が削除されたときはTrue、されなかったときはFlaseが返る
172    */
173    Override Function Remove( item As T ) As Boolean
174        Dim index = IndexOf( item )
175        If index = -1 Then
176            Return False
177        End If
178
179        RemoveAt( index )
180        Return True
181    End Function
182
183    /*!
184    @brief  List内の指定したインデックスの要素を削除する
185    @author Daisuke Yamamoto
186    @date   2007/10/03
187    */
188    Override Sub RemoveAt( index As Long )
189        memmove( items + index*SizeOf(T), items + (index+1)*SizeOf(T), (This.count - (index+1))*SizeOf(T) )
190        This.count--
191    End Sub
192
193    /*!
194    @brief  Listの要素を文字列で返す
195    @author OverTaker
196    @date   2008/6/26
197    @return 文字列
198    */
199    Override Function ToString() As String
200        Dim string As String
201        Dim i As Long
202        For i = 0 To ELM( This.count )
203            string += This[i].ToString() + Ex"\r\n"
204        Next
205        Return string + This[i].ToString()
206    End Function
207
208    /*!
209    @brief  実際の要素数が現在の容量の 90% 未満の場合は、容量をその数に設定します
210    @author NoWest
211    @date   2008/07/20
212    */
213    Sub TrimExcess ()
214        Dim pmemobj = _System_pGC->GetMemoryObjectPtr( items )
215        If ( This.size ) * 0.9 > This.count Then
216            This.size = This.count
217            Realloc( This.size )
218        End If
219    End Sub
220
221    /*!
222    @brief  IEnumeratorインターフェイスを取得する
223    @author Daisuke Yamamoto
224    @date   2007/11/19
225    @return IEnumeratorインターフェイスが返る
226    */
227    Override Function GetEnumerator() As IEnumerator<T>
228        Return This
229    End Function
230
231    /*!
232    @brief  イテレータのカレントインデックスを増加させる
233    @author Daisuke Yamamoto
234    @date   2007/11/19
235    @return 上限に達していなければTrueが、達していればFalseが返る
236    */
237    Override Function MoveNext() As Boolean
238        If currentIndexForEnumerator + 1 >= size Then
239            ' 上限に達した
240            Return False
241        End If
242
243        currentIndexForEnumerator ++
244        Return True
245    End Function
246
247    /*!
248    @brief  イテレータをリセットする
249    @author Daisuke Yamamoto
250    @date   2007/11/19
251    */
252    Override Sub Reset()
253        currentIndexForEnumerator = -1
254    End Sub
255
256    /*!
257    @brief  イテレータのカレントオブジェクトを取得する
258    @author Daisuke Yamamoto
259    @date   2007/11/19
260    @return カレントオブジェクトが返る
261    */
262    Override Function Current() As T
263        If currentIndexForEnumerator = -1 Then
264            ' MoveNextメソッドがReset後、一度も呼び出されなかった
265            Return Nothing
266        End If
267        Return items[currentIndexForEnumerator]
268    End Function
269End Class
270
271
272End Namespace
273End Namespace
274End Namespace
Note: See TracBrowser for help on using the repository browser.