Ignore:
Timestamp:
Aug 8, 2008, 12:15:30 AM (16 years ago)
Author:
dai
Message:
  • ForeachがIDisposableを実装したIEnumerator<T>を取り扱うように変更
  • #120(列挙体のUnicode対応)の修正
Location:
trunk/ab5.0/ablib/src/Classes/System/Collections/Generic
Files:
4 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
  • trunk/ab5.0/ablib/src/Classes/System/Collections/Generic/Queue.ab

    r577 r579  
    1818    Sub Queue ()
    1919        This.items = GC_malloc( 1 )
    20         Reset()
    2120    End Sub
    2221
    2322    Sub Queue ( capacity As Long )
    2423        This.items = GC_malloc( 1 )
    25         Reset()
    2624        If capacity > 0 Then
    2725            This.size = capacity
     
    6462    */
    6563    Override Function GetEnumerator () As IEnumerator<T>
    66         Return This
     64        Return New Detail.PointerEnumerator(items, count)
    6765    End Function
    6866
     
    116114        End If
    117115    End Sub
    118 
    119 
    120     '------------------------
    121     '   IEnumeratorの実装
    122     '------------------------
    123     currentIndexForEnumerator As Long
    124 
    125     Override Function Current () As T
    126         If This.currentIndexForEnumerator = -1 Then
    127             ' MoveNextメソッドがReset後、一度も呼び出されなかった
    128             Return Nothing
    129         End If
    130         Return This.items[ This.currentIndexForEnumerator ]
    131     End Function
    132 
    133     Override Function MoveNext() As Boolean
    134         If This.currentIndexForEnumerator + 1 >= This.size Then
    135             ' 上限に達した
    136             Return False
    137         End If
    138 
    139         This.currentIndexForEnumerator ++
    140         Return True
    141     End Function
    142 
    143     Override Sub Reset ()
    144         This.currentIndexForEnumerator = -1
    145     End Sub
    146116End Class
    147117
  • trunk/ab5.0/ablib/src/Classes/System/Collections/Generic/Stack.ab

    r577 r579  
    1818    Sub Stack ()
    1919        This.items = GC_malloc( 1 )
    20         Reset()
    2120    End Sub
    2221
    2322    Sub Stack ( capacity As Long )
    2423        This.items = GC_malloc( 1 )
    25         Reset()
    2624        If capacity > 0 Then
    2725            This.size = capacity
     
    6462    */
    6563    Override Function GetEnumerator () As IEnumerator<T>
    66         Return This
     64        Return New Detail.PointerEnumerator(items, count)
    6765    End Function
    6866
     
    117115        End If
    118116    End Sub
    119 
    120 
    121     '------------------------
    122     '   IEnumeratorの実装
    123     '------------------------
    124     currentIndexForEnumerator As Long
    125 
    126     Override Function Current () As T
    127         If This.currentIndexForEnumerator = -1 Then
    128             ' MoveNextメソッドがReset後、一度も呼び出されなかった
    129             Return Nothing
    130         End If
    131         Return This.items[ This.currentIndexForEnumerator ]
    132     End Function
    133 
    134     Override Function MoveNext() As Boolean
    135         If This.currentIndexForEnumerator + 1 >= This.count Then
    136             ' 上限に達した
    137             Return False
    138         End If
    139 
    140         This.currentIndexForEnumerator ++
    141         Return True
    142     End Function
    143 
    144     Override Sub Reset ()
    145         This.currentIndexForEnumerator = -1
    146     End Sub
    147117End Class
    148118
  • trunk/ab5.0/ablib/src/Classes/System/Collections/Generic/misc.ab

    r577 r579  
    1010
    1111Interface IEnumerator<T>
     12    Inherits IDisposable
    1213    ' Methods
    1314    Function MoveNext () As Boolean
     
    1920
    2021Class ICollection<T>
    21     Implements IEnumerable<T>, IEnumerator<T>
     22    Implements IEnumerable<T>
    2223Public
    2324    ' Property
Note: See TracChangeset for help on using the changeset viewer.