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, 14 years ago

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

File size: 5.9 KB
RevLine 
[298]1
2Namespace System
3Namespace Collections
[305]4Namespace Generic
[298]5
6Class List<T>
[543]7    Inherits IList<T>
8
[298]9    items As *T
10    size As Long
[558]11    count As Long
[298]12
[386]13    currentIndexForEnumerator As Long
14
[298]15    Sub Realloc( allocateSize As Long )
[519]16        items = realloc( items, allocateSize * SizeOf(T) )
[298]17    End Sub
18
[560]19    Sub _Initialize( capacity = 0 As Long )
[298]20        items = GC_malloc( 1 )
[387]21
22        ' 列挙子の位置を初期化
23        Reset()
[560]24
25        If capacity > 0 Then
26            This.size = capacity
27            Realloc(capacity)
28        End If
[298]29    End Sub
[543]30
[560]31Public
32    Sub List()
33        _Initialize()
34    End Sub
35
[543]36    /*!
37    @brief  予め要素数を指定してList<T>を初期化
38    @author NoWest
39    @date   2008/07/13
40    @param  リストの要素数
41    */
42    Sub List( capacity As Long )
[560]43        _Initialize( capacity )
[543]44    End Sub
45
46    /*!
47    @brief  既存の配列List<T>を初期化
48    @author NoWest
49    @date   2008/07/13
50    @param  インデックス
51    */
[558]52    Sub List( array As *T, length As Long )
[560]53        _Initialize( length )
54
[558]55        memmove( This.items, array, length * SizeOf(T) )
56        This.count = length
[543]57    End Sub
[558]58
[298]59    Sub ~List()
60    End Sub
61
62    /*!
63    @brief  インデクサ
64    @author Daisuke Yamamoto
65    @date   2007/08/22
66    @param  インデックス
67    */
[543]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
[298]72        Return items[index]
73    End Function
74
[519]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
[298]84
[519]85
[298]86    '----------------------------------------------------------------
87    ' パブリック プロパティ
88    '----------------------------------------------------------------
89
90    /*!
91    @brief  Listに格納されている要素の数を取得する
92    @author Daisuke Yamamoto
93    @date   2007/08/22
94    */
[543]95    Override Function Count() As Long
[558]96        Return This.count
[298]97    End Function
98
[543]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
[298]107
108    '----------------------------------------------------------------
109    ' パブリック メソッド
110    '----------------------------------------------------------------
111
112    /*!
113    @brief  Listの末端に要素を追加する
114    @author Daisuke Yamamoto
115    @date   2007/08/22
116    @param  追加するオブジェクト
117    */
[543]118    Override Sub Add( item As T )
[558]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++
[298]125    End Sub
126
[543]127'   Function AsReadOnly() As ReadOnlyCollection
128
[298]129    /*!
130    @brief  Listからすべての要素を削除する
131    @author Daisuke Yamamoto
132    @date   2007/08/22
133    */
[543]134    Override Sub Clear()
[558]135        This.count = 0
[298]136    End Sub
137
[543]138/*  Override Function Contains ( item As T ) As Boolean
139        TODO
140    End Function*/
141
[298]142    /*!
143    @brief  List内から、最初に出現する値のインデックスを取得する
144    @author Daisuke Yamamoto
145    @date   2007/08/22
146    @return インデックス(見つからなかったときは-1)
147    */
[543]148    Override Function IndexOf( item As T ) As Long
[298]149        Dim i As Long
[558]150        For i = 0 To ELM( This.count )
[298]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    */
[543]163    Override Sub Insert( index As Long, item As T )
[558]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) )
[298]169        items[index] = item
[558]170        This.count++
[298]171    End Sub
[340]172
173    /*!
174    @brief  List内で最初に出現する値を削除する
175    @author Daisuke Yamamoto
176    @date   2007/09/28
177    @return 値が削除されたときはTrue、されなかったときはFlaseが返る
178    */
[543]179    Override Function Remove( item As T ) As Boolean
[340]180        Dim index = IndexOf( item )
181        If index = -1 Then
182            Return False
183        End If
[352]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    */
[543]194    Override Sub RemoveAt( index As Long )
[558]195        memmove( items + index*SizeOf(T), items + (index+1)*SizeOf(T), (This.count - (index+1))*SizeOf(T) )
196        This.count--
[352]197    End Sub
[386]198
199    /*!
[526]200    @brief  Listの要素を文字列で返す
201    @author OverTaker
202    @date   2008/6/26
203    @return 文字列
204    */
205    Override Function ToString() As String
[531]206        Dim string As String
207        Dim i As Long
[558]208        For i = 0 To ELM( This.count )
[531]209            string += This[i].ToString() + Ex"\r\n"
[526]210        Next
[531]211        Return string + This[i].ToString()
[526]212    End Function
213
214    /*!
[558]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    /*!
[386]228    @brief  IEnumeratorインターフェイスを取得する
229    @author Daisuke Yamamoto
230    @date   2007/11/19
231    @return IEnumeratorインターフェイスが返る
232    */
[543]233    Override Function GetEnumerator() As IEnumerator<T>
[386]234        Return This
235    End Function
236
237    /*!
238    @brief  イテレータのカレントインデックスを増加させる
239    @author Daisuke Yamamoto
240    @date   2007/11/19
241    @return 上限に達していなければTrueが、達していればFalseが返る
242    */
[543]243    Override Function MoveNext() As Boolean
[387]244        If currentIndexForEnumerator + 1 >= size Then
[386]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    */
[543]258    Override Sub Reset()
[387]259        currentIndexForEnumerator = -1
[386]260    End Sub
261
262    /*!
263    @brief  イテレータのカレントオブジェクトを取得する
264    @author Daisuke Yamamoto
265    @date   2007/11/19
266    @return カレントオブジェクトが返る
267    */
[543]268    Override Function Current() As T
[387]269        If currentIndexForEnumerator = -1 Then
270            ' MoveNextメソッドがReset後、一度も呼び出されなかった
271            Return Nothing
272        End If
[396]273        Return items[currentIndexForEnumerator]
[386]274    End Function
[298]275End Class
276
[543]277
[298]278End Namespace
279End Namespace
[305]280End Namespace
Note: See TracBrowser for help on using the repository browser.