Memory<T>
using System.Buffers;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace System
{
[DebuggerDisplay("{DebuggerDisplay,nq}")]
[DebuggerTypeProxy(typeof(System.MemoryDebugView<>))]
public readonly struct Memory<T>
{
private readonly object _object;
private readonly int _index;
private readonly int _length;
private const int RemoveOwnedFlagBitMask = int.MaxValue;
private string DebuggerDisplay => string.Format("{{{0}[{1}]}}", new object[2] {
typeof(T).get_Name(),
_length
});
public static Memory<T> Empty => default(Memory<T>);
public int Length => _length;
public bool IsEmpty => _length == 0;
public Span<T> Span {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get {
Span<T> result;
if (_index < 0) {
result = ((OwnedMemory<T>)_object).Span;
return result.Slice(_index & 2147483647, _length);
}
string text;
if ((object)typeof(T) == typeof(char) && (text = (_object as string)) != null) {
result = new Span<T>(Unsafe.As<Pinnable<T>>((object)text), MemoryExtensions.StringAdjustment, text.Length);
return result.Slice(_index, _length);
}
if (_object != null)
return new Span<T>((T[])_object, _index, _length);
result = default(Span<T>);
return result;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Memory(T[] array)
{
if (array == null)
System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.array);
if (default(T) == null && (object)array.GetType() != typeof(T[]))
System.ThrowHelper.ThrowArrayTypeMismatchException();
_object = array;
_index = 0;
_length = array.Length;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Memory(T[] array, int start, int length)
{
if (array == null)
System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.array);
if (default(T) == null && (object)array.GetType() != typeof(T[]))
System.ThrowHelper.ThrowArrayTypeMismatchException();
if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
System.ThrowHelper.ThrowArgumentOutOfRangeException();
_object = array;
_index = start;
_length = length;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal Memory(OwnedMemory<T> owner, int index, int length)
{
_object = owner;
_index = (index | -2147483648);
_length = length;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private Memory(object obj, int index, int length)
{
_object = obj;
_index = index;
_length = length;
}
public static implicit operator Memory<T>(T[] array)
{
if (array == null)
return default(Memory<T>);
return new Memory<T>(array);
}
public static implicit operator Memory<T>(ArraySegment<T> arraySegment)
{
return new Memory<T>(arraySegment.Array, arraySegment.Offset, arraySegment.Count);
}
public static implicit operator ReadOnlyMemory<T>(Memory<T> memory)
{
return Unsafe.As<Memory<T>, ReadOnlyMemory<T>>(ref memory);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Memory<T> Slice(int start)
{
if ((uint)start > (uint)_length)
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
return new Memory<T>(_object, _index + start, _length - start);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Memory<T> Slice(int start, int length)
{
if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start))
System.ThrowHelper.ThrowArgumentOutOfRangeException();
return new Memory<T>(_object, _index + start, length);
}
public void CopyTo(Memory<T> destination)
{
Span.CopyTo(destination.Span);
}
public bool TryCopyTo(Memory<T> destination)
{
return Span.TryCopyTo(destination.Span);
}
public unsafe MemoryHandle Retain(bool pin = false)
{
MemoryHandle result = default(MemoryHandle);
if (pin) {
if (_index < 0) {
result = ((OwnedMemory<T>)_object).Pin((_index & 2147483647) * Unsafe.SizeOf<T>());
return result;
}
string value;
T[] value2;
if ((object)typeof(T) == typeof(char) && (value = (_object as string)) != null) {
GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned);
void* pointer = Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
result = new MemoryHandle(null, pointer, handle);
} else if ((value2 = (_object as T[])) != null) {
GCHandle handle2 = GCHandle.Alloc(value2, GCHandleType.Pinned);
void* pointer2 = Unsafe.Add<T>((void*)handle2.AddrOfPinnedObject(), _index);
result = new MemoryHandle(null, pointer2, handle2);
}
} else if (_index < 0) {
((OwnedMemory<T>)_object).Retain();
result = new MemoryHandle((OwnedMemory<T>)_object, null, default(GCHandle));
}
return result;
}
public bool TryGetArray(out ArraySegment<T> arraySegment)
{
T[] array;
if (_index < 0) {
if (((OwnedMemory<T>)_object).TryGetArray(out ArraySegment<T> arraySegment2)) {
arraySegment = new ArraySegment<T>(arraySegment2.Array, arraySegment2.Offset + (_index & 2147483647), _length);
return true;
}
} else if ((array = (_object as T[])) != null) {
arraySegment = new ArraySegment<T>(array, _index, _length);
return true;
}
arraySegment = default(ArraySegment<T>);
return false;
}
public T[] ToArray()
{
return Span.ToArray();
}
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals(object obj)
{
if (obj is ReadOnlyMemory<T>)
return ((ReadOnlyMemory<T>)obj).Equals(this);
bool num = obj is Memory<T>;
Memory<T> other = num ? ((Memory<T>)obj) : default(Memory<T>);
if (num)
return Equals(other);
return false;
}
public bool Equals(Memory<T> other)
{
if (_object == other._object && _index == other._index)
return _length == other._length;
return false;
}
[EditorBrowsable(EditorBrowsableState.Never)]
public override int GetHashCode()
{
if (_object == null)
return 0;
int hashCode = _object.GetHashCode();
int num = _index;
int hashCode2 = num.GetHashCode();
num = _length;
return CombineHashCodes(hashCode, hashCode2, num.GetHashCode());
}
private static int CombineHashCodes(int left, int right)
{
return ((left << 5) + left) ^ right;
}
private static int CombineHashCodes(int h1, int h2, int h3)
{
return CombineHashCodes(CombineHashCodes(h1, h2), h3);
}
}
}