// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT License. // See the LICENSE file in the project root for more information. using System.Collections.Generic; using System.Reactive.Concurrency; using System.Threading; using System.Threading.Tasks; namespace System.Reactive.Linq { using ObservableImpl; internal partial class QueryLanguage { #region + Cast + public virtual IObservable Cast(IObservable source) { return new Cast(source); } #endregion #region + DefaultIfEmpty + public virtual IObservable DefaultIfEmpty(IObservable source) { return new DefaultIfEmpty(source, default!); } public virtual IObservable DefaultIfEmpty(IObservable source, TSource defaultValue) { return new DefaultIfEmpty(source, defaultValue); } #endregion #region + Distinct + public virtual IObservable Distinct(IObservable source) { return new Distinct(source, x => x, EqualityComparer.Default); } public virtual IObservable Distinct(IObservable source, IEqualityComparer comparer) { return new Distinct(source, x => x, comparer); } public virtual IObservable Distinct(IObservable source, Func keySelector) { return new Distinct(source, keySelector, EqualityComparer.Default); } public virtual IObservable Distinct(IObservable source, Func keySelector, IEqualityComparer comparer) { return new Distinct(source, keySelector, comparer); } #endregion #region + GroupBy + public virtual IObservable> GroupBy(IObservable source, Func keySelector, Func elementSelector) { return GroupBy_(source, keySelector, elementSelector, null, EqualityComparer.Default); } public virtual IObservable> GroupBy(IObservable source, Func keySelector, IEqualityComparer comparer) { return GroupBy_(source, keySelector, x => x, null, comparer); } public virtual IObservable> GroupBy(IObservable source, Func keySelector) { return GroupBy_(source, keySelector, x => x, null, EqualityComparer.Default); } public virtual IObservable> GroupBy(IObservable source, Func keySelector, Func elementSelector, IEqualityComparer comparer) { return GroupBy_(source, keySelector, elementSelector, null, comparer); } public virtual IObservable> GroupBy(IObservable source, Func keySelector, Func elementSelector, int capacity) { return GroupBy_(source, keySelector, elementSelector, capacity, EqualityComparer.Default); } public virtual IObservable> GroupBy(IObservable source, Func keySelector, int capacity, IEqualityComparer comparer) { return GroupBy_(source, keySelector, x => x, capacity, comparer); } public virtual IObservable> GroupBy(IObservable source, Func keySelector, int capacity) { return GroupBy_(source, keySelector, x => x, capacity, EqualityComparer.Default); } public virtual IObservable> GroupBy(IObservable source, Func keySelector, Func elementSelector, int capacity, IEqualityComparer comparer) { return GroupBy_(source, keySelector, elementSelector, capacity, comparer); } private static IObservable> GroupBy_(IObservable source, Func keySelector, Func elementSelector, int? capacity, IEqualityComparer comparer) { return new GroupBy(source, keySelector, elementSelector, capacity, comparer); } #endregion #region + GroupByUntil + public virtual IObservable> GroupByUntil(IObservable source, Func keySelector, Func elementSelector, Func, IObservable> durationSelector, IEqualityComparer comparer) { return GroupByUntil_(source, keySelector, elementSelector, durationSelector, null, comparer); } public virtual IObservable> GroupByUntil(IObservable source, Func keySelector, Func elementSelector, Func, IObservable> durationSelector) { return GroupByUntil_(source, keySelector, elementSelector, durationSelector, null, EqualityComparer.Default); } public virtual IObservable> GroupByUntil(IObservable source, Func keySelector, Func, IObservable> durationSelector, IEqualityComparer comparer) { return GroupByUntil_(source, keySelector, x => x, durationSelector, null, comparer); } public virtual IObservable> GroupByUntil(IObservable source, Func keySelector, Func, IObservable> durationSelector) { return GroupByUntil_(source, keySelector, x => x, durationSelector, null, EqualityComparer.Default); } public virtual IObservable> GroupByUntil(IObservable source, Func keySelector, Func elementSelector, Func, IObservable> durationSelector, int capacity, IEqualityComparer comparer) { return GroupByUntil_(source, keySelector, elementSelector, durationSelector, capacity, comparer); } public virtual IObservable> GroupByUntil(IObservable source, Func keySelector, Func elementSelector, Func, IObservable> durationSelector, int capacity) { return GroupByUntil_(source, keySelector, elementSelector, durationSelector, capacity, EqualityComparer.Default); } public virtual IObservable> GroupByUntil(IObservable source, Func keySelector, Func, IObservable> durationSelector, int capacity, IEqualityComparer comparer) { return GroupByUntil_(source, keySelector, x => x, durationSelector, capacity, comparer); } public virtual IObservable> GroupByUntil(IObservable source, Func keySelector, Func, IObservable> durationSelector, int capacity) { return GroupByUntil_(source, keySelector, x => x, durationSelector, capacity, EqualityComparer.Default); } private static IObservable> GroupByUntil_(IObservable source, Func keySelector, Func elementSelector, Func, IObservable> durationSelector, int? capacity, IEqualityComparer comparer) { return new GroupByUntil(source, keySelector, elementSelector, durationSelector, capacity, comparer); } #endregion #region + GroupJoin + public virtual IObservable GroupJoin(IObservable left, IObservable right, Func> leftDurationSelector, Func> rightDurationSelector, Func, TResult> resultSelector) { return GroupJoin_(left, right, leftDurationSelector, rightDurationSelector, resultSelector); } private static IObservable GroupJoin_(IObservable left, IObservable right, Func> leftDurationSelector, Func> rightDurationSelector, Func, TResult> resultSelector) { return new GroupJoin(left, right, leftDurationSelector, rightDurationSelector, resultSelector); } #endregion #region + Join + public virtual IObservable Join(IObservable left, IObservable right, Func> leftDurationSelector, Func> rightDurationSelector, Func resultSelector) { return Join_(left, right, leftDurationSelector, rightDurationSelector, resultSelector); } private static IObservable Join_(IObservable left, IObservable right, Func> leftDurationSelector, Func> rightDurationSelector, Func resultSelector) { return new Join(left, right, leftDurationSelector, rightDurationSelector, resultSelector); } #endregion #region + OfType + public virtual IObservable OfType(IObservable source) { return new OfType(source); } #endregion #region + Select + public virtual IObservable Select(IObservable source, Func selector) { // CONSIDER: Add fusion for Select/Select pairs. return new Select.Selector(source, selector); } public virtual IObservable Select(IObservable source, Func selector) { return new Select.SelectorIndexed(source, selector); } #endregion #region + SelectMany + public virtual IObservable SelectMany(IObservable source, IObservable other) { return SelectMany_(source, _ => other); } public virtual IObservable SelectMany(IObservable source, Func> selector) { return SelectMany_(source, selector); } public virtual IObservable SelectMany(IObservable source, Func> selector) { return SelectMany_(source, selector); } public virtual IObservable SelectMany(IObservable source, Func> selector) { return new SelectMany.TaskSelector(source, (x, token) => selector(x)); } public virtual IObservable SelectMany(IObservable source, Func> selector) { return new SelectMany.TaskSelectorIndexed(source, (x, i, token) => selector(x, i)); } public virtual IObservable SelectMany(IObservable source, Func> selector) { return new SelectMany.TaskSelector(source, selector); } public virtual IObservable SelectMany(IObservable source, Func> selector) { return new SelectMany.TaskSelectorIndexed(source, selector); } public virtual IObservable SelectMany(IObservable source, Func> collectionSelector, Func resultSelector) { return SelectMany_(source, collectionSelector, resultSelector); } public virtual IObservable SelectMany(IObservable source, Func> collectionSelector, Func resultSelector) { return SelectMany_(source, collectionSelector, resultSelector); } public virtual IObservable SelectMany(IObservable source, Func> taskSelector, Func resultSelector) { return new SelectMany.TaskSelector(source, (x, token) => taskSelector(x), resultSelector); } public virtual IObservable SelectMany(IObservable source, Func> taskSelector, Func resultSelector) { return new SelectMany.TaskSelectorIndexed(source, (x, i, token) => taskSelector(x, i), resultSelector); } public virtual IObservable SelectMany(IObservable source, Func> taskSelector, Func resultSelector) { return new SelectMany.TaskSelector(source, taskSelector, resultSelector); } public virtual IObservable SelectMany(IObservable source, Func> taskSelector, Func resultSelector) { return new SelectMany.TaskSelectorIndexed(source, taskSelector, resultSelector); } private static IObservable SelectMany_(IObservable source, Func> selector) { return new SelectMany.ObservableSelector(source, selector); } private static IObservable SelectMany_(IObservable source, Func> selector) { return new SelectMany.ObservableSelectorIndexed(source, selector); } private static IObservable SelectMany_(IObservable source, Func> collectionSelector, Func resultSelector) { return new SelectMany.ObservableSelector(source, collectionSelector, resultSelector); } private static IObservable SelectMany_(IObservable source, Func> collectionSelector, Func resultSelector) { return new SelectMany.ObservableSelectorIndexed(source, collectionSelector, resultSelector); } public virtual IObservable SelectMany(IObservable source, Func> onNext, Func> onError, Func> onCompleted) { return new SelectMany.ObservableSelectors(source, onNext, onError, onCompleted); } public virtual IObservable SelectMany(IObservable source, Func> onNext, Func> onError, Func> onCompleted) { return new SelectMany.ObservableSelectorsIndexed(source, onNext, onError, onCompleted); } public virtual IObservable SelectMany(IObservable source, Func> selector) { return new SelectMany.EnumerableSelector(source, selector); } public virtual IObservable SelectMany(IObservable source, Func> selector) { return new SelectMany.EnumerableSelectorIndexed(source, selector); } public virtual IObservable SelectMany(IObservable source, Func> collectionSelector, Func resultSelector) { return SelectMany_(source, collectionSelector, resultSelector); } public virtual IObservable SelectMany(IObservable source, Func> collectionSelector, Func resultSelector) { return SelectMany_(source, collectionSelector, resultSelector); } private static IObservable SelectMany_(IObservable source, Func> collectionSelector, Func resultSelector) { return new SelectMany.EnumerableSelector(source, collectionSelector, resultSelector); } private static IObservable SelectMany_(IObservable source, Func> collectionSelector, Func resultSelector) { return new SelectMany.EnumerableSelectorIndexed(source, collectionSelector, resultSelector); } #endregion #region + Skip + public virtual IObservable Skip(IObservable source, int count) { if (source is Skip.Count skip) { return skip.Combine(count); } return new Skip.Count(source, count); } #endregion #region + SkipWhile + public virtual IObservable SkipWhile(IObservable source, Func predicate) { return new SkipWhile.Predicate(source, predicate); } public virtual IObservable SkipWhile(IObservable source, Func predicate) { return new SkipWhile.PredicateIndexed(source, predicate); } #endregion #region + Take + public virtual IObservable Take(IObservable source, int count) { if (count == 0) { return Empty(); } return Take_(source, count); } public virtual IObservable Take(IObservable source, int count, IScheduler scheduler) { if (count == 0) { return Empty(scheduler); } return Take_(source, count); } private static IObservable Take_(IObservable source, int count) { if (source is Take.Count take) { return take.Combine(count); } return new Take.Count(source, count); } #endregion #region + TakeWhile + public virtual IObservable TakeWhile(IObservable source, Func predicate) { return new TakeWhile.Predicate(source, predicate); } public virtual IObservable TakeWhile(IObservable source, Func predicate) { return new TakeWhile.PredicateIndexed(source, predicate); } #endregion #region + Where + public virtual IObservable Where(IObservable source, Func predicate) { if (source is Where.Predicate where) { return where.Combine(predicate); } return new Where.Predicate(source, predicate); } public virtual IObservable Where(IObservable source, Func predicate) { return new Where.PredicateIndexed(source, predicate); } #endregion } }