mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Ported MemorySlice over from Noggog.CSharpExt
This commit is contained in:
parent
65ad0457ed
commit
9e6468d517
218
Wabbajack.Common/MemorySlice.cs
Normal file
218
Wabbajack.Common/MemorySlice.cs
Normal file
@ -0,0 +1,218 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
namespace Wabbajack.Common
|
||||
{
|
||||
public struct MemorySlice<T> : IEnumerable<T>
|
||||
{
|
||||
private T[] _arr;
|
||||
private int _startPos;
|
||||
private int _length;
|
||||
public int Length => _length;
|
||||
public int StartPosition => _startPos;
|
||||
|
||||
[DebuggerStepThrough]
|
||||
public MemorySlice(T[] arr)
|
||||
{
|
||||
this._arr = arr;
|
||||
this._startPos = 0;
|
||||
this._length = arr.Length;
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
public MemorySlice(T[] arr, int startPos, int length)
|
||||
{
|
||||
this._arr = arr;
|
||||
this._startPos = startPos;
|
||||
this._length = length;
|
||||
}
|
||||
|
||||
public Span<T> Span => _arr.AsSpan(start: _startPos, length: _length);
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
get => _arr[index + _startPos];
|
||||
set => _arr[index + _startPos] = value;
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
public MemorySlice<T> Slice(int start)
|
||||
{
|
||||
var startPos = _startPos + start;
|
||||
if (startPos < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
return new MemorySlice<T>()
|
||||
{
|
||||
_arr = _arr,
|
||||
_startPos = startPos,
|
||||
_length = _length - start
|
||||
};
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
public MemorySlice<T> Slice(int start, int length)
|
||||
{
|
||||
var startPos = _startPos + start;
|
||||
if (startPos < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
if (startPos + length > _arr.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
return new MemorySlice<T>()
|
||||
{
|
||||
_arr = _arr,
|
||||
_startPos = startPos,
|
||||
_length = length
|
||||
};
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
for (int i = 0; i < _length; i++)
|
||||
{
|
||||
yield return this._arr[i + _startPos];
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
|
||||
|
||||
public static implicit operator ReadOnlyMemorySlice<T>(MemorySlice<T> mem)
|
||||
{
|
||||
return new ReadOnlyMemorySlice<T>(
|
||||
mem._arr,
|
||||
mem._startPos,
|
||||
mem._length);
|
||||
}
|
||||
|
||||
public static implicit operator ReadOnlySpan<T>(MemorySlice<T> mem)
|
||||
{
|
||||
return mem.Span;
|
||||
}
|
||||
|
||||
public static implicit operator Span<T>(MemorySlice<T> mem)
|
||||
{
|
||||
return mem.Span;
|
||||
}
|
||||
|
||||
public static implicit operator MemorySlice<T>(T[] mem)
|
||||
{
|
||||
return new MemorySlice<T>(mem);
|
||||
}
|
||||
|
||||
public static implicit operator MemorySlice<T>?(T[]? mem)
|
||||
{
|
||||
if (mem == null) return null;
|
||||
return new MemorySlice<T>(mem);
|
||||
}
|
||||
}
|
||||
|
||||
public struct ReadOnlyMemorySlice<T> : IEnumerable<T>
|
||||
{
|
||||
private T[] _arr;
|
||||
private int _startPos;
|
||||
private int _length;
|
||||
public int Length => _length;
|
||||
public int StartPosition => _startPos;
|
||||
|
||||
[DebuggerStepThrough]
|
||||
public ReadOnlyMemorySlice(T[] arr)
|
||||
{
|
||||
this._arr = arr;
|
||||
this._startPos = 0;
|
||||
this._length = arr.Length;
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
public ReadOnlyMemorySlice(T[] arr, int startPos, int length)
|
||||
{
|
||||
this._arr = arr;
|
||||
this._startPos = startPos;
|
||||
this._length = length;
|
||||
}
|
||||
|
||||
public ReadOnlySpan<T> Span => _arr.AsSpan(start: _startPos, length: _length);
|
||||
|
||||
public T this[int index] => _arr[index + _startPos];
|
||||
|
||||
[DebuggerStepThrough]
|
||||
public ReadOnlyMemorySlice<T> Slice(int start)
|
||||
{
|
||||
var startPos = _startPos + start;
|
||||
if (startPos < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
return new ReadOnlyMemorySlice<T>()
|
||||
{
|
||||
_arr = _arr,
|
||||
_startPos = _startPos + start,
|
||||
_length = _length - start
|
||||
};
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
public ReadOnlyMemorySlice<T> Slice(int start, int length)
|
||||
{
|
||||
var startPos = _startPos + start;
|
||||
if (startPos < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
if (startPos + length > _arr.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
return new ReadOnlyMemorySlice<T>()
|
||||
{
|
||||
_arr = _arr,
|
||||
_startPos = _startPos + start,
|
||||
_length = length
|
||||
};
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
for (int i = 0; i < _length; i++)
|
||||
{
|
||||
yield return this._arr[i + _startPos];
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
|
||||
|
||||
public static implicit operator ReadOnlySpan<T>(ReadOnlyMemorySlice<T> mem)
|
||||
{
|
||||
return mem.Span;
|
||||
}
|
||||
|
||||
public static implicit operator ReadOnlyMemorySlice<T>?(T[]? mem)
|
||||
{
|
||||
if (mem == null) return null;
|
||||
return new ReadOnlyMemorySlice<T>(mem);
|
||||
}
|
||||
|
||||
public static implicit operator ReadOnlyMemorySlice<T>(T[] mem)
|
||||
{
|
||||
return new ReadOnlyMemorySlice<T>(mem);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MemorySliceExt
|
||||
{
|
||||
public static bool Equal<T>(ReadOnlyMemorySlice<T>? lhs, ReadOnlyMemorySlice<T>? rhs)
|
||||
where T : IEquatable<T>
|
||||
{
|
||||
if (lhs == null && rhs == null) return true;
|
||||
if (lhs == null || rhs == null) return false;
|
||||
return MemoryExtensions.SequenceEqual(lhs.Value.Span, rhs.Value.Span);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user