コード例 #1
0
ファイル: SelectMany.cs プロジェクト: manofstick/Cistern.Linq
        public override bool MoveNext()
        {
            switch (_state)
            {
            case Start:
                _chain = _link.Compose(this);
                _link  = null;

                _outer      = _consumable.GetEnumerator();
                _consumable = null;

                _state = OuterEnumeratorMoveNext;
                goto case OuterEnumeratorMoveNext;

            case OuterEnumeratorMoveNext:
                if (_outer.MoveNext())
                {
                    _inner = _outer.Current.GetEnumerator();

                    if (ReferenceEquals(_chain, this))
                    {
                        _state = InnerEnumeratorMoveNextOnSelf;
                        goto case InnerEnumeratorMoveNextOnSelf;
                    }
                    else
                    {
                        _state = InnerEnumeratorMoveNext;
                        goto case InnerEnumeratorMoveNext;
                    }
                }

                _state = Completing;
                goto case Completing;

            case InnerEnumeratorMoveNextOnSelf:
                if (!_inner.MoveNext())
                {
                    _inner.Dispose();
                    _inner = default;
                    _state = OuterEnumeratorMoveNext;
                    goto case OuterEnumeratorMoveNext;
                }

                Result = (V)(object)_inner.Current;     // should be no-op as TResult should equal T
                return(true);

            case InnerEnumeratorMoveNext:
                if (_inner.MoveNext())
                {
                    _status = _chain.ProcessNext(_inner.Current);
                    if (_status.IsFlowing())
                    {
                        _state = CheckStopped;
                        return(true);
                    }

                    _state = CheckStopped;
                    goto case CheckStopped;
                }

                _inner.Dispose();
                _inner = null;

                _state = OuterEnumeratorMoveNext;
                goto case OuterEnumeratorMoveNext;

            case CheckStopped:
                if (_status.IsStopped())
                {
                    _inner.Dispose();
                    _inner = null;

                    _state = Completing;
                    goto case Completing;
                }

                _state = InnerEnumeratorMoveNext;
                goto case InnerEnumeratorMoveNext;

            case Completing:
                if (_chain.ChainComplete(status & ~ChainStatus.Flow).NotStoppedAndFlowing())
                {
                    _state = Finished;
                    return(true);
                }
                goto case Finished;

            case Finished:
                Result = default;

                _outer.Dispose();
                _outer = null;

                _chain.ChainDispose();
                _chain = null;

                _state = PostFinished;
                goto default;

            default:
                return(false);
            }
        }