Hi.
I am trying address TODO in internal function _applyMapping of Unicode.Scalar.Properties swift/UnicodeScalarProperties.swift at 172c0472f6acbc37a6a0b70b57fadf181d2e30b0 · apple/swift · GitHub
Here is my implementation using _FixedArray16:
internal func _applyMapping(_ u_strTo: _U_StrToX) -> String {
let count = 64
var array = _FixedArray16<UInt64>(allZeros: ()) // 16 * UInt64 take 128 bytes, same as 64 * UInt16
let len: Int = array.withUnsafeMutableBufferPointer { bufPtr in
return _scalar.withUTF16CodeUnits { utf16 in
var err = __swift_stdlib_U_ZERO_ERROR
let correctSize = u_strTo(
UnsafeMutableRawPointer(bufPtr.baseAddress!).bindMemory(to: UInt16.self, capacity: count),
Int32(count),
utf16.baseAddress._unsafelyUnwrappedUnchecked,
Int32(utf16.count),
"",
&err)
guard err.isSuccess else {
fatalError("Unexpected error case-converting Unicode scalar.")
}
// TODO: _internalInvariant(count == correctSize, "inconsistent ICU behavior")
return Int(correctSize)
}
}
// TODO: replace `len` with `count`
let result: String = array.withUnsafeBufferPointer{
// error: type of expression is ambiguous without more context
// let result: String = array.withUnsafeBufferPointer{
// ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
return String._uncheckedFromUTF16(UnsafeRawPointer($0).bindMemory(to: UInt16.self, capacity: len))
}
return result
}
I am having compile error "type of expression is ambiguous without more context" as shown in snippet above.
Whatever I do I can't fix this compile error.
Any help is appreciated.
Regards,
Valeriy Van
Let's try to go backwards.
_uncheckedFromUTF16 expects an UnsafeBufferPointer<UInt16>. However, the return type on UnsafeRawPointer.bindMemory(to:capacity:) is UnsafePointer. That seems to be tripping up the compiler. The correct thing (from a types perspective, I'm hardly an expert on memory binding) to do would be to create an UnsafeRawBufferPointer and then call bindMemory on it, which would give you an UnsafeBufferPointer.
Here's a verbose version:
let result = array.withUnsafeBufferPointer { (bp : UnsafeBufferPointer<UInt64>) -> String in
let ubp = UnsafeRawBufferPointer(bp).bindMemory(to: UInt16.self)
return String._uncheckedFromUTF16(ubp)
}
Torust
(Thomas Roughton)
4
To follow up on that, I think from a memory binding perspective withMemoryRebound should be what you're looking for here:
let result = array.withUnsafeBufferPointer { (bp : UnsafeBufferPointer<UInt64>) -> String in
return bp.withMemoryRebound(to: UInt16.self) {
String._uncheckedFromUTF16($0)
}
}
1 Like