1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-21 01:18:02 +02:00

Enhanced ranges

This commit is contained in:
Brian Fiete 2021-10-24 08:12:18 -07:00
parent eec2cb5e6c
commit 27fd5552cc
12 changed files with 365 additions and 22 deletions

View file

@ -260,6 +260,17 @@ namespace System
}
}
public Span<T> this[IndexRange range]
{
#if !DEBUG
[Inline]
#endif
get
{
return Span<T>(&mFirstElement, mLength)[range];
}
}
[Inline]
public T* CArray()
{

View file

@ -211,6 +211,17 @@ namespace System.Collections
}
}
public Span<T> this[IndexRange range]
{
#if !DEBUG
[Inline]
#endif
get
{
return Span<T>(mItems, mSize)[range];
}
}
public ref T Front
{
get

View file

@ -8,6 +8,24 @@ namespace System
}
enum Index
{
case FromFront(int offset);
case FromEnd(int offset);
public override void ToString(String strBuffer)
{
switch (this)
{
case .FromFront(let offset):
offset.ToString(strBuffer);
case .FromEnd(let offset):
strBuffer.Append('^');
offset.ToString(strBuffer);
}
}
}
struct Range : RangeExpression, IEnumerable<int>
{
protected int mStart;
@ -110,6 +128,11 @@ namespace System
mEnd = 0;
}
public static operator IndexRange(Range list)
{
return .(.FromFront(list.mStart), .FromFront(list.mEnd), false);
}
[Inline]
public Enumerator GetEnumerator()
{
@ -192,6 +215,103 @@ namespace System
}
}
struct IndexRange : RangeExpression
{
public Index mStart;
public Index mEnd;
public bool mIsClosed;
public this()
{
this = default;
}
[Inline]
public this(Index start, Index end, bool isClosed=true)
{
mStart = start;
mEnd = end;
mIsClosed = isClosed;
}
[Inline]
public this(int start, Index end, bool isClosed=true)
{
mStart = .FromFront(start);
mEnd = end;
mIsClosed = isClosed;
}
[Inline]
public this(Index start, int end, bool isClosed=true)
{
mStart = start;
mEnd = .FromFront(end);
mIsClosed = isClosed;
}
[Inline]
public this(int start, int end, bool isClosed=true)
{
mStart = .FromFront(start);
mEnd = .FromFront(end);
mIsClosed = isClosed;
}
public Index Start
{
[Inline]
get
{
return mStart;
}
[Inline]
set mut
{
mStart = value;
}
}
public Index End
{
[Inline]
get
{
return mEnd;
}
set mut
{
mEnd = value;
}
}
public bool IsClosed
{
[Inline]
get
{
return mIsClosed;
}
set mut
{
mIsClosed = value;
}
}
public override void ToString(String strBuffer)
{
mStart.ToString(strBuffer);
if (mIsClosed)
strBuffer.Append("...");
else
strBuffer.Append("..<");
mEnd.ToString(strBuffer);
}
}
struct ClosedRange : RangeExpression, IEnumerable<int>
{
protected int mStart;
@ -294,6 +414,11 @@ namespace System
mEnd = 0;
}
public static operator IndexRange(ClosedRange list)
{
return .(.FromFront(list.mStart), .FromFront(list.mEnd), true);
}
[Inline]
public Enumerator GetEnumerator()
{

View file

@ -134,6 +134,53 @@ namespace System
}
}
public Span<T> this[IndexRange range]
{
#if !DEBUG
[Inline]
#endif
get
{
T* start;
switch (range.mStart)
{
case .FromFront(let offset):
Debug.Assert((uint)offset <= (uint)mLength);
start = mPtr + offset;
case .FromEnd(let offset):
Debug.Assert((uint)offset <= (uint)mLength);
start = mPtr + mLength - 1 - offset;
}
T* end;
if (range.mIsClosed)
{
switch (range.mEnd)
{
case .FromFront(let offset):
Debug.Assert((uint)offset < (uint)mLength);
end = mPtr + offset + 1;
case .FromEnd(let offset):
Debug.Assert((uint)offset < (uint)mLength);
end = mPtr + mLength - offset;
}
}
else
{
switch (range.mEnd)
{
case .FromFront(let offset):
Debug.Assert((uint)offset <= (uint)mLength);
end = mPtr + offset;
case .FromEnd(let offset):
Debug.Assert((uint)offset <= (uint)mLength);
end = mPtr + mLength - 1 - offset;
}
}
return .(start, end - start);
}
}
public Span<T> Slice(int index)
{
Debug.Assert((uint)index <= (uint)mLength);