@@ -11,6 +11,7 @@ public class SourceCollection : IEnumerable<ComparisonSource>
11
11
{
12
12
private const int SOURCE_REMOVED = - 1 ;
13
13
private const int SOURCE_UNMATCHED = 0 ;
14
+ private const int SOURCE_MATCHED = 1 ;
14
15
15
16
private readonly int [ ] _status ;
16
17
private ComparisonSource [ ] _sources ;
@@ -21,7 +22,12 @@ public class SourceCollection : IEnumerable<ComparisonSource>
21
22
22
23
public ComparisonSource this [ int index ]
23
24
{
24
- get => _sources [ index ] ;
25
+ get
26
+ {
27
+ if ( _status [ _sources [ index ] . Index ] == SOURCE_REMOVED )
28
+ throw new InvalidOperationException ( "The source at the specified index has been removed." ) ;
29
+ return _sources [ index ] ;
30
+ }
25
31
}
26
32
27
33
public SourceCollection ( ComparisonSourceType sourceType , IEnumerable < ComparisonSource > sources )
@@ -49,21 +55,37 @@ public IEnumerator<ComparisonSource> GetEnumerator()
49
55
{
50
56
for ( int i = 0 ; i < _sources . Length ; i ++ )
51
57
{
52
- yield return _sources [ i ] ;
58
+ if ( _status [ _sources [ i ] . Index ] != SOURCE_REMOVED )
59
+ {
60
+ yield return _sources [ i ] ;
61
+ }
53
62
}
54
63
yield break ;
55
64
}
56
65
57
66
IEnumerator IEnumerable . GetEnumerator ( ) => GetEnumerator ( ) ;
58
67
68
+ /// <summary>
69
+ /// Gets all the sources originally in the collection, even those removed and those marked as matched.
70
+ /// </summary>
71
+ public IEnumerable < ComparisonSource > GetAllSources ( ) => _sources ;
72
+
73
+ /// <summary>
74
+ /// Mark a source as matched. After it has been marked, it will not be returned by <see cref="GetUnmatched(int)"/>.
75
+ /// </summary>
59
76
public void MarkAsMatched ( in ComparisonSource source )
60
77
{
61
78
if ( _status [ source . Index ] == SOURCE_REMOVED )
62
79
throw new InvalidOperationException ( "A removed source cannot be marked as matched. The source is not supposed to be part of the comparison." ) ;
63
80
64
- _status [ source . Index ] ++ ;
81
+ _status [ source . Index ] = SOURCE_MATCHED ;
65
82
}
66
83
84
+ /// <summary>
85
+ /// Apply a filter predicate to the collection. All matched sources will not be returned
86
+ /// by <see cref="GetUnmatched(int)"/> or by <see cref="GetEnumerator"/>.
87
+ /// </summary>
88
+ /// <param name="predicate"></param>
67
89
public void Remove ( SourceCollectionRemovePredicate predicate )
68
90
{
69
91
for ( int i = 0 ; i < _sources . Length ; i ++ )
@@ -75,18 +97,6 @@ public void Remove(SourceCollectionRemovePredicate predicate)
75
97
Count -- ;
76
98
}
77
99
}
78
- var oldSources = _sources ;
79
- _sources = Count == 0 ? Array . Empty < ComparisonSource > ( ) : new ComparisonSource [ Count ] ;
80
- if ( Count > 0 )
81
- {
82
- for ( int i = 0 , j = 0 ; i < oldSources . Length ; i ++ )
83
- {
84
- if ( _status [ i ] != SOURCE_REMOVED )
85
- {
86
- _sources [ j ++ ] = oldSources [ i ] ;
87
- }
88
- }
89
- }
90
100
}
91
101
92
102
private void EnsureSourcesAreInCorrectOrder ( )
0 commit comments