@@ -692,29 +692,51 @@ extension Unicode.Scalar.Properties {
692
692
/// all current case mappings. In the event more space is needed, it will be
693
693
/// allocated on the heap.
694
694
internal func _applyMapping( _ u_strTo: _U_StrToX ) -> String {
695
- // TODO(String performance): Stack buffer first and then detect real count
696
- let count = 64
697
- var array = Array < UInt16 > ( repeating: 0 , count: count)
698
- let len : Int = array. withUnsafeMutableBufferPointer { bufPtr in
695
+ // Allocate 16 code units on the stack.
696
+ var fixedArray = _FixedArray16 < UInt16 > ( allZeros: ( ) )
697
+ let count : Int = fixedArray. withUnsafeMutableBufferPointer { buf in
699
698
return _scalar. withUTF16CodeUnits { utf16 in
700
699
var err = __swift_stdlib_U_ZERO_ERROR
701
700
let correctSize = u_strTo (
702
- bufPtr . baseAddress. _unsafelyUnwrappedUnchecked,
703
- Int32 ( bufPtr . count) ,
701
+ buf . baseAddress. _unsafelyUnwrappedUnchecked,
702
+ Int32 ( buf . count) ,
704
703
utf16. baseAddress. _unsafelyUnwrappedUnchecked,
705
704
Int32 ( utf16. count) ,
706
705
" " ,
707
706
& err)
708
707
guard err. isSuccess else {
709
708
fatalError ( " Unexpected error case-converting Unicode scalar. " )
710
709
}
711
- // TODO: _internalInvariant(count == correctSize, "inconsistent ICU behavior")
712
710
return Int ( correctSize)
713
711
}
714
712
}
715
- // TODO: replace `len` with `count`
716
- return array [ ..< len] . withUnsafeBufferPointer {
717
- return String . _uncheckedFromUTF16 ( $0)
713
+ if _fastPath ( count <= 16 ) {
714
+ fixedArray. count = count
715
+ return fixedArray. withUnsafeBufferPointer {
716
+ String . _uncheckedFromUTF16 ( $0)
717
+ }
718
+ }
719
+ // Allocate `count` code units on the heap.
720
+ let array = Array < UInt16 > ( unsafeUninitializedCapacity: count) {
721
+ buf, initializedCount in
722
+ _scalar. withUTF16CodeUnits { utf16 in
723
+ var err = __swift_stdlib_U_ZERO_ERROR
724
+ let correctSize = u_strTo (
725
+ buf. baseAddress. _unsafelyUnwrappedUnchecked,
726
+ Int32 ( buf. count) ,
727
+ utf16. baseAddress. _unsafelyUnwrappedUnchecked,
728
+ Int32 ( utf16. count) ,
729
+ " " ,
730
+ & err)
731
+ guard err. isSuccess else {
732
+ fatalError ( " Unexpected error case-converting Unicode scalar. " )
733
+ }
734
+ _internalInvariant ( count == correctSize, " inconsistent ICU behavior " )
735
+ initializedCount = count
736
+ }
737
+ }
738
+ return array. withUnsafeBufferPointer {
739
+ String . _uncheckedFromUTF16 ( $0)
718
740
}
719
741
}
720
742
0 commit comments