StringOrMemory
Represents a string and equivalent memory representation of this string.
Prevents multiple allocations of string by caching it
using System;
using System.Runtime.CompilerServices;
namespace AngleSharp.Common
{
public struct StringOrMemory
{
private readonly ReadOnlyMemory<char> _memory;
public ReadOnlyMemory<char> Memory {
[IsReadOnly]
get {
return _memory;
}
}
public int Length => _memory.Length;
public char this[int i] {
get {
return _memory.Span[i];
}
}
public bool IsNullOrEmpty => _memory.IsEmpty;
public static StringOrMemory Empty => new StringOrMemory(string.Empty);
[System.Runtime.CompilerServices.NullableContext(1)]
public StringOrMemory(string str)
{
_memory = str.AsMemory();
}
public StringOrMemory(ReadOnlyMemory<char> memory)
{
_memory = memory;
}
public static implicit operator StringOrMemory(string str)
{
return new StringOrMemory(str);
}
public static implicit operator StringOrMemory(ReadOnlyMemory<char> memory)
{
return new StringOrMemory(memory);
}
public static implicit operator ReadOnlyMemory<char>(StringOrMemory str)
{
return str.Memory;
}
public static implicit operator ReadOnlySpan<char>(StringOrMemory str)
{
return str.Memory.Span;
}
public static bool operator ==(StringOrMemory left, string right)
{
return left.Memory.Span.SequenceEqual(right.AsSpan());
}
public static bool operator ==(StringOrMemory left, StringOrMemory right)
{
ReadOnlyMemory<char> memory = left.Memory;
ReadOnlySpan<char> span = memory.Span;
memory = right.Memory;
return span.SequenceEqual(memory.Span);
}
public static bool operator ==(StringOrMemory left, ReadOnlyMemory<char> right)
{
return left.Memory.Span.SequenceEqual(right.Span);
}
public static bool operator ==(StringOrMemory left, ReadOnlySpan<char> right)
{
return left.Memory.Span.SequenceEqual(right);
}
public static bool operator !=(StringOrMemory left, string right)
{
return !(left == right);
}
public static bool operator !=(StringOrMemory left, StringOrMemory right)
{
return !(left == right);
}
public static bool operator !=(StringOrMemory left, ReadOnlyMemory<char> right)
{
return !(left == right);
}
public static bool operator !=(StringOrMemory left, ReadOnlySpan<char> right)
{
return !(left == right);
}
public bool Equals(StringOrMemory other)
{
if (!_memory.Equals(other._memory))
return _memory.Span.SequenceEqual(other._memory.Span);
return true;
}
[System.Runtime.CompilerServices.NullableContext(2)]
public override bool Equals(object obj)
{
if (obj is StringOrMemory) {
StringOrMemory other = (StringOrMemory)obj;
return Equals(other);
}
return false;
}
public override int GetHashCode()
{
return GetHashCode(_memory.Span);
}
public StringOrMemory Replace(char target, char replacement)
{
return new StringOrMemory(ToString().Replace(target, replacement));
}
[System.Runtime.CompilerServices.NullableContext(1)]
public override string ToString()
{
if (_memory.IsEmpty)
return string.Empty;
return _memory.ToString();
}
private static int GetHashCode(ReadOnlySpan<char> span)
{
int num = 352654597;
for (int i = 0; i < span.Length; i++) {
num = (((num << 5) + num + (num >> 27)) ^ span[i]);
}
return num * 1566083941;
}
}
}