Untitled diff

Created Diff never expires
76 removals
Lines
Total
Removed
Words
Total
Removed
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
719 lines
75 additions
Lines
Total
Added
Words
Total
Added
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
715 lines
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
//
//
// This source file is part of the Swift.org open source project
// This source file is part of the Swift.org open source project
//
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
// Licensed under Apache License v2.0 with Runtime Library Exception
//
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
//
//
// Exposing the API of NSString on Swift's String
// Exposing the API of NSString on Swift's String
//
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//


@_exported import Foundation // Clang module

// Open Issues
// Open Issues
// ===========
// ===========
//
//
// Property Lists need to be properly bridged
// Property Lists need to be properly bridged
//
//


func _toNSArray<T, U : AnyObject>(_ a: [T], f: (T) -> U) -> NSArray {
func _toNSArray<T, U : AnyObject>(_ a: [T], f: (T) -> U) -> NSArray {
let result = NSMutableArray(capacity: a.count)
let result = NSMutableArray(capacity: a.count)
for s in a {
for s in a {
result.add(f(s))
result.add(f(s))
}
}
return result
return result
}
}


func _toNSRange(_ r: Range<String.Index>) -> NSRange {
func _toNSRange(_ r: Range<String.Index>) -> NSRange {
return NSRange(
return NSRange(
location: r.lowerBound.encodedOffset,
location: r.lowerBound.encodedOffset,
length: r.upperBound.encodedOffset - r.lowerBound.encodedOffset)
length: r.upperBound.encodedOffset - r.lowerBound.encodedOffset)
}
}


// We only need this for UnsafeMutablePointer, but there's not currently a way
// to write that constraint.
extension Optional {
/// Invokes `body` with `nil` if `self` is `nil`; otherwise, passes the
/// address of `object` to `body`.
///
/// This is intended for use with Foundation APIs that return an Objective-C
/// type via out-parameter where it is important to be able to *ignore* that
/// parameter by passing `nil`. (For some APIs, this may allow the
/// implementation to avoid some work.)
///
/// In most cases it would be simpler to just write this code inline, but if
/// `body` is complicated than that results in unnecessarily repeated code.
internal func _withNilOrAddress<NSType : AnyObject, ResultType>(
of object: inout NSType?,
_ body:
(AutoreleasingUnsafeMutablePointer<NSType?>?) -> ResultType
) -> ResultType {
return self == nil ? body(nil) : body(&object)
}
}

extension String {
extension String {
//===--- Class Methods --------------------------------------------------===//
//===--- Class Methods --------------------------------------------------===//
//===--------------------------------------------------------------------===//
//===--------------------------------------------------------------------===//


// @property (class) const NSStringEncoding *availableStringEncodings;
// @property (class) const NSStringEncoding *availableStringEncodings;


/// An array of the encodings that strings support in the application's
/// An array of the encodings that strings support in the application's
/// environment.
/// environment.
public static var availableStringEncodings: [Encoding] {
public static var availableStringEncodings: [Encoding] {
var result = [Encoding]()
var result = [Encoding]()
var p = NSString.availableStringEncodings
var p = NSString.availableStringEncodings
while p.pointee != 0 {
while p.pointee != 0 {
result.append(Encoding(rawValue: p.pointee))
result.append(Encoding(rawValue: p.pointee))
p += 1
p += 1
}
}
return result
return result
}
}


// @property (class) NSStringEncoding defaultCStringEncoding;
// @property (class) NSStringEncoding defaultCStringEncoding;


/// The C-string encoding assumed for any method accepting a C string as an
/// The C-string encoding assumed for any method accepting a C string as an
/// argument.
/// argument.
public static var defaultCStringEncoding: Encoding {
public static var defaultCStringEncoding: Encoding {
return Encoding(rawValue: NSString.defaultCStringEncoding)
return Encoding(rawValue: NSString.defaultCStringEncoding)
}
}


// + (NSString *)localizedNameOfStringEncoding:(NSStringEncoding)encoding
// + (NSString *)localizedNameOfStringEncoding:(NSStringEncoding)encoding


/// Returns a human-readable string giving the name of the specified encoding.
/// Returns a human-readable string giving the name of the specified encoding.
///
///
/// - Parameter encoding: A string encoding. For possible values, see
/// - Parameter encoding: A string encoding. For possible values, see
/// `String.Encoding`.
/// `String.Encoding`.
/// - Returns: A human-readable string giving the name of `encoding` in the
/// - Returns: A human-readable string giving the name of `encoding` in the
/// current locale.
/// current locale.
public static func localizedName(
public static func localizedName(
of encoding: Encoding
of encoding: Encoding
) -> String {
) -> String {
return NSString.localizedName(of: encoding.rawValue)
return NSString.localizedName(of: encoding.rawValue)
}
}


// + (instancetype)localizedStringWithFormat:(NSString *)format, ...
// + (instancetype)localizedStringWithFormat:(NSString *)format, ...


/// Returns a string created by using a given format string as a
/// Returns a string created by using a given format string as a
/// template into which the remaining argument values are substituted
/// template into which the remaining argument values are substituted
/// according to the user's default locale.
/// according to the user's default locale.
public static func localizedStringWithFormat(
public static func localizedStringWithFormat(
_ format: String, _ arguments: CVarArg...
_ format: String, _ arguments: CVarArg...
) -> String {
) -> String {
return String(format: format, locale: Locale.current,
return String(format: format, locale: Locale.current,
arguments: arguments)
arguments: arguments)
}
}


//===--------------------------------------------------------------------===//
//===--------------------------------------------------------------------===//
// NSString factory functions that have a corresponding constructor
// NSString factory functions that have a corresponding constructor
// are omitted.
// are omitted.
//
//
// + (instancetype)string
// + (instancetype)string
//
//
// + (instancetype)
// + (instancetype)
// stringWithCharacters:(const unichar *)chars length:(NSUInteger)length
// stringWithCharacters:(const unichar *)chars length:(NSUInteger)length
//
//
// + (instancetype)stringWithFormat:(NSString *)format, ...
// + (instancetype)stringWithFormat:(NSString *)format, ...
//
//
// + (instancetype)
// + (instancetype)
// stringWithContentsOfFile:(NSString *)path
// stringWithContentsOfFile:(NSString *)path
// encoding:(NSStringEncoding)enc
// encoding:(NSStringEncoding)enc
// error:(NSError **)error
// error:(NSError **)error
//
//
// + (instancetype)
// + (instancetype)
// stringWithContentsOfFile:(NSString *)path
// stringWithContentsOfFile:(NSString *)path
// usedEncoding:(NSStringEncoding *)enc
// usedEncoding:(NSStringEncoding *)enc
// error:(NSError **)error
// error:(NSError **)error
//
//
// + (instancetype)
// + (instancetype)
// stringWithContentsOfURL:(NSURL *)url
// stringWithContentsOfURL:(NSURL *)url
// encoding:(NSStringEncoding)enc
// encoding:(NSStringEncoding)enc
// error:(NSError **)error
// error:(NSError **)error
//
//
// + (instancetype)
// + (instancetype)
// stringWithContentsOfURL:(NSURL *)url
// stringWithContentsOfURL:(NSURL *)url
// usedEncoding:(NSStringEncoding *)enc
// usedEncoding:(NSStringEncoding *)enc
// error:(NSError **)error
// error:(NSError **)error
//
//
// + (instancetype)
// + (instancetype)
// stringWithCString:(const char *)cString
// stringWithCString:(const char *)cString
// encoding:(NSStringEncoding)enc
// encoding:(NSStringEncoding)enc
//===--------------------------------------------------------------------===//
//===--------------------------------------------------------------------===//


//===--- Adds nothing for String beyond what String(s) does -------------===//
//===--- Adds nothing for String beyond what String(s) does -------------===//
// + (instancetype)stringWithString:(NSString *)aString
// + (instancetype)stringWithString:(NSString *)aString
//===--------------------------------------------------------------------===//
//===--------------------------------------------------------------------===//


// + (instancetype)stringWithUTF8String:(const char *)bytes
// + (instancetype)stringWithUTF8String:(const char *)bytes


/// Creates a string by copying the data from a given
/// Creates a string by copying the data from a given
/// C array of UTF8-encoded bytes.
/// C array of UTF8-encoded bytes.
public init?(utf8String bytes: UnsafePointer<CChar>) {
public init?(utf8String bytes: UnsafePointer<CChar>) {
if let ns = NSString(utf8String: bytes) {
if let ns = NSString(utf8String: bytes) {
self = ns as String
self = ns._swiftObject
} else {
} else {
return nil
return nil
}
}
}
}
}
}


extension String {
extension String {
//===--- Already provided by String's core ------------------------------===//
//===--- Already provided by String's core ------------------------------===//
// - (instancetype)init
// - (instancetype)init


//===--- Initializers that can fail -------------------------------------===//
//===--- Initializers that can fail -------------------------------------===//
// - (instancetype)
// - (instancetype)
// initWithBytes:(const void *)bytes
// initWithBytes:(const void *)bytes
// length:(NSUInteger)length
// length:(NSUInteger)length
// encoding:(NSStringEncoding)encoding
// encoding:(NSStringEncoding)encoding


/// Creates a new string equivalent to the given bytes interpreted in the
/// Creates a new string equivalent to the given bytes interpreted in the
/// specified encoding.
/// specified encoding.
///
///
/// - Parameters:
/// - Parameters:
/// - bytes: A sequence of bytes to interpret using `encoding`.
/// - bytes: A sequence of bytes to interpret using `encoding`.
/// - encoding: The ecoding to use to interpret `bytes`.
/// - encoding: The ecoding to use to interpret `bytes`.
public init? <S: Sequence>(bytes: S, encoding: Encoding)
public init? <S: Sequence>(bytes: S, encoding: Encoding)
where S.Iterator.Element == UInt8 {
where S.Iterator.Element == UInt8 {
let byteArray = Array(bytes)
let byteArray = Array(bytes)
if let ns = NSString(
if let ns = NSString(
bytes: byteArray, length: byteArray.count, encoding: encoding.rawValue) {
bytes: byteArray, length: byteArray.count, encoding: encoding.rawValue) {

self = String._unconditionallyBridgeFromObjectiveC(ns)
self = ns as String
} else {
} else {
return nil
return nil
}
}
}
}


// - (instancetype)
// - (instancetype)
// initWithBytesNoCopy:(void *)bytes
// initWithBytesNoCopy:(void *)bytes
// length:(NSUInteger)length
// length:(NSUInteger)length
// encoding:(NSStringEncoding)encoding
// encoding:(NSStringEncoding)encoding
// freeWhenDone:(BOOL)flag
// freeWhenDone:(BOOL)flag


/// Creates a new string that contains the specified number of bytes from the
/// Creates a new string that contains the specified number of bytes from the
/// given buffer, interpreted in the specified encoding, and optionally
/// given buffer, interpreted in the specified encoding, and optionally
/// frees the buffer.
/// frees the buffer.
///
///
/// - Warning: This initializer is not memory-safe!
/// - Warning: This initializer is not memory-safe!
public init?(
public init?(
bytesNoCopy bytes: UnsafeMutableRawPointer, length: Int,
bytesNoCopy bytes: UnsafeMutableRawPointer, length: Int,
encoding: Encoding, freeWhenDone flag: Bool
encoding: Encoding, freeWhenDone flag: Bool
) {
) {
if let ns = NSString(
if let ns = NSString(
bytesNoCopy: bytes, length: length, encoding: encoding.rawValue,
bytesNoCopy: bytes, length: length, encoding: encoding.rawValue,
freeWhenDone: flag) {
freeWhenDone: flag) {

self = String._unconditionallyBridgeFromObjectiveC(ns)
self = ns as String
} else {
} else {
return nil
return nil
}
}
}
}




// - (instancetype)
// - (instancetype)
// initWithCharacters:(const unichar *)characters
// initWithCharacters:(const unichar *)characters
// length:(NSUInteger)length
// length:(NSUInteger)length


/// Creates a new string that contains the specified number of characters
/// Creates a new string that contains the specified number of characters
/// from the given C array of Unicode characters.
/// from the given C array of Unicode characters.
public init(
public init(
utf16CodeUnits: UnsafePointer<unichar>,
utf16CodeUnits: UnsafePointer<unichar>,
count: Int
count: Int
) {
) {
self = NSString(characters: utf16CodeUnits, length: count) as String
self = String._unconditionallyBridgeFromObjectiveC(NSString(characters: utf16CodeUnits, length: count))
}
}


// - (instancetype)
// - (instancetype)
// initWithCharactersNoCopy:(unichar *)characters
// initWithCharactersNoCopy:(unichar *)characters
// length:(NSUInteger)length
// length:(NSUInteger)length
// freeWhenDone:(BOOL)flag
// freeWhenDone:(BOOL)flag


/// Creates a new string that contains the specified number of characters
/// Creates a new string that contains the specified number of characters
/// from the given C array of UTF-16 code units.
/// from the given C array of UTF-16 code units.
public init(
public init(
utf16CodeUnitsNoCopy: UnsafePointer<unichar>,
utf16CodeUnitsNoCopy: UnsafePointer<unichar>,
count: Int,
count: Int,
freeWhenDone flag: Bool
freeWhenDone flag: Bool
) {
) {
self = NSString(
self = String._unconditionallyBridgeFromObjectiveC(NSString(
charactersNoCopy: UnsafeMutablePointer(mutating: utf16CodeUnitsNoCopy),
charactersNoCopy: UnsafeMutablePointer(mutating: utf16CodeUnitsNoCopy),
length: count,
length: count,
freeWhenDone: flag) as String
freeWhenDone: flag))
}
}


//===--- Initializers that can fail -------------------------------------===//
//===--- Initializers that can fail -------------------------------------===//


// - (instancetype)
// - (instancetype)
// initWithContentsOfFile:(NSString *)path
// initWithContentsOfFile:(NSString *)path
// encoding:(NSStringEncoding)enc
// encoding:(NSStringEncoding)enc
// error:(NSError **)error
// error:(NSError **)error
//
//


/// Produces a string created by reading data from the file at a
/// Produces a string created by reading data from the file at a
/// given path interpreted using a given encoding.
/// given path interpreted using a given encoding.
public init(
public init(
contentsOfFile path: String,
contentsOfFile path: String,
encoding enc: Encoding
encoding enc: Encoding
) throws {
) throws {
let ns = try NSString(contentsOfFile: path, encoding: enc.rawValue)
let ns = try NSString(contentsOfFile: path, encoding: enc.rawValue)
self = ns as String
self = String._unconditionallyBridgeFromObjectiveC(ns)
}
}


// - (instancetype)
// - (instancetype)
// initWithContentsOfFile:(NSString *)path
// initWithContentsOfFile:(NSString *)path
// usedEncoding:(NSStringEncoding *)enc
// usedEncoding:(NSStringEncoding *)enc
// error:(NSError **)error
// error:(NSError **)error


/// Produces a string created by reading data from the file at
/// Produces a string created by reading data from the file at
/// a given path and returns by reference the encoding used to
/// a given path and returns by reference the encoding used to
/// interpret the file.
/// interpret the file.
public init(
public init(
contentsOfFile path: String,
contentsOfFile path: String,
usedEncoding: inout Encoding
usedEncoding: inout Encoding
) throws {
) throws {
var enc: UInt = 0
var enc: UInt = 0
let ns = try NSString(contentsOfFile: path, usedEncoding: &enc)
let ns = try NSString(contentsOfFile: path, usedEncoding: &enc)
usedEncoding = Encoding(rawValue: enc)
usedEncoding = Encoding(rawValue: enc)
self = ns as String
self = String._unconditionallyBridgeFromObjectiveC(ns)
}
}


public init(
public init(
contentsOfFile path: String
contentsOfFile path: String
) throws {
) throws {
let ns = try NSString(contentsOfFile: path, usedEncoding: nil)
let ns = try NSString(contentsOfFile: path, usedEncoding: nil)
self = ns as String
self = String._unconditionallyBridgeFromObjectiveC(ns)
}
}


// - (instancetype)
// - (instancetype)
// initWithContentsOfURL:(NSURL *)url
// initWithContentsOfURL:(NSURL *)url
// encoding:(NSStringEncoding)enc
// encoding:(NSStringEncoding)enc
// error:(NSError**)error
// error:(NSError**)error


/// Produces a string created by reading data from a given URL
/// Produces a string created by reading data from a given URL
/// interpreted using a given encoding. Errors are written into the
/// interpreted using a given encoding. Errors are written into the
/// inout `error` argument.
/// inout `error` argument.
public init(
public init(
contentsOf url: URL,
contentsOf url: URL,
encoding enc: Encoding
encoding enc: Encoding
) throws {
) throws {
let ns = try NSString(contentsOf: url, encoding: enc.rawValue)
let ns = try NSString(contentsOf: url, encoding: enc.rawValue)
self = ns as String
self = String._unconditionallyBridgeFromObjectiveC(ns)
}
}


// - (instancetype)
// - (instancetype)
// initWithContentsOfURL:(NSURL *)url
// initWithContentsOfURL:(NSURL *)url
// usedEncoding:(NSStringEncoding *)enc
// usedEncoding:(NSStringEncoding *)enc
// error:(NSError **)error
// error:(NSError **)error


/// Produces a string created by reading data from a given URL
/// Produces a string created by reading data from a given URL
/// and returns by reference the encoding used to interpret the
/// and returns by reference the encoding used to interpret the
/// data. Errors are written into the inout `error` argument.
/// data. Errors are written into the inout `error` argument.
public init(
public init(
contentsOf url: URL,
contentsOf url: URL,
usedEncoding: inout Encoding
usedEncoding: inout Encoding
) throws {
) throws {
var enc: UInt = 0
var enc: UInt = 0
let ns = try NSString(contentsOf: url as URL, usedEncoding: &enc)
let ns = try NSString(contentsOf: url as URL, usedEncoding: &enc)
usedEncoding = Encoding(rawValue: enc)
usedEncoding = Encoding(rawValue: enc)
self = ns as String
self = String._unconditionallyBridgeFromObjectiveC(ns)
}
}


public init(
public init(
contentsOf url: URL
contentsOf url: URL
) throws {
) throws {
let ns = try NSString(contentsOf: url, usedEncoding: nil)
let ns = try NSString(contentsOf: url, usedEncoding: nil)
self = ns as String
self = String._unconditionallyBridgeFromObjectiveC(ns)
}
}


// - (instancetype)
// - (instancetype)
// initWithCString:(const char *)nullTerminatedCString
// initWithCString:(const char *)nullTerminatedCString
// encoding:(NSStringEncoding)encoding
// encoding:(NSStringEncoding)encoding


/// Produces a string containing the bytes in a given C array,
/// Produces a string containing the bytes in a given C array,
/// interpreted according to a given encoding.
/// interpreted according to a given encoding.
public init?(
public init?(
cString: UnsafePointer<CChar>,
cString: UnsafePointer<CChar>,
encoding enc: Encoding
encoding enc: Encoding
) {
) {
if let ns = NSString(cString: cString, encoding: enc.rawValue) {
if let ns = NSString(cString: cString, encoding: enc.rawValue) {
self = ns as String
self = String._unconditionallyBridgeFromObjectiveC(ns)
} else {
} else {
return nil
return nil
}
}
}
}


// FIXME: handle optional locale with default arguments
// FIXME: handle optional locale with default arguments


// - (instancetype)
// - (instancetype)
// initWithData:(NSData *)data
// initWithData:(NSData *)data
// encoding:(NSStringEncoding)encoding
// encoding:(NSStringEncoding)encoding


/// Returns a `String` initialized by converting given `data` into
/// Returns a `String` initialized by converting given `data` into
/// Unicode characters using a given `encoding`.
/// Unicode characters using a given `encoding`.
public init?(data: Data, encoding: Encoding) {
public init?(data: Data, encoding: Encoding) {
guard let s = NSString(data: data, encoding: encoding.rawValue) else { return nil }
guard let s = NSString(data: data, encoding: encoding.rawValue) else { return nil }
self = s as String
self = String._unconditionallyBridgeFromObjectiveC(s)
}
}


// - (instancetype)initWithFormat:(NSString *)format, ...
// - (instancetype)initWithFormat:(NSString *)format, ...


/// Returns a `String` object initialized by using a given
/// Returns a `String` object initialized by using a given
/// format string as a template into which the remaining argument
/// format string as a template into which the remaining argument
/// values are substituted.
/// values are substituted.
public init(format: String, _ arguments: CVarArg...) {
public init(format: String, _ arguments: CVarArg...) {
self = String(format: format, arguments: arguments)
self = String(format: format, arguments: arguments)
}
}


// - (instancetype)
// - (instancetype)
// initWithFormat:(NSString *)format
// initWithFormat:(NSString *)format
// arguments:(va_list)argList
// arguments:(va_list)argList


/// Returns a `String` object initialized by using a given
/// Returns a `String` object initialized by using a given
/// format string as a template into which the remaining argument
/// format string as a template into which the remaining argument
/// values are substituted according to the user's default locale.
/// values are substituted according to the user's default locale.
public init(format: String, arguments: [CVarArg]) {
public init(format: String, arguments: [CVarArg]) {
self = String(format: format, locale: nil, arguments: arguments)
self = String(format: format, locale: nil, arguments: arguments)
}
}


// - (instancetype)initWithFormat:(NSString *)format locale:(id)locale, ...
// - (instancetype)initWithFormat:(NSString *)format locale:(id)locale, ...


/// Returns a `String` object initialized by using a given
/// Returns a `String` object initialized by using a given
/// format string as a template into which the remaining argument
/// format string as a template into which the remaining argument
/// values are substituted according to given locale information.
/// values are substituted according to given locale information.
public init(format: String, locale: Locale?, _ args: CVarArg...) {
public init(format: String, locale: Locale?, _ args: CVarArg...) {
self = String(format: format, locale: locale, arguments: args)
self = String(format: format, locale: locale, arguments: args)
}
}


// - (instancetype)
// - (instancetype)
// initWithFormat:(NSString *)format
// initWithFormat:(NSString *)format
// locale:(id)locale
// locale:(id)locale
// arguments:(va_list)argList
// arguments:(va_list)argList


/// Returns a `String` object initialized by using a given
/// Returns a `String` object initialized by using a given
/// format string as a template into which the remaining argument
/// format string as a template into which the remaining argument
/// values are substituted according to given locale information.
/// values are substituted according to given locale information.
public init(format: String, locale: Locale?, arguments: [CVarArg]) {
public init(format: String, locale: Locale?, arguments: [CVarArg]) {
self = withVaList(arguments) {
self = withVaList(arguments) {
NSString(format: format, locale: locale, arguments: $0) as String
String._unconditionallyBridgeFromObjectiveC(
NSString(format: format, locale: locale?._bridgeToObjectiveC(), arguments: $0)
)
}
}
}
}


}
}


extension StringProtocol where Index == String.Index {
extension StringProtocol where Index == String.Index {
//===--- Bridging Helpers -----------------------------------------------===//
//===--- Bridging Helpers -----------------------------------------------===//
//===--------------------------------------------------------------------===//
//===--------------------------------------------------------------------===//


/// The corresponding `NSString` - a convenience for bridging code.
/// The corresponding `NSString` - a convenience for bridging code.
// FIXME(strings): There is probably a better way to bridge Self to NSString
// FIXME(strings): There is probably a better way to bridge Self to NSString
var _ns: NSString {
var _ns: NSString {
return self._ephemeralString as NSString
return self._ephemeralString._bridgeToObjectiveC()
}
}


/// Return an `Index` corresponding to the given offset in our UTF-16
/// Return an `Index` corresponding to the given offset in our UTF-16
/// representation.
/// representation.
func _index(_ utf16Index: Int) -> Index {
func _index(_ utf16Index: Int) -> Index {
return Index(encodedOffset: utf16Index)
return Index(encodedOffset: utf16Index)
}
}


/// Return a `Range<Index>` corresponding to the given `NSRange` of
/// Return a `Range<Index>` corresponding to the given `NSRange` of
/// our UTF-16 representation.
/// our UTF-16 representation.
func _range(_ r: NSRange) -> Range<Index> {
func _range(_ r: NSRange) -> Range<Index> {
return _index(r.location)..<_index(r.location + r.length)
return _index(r.location)..<_index(r.location + r.length)
}
}


/// Return a `Range<Index>?` corresponding to the given `NSRange` of
/// Return a `Range<Index>?` corresponding to the given `NSRange` of
/// our UTF-16 representation.
/// our UTF-16 representation.
func _optionalRange(_ r: NSRange) -> Range<Index>? {
func _optionalRange(_ r: NSRange) -> Range<Index>? {
if r.location == NSNotFound {
if r.location == NSNotFound {
return nil
return nil
}
}
return _range(r)
return _range(r)
}
}


/// Invoke `body` on an `Int` buffer. If `index` was converted from
/// Invoke `body` on an `Int` buffer. If `index` was converted from
/// non-`nil`, convert the buffer to an `Index` and write it into the
/// non-`nil`, convert the buffer to an `Index` and write it into the
/// memory referred to by `index`
/// memory referred to by `index`
func _withOptionalOutParameter<Result>(
func _withOptionalOutParameter<Result>(
_ index: UnsafeMutablePointer<Index>?,
_ index: UnsafeMutablePointer<Index>?,
_ body: (UnsafeMutablePointer<Int>?) -> Result
_ body: (UnsafeMutablePointer<Int>?) -> Result
) -> Result {
) -> Result {
var utf16Index: Int = 0
var utf16Index: Int = 0
let result = (index != nil ? body(&utf16Index) : body(nil))
let result = (index != nil ? body(&utf16Index) : body(nil))
index?.pointee = _index(utf16Index)
index?.pointee = _index(utf16Index)
return result
return result
}
}


/// Invoke `body` on an `NSRange` buffer. If `range` was converted
/// Invoke `body` on an `NSRange` buffer. If `range` was converted
/// from non-`nil`, convert the buffer to a `Range<Index>` and write
/// from non-`nil`, convert the buffer to a `Range<Index>` and write
/// it into the memory referred to by `range`
/// it into the memory referred to by `range`
func _withOptionalOutParameter<Result>(
func _withOptionalOutParameter<Result>(
_ range: UnsafeMutablePointer<Range<Index>>?,
_ range: UnsafeMutablePointer<Range<Index>>?,
_ body: (UnsafeMutablePointer<NSRange>?) -> Result
_ body: (UnsafeMutablePointer<NSRange>?) -> Result
) -> Result {
) -> Result {
var nsRange = NSRange(location: 0, length: 0)
var nsRange = NSRange(location: 0, length: 0)
let result = (range != nil ? body(&nsRange) : body(nil))
let result = (range != nil ? body(&nsRange) : body(nil))
range?.pointee = self._range(nsRange)
range?.pointee = self._range(nsRange)
return result
return result
}
}


//===--- Instance Methods/Properties-------------------------------------===//
//===--- Instance Methods/Properties-------------------------------------===//
//===--------------------------------------------------------------------===//
//===--------------------------------------------------------------------===//


//===--- Omitted by agreement during API review 5/20/2014 ---------------===//
//===--- Omitted by agreement during API review 5/20/2014 ---------------===//
// @property BOOL boolValue;
// @property BOOL boolValue;


// - (BOOL)canBeConvertedToEncoding:(NSStringEncoding)encoding
// - (BOOL)canBeConvertedToEncoding:(NSStringEncoding)encoding


/// Returns a Boolean value that indicates whether the string can be
/// Returns a Boolean value that indicates whether the string can be
/// converted to the specified encoding without loss of information.
/// converted to the specified encoding without loss of information.
///
///
/// - Parameter encoding: A string encoding.
/// - Parameter encoding: A string encoding.
/// - Returns: `true` if the string can be encoded in `encoding` without loss
/// - Returns: `true` if the string can be encoded in `encoding` without loss
/// of information; otherwise, `false`.
/// of information; otherwise, `false`.
public func canBeConverted(to encoding: String.Encoding) -> Bool {
public func canBeConverted(to encoding: String.Encoding) -> Bool {
return _ns.canBeConverted(to: encoding.rawValue)
return _ns.canBeConverted(to: encoding.rawValue)
}
}


// @property NSString* capitalizedString
// @property NSString* capitalizedString


/// A copy of the string with each word changed to its corresponding
/// A copy of the string with each word changed to its corresponding
/// capitalized spelling.
/// capitalized spelling.
///
///
/// This property performs the canonical (non-localized) mapping. It is
/// This property performs the canonical (non-localized) mapping. It is
/// suitable for programming operations that require stable results not
/// suitable for programming operations that require stable results not
/// depending on the current locale.
/// depending on the current locale.
///
///
/// A capitalized string is a string with the first character in each word
/// A capitalized string is a string with the first character in each word
/// changed to its corresponding uppercase value, and all remaining
/// changed to its corresponding uppercase value, and all remaining
/// characters set to their corresponding lowercase values. A "word" is any
/// characters set to their corresponding lowercase values. A "word" is any
/// sequence of characters delimited by spaces, tabs, or line terminators.
/// sequence of characters delimited by spaces, tabs, or line terminators.
/// Some common word delimiting punctuation isn't considered, so this
/// Some common word delimiting punctuation isn't considered, so this
/// property may not generally produce the desired results for multiword
/// property may not generally produce the desired results for multiword
/// strings. See the `getLineStart(_:end:contentsEnd:for:)` method for
/// strings. See the `getLineStart(_:end:contentsEnd:for:)` method for
/// additional information.
/// additional information.
///
///
/// Case transformations aren’t guaranteed to be symmetrical or to produce
/// Case transformations aren’t guaranteed to be symmetrical or to produce
/// strings of the same lengths as the originals.
/// strings of the same lengths as the originals.
public var capitalized: String {
public var capitalized: String {
return _ns.capitalized as String
return _ns.capitalized as String
}
}


// @property (readonly, copy) NSString *localizedCapitalizedString NS_AVAILABLE(10_11, 9_0);
// @property (readonly, copy) NSString *localizedCapitalizedString NS_AVAILABLE(10_11, 9_0);


/// A capitalized representation of the string that is produced
/// A capitalized representation of the string that is produced
/// using the current locale.
/// using the current locale.
@available(OSX 10.11, iOS 9.0, *)
@available(OSX 10.11, iOS 9.0, *)
public var localizedCapitalized: String {
public var localizedCapitalized: String {
return _ns.localizedCapitalized
return _ns.localizedCapitalized
}
}


// - (NSString *)capitalizedStringWithLocale:(Locale *)locale
// - (NSString *)capitalizedStringWithLocale:(Locale *)locale


/// Returns a capitalized representation of the string
/// Returns a capitalized representation of the string
/// using the specified locale.
/// using the specified locale.
public func capitalized(with locale: Locale?) -> String {
public func capitalized(with locale: Locale?) -> String {
return _ns.capitalized(with: locale) as String
return _ns.capitalized(with: locale) as String
}
}


// - (NSComparisonResult)caseInsensitiveCompare:(NSString *)aString
// - (NSComparisonResult)caseInsensitiveCompare:(NSString *)aString


/// Returns the result of invoking `compare:options:` with
/// Returns the result of invoking `compare:options:` with
/// `NSCaseInsensitiveSearch` as the only option.
/// `NSCaseInsensitiveSearch` as the only option.
public func caseInsensitiveCompare<
public func caseInsensitiveCompare<
T : StringProtocol
T : StringProtocol
>(_ aString: T) -> ComparisonResult {
>(_ aString: T) -> ComparisonResult {
return _ns.caseInsensitiveCompare(aString._ephemeralString)
return _ns.caseInsensitiveCompare(aString._ephemeralString)
}
}


//===--- Omitted by agreement during API review 5/20/2014 ---------------===//
//===--- Omitted by agreement during API review 5/20/2014 ---------------===//
// - (unichar)characterAtIndex:(NSUInteger)index
// - (unichar)characterAtIndex:(NSUInteger)index
//
//
// We have a different meaning for "Character" in Swift, and we are
// We have a different meaning for "Character" in Swift, and we are
// trying not to expose error-prone UTF-16 integer indexes
// trying not to expose error-prone UTF-16 integer indexes


// - (NSString *)
// - (NSString *)
// commonPrefixWithString:(NSString *)aString
// commonPrefixWithString:(NSString *)aString
// options:(StringCompareOptions)mask
// options:(StringCompareOptions)mask


/// Returns a string containing characters this string and the
/// Returns a string containing characters this string and the
/// given string have in common, starting from the beginning of each
/// given string have in common, starting from the beginning of each
/// up to the first characters that aren't equivalent.
/// up to the first characters that aren't equivalent.
public func commonPrefix<
public func commonPrefix<
T : StringProtocol
T : StringProtocol
>(with aString: T, options: String.CompareOptions = []) -> String {
>(with aString: T, options: String.CompareOptions = []) -> String {
return _ns.commonPrefix(with: aString._ephemeralString, options: options)
return _ns.commonPrefix(with: aString._ephemeralString, options: options)
}
}


// - (NSComparisonResult)
// - (NSComparisonResult)
// compare:(NSString *)aString
// compare:(NSString *)aString
//
//
// - (NSComparisonResult)
// - (NSComparisonResult)
// compare:(NSString *)aString options:(StringCompareOptions)mask
// compare:(NSString *)aString options:(StringCompareOptions)mask
//
//
// - (NSComparisonResult)
// - (NSComparisonResult)
// compare:(NSString *)aString options:(StringCompareOptions)mask
// compare:(NSString *)aString options:(StringCompareOptions)mask
// range:(NSRange)range
// range:(NSRange)range
//
//
// - (NSComparisonResult)
// - (NSComparisonResult)
// compare:(NSString *)aString options:(StringCompareOptions)mask
// compare:(NSString *)aString options:(StringCompareOptions)mask
// range:(NSRange)range locale:(id)locale
// range:(NSRange)range locale:(id)locale


/// Compares the string using the specified options and
/// Compares the string using the specified options and
/// returns the lexical ordering for the range.
/// returns the lexical ordering for the range.
public func compare<T : StringProtocol>(
public func compare<T : StringProtocol>(
_ aString: T,
_ aString: T,
options mask: String.CompareOptions = [],
options mask: String.CompareOptions = [],
range: Range<Index>? = nil,
range: Range<Index>? = nil,
locale: Locale? = nil
locale: Locale? = nil
) -> ComparisonResult {
) -> ComparisonResult {
// According to Ali Ozer, there may be some real advantage to
// According to Ali Ozer, there may be some real advantage to
// dispatching to the minimal selector for the supplied options.
// dispatching to the minimal selector for the supplied options.
// So let's do that; the switch should compile away anyhow.
// So let's do that; the switch should compile away anyhow.
let aString = aString._ephemeralString
let aString = aString._ephemeralString
return locale != nil ? _ns.compare(
return locale != nil ? _ns.compare(
aString,
aString,
options: mask,
options: mask,
range: _toNSRange(
range: _toNSRange(
range ?? startIndex..<endIndex
range ?? startIndex..<endIndex
),
),
locale: locale
locale: locale?._bridgeToObjectiveC()
)
)


: range != nil ? _ns.compare(
: range != nil ? _ns.compare(
aString,
aString,
options: mask,
options: mask,
range: _toNSRange(range!)
range: _toNSRange(range!)
)
)


: !mask.isEmpty ? _ns.compare(aString, options: mask)
: !mask.isEmpty ? _ns.compare(aString, options: mask)


: _ns.compare(aString)
: _ns.compare(aString)
}
}


// - (NSUInteger)
// - (NSUInteger)
// completePathIntoString:(NSString **)outputName
// completePathIntoString:(NSString **)outputName
// caseSensitive:(BOOL)flag
// caseSensitive:(BOOL)flag
// matchesIntoArray:(NSArray **)outputArray
// matchesIntoArray:(NSArray **)outputArray
// filterTypes:(NSArray *)filterTypes
// filterTypes:(NSArray *)filterTypes


/// Interprets the string as a path in the file system and
/// Interprets the string as a path in the file system and
/// attempts to perform filename completion, returning a numeric
/// attempts to perform filename completion, returning a numeric
/// value that indicates whether a match was possible, and by
/// value that indicates whether a match was possible, and by
/// reference the longest path that matches the string.
/// reference the longest path that matches the string.
///
///
/// - Returns: The actual number of matching paths.
/// - Returns: The actual number of matching paths.
public func completePath(
public func completePath(
into outputName: UnsafeMutablePointer<String>? = nil,
into outputName: UnsafeMutablePointer<String>? = nil,
caseSensitive: Bool,
caseSensitive: Bool,
matchesInto outputArray: UnsafeMutablePointer<[String]>? = nil,
matchesInto outputArray: UnsafeMutablePointer<[String]>? = nil,
filterTypes: [String]? = nil
filterTypes: [String]? = nil
) -> Int {
) -> Int {
var nsMatches: NSArray?
var nsOutputName: NSString?

let result: Int = outputName._withNilOrAddress(of: &nsOutputName) {
outputName in outputArray._withNilOrAddress(of: &nsMatches) {
outputArray in
// FIXME: completePath(...) is incorrectly annotated as requiring
// non-optional output parameters. rdar://problem/25494184
let outputNonOptionalName = unsafeBitCast(
outputName, to: AutoreleasingUnsafeMutablePointer<NSString?>.self)
let outputNonOptionalArray = unsafeBitCast(
outputArray, to: AutoreleasingUnsafeMutablePointer<NSArray?>.self)
return self._ns.completePath(
into: outputNonOptionalName,
caseSensitive: caseSensitive,
matchesInto: outputNonOptionalArray,
filterTypes: filterTypes
)
}
}

if let matches = nsMatches {
// Since this function is effectively a bridge thunk, use the
// bridge thunk semantics for the NSArray conversion
outputArray?.pointee = matches as! [String]
}


if let n = nsOutputName {
var outputNamePlaceholder: String?
outputName?.pointee = n as String
var outputArrayPlaceholder = [String]()
let res = self._ns.completePath(
into: &outputNamePlaceholder,
caseSensitive: caseSensitive,
matchesInto: &outputArrayPlaceholder,
filterTypes: filterTypes
)
if let n = outputNamePlaceholder {
outputName?.pointee = n
} else {
outputName?.pointee = ""
}
}
return result
outputArray?.pointee = outputArrayPlaceholder
return res
}
}


// - (NSArray *)
// - (NSArray *)
// componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator
// componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator


/// Returns an array containing substrings from the string
/// Returns an array containing substrings from the string
/// that have been divided by characters in the given set.
/// that have been divided by characters in the given set.
public func components(separatedBy separator: CharacterSet) -> [String] {
public func components(separatedBy separator: CharacterSet) -> [String] {
return _ns.components(separatedBy: separator)
return _ns.components(separatedBy: separator)
}
}


// - (NSArray *)componentsSeparatedByString:(NSString *)separator
// - (NSArray *)componentsSeparatedByString:(NSString *)separator


/// Returns an array containing substrings from the string that have been
/// Returns an array containing substrings from the string that have been
/// divided by the given separator.
/// divided by the given separator.
///
///
/// The substrings in the resulting array appear in the same order as the
/// The substrings in the resulting array appear in the same order as the
/// original string. Adjacent occurrences of the separator string produce
/// original string. Adjacent occurrences of the separator string produce
/// empty strings in the result. Similarly, if the string begins or ends
/// empty strings in the result. Similarly, if the string begins or ends
/// with the separator, the first or last substring, respectively, is empty.
/// with the separator, the first or last substring, respectively, is empty.
/// The following example shows this behavior:
/// The following example shows this behavior:
///
///
/// let list1 = "Karin, Carrie, David"
/// let list1 = "Karin, Carrie, David"
/// let items1 = list1.components(separatedBy: ", ")
/// let items1 = list1.components(separatedBy: ", ")
/// // ["Karin", "Carrie", "David"]
/// // ["Karin", "Carrie", "David"]
///
///
/// // Beginning with the separator:
/// // Beginning with the separator:
/// let list2 = ", Norman, Stanley, Fletcher"
/// let list2 = ", Norman, Stanley, Fletcher"
/// let items2 = list2.components(separatedBy: ", ")
/// let items2 = list2.components(separatedBy: ", ")
/// // ["", "Norman", "Stanley", "Fletcher"
/// // ["", "Norman", "Stanley", "Fletcher"
///
///
/// If the list has no separators, the array contains only the original
/// If the list has no separators, the array contains only the original
/// string itself.
/// string itself.
///
///
/// let name = "Karin"
/// let name = "Karin"
/// let list = name.components(separatedBy: ", ")
/// let list = name.components(separatedBy: ", ")
/// // ["Karin"]
/// // ["Karin"]
///
///
/// - Parameter separator: The separator string.
/// - Parameter separator: The separator string.
/// - Returns: An array containing substrings that have been divided from the
/// - Returns: An array containing substrings that have been divided from the
/// string using `separator`.
/// string using `separator`.
// FIXME(strings): now when String conforms to Collection, this can be
// FIXME(strings): now when String conforms to Collection, this can be
// replaced by split(separator:maxSplits:omittingEmptySubsequences:)
// replaced by split(separator:maxSplits:omittingEmptySubsequences:)
public func components<
public func components<
T : StringProtocol
T : StringProtocol
>(separatedBy separator: T) -> [String] {
>(separatedBy separator: T) -> [String] {
return _ns.components(separatedBy: separator._ephemeralString)
return _ns.components(separatedBy: separator._ephemeralString)
}
}


// - (const char *)cStringUsingEncoding:(NSStringEncoding)encoding
// - (const char *)cStringUsingEncoding:(NSStringEncoding)encoding


/// Returns a representation of the string as a C string
/// Returns a representation of the string as a C string
/// using a given encoding.
/// using a given encoding.
public func cString(using encoding: String.Encoding) -> [CChar]? {
public func cString(using encoding: String.Encoding) -> [CChar]? {
return withExtendedLifetime(_ns) {
return withExtendedLifetime(_ns) {
(s: NSString) -> [CChar]? in
(s: NSString) -> [CChar]? in
_persistCString(s.cString(using: encoding.rawValue))
_persistCString(s.cString(using: encoding.rawValue))
}
}
}
}


// - (NSData *)dataUsingEncoding:(NSStringEncoding)encoding
// - (NSData *)dataUsingEncoding:(NSStringEncoding)encoding
//
//
// - (NSData *)
// - (NSData *)
// dataUsingEncoding:(NSStringEncoding)encoding
// dataUsingEncoding:(NSStringEncoding)encoding
// allowLossyConversion:(BOOL)flag
// allowLossyConversion:(BOOL)flag


/// Returns a `Data` containing a representation of
/// Returns a `Data` containing a representation of
/// the `String` encoded using a given encoding.
/// the `String` encoded using a given encoding.
public func data(
public func data(
using encoding:
using encoding: String.Encoding,
allowLossyConversion: Bool = false
) -> Data? {
return _ns.data(
using: encoding.rawValue,
allowLossyConversion: allowLossyConversion)
}

// @property NSString* decomposedStringWithCanonicalMapping;

/// A string created by normalizing the string's contents using Form D.
public var decomposedStringWithCanonicalMapping: String {
return _ns.decomposedStringWithCanonicalMapping
}

// @property NSString* decomposedStringWithCompatibilityMapping;

/// A string created by normalizing the string's contents using Form KD.
public var decomposedStringWithCompatibilityMapping: String {
return _ns.decomposedStringWithCompatibilityMapping
}

//===--- Importing Foundation should not affect String printing ---------===//
// Therefore, we're not exposing this:
//
// @property NSString* description


//===--- Omitted for consistency with API review results 5/20/2014 -----===//
// @property double doubleValue;

// - (void)
// enumerateLinesUsing:(void (^)(NSString *line, BOOL *stop))block

/// Enumerates all the lines in a string.
public func enum