Index.cs 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Diagnostics;
  5. namespace System
  6. {
  7. public readonly struct Index : IEquatable<Index>
  8. {
  9. private readonly int _value;
  10. public Index(int value, bool fromEnd)
  11. {
  12. if (value < 0)
  13. {
  14. ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
  15. }
  16. _value = fromEnd ? ~value : value;
  17. }
  18. public int Value => _value < 0 ? ~_value : _value;
  19. public bool FromEnd => _value < 0;
  20. public override bool Equals(object value) => value is Index && _value == ((Index)value)._value;
  21. public bool Equals (Index other) => _value == other._value;
  22. public override int GetHashCode()
  23. {
  24. return _value;
  25. }
  26. public override string ToString() => FromEnd ? ToStringFromEnd() : ((uint)Value).ToString();
  27. private string ToStringFromEnd()
  28. {
  29. Span<char> span = stackalloc char[11]; // 1 for ^ and 10 for longest possible uint value
  30. bool formatted = ((uint)Value).TryFormat(span.Slice(1), out int charsWritten);
  31. Debug.Assert(formatted);
  32. span[0] = '^';
  33. return new string(span.Slice(0, charsWritten + 1));
  34. }
  35. public static implicit operator Index(int value)
  36. => new Index(value, fromEnd: false);
  37. }
  38. }