1

Look at the program:

let s = "1"
print(s.startIndex)
print(s.index(before: s.endIndex))
print(s.index(before: s.endIndex) == s.startIndex)

It returns:

Index(_rawBits: 0)
Index(_rawBits: 256)
true

So, the same position in the string is represented with rawBits 0 and 256. Why?

2
  • 5
    Why are you looking at the rawBits at all? Commented May 9, 2019 at 19:13
  • maybe it's something with the print() command and not with the equality Commented May 9, 2019 at 19:28

2 Answers 2

3

The raw bits of the index are an implementation detail. As you see in your example, the two values are equal (they return true for ==).

As to the current implementation, bit 8 is set, which is not part of the position. That's a cached value for the offset to the next grapheme cluster, which is 1 byte away. It's telling you that there's one byte to the next grapheme (which it didn't know until you calculated the endIndex).

Sign up to request clarification or add additional context in comments.

Comments

3

Equality between two String.Indexes is defined on the upper 50 bits of the _rawBits, aka orderingValue, as follows:

extension String.Index: Equatable {
  @inlinable @inline(__always)
  public static func == (lhs: String.Index, rhs: String.Index) -> Bool {
    return lhs.orderingValue == rhs.orderingValue
  }
}

And since 0 &>> 14 and 256 &>> 14 both equal 0, the positions are equal, and thus the indices are considered equal.


&>> is the infix operator to shift bits to the right, masking the shift amount to 64 bits.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.