//===--- MutableSpanTests.swift -------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2025 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 // //===----------------------------------------------------------------------===// // RUN: %target-run-stdlib-swift // REQUIRES: executable_test import StdlibUnittest var suite = TestSuite("MutableSpan Tests") defer { runAllTests() } suite.test("Initialize with ordinary element") .skip(.custom( { if #available(SwiftStdlib 6.2, *) { false } else { true } }, reason: "Requires Swift 6.2's standard library" )) .code { guard #available(SwiftStdlib 6.2, *) else { return } let capacity = 4 var s = (0..(_unsafeStart: rp, byteCount: bc) expectEqual(b.count, capacity) let stride = MemoryLayout.stride let r = MutableSpan(_unsafeBytes: $0.dropFirst(stride)) expectEqual(r.count, (capacity-1)*stride) expectEqual(r.count, bc-stride) } let v = UnsafeMutableRawBufferPointer(start: nil, count: 0) let m = MutableSpan(_unsafeBytes: v) expectEqual(m.count, 0) } suite.test("isEmpty") .skip(.custom( { if #available(SwiftStdlib 6.2, *) { false } else { true } }, reason: "Requires Swift 6.2's standard library" )) .code { guard #available(SwiftStdlib 6.2, *) else { return } var array = [0, 1, 2] array.withUnsafeMutableBufferPointer { let span = MutableSpan(_unsafeElements: $0) let e = span.isEmpty expectFalse(e) } array = [] array.withUnsafeMutableBufferPointer { let span = MutableSpan(_unsafeElements: $0) let e = span.isEmpty expectTrue(e) } } suite.test("Span from MutableSpan") .skip(.custom( { if #available(SwiftStdlib 6.2, *) { false } else { true } }, reason: "Requires Swift 6.2's standard library" )) .code { guard #available(SwiftStdlib 6.2, *) else { return } var array = [0, 1, 2] array.withUnsafeMutableBufferPointer { let mutable = MutableSpan(_unsafeElements: $0) let immutable = Span(_mutableSpan: mutable) expectEqual(mutable.count, immutable.count) } } suite.test("RawSpan from MutableSpan") .skip(.custom( { if #available(SwiftStdlib 6.2, *) { false } else { true } }, reason: "Requires Swift 6.2's standard library" )) .code { guard #available(SwiftStdlib 6.2, *) else { return } let count = 4 var array = Array(0...stride) let v = bytes.unsafeLoad( fromByteOffset: MemoryLayout.stride, as: Int.self ) expectEqual(v, 1) } } suite.test("MutableRawSpan from MutableSpan") .require(.stdlib_6_2).code { guard #available(SwiftStdlib 6.2, *) else { return } let count = 4 var array = Array(0...stride) bytes.storeBytes(of: 1, as: Int.self) } expectEqual(array[0], 1) } suite.test("indices property") .skip(.custom( { if #available(SwiftStdlib 6.2, *) { false } else { true } }, reason: "Requires Swift 6.2's standard library" )) .code { guard #available(SwiftStdlib 6.2, *) else { return } let capacity = 4 var a = Array(0...allocate(capacity: count) _ = b.initialize(fromContentsOf: 0..(start: nil, count: 0) defer { _ = e } var m = MutableSpan(_unsafeElements: b) m[0] = 100 expectEqual(m.count, count) expectEqual(m[0], 100) var s = m.span expectEqual(s.count, m.count) expectEqual(s[0], m[0]) // we're done using `s` before it gets reassigned m.update(repeating: 7) s = m.span // m[0] = -1 // exclusivity violation expectEqual(s.count, m.count) expectEqual(s[0], m[0]) } suite.test("swapAt") .skip(.custom( { if #available(SwiftStdlib 6.2, *) { false } else { true } }, reason: "Requires Swift 6.2's standard library" )) .code { guard #available(SwiftStdlib 6.2, *) else { return } let count = 8 var array = Array(0...allocate(capacity: c) defer { b.deallocate() } _ = b.initialize(fromContentsOf: 0.. var span = MutableSpan(_unsafeElements: $0) expectEqual(span.count, capacity) prefix = span._mutatingExtracting(first: 1) expectEqual(prefix[0], 0) prefix = span._mutatingExtracting(first: capacity) expectEqual(prefix[capacity-1], UInt8(capacity-1)) prefix = span._mutatingExtracting(droppingLast: capacity) expectEqual(prefix.isEmpty, true) prefix = span._mutatingExtracting(droppingLast: 1) expectEqual(prefix[capacity-2], UInt8(capacity-2)) } do { let b = UnsafeMutableBufferPointer(start: nil, count: 0) var span = MutableSpan(_unsafeElements: b) expectEqual(span.count, b.count) expectEqual(span._mutatingExtracting(first: 1).count, b.count) expectEqual(span._mutatingExtracting(droppingLast: 1).count, b.count) } } suite.test("_consumingExtracting prefixes") .require(.stdlib_6_2).code { let capacity = 4 var a = Array(0..(start: nil, count: 0) var span = b.mutableSpan expectEqual(span.count, b.count) span = b.mutableSpan._consumingExtracting(first: 1) expectEqual(span.count, b.count) span = b.mutableSpan._consumingExtracting(droppingLast: 1) expectEqual(span.count, b.count) } } suite.test("_mutatingExtracting suffixes") .skip(.custom( { if #available(SwiftStdlib 6.2, *) { false } else { true } }, reason: "Requires Swift 6.2's standard library" )) .code { guard #available(SwiftStdlib 6.2, *) else { return } let capacity = 4 var a = Array(0.. var span = MutableSpan(_unsafeElements: $0) expectEqual(span.count, capacity) suffix = span._mutatingExtracting(last: capacity) expectEqual(suffix[0], 0) suffix = span._mutatingExtracting(last: capacity-1) expectEqual(suffix[0], 1) suffix = span._mutatingExtracting(last: 1) expectEqual(suffix[0], UInt8(capacity-1)) suffix = span._mutatingExtracting(droppingFirst: capacity) expectTrue(suffix.isEmpty) suffix = span._mutatingExtracting(droppingFirst: 1) expectEqual(suffix[0], 1) } do { let b = UnsafeMutableBufferPointer(start: nil, count: 0) var span = MutableSpan(_unsafeElements: b) expectEqual(span.count, b.count) expectEqual(span._mutatingExtracting(last: 1).count, b.count) expectEqual(span._mutatingExtracting(droppingFirst: 1).count, b.count) } } suite.test("_consumingExtracting suffixes") .require(.stdlib_6_2).code { let capacity = 4 var a = Array(0..(start: nil, count: 0) var span = b.mutableSpan expectEqual(span.count, b.count) span = b.mutableSpan._consumingExtracting(last: 1) expectEqual(span.count, b.count) span = b.mutableSpan._consumingExtracting(droppingFirst: 1) expectEqual(span.count, b.count) } } suite.test("MutableSpan from UnsafeMutableBufferPointer") .require(.stdlib_6_2).code { guard #available(SwiftStdlib 6.2, *) else { return } let capacity = 4 let b = UnsafeMutableBufferPointer.allocate(capacity: capacity) defer { b.deallocate() } _ = b.initialize(fromContentsOf: 0..