1+ using System . Collections ;
2+
3+ namespace Intersect . Collections . Slotting ;
4+
5+ public class SlotList < TSlot > : IList < TSlot > where TSlot : ISlot
6+ {
7+ private readonly SortedList < int , TSlot > _slots ;
8+ private readonly Func < int , TSlot > _factory ;
9+
10+ public SlotList ( int capacity , Func < int , TSlot > factory )
11+ {
12+ _slots = new SortedList < int , TSlot > ( capacity ) ;
13+ _factory = factory ;
14+ }
15+
16+ IEnumerator IEnumerable . GetEnumerator ( ) => GetEnumerator ( ) ;
17+
18+ public IEnumerator < TSlot > GetEnumerator ( ) => _slots . Values . GetEnumerator ( ) ;
19+
20+ public void Add ( TSlot slot )
21+ {
22+ if ( _slots . TryGetValue ( slot . Slot , out var existingSlot ) )
23+ {
24+ if ( existingSlot . IsEmpty )
25+ {
26+ _slots [ slot . Slot ] = slot ;
27+ }
28+ else
29+ {
30+ throw new ArgumentException ( $ "Slot { slot . Slot } is already filled with a non-empty slot.", nameof ( slot ) ) ;
31+ }
32+ }
33+ else
34+ {
35+ _slots . Add ( slot . Slot , slot ) ;
36+ }
37+ }
38+
39+ public void Clear ( ) => _slots . Clear ( ) ;
40+
41+ public bool Contains ( TSlot slot ) => _slots . ContainsValue ( slot ) ;
42+
43+ public void CopyTo ( TSlot [ ] array , int arrayIndex ) =>
44+ _slots . Select ( kvp => kvp . Value ) . ToArray ( ) . CopyTo ( array , arrayIndex ) ;
45+
46+ public bool Remove ( TSlot slot ) => _slots . Remove ( slot . Slot ) ;
47+
48+ public int Capacity
49+ {
50+ get => _slots . Capacity ;
51+ set => _slots . Capacity = value ;
52+ }
53+
54+ public int Count => _slots . Count ;
55+
56+ public bool IsReadOnly => ( ( IDictionary ) _slots ) . IsReadOnly ;
57+
58+ public int IndexOf ( TSlot slot ) => _slots . IndexOfValue ( slot ) ;
59+
60+ public void Insert ( int slotIndex , TSlot slot )
61+ {
62+ if ( slotIndex != slot . Slot )
63+ {
64+ throw new ArgumentException ( $ "Tried to insert slot { slot . Slot } to slot index { slotIndex } ", nameof ( slotIndex ) ) ;
65+ }
66+
67+ _slots . Add ( slotIndex , slot ) ;
68+ }
69+
70+ public void RemoveAt ( int slotIndex ) => _slots . Remove ( slotIndex ) ;
71+
72+ public TSlot this [ int slotIndex ]
73+ {
74+ get
75+ {
76+ if ( _slots . TryGetValue ( slotIndex , out var slot ) )
77+ {
78+ return slot ;
79+ }
80+
81+ slot = _factory ( slotIndex ) ;
82+ _slots [ slotIndex ] = slot ;
83+ return slot ;
84+ }
85+ set => _slots [ slotIndex ] = value ;
86+ }
87+
88+ public int FindIndex ( Func < TSlot , bool > predicate )
89+ {
90+ var copy = this . ToArray ( ) ;
91+ for ( var index = 0 ; index < copy . Length ; ++ index )
92+ {
93+ if ( predicate ( copy [ index ] ) )
94+ {
95+ return index ;
96+ }
97+ }
98+
99+ return - 1 ;
100+ }
101+ }
0 commit comments