Skip to content
Draft
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
15 changes: 7 additions & 8 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import PackageDescription

#if false // FIXME: Disabled while we're debugging a runtime crash (rdar://150240032)
// FIXME: This can sometimes induce a runtime crash (rdar://150240032)
let _traits: Set<Trait> = [
.default(
enabledTraits: [
Expand All @@ -35,17 +35,16 @@ let _traits: Set<Trait> = [
types before they ship.
"""),
]
#endif

// This package recognizes the conditional compilation flags listed below.
// To use enable them, uncomment the corresponding lines or define them
// from the package manager command line:
//
// swift build -Xswiftc -DCOLLECTIONS_INTERNAL_CHECKS
var defines: [SwiftSetting] = [
// .define(
// "COLLECTIONS_UNSTABLE_CONTAINERS_PREVIEW",
// .when(traits: ["UnstableContainersPreview"])),
.define(
"COLLECTIONS_UNSTABLE_CONTAINERS_PREVIEW",
.when(traits: ["UnstableContainersPreview"])),
.define(
"COLLECTIONS_UNSTABLE_SORTED_COLLECTIONS",
.when(traits: ["UnstableSortedCollections"])),
Expand Down Expand Up @@ -104,8 +103,8 @@ let extraSettings: [SwiftSetting] = [
.enableExperimentalFeature("Lifetimes"),
.enableExperimentalFeature("InoutLifetimeDependence"),
.enableExperimentalFeature("SuppressedAssociatedTypes"),
// .enableExperimentalFeature("AddressableParameters"),
// .enableExperimentalFeature("AddressableTypes"),
.enableExperimentalFeature("AddressableParameters"),
.enableExperimentalFeature("AddressableTypes"),

// Note: if you touch these, please make sure to also update the similar lists in
// CMakeLists.txt and Xcode/Shared.xcconfig.
Expand Down Expand Up @@ -359,6 +358,6 @@ let _targets: [Target] = targets.map { $0.toTarget() }
let package = Package(
name: "swift-collections",
products: _products,
traits: [], //_traits,
traits: _traits,
targets: _targets
)
12 changes: 6 additions & 6 deletions Sources/BasicContainers/RigidArray+Append.swift
Original file line number Diff line number Diff line change
Expand Up @@ -274,9 +274,9 @@ extension RigidArray {
#if COLLECTIONS_UNSTABLE_CONTAINERS_PREVIEW
@inlinable
internal mutating func _append<
Source: Container<Element> & ~Copyable & ~Escapable
Source: Iterable<Element> & ~Copyable & ~Escapable
>(
copyingContainer newElements: borrowing Source
copyingIterable newElements: borrowing Source
) {
let target = _freeSpace
_count += newElements._copyContents(intoPrefixOf: target)
Expand All @@ -296,11 +296,11 @@ extension RigidArray {
@_alwaysEmitIntoClient
@inline(__always)
public mutating func append<
Source: Container<Element> & ~Copyable & ~Escapable
Source: Iterable<Element> & ~Copyable & ~Escapable
>(
copying newElements: borrowing Source
) {
_append(copyingContainer: newElements)
_append(copyingIterable: newElements)
}
#endif

Expand Down Expand Up @@ -338,9 +338,9 @@ extension RigidArray {
@_alwaysEmitIntoClient
@inline(__always)
public mutating func append<
Source: Container<Element> & Sequence<Element>
Source: Iterable<Element> & Sequence<Element>
>(copying newElements: Source) {
_append(copyingContainer: newElements)
_append(copyingIterable: newElements)
}
#endif
}
Expand Down
39 changes: 21 additions & 18 deletions Sources/BasicContainers/RigidArray+Initializers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,52 +98,55 @@ extension RigidArray /*where Element: Copyable*/ {
/// The container must not contain more than `capacity` elements.
@_alwaysEmitIntoClient
@inline(__always)
public init<Source: Container<Element> & ~Copyable & ~Escapable>(
capacity: Int? = nil,
public init<Source: Iterable<Element> & ~Copyable & ~Escapable>(
capacity: Int,
copying contents: borrowing Source
) {
self.init(capacity: capacity ?? contents.count)
self.init(capacity: capacity)
self.append(copying: contents)
}

#endif


#if COLLECTIONS_UNSTABLE_CONTAINERS_PREVIEW
/// Creates a new array with the specified capacity, holding a copy
/// of the contents of a given collection.
/// of the contents of a given container.
///
/// - Parameters:
/// - capacity: The storage capacity of the new array, or nil to allocate
/// just enough capacity to store the contents.
/// - contents: The collection whose contents to copy into the new array.
/// The collection must not contain more than `capacity` elements.
/// - contents: The container whose contents to copy into the new array.
/// The container must not contain more than `capacity` elements.
@_alwaysEmitIntoClient
@inline(__always)
public init(
capacity: Int? = nil,
copying contents: some Collection<Element>
public init<Source: Iterable<Element> & Sequence<Element>>(
capacity: Int,
copying contents: Source
) {
self.init(capacity: capacity ?? contents.count)
self.init(capacity: capacity)
self.append(copying: contents)
}
#endif

// FIXME: Add a version that's generic over `Container`, with an optional capacity

#if COLLECTIONS_UNSTABLE_CONTAINERS_PREVIEW
/// Creates a new array with the specified capacity, holding a copy
/// of the contents of a given container.
/// of the contents of a given collection.
///
/// - Parameters:
/// - capacity: The storage capacity of the new array, or nil to allocate
/// just enough capacity to store the contents.
/// - contents: The container whose contents to copy into the new array.
/// The container must not contain more than `capacity` elements.
/// - contents: The collection whose contents to copy into the new array.
/// The collection must not contain more than `capacity` elements.
@_alwaysEmitIntoClient
@inline(__always)
public init<Source: Container<Element> & Sequence<Element>>(
public init(
capacity: Int? = nil,
copying contents: Source
copying contents: some Collection<Element>
) {
self.init(capacity: capacity ?? contents.count)
self.append(copying: contents)
}
#endif
}

// FIXME: Add init(moving:), init(consuming:)
Expand Down
6 changes: 6 additions & 0 deletions Sources/BasicContainers/RigidArray+Insertions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ extension RigidArray {
}

#if COLLECTIONS_UNSTABLE_CONTAINERS_PREVIEW
#if false // FIXME: This needs a container with an exact count.
@inlinable
internal mutating func _insertContainer<
C: Container<Element> & ~Copyable & ~Escapable
Expand All @@ -359,6 +360,7 @@ extension RigidArray {
}
}
}
#endif
#endif

@inlinable
Expand Down Expand Up @@ -388,6 +390,7 @@ extension RigidArray {
}

#if COLLECTIONS_UNSTABLE_CONTAINERS_PREVIEW
#if false // FIXME: This needs a container with an exact count.
/// Copies the elements of a container into this array at the specified
/// position.
///
Expand Down Expand Up @@ -417,6 +420,7 @@ extension RigidArray {
_insertContainer(
at: index, copying: newElements, newCount: newElements.count)
}
#endif
#endif

/// Copies the elements of a collection into this array at the specified
Expand Down Expand Up @@ -448,6 +452,7 @@ extension RigidArray {
}

#if COLLECTIONS_UNSTABLE_CONTAINERS_PREVIEW
#if false // FIXME: This needs a container with an exact count.
/// Copies the elements of a container into this array at the specified
/// position.
///
Expand Down Expand Up @@ -478,6 +483,7 @@ extension RigidArray {
at: index, copying: newElements, newCount: newElements.count)
}
#endif
#endif
}

#endif
6 changes: 6 additions & 0 deletions Sources/BasicContainers/RigidArray+Replacements.swift
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ extension RigidArray {
}

#if COLLECTIONS_UNSTABLE_CONTAINERS_PREVIEW
#if false // FIXME: This needs a container with an exact count.
@inlinable
internal mutating func _replaceSubrange<
C: Container<Element> & ~Copyable & ~Escapable
Expand All @@ -399,6 +400,7 @@ extension RigidArray {
}
}
}
#endif
#endif

@inlinable
Expand Down Expand Up @@ -429,6 +431,7 @@ extension RigidArray {
}

#if COLLECTIONS_UNSTABLE_CONTAINERS_PREVIEW
#if false // FIXME: This needs a container with an exact count.
/// Replaces the specified subrange of elements by copying the elements of
/// the given container.
///
Expand Down Expand Up @@ -466,6 +469,7 @@ extension RigidArray {
_replaceSubrange(
subrange, copyingContainer: newElements, newCount: newElements.count)
}
#endif
#endif

/// Replaces the specified subrange of elements by copying the elements of
Expand Down Expand Up @@ -505,6 +509,7 @@ extension RigidArray {
}

#if COLLECTIONS_UNSTABLE_CONTAINERS_PREVIEW
#if false
/// Replaces the specified subrange of elements by copying the elements of
/// the given container.
///
Expand Down Expand Up @@ -544,6 +549,7 @@ extension RigidArray {
subrange, copyingContainer: newElements, newCount: newElements.count)
}
#endif
#endif
}

#endif
46 changes: 41 additions & 5 deletions Sources/BasicContainers/RigidArray.swift
Original file line number Diff line number Diff line change
Expand Up @@ -286,13 +286,49 @@ extension RigidArray where Element: ~Copyable {

#if compiler(>=6.2) && COLLECTIONS_UNSTABLE_CONTAINERS_PREVIEW
@available(SwiftStdlib 5.0, *)
extension RigidArray: Container where Element: ~Copyable {
public typealias BorrowIterator = Span<Element>

extension RigidArray: Iterable where Element: ~Copyable {
@frozen
public struct BorrowIterator: ~Copyable, ~Escapable, BorrowIteratorProtocol {
@usableFromInline
internal let _span: Span<Element>

@usableFromInline
internal var _offset: Int

@inlinable
@_lifetime(copy span)
internal init(_span span: Span<Element>, offset: Int) {
self._span = span
self._offset = offset
}

@_lifetime(&self)
@_lifetime(self: copy self)
public mutating func nextSpan(maximumCount: Int) -> Span<Element> {
let c = Swift.min(maximumCount, _span.count - _offset)
let end = _offset &+ c
let result = _span.extracting(Range(uncheckedBounds: (_offset, end)))
_offset = end
return result
}

@_lifetime(self: copy self)
public mutating func skip(by offset: Int) -> Int {
let c = Swift.min(offset, _span.count &- _offset)
_offset += offset
return c
}
}

@inlinable
public var estimatedCount: EstimatedCount {
.exactly(count)
}

@_alwaysEmitIntoClient
@inline(__always)
public func startBorrowIteration() -> Span<Element> {
self.span
public func startBorrowIteration() -> BorrowIterator {
.init(_span: self.span, offset: 0)
}
}
#endif
Expand Down
37 changes: 28 additions & 9 deletions Sources/BasicContainers/UniqueArray+Append.swift
Original file line number Diff line number Diff line change
Expand Up @@ -231,11 +231,32 @@ extension UniqueArray {
}

#if COLLECTIONS_UNSTABLE_CONTAINERS_PREVIEW
/// Copies the elements of a container to the end of this array.
@inlinable
internal mutating func _append<
Source: Iterable<Element> & ~Copyable & ~Escapable
>(
copyingIterable newElements: borrowing Source
) {
_ensureFreeCapacity(newElements.underestimatedCount)
var it = newElements.startBorrowIteration()
while true {
let span = it.nextSpan()
if span.isEmpty { break }
_ensureFreeCapacity(span.count)
_storage.append(copying: span)
}
}
// FIXME: Add _append(copyingContainer:), forwarding to the same method on RigidArray
#endif

#if COLLECTIONS_UNSTABLE_CONTAINERS_PREVIEW
/// Copies the elements of an iterable to the end of this array.
///
/// If the array does not have sufficient capacity to hold enough elements,
/// then this reallocates the array's storage to extend its capacity, using
/// a geometric growth rate.
/// a geometric growth rate. If the input sequence does not provide a precise
/// estimate of its count, then the array's storage may need to be resized
/// more than once.
///
/// - Parameters
/// - newElements: A container whose contents to copy into the array.
Expand All @@ -245,12 +266,11 @@ extension UniqueArray {
@_alwaysEmitIntoClient
@inline(__always)
public mutating func append<
Source: Container<Element> & ~Copyable & ~Escapable
Source: Iterable<Element> & ~Copyable & ~Escapable
>(
copying newElements: borrowing Source
) {
_ensureFreeCapacity(newElements.count)
_storage._append(copyingContainer: newElements)
self._append(copyingIterable: newElements)
}

#endif
Expand All @@ -259,7 +279,7 @@ extension UniqueArray {
///
/// If the array does not have sufficient capacity to hold enough elements,
/// then this reallocates the array's storage to extend its capacity, using
/// a geometric growth rate. If the input sequence does not provide a correct
/// a geometric growth rate. If the input sequence does not provide a precise
/// estimate of its count, then the array's storage may need to be resized
/// more than once.
///
Expand Down Expand Up @@ -300,10 +320,9 @@ extension UniqueArray {
@_alwaysEmitIntoClient
@inline(__always)
public mutating func append<
Source: Container<Element> & Sequence<Element>
Source: Iterable<Element> & Sequence<Element>
>(copying newElements: Source) {
_ensureFreeCapacity(newElements.count)
_storage._append(copyingContainer: newElements)
self._append(copyingIterable: newElements)
}
#endif
}
Expand Down
Loading
Loading