mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
77 lines
2.6 KiB
Swift
77 lines
2.6 KiB
Swift
//===--- CocoaArray.swift - A subset of the NSArray interface -------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See http://swift.org/LICENSE.txt for license information
|
|
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// To implement bridging, the core standard library needs to interact
|
|
// a little bit with Cocoa. Because we want to keep the core
|
|
// decoupled from the Foundation module, we can't use NSArray
|
|
// directly. We _can_, however, use an @objc protocol with a
|
|
// compatible API. That's _NSArrayCore.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#if _runtime(_ObjC)
|
|
import SwiftShims
|
|
|
|
/// A wrapper around any `_NSArrayCore` that gives it
|
|
/// `Collection` conformance. Why not make
|
|
/// `_NSArrayCore` conform directly? It's a class, and I
|
|
/// don't want to pay for the dynamic dispatch overhead.
|
|
internal struct _CocoaArrayWrapper : Collection {
|
|
var startIndex: Int {
|
|
return 0
|
|
}
|
|
|
|
var endIndex: Int {
|
|
return buffer.count
|
|
}
|
|
|
|
subscript(i: Int) -> AnyObject {
|
|
return buffer.objectAtIndex(i)
|
|
}
|
|
|
|
/// Returns a pointer to the first element in the given subRange if
|
|
/// the subRange is stored contiguously. Otherwise, return `nil`.
|
|
///
|
|
/// - Note: This method should only be used as an optimization; it
|
|
/// is sometimes conservative and may return `nil` even when
|
|
/// contiguous storage exists, e.g., if array doesn't have a smart
|
|
/// implementation of countByEnumeratingWithState.
|
|
func contiguousStorage(
|
|
subRange: Range<Int>
|
|
) -> UnsafeMutablePointer<AnyObject>
|
|
{
|
|
var enumerationState = _makeSwiftNSFastEnumerationState()
|
|
|
|
// This function currently returns nil unless the first
|
|
// subRange.endIndex items are stored contiguously. This is an
|
|
// acceptable conservative behavior, but could potentially be
|
|
// optimized for other cases.
|
|
let contiguousCount = withUnsafeMutablePointer(&enumerationState) {
|
|
self.buffer.countByEnumeratingWithState($0, objects: nil, count: 0)
|
|
}
|
|
|
|
return contiguousCount >= subRange.endIndex
|
|
? unsafeBitCast(
|
|
enumerationState.itemsPtr, UnsafeMutablePointer<AnyObject>.self
|
|
) + subRange.startIndex
|
|
: nil
|
|
}
|
|
|
|
@_transparent
|
|
init(_ buffer: _NSArrayCore) {
|
|
self.buffer = buffer
|
|
}
|
|
|
|
var buffer: _NSArrayCore
|
|
}
|
|
#endif
|