Skip to content

[5.0] DataProtocol ContiguousCollection and new inline Data #21292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions stdlib/public/SDK/Foundation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@ add_swift_target_library(swiftFoundation ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES
Calendar.swift
CharacterSet.swift
Codable.swift
Collections+DataProtocol.swift
ContiguousBytes.swift
Data.swift
DataProtocol.swift
DispatchData+DataProtocol.swift
NSData+DataProtocol.swift
Pointers+DataProtocol.swift
DataThunks.m
Date.swift
DateComponents.swift
Expand Down
61 changes: 61 additions & 0 deletions stdlib/public/SDK/Foundation/Collections+DataProtocol.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

//===--- DataProtocol -----------------------------------------------------===//

extension Array: DataProtocol where Element == UInt8 {
public var regions: CollectionOfOne<Array<UInt8>> {
return CollectionOfOne(self)
}
}

extension ArraySlice: DataProtocol where Element == UInt8 {
public var regions: CollectionOfOne<ArraySlice<UInt8>> {
return CollectionOfOne(self)
}
}

extension ContiguousArray: DataProtocol where Element == UInt8 {
public var regions: CollectionOfOne<ContiguousArray<UInt8>> {
return CollectionOfOne(self)
}
}

// FIXME: This currently crashes compilation in the Late Inliner.
// extension CollectionOfOne : DataProtocol where Element == UInt8 {
// public typealias Regions = CollectionOfOne<Data>
//
// public var regions: CollectionOfOne<Data> {
// return CollectionOfOne<Data>(Data(self))
// }
// }

extension EmptyCollection : DataProtocol where Element == UInt8 {
public var regions: EmptyCollection<Data> {
return EmptyCollection<Data>()
}
}

extension Repeated: DataProtocol where Element == UInt8 {
public typealias Regions = Repeated<Data>

public var regions: Repeated<Data> {
guard self.count > 0 else { return repeatElement(Data(), count: 0) }
return repeatElement(Data(CollectionOfOne(self.first!)), count: self.count)
}
}

//===--- MutableDataProtocol ----------------------------------------------===//

extension Array: MutableDataProtocol where Element == UInt8 { }

extension ContiguousArray: MutableDataProtocol where Element == UInt8 { }
100 changes: 100 additions & 0 deletions stdlib/public/SDK/Foundation/ContiguousBytes.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

//===--- ContiguousBytes --------------------------------------------------===//

/// Indicates that the conforming type is a contiguous collection of raw bytes
/// whose underlying storage is directly accessible by withUnsafeBytes.
public protocol ContiguousBytes {
/// Calls the given closure with the contents of underlying storage.
///
/// - note: Calling `withUnsafeBytes` multiple times does not guarantee that
/// the same buffer pointer will be passed in every time.
/// - warning: The buffer argument to the body should not be stored or used
/// outside of the lifetime of the call to the closure.
func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R
}

//===--- Collection Conformances ------------------------------------------===//

// FIXME: When possible, expand conformance to `where Element : Trivial`.
extension Array : ContiguousBytes where Element == UInt8 { }

// FIXME: When possible, expand conformance to `where Element : Trivial`.
extension ArraySlice : ContiguousBytes where Element == UInt8 { }

// FIXME: When possible, expand conformance to `where Element : Trivial`.
extension ContiguousArray : ContiguousBytes where Element == UInt8 { }

//===--- Pointer Conformances ---------------------------------------------===//

extension UnsafeRawBufferPointer : ContiguousBytes {
@inlinable
public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
return try body(self)
}
}

extension UnsafeMutableRawBufferPointer : ContiguousBytes {
@inlinable
public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
return try body(UnsafeRawBufferPointer(self))
}
}

// FIXME: When possible, expand conformance to `where Element : Trivial`.
extension UnsafeBufferPointer : ContiguousBytes where Element == UInt8 {
@inlinable
public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
return try body(UnsafeRawBufferPointer(self))
}
}

// FIXME: When possible, expand conformance to `where Element : Trivial`.
extension UnsafeMutableBufferPointer : ContiguousBytes where Element == UInt8 {
@inlinable
public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
return try body(UnsafeRawBufferPointer(self))
}
}

// FIXME: When possible, expand conformance to `where Element : Trivial`.
extension EmptyCollection : ContiguousBytes where Element == UInt8 {
@inlinable
public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
return try body(UnsafeRawBufferPointer(start: nil, count: 0))
}
}

// FIXME: When possible, expand conformance to `where Element : Trivial`.
extension CollectionOfOne : ContiguousBytes where Element == UInt8 {
@inlinable
public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
let element = self.first!
return try Swift.withUnsafeBytes(of: element) {
return try body($0)
}
}
}

//===--- Conditional Conformances -----------------------------------------===//

extension Slice : ContiguousBytes where Base : ContiguousBytes {
public func withUnsafeBytes<ResultType>(_ body: (UnsafeRawBufferPointer) throws -> ResultType) rethrows -> ResultType {
let offset = base.distance(from: base.startIndex, to: self.startIndex)
return try base.withUnsafeBytes { ptr in
let slicePtr = ptr.baseAddress?.advanced(by: offset)
let sliceBuffer = UnsafeRawBufferPointer(start: slicePtr, count: self.count)
return try body(sliceBuffer)
}
}
}
Loading