stdlib: remove Sliceable conformance from String

Swift SVN r28442
This commit is contained in:
Dmitri Hrybenko
2015-05-11 20:58:31 +00:00
parent e590a9b63d
commit 61214ec55b
19 changed files with 114 additions and 67 deletions

View File

@@ -370,10 +370,13 @@ extension String {
// So let's do that; the switch should compile away anyhow.
return locale != nil ? _ns.compare(
aString, options: mask,
range: _toNSRange(range != nil ? range! : self.indices), locale: locale)
range: _toNSRange(range ?? self.characters.indices),
locale: locale)
: range != nil ? _ns.compare(
aString, options: mask, range: _toNSRange(range != nil ? range! : self.indices))
aString,
options: mask,
range: _toNSRange(range ?? self.characters.indices))
: mask != nil ? _ns.compare(aString, options: mask)
@@ -1095,7 +1098,7 @@ extension String {
return _optionalRange(
_ns.rangeOfCharacterFromSet(
aSet, options: mask,
range: _toNSRange(aRange != nil ? aRange! : self.indices)))
range: _toNSRange(aRange ?? self.characters.indices)))
}
// - (NSRange)rangeOfComposedCharacterSequenceAtIndex:(NSUInteger)anIndex
@@ -1150,7 +1153,7 @@ extension String {
return _optionalRange(
locale != nil ? _ns.rangeOfString(
aString, options: mask,
range: _toNSRange(searchRange != nil ? searchRange! : self.indices),
range: _toNSRange(searchRange ?? self.characters.indices),
locale: locale
)
: searchRange != nil ? _ns.rangeOfString(
@@ -1351,7 +1354,7 @@ extension String {
? _ns.stringByReplacingOccurrencesOfString(
target,
withString: replacement, options: options,
range: _toNSRange(searchRange != nil ? searchRange! : self.indices)
range: _toNSRange(searchRange ?? self.characters.indices)
)
: _ns.stringByReplacingOccurrencesOfString(target, withString: replacement)
}

View File

@@ -400,7 +400,7 @@ func _uint64ToString(
func _rawPointerToString(value: Builtin.RawPointer) -> String {
var result = _uint64ToString(
UInt64(unsafeBitCast(value, UWord.self)), radix: 16, uppercase: false)
for _ in 0..<(2 * sizeof(Builtin.RawPointer) - result.count()) {
for _ in 0..<(2 * sizeof(Builtin.RawPointer) - result.utf16.count()) {
result = "0" + result
}
return "0x" + result

View File

@@ -570,14 +570,13 @@ public func < (lhs: String.Index, rhs: String.Index) -> Bool {
return lhs._base < rhs._base
}
extension String : Sliceable {
extension String {
/// Access the characters in the given `subRange`
///
/// - complexity: O(1) unless bridging from Objective-C requires an
/// O(N) conversion.
public subscript(subRange: Range<Index>) -> String {
return String(
unicodeScalars[subRange.startIndex._base..<subRange.endIndex._base]._core)
return String(characters[subRange])
}
@availability(
@@ -646,7 +645,19 @@ extension String {
(inout v: CharacterView) in v.replaceRange(subRange, with: newElements)
}
}
/// Replace the given `subRange` of elements with `newElements`.
///
/// Invalidates all indices with respect to `self`.
///
/// - complexity: O(`subRange.count()`) if `subRange.endIndex
/// == self.endIndex` and `isEmpty(newElements)`, O(N) otherwise.
public mutating func replaceRange(
subRange: Range<Index>, with newElements: String
) {
replaceRange(subRange, with: newElements.characters)
}
/// Insert `newElement` at index `i`.
///
/// Invalidates all indices with respect to `self`.

View File

@@ -56,6 +56,12 @@ extension String {
swap(&_core, &tmp._core)
return r
}
/// Construct the `String` corresponding to the given sequence of
/// Unicode scalars.
public init(_ characters: CharacterView) {
self.init(characters._core)
}
}
/// `String.CharacterView` is a collection of `Character`
@@ -383,3 +389,17 @@ extension String.CharacterView : RangeReplaceableCollectionType {
Swift.removeAll(&self, keepCapacity: keepCapacity)
}
}
extension String.CharacterView : Sliceable {
/// Access the characters in the given `subRange`
///
/// - complexity: O(1) unless bridging from Objective-C requires an
/// O(N) conversion.
public subscript(subRange: Range<Index>) -> String.CharacterView {
let unicodeScalarRange =
subRange.startIndex._base..<subRange.endIndex._base
return String.CharacterView(
String(_core).unicodeScalars[unicodeScalarRange]._core)
}
}

View File

@@ -265,7 +265,7 @@ Algorithm.test("sorted/strings")
sorted([ "apple", "Banana", "cherry" ]))
let s = sorted(["apple", "Banana", "cherry"]) {
$0.count() > $1.count()
$0.characters.count() > $1.characters.count()
}
expectEqual([ "Banana", "cherry", "apple" ], s)
}

View File

@@ -1,7 +1,7 @@
// RUN: %target-run-simple-swift | FileCheck %s
struct X : CollectionType {
typealias Element = String.Generator.Element
typealias Element = String.CharacterView.Generator.Element
typealias Index = String.Index
var msg: String

View File

@@ -166,7 +166,7 @@ tests.test("BidirectionalCollection") {
}
// Can't upgrade a non-random-access collection to random access
let s0 = "Hello, Woyld"
let s0 = "Hello, Woyld".characters
let bc1 = AnyBidirectionalCollection(s0)
let fc3 = AnyForwardCollection(bc1)
expectTrue(fc3 === bc1)

View File

@@ -48,8 +48,8 @@ mirrors.test("RandomAccessStructure") {
let letters = "abcdefghijklmnopqrstuvwxyz "
func find(substring: String, within domain: String) -> String.Index? {
let domainCount = domain.count()
let substringCount = substring.count()
let domainCount = domain.characters.count()
let substringCount = substring.characters.count()
if (domainCount < substringCount) { return nil }
var sliceStart = domain.startIndex
@@ -68,18 +68,21 @@ func find(substring: String, within domain: String) -> String.Index? {
mirrors.test("ForwardStructure") {
struct DoubleYou : CustomReflectable {
func customMirror() -> Mirror {
return Mirror(self, unlabeledChildren: Set(letters), displayStyle: .Set)
return Mirror(
self,
unlabeledChildren: Set(letters.characters),
displayStyle: .Set)
}
}
let w = DoubleYou().customMirror()
expectEqual(.Set, w.displayStyle)
expectEqual(letters.count(), numericCast(w.children.count()))
expectEqual(letters.characters.count(), numericCast(w.children.count()))
// Because we don't control the order of a Set, we need to do a
// fancy dance in order to validate the result.
let description = w.description
for c in letters {
for c in letters.characters {
let expected = "nil: \"\(c)\""
expectNotEmpty(find(expected, within: description))
}
@@ -88,7 +91,10 @@ mirrors.test("ForwardStructure") {
mirrors.test("BidirectionalStructure") {
struct Why : CustomReflectable {
func customMirror() -> Mirror {
return Mirror(self, unlabeledChildren: letters, displayStyle: .Collection)
return Mirror(
self,
unlabeledChildren: letters.characters,
displayStyle: .Collection)
}
}
@@ -99,7 +105,7 @@ mirrors.test("BidirectionalStructure") {
let description = y.description
expectEqual(
"[nil: \"a\", nil: \"b\", nil: \"c\", nil: \"",
description[description.startIndex..<description.indexOf("d")!])
description[description.startIndex..<description.characters.indexOf("d")!])
}
mirrors.test("LabeledStructure") {

View File

@@ -1779,7 +1779,7 @@ func checkCharacterComparison(
NSStringAPIs.test("Character.{Equatable,Hashable,Comparable}") {
for test in comparisonTests {
if test.lhs.count() == 1 && test.rhs.count() == 1 {
if test.lhs.characters.count() == 1 && test.rhs.characters.count() == 1 {
let lhsCharacter = Character(test.lhs)
let rhsCharacter = Character(test.rhs)
checkCharacterComparison(
@@ -1807,11 +1807,11 @@ func checkHasPrefixHasSuffix(
// To determine the expected results, compare grapheme clusters,
// scalar-to-scalar, of the NFD form of the strings.
let lhsNFDGraphemeClusters =
map(lhs.decomposedStringWithCanonicalMapping) {
map(lhs.decomposedStringWithCanonicalMapping.characters) {
Array(String($0).unicodeScalars)
}
let rhsNFDGraphemeClusters =
map(rhs.decomposedStringWithCanonicalMapping) {
map(rhs.decomposedStringWithCanonicalMapping.characters) {
Array(String($0).unicodeScalars)
}
let expectHasPrefix = lhsNFDGraphemeClusters.startsWith(

View File

@@ -9,13 +9,13 @@ var SliceableTests = TestSuite("SliceableTests")
SliceableTests.test("dropFirstLast") {
if true {
let a = [2, 3, 5, 7, 11]
expectEqual(a[a.startIndex.successor()..<a.endIndex], dropFirst(a))
expectEqual(a[a.startIndex..<a.endIndex.predecessor()], dropLast(a))
expectEqualSequence(a[a.startIndex.successor()..<a.endIndex], dropFirst(a))
expectEqualSequence(a[a.startIndex..<a.endIndex.predecessor()], dropLast(a))
}
if true {
let a = "bird in the hand"
expectEqual(a[a.startIndex.successor()..<a.endIndex], dropFirst(a))
expectEqual(a[a.startIndex..<a.endIndex.predecessor()], dropLast(a))
let a = "bird in the hand".characters
expectEqualSequence(a[a.startIndex.successor()..<a.endIndex], dropFirst(a))
expectEqualSequence(a[a.startIndex..<a.endIndex.predecessor()], dropLast(a))
}
}
@@ -37,10 +37,10 @@ SliceableTests.test("prefixSuffix") {
}
if true {
let a = "bird in the hand"
let a = "bird in the hand".characters
let count = a.count()
expectEqualSequence("", prefix(a, -10))
expectEqualSequence("", suffix(a, -10))
expectEqualSequence("".characters, prefix(a, -10))
expectEqualSequence("".characters, suffix(a, -10))
expectEqualSequence(a, prefix(a, count + 1))
expectEqualSequence(a, prefix(a, count))
expectEqualSequence(dropLast(a), prefix(a, count - 1))

View File

@@ -35,3 +35,10 @@ func testAmbiguousStringComparisons(s: String) {
let a11 = nsString >= s // expected-error{{'NSString' is not implicitly convertible to 'String'; did you mean to use 'as' to explicitly convert?}}
let a12 = nsString > s // expected-error{{'NSString' is not implicitly convertible to 'String'; did you mean to use 'as' to explicitly convert?}}
}
func acceptsSequence<S : SequenceType>(sequence: S) {}
func testStringIsNotASequence(s: String) {
acceptsSequence(s) // expected-error {{cannot invoke 'acceptsSequence' with an argument list of type '(String)'}} expected-note {{expected an argument list of type '(S)'}}
}

View File

@@ -66,14 +66,14 @@ func testCStrings() -> Bool {
_ = str
}
func testObjCString() -> Int {
func testObjCString() -> String {
let str: String = OBJC_STRING
return str.count()
return str
}
func testCFString() -> Int {
func testCFString() -> String {
let str: String = CF_STRING
return str.count()
return str
}
func testInvalidIntegerLiterals() {

View File

@@ -3,12 +3,11 @@
func markUsed<T>(t: T) {}
var puzzleInput = "great minds think alike"
var puzzleOutput = ""
var puzzleOutput: [String] = []
// CHECK-NOT: !DILocalVariable(tag: DW_TAG_auto_variable, name: "$letter$generator"
// CHECK: !DILocalVariable(tag: DW_TAG_auto_variable, name: "letter",
// CHECK-SAME: line: [[@LINE+1]]
for letter in puzzleInput {
for letter in [ "g", "r", "e", "a", "t" ] {
switch letter {
case "a", "e", "i", "o", "u", " ":
continue

View File

@@ -28,7 +28,7 @@ func stateFromPlistLame(plist: Dictionary<String, AnyObject>) -> State? {
func stateFromPlistCool(plist: Dictionary<String, AnyObject>) -> State? {
switch (plist["name"], plist["population"], plist["abbrev"]) {
case let (name as String, pop as Int, abbr as String)
where abbr.count() == 2:
where abbr.characters.count() == 2:
return State(name: name,
population: pop,
abbrev: abbr)
@@ -128,7 +128,7 @@ struct StatMirror: MirrorType {
func statisticFromPlist(plist: Dictionary<String, AnyObject>) -> Statistic? {
switch (plist["kind"], plist["name"], plist["population"], plist["abbrev"]) {
case let ("state" as String, name as String, population as Int, abbrev as String)
where abbrev.count() == 2:
where abbrev.characters.count() == 2:
return Statistic.ForState(State(name: name,
population: population,
abbrev: abbrev))

View File

@@ -2969,13 +2969,13 @@ SetTestSuite.test("") {
SetTestSuite.test("unionInPlace") {
// These are anagrams - they should amount to the same sets.
var s1 = Set("the morse code")
let s2 = Set("here come dots")
let s3 = Set("and then dashes")
var s1 = Set("the morse code".characters)
let s2 = Set("here come dots".characters)
let s3 = Set("and then dashes".characters)
let identity1 = unsafeBitCast(s1, Word.self)
s1.unionInPlace("")
s1.unionInPlace("".characters)
expectEqual(identity1, unsafeBitCast(s1, Word.self))
expectEqual(s1, s2)
@@ -2990,13 +2990,13 @@ SetTestSuite.test("unionInPlace") {
SetTestSuite.test("=") {
// These are anagrams - they should amount to the same sets.
var s1 = Set("the morse code")
let s2 = Set("here come dots")
let s3 = Set("and then dashes")
var s1 = Set("the morse code".characters)
let s2 = Set("here come dots".characters)
let s3 = Set("and then dashes".characters)
let identity1 = unsafeBitCast(s1, Word.self)
s1 = ""
s1 = "".characters
expectEqual(identity1, unsafeBitCast(s1, Word.self))
expectEqual(s1, s2)

View File

@@ -608,9 +608,9 @@ StringTests.test("stringCoreExtensibility") {
for boundary in 0..<length {
var x = (
k == 0 ? asciiString("b")
: k == 1 ? String("b" as NSString)
: String("b" as NSMutableString)
k == 0 ? asciiString("b".characters)
: k == 1 ? ("b" as NSString as String)
: ("b" as NSMutableString as String)
)._core
if k == 0 { expectEqual(1, x.elementWidth) }
@@ -642,7 +642,7 @@ StringTests.test("stringCoreReserve") {
switch k {
case 0: (base, startedNative) = (String(), true)
case 1: (base, startedNative) = (asciiString("x"), true)
case 1: (base, startedNative) = (asciiString("x".characters), true)
case 2: (base, startedNative) = ("Ξ", true)
case 3: (base, startedNative) = ("x" as NSString as String, false)
case 4: (base, startedNative) = ("x" as NSMutableString as String, false)
@@ -860,8 +860,7 @@ StringTests.test("growth") {
}
StringTests.test("Construction") {
let text = "Thirsty pirates"
expectEqual(text, String(Array<Character>(text)))
expectEqual("abc", String([ "a", "b", "c" ] as [Character]))
}
StringTests.test("Conversions") {
@@ -1125,10 +1124,12 @@ StringTests.test("String.append(_: Character)") {
for prefix in ["", " "] {
let base = baseStrings[baseIdx]
for inputIdx in baseCharacters.indices {
let input = (prefix + String(baseCharacters[inputIdx])).last!
let input = (prefix + String(baseCharacters[inputIdx])).characters.last!
var s = base
s.append(input)
expectEqual(Array(base) + [ input ], Array(s)) {
expectEqualSequence(
Array(base.characters) + [ input ],
Array(s.characters)) {
"baseIdx=\(baseIdx) inputIdx=\(inputIdx)"
}
}

View File

@@ -88,7 +88,7 @@ tests.test("index-mapping/character-to-utf8") {
replacementUTF8
] as [[UTF8.CodeUnit]],
winter.indices.map {
winter.characters.indices.map {
i in (0..<3).map {
winter.utf8[advance(i.samePositionIn(winter.utf8), $0)]
}
@@ -98,7 +98,7 @@ tests.test("index-mapping/character-to-utf8") {
expectEqualSequence(
summerBytes,
summer.indices.map { summer.utf8[$0.samePositionIn(summer.utf8)] }
summer.characters.indices.map { summer.utf8[$0.samePositionIn(summer.utf8)] }
)
expectEqual(summer.utf8.endIndex, summer.endIndex.samePositionIn(summer.utf8))
@@ -288,7 +288,7 @@ tests.test("index-mapping/character-to-utf16") {
replacementUTF16, 0x20, replacementUTF16, replacementUTF16
] as [UTF16.CodeUnit],
winter.indices.map {
winter.characters.indices.map {
winter.utf16[$0.samePositionIn(winter.utf16)]
}, ==)
@@ -296,7 +296,7 @@ tests.test("index-mapping/character-to-utf16") {
expectEqualSequence(
summerBytes.map { UTF16.CodeUnit($0) },
summer.indices.map { summer.utf16[$0.samePositionIn(summer.utf16)] }
summer.characters.indices.map { summer.utf16[$0.samePositionIn(summer.utf16)] }
)
expectEqual(summer.utf16.endIndex, summer.endIndex.samePositionIn(summer.utf16))
@@ -391,7 +391,7 @@ tests.test("index-mapping/character-to-unicode-scalar") {
expectEqualSequence(
winterCharacterUnicodeScalars,
winter.indices.map {
winter.characters.indices.map {
winter.unicodeScalars[$0.samePositionIn(winter.unicodeScalars)]
})
@@ -399,7 +399,7 @@ tests.test("index-mapping/character-to-unicode-scalar") {
expectEqualSequence(
summerBytes.map { UnicodeScalar($0) },
summer.indices.map { summer.unicodeScalars[$0.samePositionIn(summer.unicodeScalars)] }
summer.characters.indices.map { summer.unicodeScalars[$0.samePositionIn(summer.unicodeScalars)] }
)
expectEqual(summer.unicodeScalars.endIndex, summer.endIndex.samePositionIn(summer.unicodeScalars))
@@ -713,7 +713,7 @@ tests.test("UTF8->String") {
tests.test("UnicodeScalars->String") {
let s = summer + winter + winter + summer
let v = s.unicodeScalars
for i in s.indices {
for i in s.characters.indices {
for j in i..<s.endIndex {
expectEqual(
s[i..<j],

View File

@@ -130,7 +130,7 @@ func makeString(length: Int) -> String {
for i in 0..<(length / 10) {
result += "0123456789"
}
result += String(Array("0123456789")[0 ..< length % 10])
result += String(Array("0123456789".characters)[0 ..< length % 10])
return result
}

View File

@@ -136,7 +136,7 @@ func checkGraphemeClusterSegmentation(
) {
var actualBoundaries: [Int] = [ 0 ]
var unicodeScalarCount = 0
for c in subject {
for c in subject.characters {
let currentClusterSize = String(c).unicodeScalars.count()
unicodeScalarCount += currentClusterSize
actualBoundaries += [ unicodeScalarCount ]
@@ -146,8 +146,8 @@ func checkGraphemeClusterSegmentation(
"scalars: \(asHex(lazy(subject.unicodeScalars).map { $0.value }.array))"
}
var expectedCharacters: [Character] = Array(subject)
checkSliceableWithBidirectionalIndex(expectedCharacters, subject,
var expectedCharacters: [Character] = Array(subject.characters)
checkSliceableWithBidirectionalIndex(expectedCharacters, subject.characters,
stackTrace.withCurrentLoc())
}