Ignore:
Timestamp:
Aug 8, 2008, 12:15:30 AM (16 years ago)
Author:
dai
Message:
  • ForeachがIDisposableを実装したIEnumerator<T>を取り扱うように変更
  • #120(列挙体のUnicode対応)の修正
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ab5.0/ablib/src/Classes/System/Collections/Generic/List.ab

    r560 r579  
    44Namespace Generic
    55
     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
    641Class List<T>
    742    Inherits IList<T>
    843
    944    items As *T
    10     size As Long
     45    capacity As Long
    1146    count As Long
    12 
    13     currentIndexForEnumerator As Long
    1447
    1548    Sub Realloc( allocateSize As Long )
    1649        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
     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
    2760            Realloc(capacity)
    2861        End If
    2962    End Sub
    30 
    3163Public
    3264    Sub List()
    33         _Initialize()
     65        _Initialize(16)
    3466    End Sub
    3567
     
    5789    End Sub
    5890
    59     Sub ~List()
    60     End Sub
    61 
    6291    /*!
    6392    @brief  インデクサ
     
    6796    */
    6897    Override Sub Operator[] ( index As Long, item As T )
    69         items[index]=item
     98        If 0 <= index And index < capacity Then
     99            items[index]=item
     100        Else
     101            Throw New ArgumentOutOfRangeException("index")
     102        End If
    70103    End Sub
    71104    Override Function Operator[] ( index As Long ) As T
    72         Return items[index]
     105        If 0 <= index And index < capacity Then
     106            Return items[index]
     107        Else
     108            Throw New ArgumentOutOfRangeException("index")
     109        End If
    73110    End Function
    74111
     
    97134    End Function
    98135
     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   
    99150    /*!
    100151    @brief  Listが読み込み専用かどうかを取得する
     
    117168    */
    118169    Override Sub Add( item As T )
    119         If This.size < (This.count + 1) Then
    120             This.size++
    121             Realloc( This.size )
    122         End If
     170        SetLeastCapacity(This.count + 1)
    123171        This.items[ This.count ] = item
    124172        This.count++
     
    162210    */
    163211    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
     212        SetLeastCapacity(This.count + 1)
    168213        memmove( items + (index+1)*SizeOf(T), items + index*SizeOf(T), (This.count - index)*SizeOf(T) )
    169214        items[index] = item
     
    183228        End If
    184229
    185         RemoveAt( index )
     230        removeAtImpl( index )
    186231        Return True
    187232    End Function
     
    193238    */
    194239    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 )
    195248        memmove( items + index*SizeOf(T), items + (index+1)*SizeOf(T), (This.count - (index+1))*SizeOf(T) )
    196249        This.count--
    197     End Sub
     250    End Sub
     251
     252Public
    198253
    199254    /*!
     
    204259    */
    205260    Override Function ToString() As String
    206         Dim string As String
     261        Dim string = New Text.StringBuilder
    207262        Dim i As Long
    208263        For i = 0 To ELM( This.count )
    209             string += This[i].ToString() + Ex"\r\n"
     264            string.Append(This[i]).Append(Ex"\r\n")
    210265        Next
    211         Return string + This[i].ToString()
     266        Return string.ToString
    212267    End Function
    213268
     
    218273    */
    219274    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 )
     275        If ( This.capacity ) * 0.9 > This.count Then
     276            Realloc( This.count )
    224277        End If
    225278    End Sub
     
    232285    */
    233286    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]
     287        Return New Detail.PointerEnumerator(items, count)
    274288    End Function
    275289End Class
Note: See TracChangeset for help on using the changeset viewer.