initial commit
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace System;
|
||||
|
||||
internal readonly struct Index : IEquatable<Index>
|
||||
{
|
||||
private readonly int _value;
|
||||
|
||||
public static Index Start => new Index(0);
|
||||
|
||||
public static Index End => new Index(-1);
|
||||
|
||||
public int Value
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_value < 0)
|
||||
{
|
||||
return ~_value;
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsFromEnd => _value < 0;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Index(int value, bool fromEnd = false)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("value", value, "Non-negative number required.");
|
||||
}
|
||||
if (fromEnd)
|
||||
{
|
||||
_value = ~value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private Index(int value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Index FromStart(int value)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("value", value, "Non-negative number required.");
|
||||
}
|
||||
return new Index(value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Index FromEnd(int value)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("value", value, "Non-negative number required.");
|
||||
}
|
||||
return new Index(~value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int GetOffset(int length)
|
||||
{
|
||||
int num = _value;
|
||||
if (IsFromEnd)
|
||||
{
|
||||
num += length + 1;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
public override bool Equals(object? value)
|
||||
{
|
||||
if (value is Index)
|
||||
{
|
||||
return _value == ((Index)value)._value;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Equals(Index other)
|
||||
{
|
||||
return _value == other._value;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
public static implicit operator Index(int value)
|
||||
{
|
||||
return FromStart(value);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (IsFromEnd)
|
||||
{
|
||||
return "^" + (uint)Value;
|
||||
}
|
||||
return ((uint)Value).ToString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using Roslyn.Utilities;
|
||||
|
||||
namespace System;
|
||||
|
||||
internal readonly struct Range : IEquatable<Range>
|
||||
{
|
||||
public Index Start { get; }
|
||||
|
||||
public Index End { get; }
|
||||
|
||||
public static Range All => Index.Start..Index.End;
|
||||
|
||||
public Range(Index start, Index end)
|
||||
{
|
||||
Start = start;
|
||||
End = end;
|
||||
}
|
||||
|
||||
public override bool Equals(object? value)
|
||||
{
|
||||
if (value is Range { Start: var start } range && start.Equals(Start))
|
||||
{
|
||||
return range.End.Equals(End);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Equals(Range other)
|
||||
{
|
||||
if (other.Start.Equals(Start))
|
||||
{
|
||||
return other.End.Equals(End);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Hash.Combine(Start.GetHashCode(), End.GetHashCode());
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return getFromEndSpecifier(Start) + toString(Start) + ".." + getFromEndSpecifier(End) + toString(End);
|
||||
static string getFromEndSpecifier(Index index)
|
||||
{
|
||||
if (!index.IsFromEnd)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
return "^";
|
||||
}
|
||||
static string toString(Index index)
|
||||
{
|
||||
return ((uint)index.Value).ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public static Range StartAt(Index start)
|
||||
{
|
||||
return start..Index.End;
|
||||
}
|
||||
|
||||
public static Range EndAt(Index end)
|
||||
{
|
||||
return Index.Start..end;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public (int Offset, int Length) GetOffsetAndLength(int length)
|
||||
{
|
||||
Index start = Start;
|
||||
int num = ((!start.IsFromEnd) ? start.Value : (length - start.Value));
|
||||
Index end = End;
|
||||
int num2 = ((!end.IsFromEnd) ? end.Value : (length - end.Value));
|
||||
if ((uint)num2 > (uint)length || (uint)num > (uint)num2)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("length");
|
||||
}
|
||||
return (Offset: num, Length: num2 - num);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user