using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace Loyc.Collections
{
public static class Range
{
/// <summary>Advances by the specified number of elements.</summary>
/// <param name="count">Number of items to remove from the beginning of the
/// range. If count is higher than the number of items in the range, no
/// exception is thrown but the return value will be less than this value.</param>
/// <returns>Returns the number of items skipped.</returns>
public static int Skip<R, T>(ref R range, int count) where R : IFRange<T>
{
bool fail;
for (int i = 0; i < count; i++) {
range.PopFront(out fail);
if (fail) return i;
}
return count;
}
public static int DropLast<R, T>(ref R range, int count) where R : IBRange<T>
{
bool fail;
for (int i = 0; i < count; i++)
{
range.PopBack(out fail);
if (fail) return i;
}
return count;
}
public static T PopFirst<R, T>(ref R range, T defaultValue) where R : IFRange<T>
{
bool fail;
T next = range.PopFront(out fail);
if (!fail)
return next;
else
return defaultValue;
}
public static T PopFirst<R,T>(ref R range) where R:IFRange<T>
{
bool fail;
T next = range.PopFront(out fail);
if (fail) throw new EmptySequenceException();
return next;
}
public static T PopLast<R, T>(ref R range, T defaultValue) where R : IBRange<T>
{
bool fail;
T next = range.PopBack(out fail);
if (!fail)
return next;
else
return defaultValue;
}
public static T PopLast<R, T>(ref R range) where R : IBRange<T>
{
bool fail;
T next = range.PopBack(out fail);
if (fail) throw new EmptySequenceException();
return next;
}
public static bool Contains<R,T>(this R range, IRangeEx<R,T> other) where R : IRangeEx<R,T>, ICloneable<R>
{
int r0 = range.SliceStart, o0 = other.SliceStart;
return r0 <= o0 && r0 + range.Count >= o0 + other.Count
&& object.Equals(range.InnerList, other.InnerList);
}
public static bool Overlaps<R, T>(this R range, IRangeEx<R, T> other) where R : IRangeEx<R,T>, ICloneable<R>
{
int r0 = range.SliceStart, r1 = r0 + range.Count;
int o0 = other.SliceStart, o1 = o0 + other.Count;
return r1 > o0 && o1 > r0
&& object.Equals(range.InnerList, other.InnerList);
}
public static Repeated<T> Repeat<T>(T value, int count)
{
return new Repeated<T>(value, count);
}
public static Repeated<T> Single<T>(T value)
{
return new Repeated<T>(value, 1);
}
/// <summary>Returns <c>new IntRange(start, count)</c>.</summary>
public static IntRange IntRange(int start, int count)
{
return new IntRange(start, count);
}
}
}