// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;
using System.Threading.Tasks;
namespace System.Linq
{
///
/// Interface for yielding elements to enumerator.
///
/// Type of the elements yielded to an enumerator.
public interface IYielder
{
///
/// Stops the enumeration.
///
/// Awaitable object for use in an asynchronous method.
IAwaitable Break();
///
/// Yields a value to the enumerator.
///
/// Value to yield return.
/// Awaitable object for use in an asynchronous method.
IAwaitable Return(T value);
}
internal class Yielder : IYielder, IAwaitable, IAwaiter
{
private readonly Action> _create;
private Action _continuation;
private bool _hasValue;
private bool _running;
private bool _stopped;
public Yielder(Action> create)
{
_create = create;
}
public T Current { get; private set; }
public IAwaiter GetAwaiter()
{
return this;
}
public bool IsCompleted
{
get { return false; }
}
public void GetResult()
{
}
[SecurityCritical]
public void UnsafeOnCompleted(Action continuation)
{
_continuation = continuation;
}
public void OnCompleted(Action continuation)
{
_continuation = continuation;
}
public IAwaitable Return(T value)
{
_hasValue = true;
Current = value;
return this;
}
public IAwaitable Break()
{
_stopped = true;
return this;
}
public Yielder GetEnumerator()
{
return this;
}
public bool MoveNext()
{
if (!_running)
{
_running = true;
_create(this);
}
else
{
_hasValue = false;
_continuation();
}
return !_stopped && _hasValue;
}
public void Reset()
{
throw new NotSupportedException();
}
}
}