2021-09-27 12:42:46 +00:00
|
|
|
using System;
|
|
|
|
using System.Collections;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
namespace Wabbajack.Common;
|
|
|
|
|
|
|
|
public struct ReadOnlyMemorySlice<T> : IEnumerable<T>
|
2021-09-27 12:42:46 +00:00
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
private T[] _arr;
|
|
|
|
public int Length { get; private set; }
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
public int StartPosition { get; private set; }
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
[DebuggerStepThrough]
|
|
|
|
public ReadOnlyMemorySlice(T[] arr)
|
|
|
|
{
|
|
|
|
_arr = arr;
|
|
|
|
StartPosition = 0;
|
|
|
|
Length = arr.Length;
|
|
|
|
}
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
[DebuggerStepThrough]
|
|
|
|
public ReadOnlyMemorySlice(T[] arr, int startPos, int length)
|
|
|
|
{
|
|
|
|
_arr = arr;
|
|
|
|
StartPosition = startPos;
|
|
|
|
Length = length;
|
|
|
|
}
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
public ReadOnlySpan<T> Span => _arr.AsSpan(StartPosition, Length);
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
public T this[int index] => _arr[index + StartPosition];
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
[DebuggerStepThrough]
|
|
|
|
public ReadOnlyMemorySlice<T> Slice(int start)
|
|
|
|
{
|
|
|
|
var startPos = StartPosition + start;
|
|
|
|
if (startPos < 0) throw new ArgumentOutOfRangeException();
|
|
|
|
return new ReadOnlyMemorySlice<T>
|
2021-09-27 12:42:46 +00:00
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
_arr = _arr,
|
|
|
|
StartPosition = StartPosition + start,
|
|
|
|
Length = Length - start
|
|
|
|
};
|
|
|
|
}
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
[DebuggerStepThrough]
|
|
|
|
public ReadOnlyMemorySlice<T> Slice(int start, int length)
|
|
|
|
{
|
|
|
|
var startPos = StartPosition + start;
|
|
|
|
if (startPos < 0) throw new ArgumentOutOfRangeException();
|
|
|
|
if (startPos + length > _arr.Length) throw new ArgumentOutOfRangeException();
|
|
|
|
return new ReadOnlyMemorySlice<T>
|
2021-09-27 12:42:46 +00:00
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
_arr = _arr,
|
|
|
|
StartPosition = StartPosition + start,
|
|
|
|
Length = length
|
|
|
|
};
|
|
|
|
}
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
public IEnumerator<T> GetEnumerator()
|
|
|
|
{
|
|
|
|
for (var i = 0; i < Length; i++) yield return _arr[i + StartPosition];
|
|
|
|
}
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
|
|
{
|
|
|
|
return GetEnumerator();
|
|
|
|
}
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
public static implicit operator ReadOnlySpan<T>(ReadOnlyMemorySlice<T> mem)
|
|
|
|
{
|
|
|
|
return mem.Span;
|
|
|
|
}
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
public static implicit operator ReadOnlyMemorySlice<T>?(T[]? mem)
|
|
|
|
{
|
|
|
|
if (mem == null) return null;
|
|
|
|
return new ReadOnlyMemorySlice<T>(mem);
|
|
|
|
}
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
public static implicit operator ReadOnlyMemorySlice<T>(T[] mem)
|
|
|
|
{
|
|
|
|
return new ReadOnlyMemorySlice<T>(mem);
|
2021-09-27 12:42:46 +00:00
|
|
|
}
|
|
|
|
}
|