// 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.Threading.Tasks;
namespace System.Linq
{
public static partial class EnumerableEx
{
///
/// Generates a sequence of non-overlapping adjacent buffers over the source sequence.
///
/// Source sequence element type.
/// Source sequence.
/// Number of elements for allocated buffers.
/// Sequence of buffers containing source sequence elements.
public static IEnumerable> Buffer(this IEnumerable source, int count)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (count <= 0)
throw new ArgumentOutOfRangeException(nameof(count));
return source.Buffer_(count, count);
}
///
/// Generates a sequence of buffers over the source sequence, with specified length and possible overlap.
///
/// Source sequence element type.
/// Source sequence.
/// Number of elements for allocated buffers.
/// Number of elements to skip between the start of consecutive buffers.
/// Sequence of buffers containing source sequence elements.
public static IEnumerable> Buffer(this IEnumerable source, int count, int skip)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (count <= 0)
throw new ArgumentOutOfRangeException(nameof(count));
if (skip <= 0)
throw new ArgumentOutOfRangeException(nameof(skip));
return source.Buffer_(count, skip);
}
private static IEnumerable> Buffer_(this IEnumerable source, int count, int skip)
{
var buffers = new Queue>();
var i = 0;
foreach (var item in source)
{
if (i%skip == 0)
buffers.Enqueue(new List(count));
foreach (var buffer in buffers)
buffer.Add(item);
if (buffers.Count > 0 && buffers.Peek()
.Count == count)
yield return buffers.Dequeue();
i++;
}
while (buffers.Count > 0)
yield return buffers.Dequeue();
}
}
///
/// Represents a buffer exposing a shared view over an underlying enumerable sequence.
///
/// Element type.
public interface IBuffer : IEnumerable, IDisposable
{
}
}