@@ -11,6 +11,7 @@ public class SourceCollection : IEnumerable<ComparisonSource>
1111 {
1212 private const int SOURCE_REMOVED = - 1 ;
1313 private const int SOURCE_UNMATCHED = 0 ;
14+ private const int SOURCE_MATCHED = 1 ;
1415
1516 private readonly int [ ] _status ;
1617 private ComparisonSource [ ] _sources ;
@@ -21,7 +22,12 @@ public class SourceCollection : IEnumerable<ComparisonSource>
2122
2223 public ComparisonSource this [ int index ]
2324 {
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+ }
2531 }
2632
2733 public SourceCollection ( ComparisonSourceType sourceType , IEnumerable < ComparisonSource > sources )
@@ -49,21 +55,37 @@ public IEnumerator<ComparisonSource> GetEnumerator()
4955 {
5056 for ( int i = 0 ; i < _sources . Length ; i ++ )
5157 {
52- yield return _sources [ i ] ;
58+ if ( _status [ _sources [ i ] . Index ] != SOURCE_REMOVED )
59+ {
60+ yield return _sources [ i ] ;
61+ }
5362 }
5463 yield break ;
5564 }
5665
5766 IEnumerator IEnumerable . GetEnumerator ( ) => GetEnumerator ( ) ;
5867
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>
5976 public void MarkAsMatched ( in ComparisonSource source )
6077 {
6178 if ( _status [ source . Index ] == SOURCE_REMOVED )
6279 throw new InvalidOperationException ( "A removed source cannot be marked as matched. The source is not supposed to be part of the comparison." ) ;
6380
64- _status [ source . Index ] ++ ;
81+ _status [ source . Index ] = SOURCE_MATCHED ;
6582 }
6683
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>
6789 public void Remove ( SourceCollectionRemovePredicate predicate )
6890 {
6991 for ( int i = 0 ; i < _sources . Length ; i ++ )
@@ -75,18 +97,6 @@ public void Remove(SourceCollectionRemovePredicate predicate)
7597 Count -- ;
7698 }
7799 }
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- }
90100 }
91101
92102 private void EnsureSourcesAreInCorrectOrder ( )
0 commit comments