Skip to content

Instantly share code, notes, and snippets.

@tardieu
Created February 15, 2017 00:49
Show Gist options
  • Save tardieu/7ca43d19b6197033dc39b138ba0e500e to your computer and use it in GitHub Desktop.
Save tardieu/7ca43d19b6197033dc39b138ba0e500e to your computer and use it in GitHub Desktop.
Unsafe String extension for Swift 3
extension String {
/// The base address of the contiguous buffer containing the String elements
/// if the String is backed by a contiguous buffer.
///
/// There is no guarantee that the String is backed by a contiguous buffer.
/// Even if it is, there is no guarantee that the buffer is writable.
public var baseAddress: UnsafeRawPointer? {
return UnsafeRawPointer(self._core._baseAddress)
}
/// The number of elements stored in the buffer.
///
/// The count must not be increased beyond the buffer size for an immutable buffer
/// or capacity for a mutable buffer.
public var elementCount: Int {
get {
return self._core.count
}
set {
self._core.count = newValue
}
}
/// The read-only width of the elements stored in the buffer (1 or 2).
public var elementWidth: Int {
return self._core.elementWidth
}
/// The read-only capacity of the String buffer if the String is backed by a mutable contiguous buffer.
public var capacity: Int? {
if let capacity = self._core.nativeBuffer?.capacity {
return capacity + 2 - self.elementWidth
} else {
return nil
}
}
/// Ensures that the String is backed by a uniquely owned mutable contiguous buffer with at least
/// the requested capacity and returns the base address of the this buffer.
///
/// This call may require copying the String elements into a new buffer and modifying the element size.
/// The reserved capacity may be greater than the requested capacity.
/// Repeated calls with the same or lower capacity requirements are no ops.
///
/// - Parameter capacity: the requested String capacity (number of elements).
/// - Parameter minElementWidth: the requested minimum element width.
/// - Returns: the base address of the mutable contiguous buffer backing the String.
@discardableResult public mutating func claimOwnership(withCapacity capacity: Int? = nil, withMinElementWidth minElementWidth: Int = 1) -> UnsafeMutableRawPointer {
if self.elementWidth < minElementWidth {
self.append("\u{a3}") // force element width = 2
if let capacity = capacity {
self._core.reserveCapacity(capacity)
}
self.elementCount -= 1
} else {
self._core.reserveCapacity(capacity ?? 0)
}
return self._core.nativeBuffer!.start
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment