[stdlib] On-demand unique contiguous Array storage

Lift the precondition that contiguous storage already exist on the use
of Array.withUnsafe[Mutable]PointerToElements.  Automatically guarantee
that storage is unique when using the mutable variants of these methods.

Also, fix some---essentially---inout aliasing violations in
test/stdlib/Unicode.swift that were revealed by the new careful
implementation of these methods.

Swift SVN r20339
This commit is contained in:
Dave Abrahams
2014-07-22 21:34:57 +00:00
parent 41dec5b58c
commit e570866bf6
5 changed files with 53 additions and 24 deletions

View File

@@ -354,26 +354,30 @@ extension _ArrayBuffer {
}
}
/// Call body(p), where p is a pointer to the underlying contiguous storage
/// Requires: such contiguous storage exists or the buffer is empty
/// Call `body(p)`, where `p` is a pointer to the underlying
/// contiguous storage. If no contiguous storage exists, it is
/// created on-demand.
public
func withUnsafePointerToElements<R>(
body: (UnsafePointer<T>)->R
) -> R {
_precondition(
elementStorage != nil || count == 0,
"Array is bridging an opaque NSArray; can't get a pointer to the elements"
)
let ret = body(elementStorage)
if _isClassOrObjCExistential(T.self) {
if _nonNative {
indirect.replaceStorage(_copyCollectionToNativeArrayBuffer(self))
}
}
let ret = body(self.elementStorage)
_fixLifetime(self)
return ret
}
/// Call `body(p)`, where `p` is a pointer to the underlying contiguous
/// storage. Requires: Contiguous storage already exists
public
mutating func withUnsafeMutablePointerToElements<R>(
body: (UnsafeMutablePointer<T>)->R
) -> R {
_precondition(
_sanityCheck(
elementStorage != nil || count == 0,
"Array is bridging an opaque NSArray; can't get a pointer to the elements"
)