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

Last change on this file was 675, checked in by イグトランス (egtra), 14 years ago

List<T>のCapacityの増加量を2倍に修正。内部のポインタの取得用のDataプロパティの追加。Containsの実装。

File size: 7.1 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>
[592]42    Implements IList<T>
[543]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
[675]58    Sub SetLeastCapacity( leastCapacity As Long )
59        Dim c = This.capacity
60        While c < leastCapacity
61            c *= 2
62        Wend
63        Realloc(c)
[298]64    End Sub
[560]65Public
66    Sub List()
[579]67        _Initialize(16)
[560]68    End Sub
69
[543]70    /*!
71    @brief  予め要素数を指定してList<T>を初期化
72    @author NoWest
73    @date   2008/07/13
74    @param  リストの要素数
75    */
76    Sub List( capacity As Long )
[560]77        _Initialize( capacity )
[543]78    End Sub
79
80    /*!
81    @brief  既存の配列List<T>を初期化
82    @author NoWest
83    @date   2008/07/13
[631]84    @param  基になる配列へのポインタ
85    @param  配列の長さ
[543]86    */
[558]87    Sub List( array As *T, length As Long )
[560]88        _Initialize( length )
89
[558]90        memmove( This.items, array, length * SizeOf(T) )
91        This.count = length
[543]92    End Sub
[558]93
[298]94    /*!
[675]95    @brief  既存のIEnumerable<T>を使用してListを初期化
[631]96    @author NoWest
97    @date   2008/09/22
[675]98    @param  基になるIEnumerable<T>
[631]99    */
[675]100    Sub List ( enumerable As IEnumerable<T> )
[631]101        _Initialize( 1 )
[675]102        Foreach e In enumerable
103'           This.Add(e)
104        Next
[631]105    End Sub
106
107    /*!
[298]108    @brief  インデクサ
109    @author Daisuke Yamamoto
110    @date   2007/08/22
111    @param  インデックス
112    */
[592]113    Sub Operator[] ( index As Long, item As T )
[582]114        Item[index] = item
115    End Sub
[592]116    Function Operator[] ( index As Long ) As T
[582]117        Return Item[index]
118    End Function
119
120    /*!
121    @brief  インデクサ
122    @author Egtra
123    @date   2008/08/04
124    @param  インデックス
125    */
126    Override Sub Item( index As Long, item As T )
[579]127        If 0 <= index And index < capacity Then
128            items[index]=item
129        Else
130            Throw New ArgumentOutOfRangeException("index")
131        End If
[543]132    End Sub
[582]133    Override Function Item( index As Long ) As T
[579]134        If 0 <= index And index < capacity Then
135            Return items[index]
136        Else
137            Throw New ArgumentOutOfRangeException("index")
138        End If
[298]139    End Function
[519]140    /*!
141    @brief  ポインタ型へのキャスト
142    @author Daisuke Yamamoto
143    @date   2007/08/22
144    @param  インデックス
145    */
146    Function Operator() As *T
147        Return items
148    End Function
[298]149
[675]150    /*!
151    @brief  内部の配列へのポインタを取得する
152    @auther Egtra
153    @date   2009/01/13
154    @retrun 内部の配列へのポインタ
155    @pre    Count <> 0
156    */
157    Function Data() As *T
158        Return items
159    End Function
[519]160
[298]161    '----------------------------------------------------------------
162    ' パブリック プロパティ
163    '----------------------------------------------------------------
164
165    /*!
166    @brief  Listに格納されている要素の数を取得する
167    @author Daisuke Yamamoto
168    @date   2007/08/22
169    */
[543]170    Override Function Count() As Long
[558]171        Return This.count
[298]172    End Function
173
[579]174    Const Function Capacity() As Long
175        Return This.capacity
176    End Function
177
178    Sub Capacity(c As Long)
179        If c <> capacity Then
180            If c < capacity Then
181                Throw New ArgumentOutOfRangeException("capacity")
182            Else
183                Realloc(c)
184            End If
185        End If
186    End Sub
187   
[543]188    /*!
189    @brief  Listが読み込み専用かどうかを取得する
190    @author NoWest
191    @date   2008/07/12
192    */
193    Override Function IsReadOnly() As Boolean
194        Return False
195    End Function
[298]196
197    '----------------------------------------------------------------
198    ' パブリック メソッド
199    '----------------------------------------------------------------
200
201    /*!
202    @brief  Listの末端に要素を追加する
203    @author Daisuke Yamamoto
204    @date   2007/08/22
205    @param  追加するオブジェクト
206    */
[543]207    Override Sub Add( item As T )
[579]208        SetLeastCapacity(This.count + 1)
[558]209        This.items[ This.count ] = item
210        This.count++
[298]211    End Sub
212
[631]213    /*!
214    @brief  読み取り専用のListのラッパーを取得
215    @author NoWest
216    @date   2008/09/22
217    */
[633]218/*  Function AsReadOnly() As System.Collections.ObjectModel.ReadOnlyCollection<T>
[631]219        Return New System.Collections.ObjectModel.ReadOnlyCollection<T>(This)
[633]220    End Function*/
[543]221
[298]222    /*!
223    @brief  Listからすべての要素を削除する
224    @author Daisuke Yamamoto
225    @date   2007/08/22
226    */
[543]227    Override Sub Clear()
[558]228        This.count = 0
[298]229    End Sub
230
[675]231    /*!
232    @brief  Listに指定された要素が含まれるか調べる
233    @author Egtra
234    @date   2009/01/13
235    */
236    Function Contains ( item As T ) As Boolean
237        Return IndexOf(item) >= 0
238    End Function
[543]239
[298]240    /*!
241    @brief  List内から、最初に出現する値のインデックスを取得する
242    @author Daisuke Yamamoto
243    @date   2007/08/22
244    @return インデックス(見つからなかったときは-1)
245    */
[543]246    Override Function IndexOf( item As T ) As Long
[298]247        Dim i As Long
[558]248        For i = 0 To ELM( This.count )
[298]249            If items[i].Equals(item) Then
250                Return i
251            End If
252        Next
253        Return -1
254    End Function
255
256    /*!
257    @brief  List内の指定したインデックスの位置に要素を挿入する
258    @author Daisuke Yamamoto
259    @date   2007/08/22
260    */
[543]261    Override Sub Insert( index As Long, item As T )
[579]262        SetLeastCapacity(This.count + 1)
[558]263        memmove( items + (index+1)*SizeOf(T), items + index*SizeOf(T), (This.count - index)*SizeOf(T) )
[298]264        items[index] = item
[558]265        This.count++
[298]266    End Sub
[340]267
268    /*!
269    @brief  List内で最初に出現する値を削除する
270    @author Daisuke Yamamoto
271    @date   2007/09/28
272    @return 値が削除されたときはTrue、されなかったときはFlaseが返る
273    */
[543]274    Override Function Remove( item As T ) As Boolean
[340]275        Dim index = IndexOf( item )
276        If index = -1 Then
277            Return False
278        End If
[352]279
[579]280        removeAtImpl( index )
[352]281        Return True
282    End Function
283
284    /*!
285    @brief  List内の指定したインデックスの要素を削除する
286    @author Daisuke Yamamoto
287    @date   2007/10/03
288    */
[543]289    Override Sub RemoveAt( index As Long )
[579]290        If 0 <= index And index < capacity Then
291            removeAtImpl( index )
292        Else
293            Throw New ArgumentOutOfRangeException("index")
294        End If
295    End Sub
296Private
297    Sub removeAtImpl( index As Long )
[558]298        memmove( items + index*SizeOf(T), items + (index+1)*SizeOf(T), (This.count - (index+1))*SizeOf(T) )
299        This.count--
[579]300    End Sub
[386]301
[579]302Public
303
[386]304    /*!
[526]305    @brief  Listの要素を文字列で返す
306    @author OverTaker
307    @date   2008/6/26
308    @return 文字列
309    */
310    Override Function ToString() As String
[579]311        Dim string = New Text.StringBuilder
[531]312        Dim i As Long
[558]313        For i = 0 To ELM( This.count )
[579]314            string.Append(This[i]).Append(Ex"\r\n")
[526]315        Next
[579]316        Return string.ToString
[526]317    End Function
318
319    /*!
[558]320    @brief  実際の要素数が現在の容量の 90% 未満の場合は、容量をその数に設定します
321    @author NoWest
322    @date   2008/07/20
323    */
324    Sub TrimExcess ()
[579]325        If ( This.capacity ) * 0.9 > This.count Then
326            Realloc( This.count )
[558]327        End If
328    End Sub
329
330    /*!
[386]331    @brief  IEnumeratorインターフェイスを取得する
332    @author Daisuke Yamamoto
333    @date   2007/11/19
334    @return IEnumeratorインターフェイスが返る
335    */
[543]336    Override Function GetEnumerator() As IEnumerator<T>
[587]337        Return New Detail.PointerEnumerator<T>(items, count)
[386]338    End Function
[298]339End Class
340
[543]341
[298]342End Namespace
343End Namespace
[305]344End Namespace
Note: See TracBrowser for help on using the repository browser.