114 lines
2.9 KiB
Swift

//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
//
//===----------------------------------------------------------------------===//
// Bits of String.Index that are ABI but aren't exposed by public API.
extension String.Index {
@inline(__always)
var _abi_rawBits: UInt64 {
unsafeBitCast(self, to: UInt64.self)
}
@inline(__always)
var _abi_encodedOffset: Int {
Int(truncatingIfNeeded: _abi_rawBits &>> 16)
}
@inline(__always)
var _abi_transcodedOffset: Int {
Int(truncatingIfNeeded: (_abi_rawBits &>> 14) & 0x3)
}
@inline(__always)
static var _abi_scalarAlignmentBit: UInt64 { 0x1 }
@inline(__always)
static var _abi_characterAlignmentBit: UInt64 { 0x2 }
@inline(__always)
static var _abi_utf8Bit: UInt64 { 0x4 }
@inline(__always)
static var _abi_utf16Bit: UInt64 { 0x8 }
@inline(__always)
var _encodingBits: UInt64 {
_abi_rawBits & (Self._abi_utf8Bit | Self._abi_utf16Bit)
}
@inline(__always)
var _canBeUTF8: Bool {
// The only way an index cannot be UTF-8 is it has only the UTF-16 flag set.
_encodingBits != Self._abi_utf16Bit
}
var _isKnownScalarAligned: Bool {
0 != _abi_rawBits & Self._abi_scalarAlignmentBit
}
var _isKnownCharacterAligned: Bool {
0 != _abi_rawBits & Self._abi_characterAlignmentBit
}
var _knownCharacterAligned: String.Index {
let r = _abi_rawBits | Self._abi_characterAlignmentBit | Self._abi_scalarAlignmentBit
return unsafeBitCast(r, to: String.Index.self)
}
var _knownScalarAligned: String.Index {
let r = _abi_rawBits | Self._abi_scalarAlignmentBit
return unsafeBitCast(r, to: String.Index.self)
}
}
extension String.Index {
@inline(__always)
var _utf8Offset: Int {
assert(_canBeUTF8)
return _abi_encodedOffset
}
@inline(__always)
var _isUTF16TrailingSurrogate: Bool {
assert(_canBeUTF8)
let r = _abi_transcodedOffset
assert(r <= 1)
return r > 0
}
@inline(__always)
init(_rawBits: UInt64) {
self = unsafeBitCast(_rawBits, to: String.Index.self)
}
@inline(__always)
init(_utf8Offset: Int) {
self.init(_rawBits: (UInt64(_utf8Offset) &<< 16) | Self._abi_utf8Bit)
}
init(_utf8Offset: Int, utf16TrailingSurrogate: Bool) {
let transcodedOffset: UInt64 = (utf16TrailingSurrogate ? 1 &<< 14 : 0)
self.init(_rawBits: (UInt64(_utf8Offset) &<< 16) | transcodedOffset | Self._abi_utf8Bit)
}
}
extension String.Index {
@inline(__always)
var _chunkData: UInt16 {
UInt16(_abi_rawBits &>> 14)
}
@inline(__always)
init(_chunkData: UInt16) {
self.init(_rawBits: UInt64(_chunkData) &<< 14)
}
}