mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[stdlib] String API Review: NSString API
Many changes in how we're presenting the NSString APIs on String, most notably that we now traffic in String.Index and Range<String.Index> rather than Int and NSRange. Also we present NSString initializers that can fail only as factory functions, and factory functions that can't fail only as init functions. About 25% of the API changes here have been reviewd by the Foundation guys, and testing is, as it has always been, admittedly spotty. Dmitri is going to be writing some more comprehensive tests. Swift SVN r18553
This commit is contained in:
@@ -223,7 +223,7 @@ var _nilRawPointer: Builtin.RawPointer {
|
||||
/// this type; they instead get mapped to
|
||||
/// `AutoreleasingUnsafePointer<T>`. `void*` pointers are mapped to
|
||||
/// CMutableVoidPointer.
|
||||
struct CMutablePointer<T> : Equatable {
|
||||
struct CMutablePointer<T> : Equatable, LogicValue {
|
||||
let owner: AnyObject?
|
||||
let value: Builtin.RawPointer
|
||||
|
||||
@@ -265,6 +265,12 @@ struct CMutablePointer<T> : Equatable {
|
||||
return result
|
||||
}
|
||||
|
||||
/// Return true if self was not constructed with nil
|
||||
@transparent
|
||||
func getLogicValue() -> Bool {
|
||||
return reinterpretCast(value) != 0
|
||||
}
|
||||
|
||||
/// Return the result of invoking body. If self was converted from
|
||||
/// nil, passes nil as the argument. Otherwise, passes the address
|
||||
/// of a T which is written into buffer before this method returns
|
||||
@@ -272,10 +278,7 @@ struct CMutablePointer<T> : Equatable {
|
||||
func _withBridgeObject<U: AnyObject, R>(
|
||||
inout buffer: U?, body: (AutoreleasingUnsafePointer<U?>)->R
|
||||
) -> R {
|
||||
if reinterpretCast(value) != 0 {
|
||||
return body(&buffer)
|
||||
}
|
||||
return body(nil)
|
||||
return self ? body(&buffer) : body(nil)
|
||||
}
|
||||
|
||||
/// Return the result of invoking body. If self was converted from
|
||||
@@ -285,14 +288,15 @@ struct CMutablePointer<T> : Equatable {
|
||||
func _withBridgeValue<U, R>(
|
||||
inout buffer: U, body: (CMutablePointer<U>)->R
|
||||
) -> R {
|
||||
return reinterpretCast(value) == 0 ? body(nil) : body(&buffer)
|
||||
return self ? body(&buffer) : body(nil)
|
||||
}
|
||||
|
||||
/// If self was converted from nil, writes the result of invoking body into
|
||||
/// the pointee
|
||||
func _setIfNonNil(body: ()->T) {
|
||||
self.withUnsafePointer {
|
||||
(p)->() in if (p) { p.memory = body() }
|
||||
if self {
|
||||
UnsafePointer(value).memory = body()
|
||||
_fixLifetime(owner)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,6 +263,11 @@ extension String : Collection {
|
||||
return Index(_base.pred())
|
||||
}
|
||||
let _base: UnicodeScalarView.IndexType
|
||||
|
||||
/// The integer offset of this index in UTF16 text.
|
||||
var _utf16Index: Int {
|
||||
return _base._position
|
||||
}
|
||||
}
|
||||
|
||||
var startIndex: Index {
|
||||
|
||||
@@ -937,6 +937,20 @@ extension NSRange {
|
||||
}
|
||||
}
|
||||
|
||||
extension NSRange : _BridgedToObjectiveC {
|
||||
static func getObjectiveCType() -> Any.Type {
|
||||
return NSValue.self
|
||||
}
|
||||
|
||||
func bridgeToObjectiveC() -> NSValue {
|
||||
return NSValue(range: self)
|
||||
}
|
||||
|
||||
static func bridgeFromObjectiveC(x: NSValue) -> NSRange? {
|
||||
return x.rangeValue
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// NSZone
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,20 +5,16 @@
|
||||
import Foundation
|
||||
|
||||
func testFindFileAndURL(path: String) {
|
||||
var err: NSError? = .None
|
||||
|
||||
var usedEncoding = NSStringEncoding()
|
||||
var content = String.stringWithContentsOfFile(
|
||||
path, usedEncoding: &usedEncoding, error: &err)
|
||||
var err: NSError?
|
||||
var content = String.stringWithContentsOfFile(path, error: &err)
|
||||
|
||||
println("error: " + (err ? err.description : "<no error>"))
|
||||
println("content: " + (content ? content!._lines[0] : "<no content>"))
|
||||
|
||||
var url = NSURL.URLWithString("file://" + path)
|
||||
|
||||
err = .None
|
||||
content = String.stringWithContentsOfURL(
|
||||
url, usedEncoding: &usedEncoding, error: &err)
|
||||
err = nil
|
||||
content = String.stringWithContentsOfURL(url, error: &err)
|
||||
|
||||
println("error: " + (err ? err.description : "<no error>"))
|
||||
println("content: " + (content ? content!._lines[0] : "<no content>"))
|
||||
@@ -40,18 +36,19 @@ func testClassMethods() {
|
||||
}
|
||||
|
||||
// CHECK-NEXT: It is called
|
||||
println("It is called \"\(String.localizedNameOfStringEncoding(defaultCStringEncoding))\"")
|
||||
println(
|
||||
"It is called \"" +
|
||||
String.localizedNameOfStringEncoding(defaultCStringEncoding) + "\"")
|
||||
|
||||
var path = String.pathWithComponents(["flugelhorn", "baritone", "bass"])
|
||||
// CHECK-NEXT: <flugelhorn/baritone/bass>
|
||||
println("<\(path)>")
|
||||
|
||||
// CHECK-NEXT: true
|
||||
println(String.string() == "")
|
||||
|
||||
// CHECK-NEXT: <sox>
|
||||
var chars: unichar[] = [ unichar("s".value), unichar("o".value), unichar("x".value) ]
|
||||
var sox: String = String.stringWithCharacters(chars)
|
||||
var chars: unichar[] = [
|
||||
unichar("s".value), unichar("o".value), unichar("x".value) ]
|
||||
|
||||
var sox: String = String(utf16CodeUnits: chars, count: chars.count)
|
||||
println("<\(sox)>")
|
||||
|
||||
var pathToThisSource = Process.arguments[1]
|
||||
@@ -70,22 +67,32 @@ func testClassMethods() {
|
||||
testFindFileAndURL(pathToThisSource)
|
||||
|
||||
// CHECK-NEXT: foo, a basmati bar!
|
||||
println(String.stringWithCString("foo, a basmati bar!", encoding: String.defaultCStringEncoding()))
|
||||
println(
|
||||
String.stringWithCString(
|
||||
"foo, a basmati bar!", encoding: String.defaultCStringEncoding()))
|
||||
|
||||
var emptyString = ""
|
||||
|
||||
// CHECK-NEXT: {{.*}} has 0 completions and the longest is <>
|
||||
var outputName: String? = ""
|
||||
var count = nonExistentPath.completePathIntoString(&outputName, caseSensitive: false)
|
||||
println("<\(nonExistentPath)> has \(count) completions and the longest is <\(outputName ? outputName! : emptyString)>")
|
||||
// CHECK-NEXT: {{.*}} has 0 completions and the longest is <None Found>
|
||||
var outputName = "None Found"
|
||||
var count = nonExistentPath.completePathIntoString(
|
||||
&outputName, caseSensitive: false)
|
||||
|
||||
println(
|
||||
"<\(nonExistentPath)> has \(count) "
|
||||
+ "completions and the longest is <\(outputName)>")
|
||||
|
||||
// CHECK-NEXT: <[[THISPATH:.*]]> has 1 completions and the longest is <[[THISPATH]]>
|
||||
count = pathToThisSource.completePathIntoString(&outputName, caseSensitive: false)
|
||||
println("<\(pathToThisSource)> has \(count) completions and the longest is <\(outputName ? outputName! : emptyString)>")
|
||||
count = pathToThisSource.completePathIntoString(
|
||||
&outputName, caseSensitive: false)
|
||||
|
||||
println(
|
||||
"<\(pathToThisSource)> has \(count) "
|
||||
+ "completions and the longest is <\(outputName)>")
|
||||
|
||||
var world: NSString = "world"
|
||||
// CHECK-NEXT: Hello, world!%42
|
||||
println(String.stringWithFormat("Hello, %@!%%%ld", world, 42))
|
||||
println(String(format: "Hello, %@!%%%ld", world, 42))
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user