|
- using Cysharp.Threading.Tasks.Internal;
- using System;
- using System.Collections.Generic;
- using System.Threading;
-
- namespace Cysharp.Threading.Tasks.Linq
- {
- public static partial class UniTaskAsyncEnumerable
- {
- public static IUniTaskAsyncEnumerable<TSource> Distinct<TSource>(this IUniTaskAsyncEnumerable<TSource> source)
- {
- return Distinct(source, EqualityComparer<TSource>.Default);
- }
-
- public static IUniTaskAsyncEnumerable<TSource> Distinct<TSource>(this IUniTaskAsyncEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(comparer, nameof(comparer));
-
- return new Distinct<TSource>(source, comparer);
- }
-
- public static IUniTaskAsyncEnumerable<TSource> Distinct<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector)
- {
- return Distinct(source, keySelector, EqualityComparer<TKey>.Default);
- }
-
- public static IUniTaskAsyncEnumerable<TSource> Distinct<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(comparer, nameof(comparer));
-
- return new Distinct<TSource, TKey>(source, keySelector, comparer);
- }
-
- public static IUniTaskAsyncEnumerable<TSource> DistinctAwait<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector)
- {
- return DistinctAwait(source, keySelector, EqualityComparer<TKey>.Default);
- }
-
- public static IUniTaskAsyncEnumerable<TSource> DistinctAwait<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, IEqualityComparer<TKey> comparer)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(comparer, nameof(comparer));
-
- return new DistinctAwait<TSource, TKey>(source, keySelector, comparer);
- }
-
- public static IUniTaskAsyncEnumerable<TSource> DistinctAwaitWithCancellation<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector)
- {
- return DistinctAwaitWithCancellation(source, keySelector, EqualityComparer<TKey>.Default);
- }
-
- public static IUniTaskAsyncEnumerable<TSource> DistinctAwaitWithCancellation<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, IEqualityComparer<TKey> comparer)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(comparer, nameof(comparer));
-
- return new DistinctAwaitWithCancellation<TSource, TKey>(source, keySelector, comparer);
- }
- }
-
- internal sealed class Distinct<TSource> : IUniTaskAsyncEnumerable<TSource>
- {
- readonly IUniTaskAsyncEnumerable<TSource> source;
- readonly IEqualityComparer<TSource> comparer;
-
- public Distinct(IUniTaskAsyncEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
- {
- this.source = source;
- this.comparer = comparer;
- }
-
- public IUniTaskAsyncEnumerator<TSource> GetAsyncEnumerator(CancellationToken cancellationToken = default)
- {
- return new _Distinct(source, comparer, cancellationToken);
- }
-
- class _Distinct : AsyncEnumeratorBase<TSource, TSource>
- {
- readonly HashSet<TSource> set;
-
- public _Distinct(IUniTaskAsyncEnumerable<TSource> source, IEqualityComparer<TSource> comparer, CancellationToken cancellationToken)
-
- : base(source, cancellationToken)
- {
- this.set = new HashSet<TSource>(comparer);
- }
-
- protected override bool TryMoveNextCore(bool sourceHasCurrent, out bool result)
- {
- if (sourceHasCurrent)
- {
- var v = SourceCurrent;
- if (set.Add(v))
- {
- Current = v;
- result = true;
- return true;
- }
- else
- {
- result = default;
- return false;
- }
- }
-
- result = false;
- return true;
- }
- }
- }
-
- internal sealed class Distinct<TSource, TKey> : IUniTaskAsyncEnumerable<TSource>
- {
- readonly IUniTaskAsyncEnumerable<TSource> source;
- readonly Func<TSource, TKey> keySelector;
- readonly IEqualityComparer<TKey> comparer;
-
- public Distinct(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
- {
- this.source = source;
- this.keySelector = keySelector;
- this.comparer = comparer;
- }
-
- public IUniTaskAsyncEnumerator<TSource> GetAsyncEnumerator(CancellationToken cancellationToken = default)
- {
- return new _Distinct(source, keySelector, comparer, cancellationToken);
- }
-
- class _Distinct : AsyncEnumeratorBase<TSource, TSource>
- {
- readonly HashSet<TKey> set;
- readonly Func<TSource, TKey> keySelector;
-
- public _Distinct(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken)
-
- : base(source, cancellationToken)
- {
- this.set = new HashSet<TKey>(comparer);
- this.keySelector = keySelector;
- }
-
- protected override bool TryMoveNextCore(bool sourceHasCurrent, out bool result)
- {
- if (sourceHasCurrent)
- {
- var v = SourceCurrent;
- if (set.Add(keySelector(v)))
- {
- Current = v;
- result = true;
- return true;
- }
- else
- {
- result = default;
- return false;
- }
- }
-
- result = false;
- return true;
- }
- }
- }
-
- internal sealed class DistinctAwait<TSource, TKey> : IUniTaskAsyncEnumerable<TSource>
- {
- readonly IUniTaskAsyncEnumerable<TSource> source;
- readonly Func<TSource, UniTask<TKey>> keySelector;
- readonly IEqualityComparer<TKey> comparer;
-
- public DistinctAwait(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, IEqualityComparer<TKey> comparer)
- {
- this.source = source;
- this.keySelector = keySelector;
- this.comparer = comparer;
- }
-
- public IUniTaskAsyncEnumerator<TSource> GetAsyncEnumerator(CancellationToken cancellationToken = default)
- {
- return new _DistinctAwait(source, keySelector, comparer, cancellationToken);
- }
-
- class _DistinctAwait : AsyncEnumeratorAwaitSelectorBase<TSource, TSource, TKey>
- {
- readonly HashSet<TKey> set;
- readonly Func<TSource, UniTask<TKey>> keySelector;
-
- public _DistinctAwait(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken)
-
- : base(source, cancellationToken)
- {
- this.set = new HashSet<TKey>(comparer);
- this.keySelector = keySelector;
- }
-
- protected override UniTask<TKey> TransformAsync(TSource sourceCurrent)
- {
- return keySelector(sourceCurrent);
- }
-
- protected override bool TrySetCurrentCore(TKey awaitResult, out bool terminateIteration)
- {
- if (set.Add(awaitResult))
- {
- Current = SourceCurrent;
- terminateIteration = false;
- return true;
- }
- else
- {
- terminateIteration = false;
- return false;
- }
- }
- }
- }
-
- internal sealed class DistinctAwaitWithCancellation<TSource, TKey> : IUniTaskAsyncEnumerable<TSource>
- {
- readonly IUniTaskAsyncEnumerable<TSource> source;
- readonly Func<TSource, CancellationToken, UniTask<TKey>> keySelector;
- readonly IEqualityComparer<TKey> comparer;
-
- public DistinctAwaitWithCancellation(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, IEqualityComparer<TKey> comparer)
- {
- this.source = source;
- this.keySelector = keySelector;
- this.comparer = comparer;
- }
-
- public IUniTaskAsyncEnumerator<TSource> GetAsyncEnumerator(CancellationToken cancellationToken = default)
- {
- return new _DistinctAwaitWithCancellation(source, keySelector, comparer, cancellationToken);
- }
-
- class _DistinctAwaitWithCancellation : AsyncEnumeratorAwaitSelectorBase<TSource, TSource, TKey>
- {
- readonly HashSet<TKey> set;
- readonly Func<TSource, CancellationToken, UniTask<TKey>> keySelector;
-
- public _DistinctAwaitWithCancellation(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken)
-
- : base(source, cancellationToken)
- {
- this.set = new HashSet<TKey>(comparer);
- this.keySelector = keySelector;
- }
-
- protected override UniTask<TKey> TransformAsync(TSource sourceCurrent)
- {
- return keySelector(sourceCurrent, cancellationToken);
- }
-
- protected override bool TrySetCurrentCore(TKey awaitResult, out bool terminateIteration)
- {
- if (set.Add(awaitResult))
- {
- Current = SourceCurrent;
- terminateIteration = false;
- return true;
- }
- else
- {
- terminateIteration = false;
- return false;
- }
- }
- }
- }
- }
|