Reputation: 14622
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?
Upvotes: 1
Views: 266
Reputation: 18581
Equality between two String.Index
es 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.
Upvotes: 3
Reputation: 299345
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).
Upvotes: 3