18 using System.Collections;
19 using System.Collections.Generic;
31 private IEnumerator<T> _syncer;
32 private readonly IEnumerator<T>[] _enumerators;
56 object IEnumerator.Current
67 : this ((IEnumerable<IEnumerator<T>>)enumerators)
78 _enumerators = enumerators.ToArray();
79 _syncer = GetSynchronizedEnumerator(_enumerators);
91 var moveNext = _syncer.MoveNext();
92 Current = moveNext ? _syncer.Current :
default(T);
102 foreach (var enumerator
in _enumerators)
107 _syncer = GetSynchronizedEnumerator(_enumerators);
115 foreach (var enumerator
in _enumerators)
117 enumerator.Dispose();
127 private IEnumerator<T> GetSynchronizedEnumerator(IEnumerator<T>[] enumerators)
129 return GetBruteForceMethod(enumerators);
137 private IEnumerator<T> GetBruteForceMethod(IEnumerator<T>[] enumerators)
139 var ticks = DateTime.MaxValue.Ticks;
140 var collection =
new HashSet<IEnumerator<T>>();
141 foreach (var enumerator
in enumerators)
143 if (enumerator.MoveNext())
145 if (enumerator.Current !=
null)
149 collection.Add(enumerator);
153 enumerator.Dispose();
157 var frontier =
new DateTime(ticks);
158 var toRemove =
new List<IEnumerator<T>>();
159 while (collection.Count > 0)
161 var nextFrontierTicks = DateTime.MaxValue.Ticks;
162 foreach (var enumerator
in collection)
164 while (enumerator.Current ==
null ||
GetInstanceTime(enumerator.Current) <= frontier)
166 if (enumerator.Current !=
null)
168 yield
return enumerator.Current;
170 if (!enumerator.MoveNext())
172 toRemove.Add(enumerator);
175 if (enumerator.Current ==
null)
181 if (enumerator.Current !=
null)
183 nextFrontierTicks = Math.Min(nextFrontierTicks,
GetInstanceTime(enumerator.Current).Ticks);
187 if (toRemove.Count > 0)
189 foreach (var enumerator
in toRemove)
191 collection.Remove(enumerator);
196 frontier =
new DateTime(nextFrontierTicks);
197 if (frontier == DateTime.MaxValue)