Range.cs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  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 Range : IEquatable<Range>
  8. {
  9. public Index Start { get; }
  10. public Index End { get; }
  11. private Range(Index start, Index end)
  12. {
  13. Start = start;
  14. End = end;
  15. }
  16. public override bool Equals(object value)
  17. {
  18. if (value is Range)
  19. {
  20. Range r = (Range)value;
  21. return r.Start.Equals(Start) && r.End.Equals(End);
  22. }
  23. return false;
  24. }
  25. public bool Equals (Range other) => other.Start.Equals(Start) && other.End.Equals(End);
  26. public override int GetHashCode()
  27. {
  28. return HashCode.Combine(Start.GetHashCode(), End.GetHashCode());
  29. }
  30. public override string ToString()
  31. {
  32. Span<char> span = stackalloc char[2 + (2 * 11)]; // 2 for "..", then for each index 1 for '^' and 10 for longest possible uint
  33. int charsWritten;
  34. int pos = 0;
  35. if (Start.FromEnd)
  36. {
  37. span[0] = '^';
  38. pos = 1;
  39. }
  40. bool formatted = ((uint)Start.Value).TryFormat(span.Slice(pos), out charsWritten);
  41. Debug.Assert(formatted);
  42. pos += charsWritten;
  43. span[pos++] = '.';
  44. span[pos++] = '.';
  45. if (End.FromEnd)
  46. {
  47. span[pos++] = '^';
  48. }
  49. formatted = ((uint)End.Value).TryFormat(span.Slice(pos), out charsWritten);
  50. Debug.Assert(formatted);
  51. pos += charsWritten;
  52. return new string(span.Slice(0, pos));
  53. }
  54. public static Range Create(Index start, Index end) => new Range(start, end);
  55. public static Range FromStart(Index start) => new Range(start, new Index(0, fromEnd: true));
  56. public static Range ToEnd(Index end) => new Range(new Index(0, fromEnd: false), end);
  57. public static Range All() => new Range(new Index(0, fromEnd: false), new Index(0, fromEnd: true));
  58. }
  59. }