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

Last change on this file since 560 was 560, checked in by dai, 13 years ago

#183への対応。コンストラクタ、デストラクタが直接呼び出された場合はエラーとして扱うようにした。
(64bit版は後ほどコミットします)

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