diff --git a/stdlib/public/core/InlineArray.swift b/stdlib/public/core/InlineArray.swift index dda7430d21dbf..af4b93e337590 100644 --- a/stdlib/public/core/InlineArray.swift +++ b/stdlib/public/core/InlineArray.swift @@ -12,34 +12,88 @@ /// A fixed-size array. /// -/// The `InlineArray` type is a specialized array that stores its elements -/// contiguously inline, rather than allocating an out-of-line region of memory -/// with copy-on-write optimization. +/// An `InlineArray` is a specialized container that doesn't use a separate +/// memory allocation just to store its elements. When a value is copied, all of +/// its elements are copied eagerly, like those of a tuple. Use an `InlineArray` +/// when you have a fixed number of elements and need to avoid a separate heap +/// allocation. /// -/// Memory Layout -/// ------------- +/// Initializing a Value +/// -------------------- +/// +/// When initializing a new `InlineArray` value, you must initialize all of its +/// elements. You can use an array literal just as with `Array`, rely on type +/// inference for the `count` and `Element` type, and spell the type with the +/// shorthand `[count of Element]`. +/// +/// let a: InlineArray<3, Int> = [1, 2, 3] +/// let b: InlineArray<_, Int> = [1, 2, 3] +/// let c: InlineArray<3, _> = [1, 2, 3] +/// let d: InlineArray = [1, 2, 3] +/// +/// let e: [3 of Int] = [1, 2, 3] +/// let f: [_ of Int] = [1, 2, 3] +/// let g: [3 of _] = [1, 2, 3] +/// let h: [_ of _] = [1, 2, 3] +/// +/// You can also use one of the type's initializers to create a new value. +/// +/// Accessing Elements +/// ------------------ +/// +/// Just as with `Array`, you can read and modify an element in an `InlineArray` +/// using a subscript. Unless you use the memory-unsafe `unchecked` subscript, +/// any index you provide is subject to bounds checking; an invalid index +/// triggers a runtime error in your program. /// -/// An *empty* array's size is zero. Its stride and alignment are one byte. +/// var values: [3 of Double] = [1, 1.5, 2] +/// print(values[0]) // Prints "1.0" +/// values[1] -= 0.25 +/// print(values[1]) // Prints "1.25" +/// values[3] = 42.0 // Fatal error: Index out of bounds /// -/// A *nonempty* array's size and stride are equal to the element's stride -/// multiplied by the number of elements. Its alignment is equal to the -/// element's alignment. +/// You can use the `indices` property to iterate over all elements in order. +/// +/// for index in values.indices { +/// print(values[index]) +/// } +/// +/// Working with Noncopyable Elements +/// --------------------------------- +/// +/// An `InlineArray` can store elements of potentially noncopyable type. When +/// `Element` isn't copyable, the `InlineArray` itself also isn't copyable. You +/// must then explicitly move or consume the value if you want to transfer +/// ownership. +/// +/// Memory Layout +/// ------------- /// -/// MemoryLayout>.size //-> 6 -/// MemoryLayout>.stride //-> 6 -/// MemoryLayout>.alignment //-> 2 +/// An `InlineArray` stores its elements contiguously. If an `InlineArray` is a +/// stored property of a class, then it's allocated on the heap along with the +/// other stored properties of the class. Otherwise, in general, an +/// `InlineArray` is allocated on the stack. /// -/// Literal Initialization -/// ---------------------- +/// A *non-empty* `InlineArray`'s size and stride are both found by multiplying +/// the `count` of elements by the `Element`'s stride. Its alignment is equal to +/// the `Element`'s alignment. /// -/// Array literal syntax can be used to initialize an `InlineArray` instance. -/// A stack-allocated array will do in-place initialization of each element. -/// The `count` and/or `Element` can be inferred from the array literal. +/// struct Record { +/// let x: UInt32 +/// let y: Bool +/// } +/// MemoryLayout.size // 5 +/// MemoryLayout.stride // 8 +/// MemoryLayout.alignment // 4 +/// MemoryLayout<[2 of Record]>.size // 16 +/// MemoryLayout<[2 of Record]>.stride // 16 +/// MemoryLayout<[2 of Record]>.alignment // 4 +/// MemoryLayout<(Record, Record)>.size // 13 +/// MemoryLayout<(Record, Record)>.stride // 16 +/// MemoryLayout<(Record, Record)>.alignment // 4 /// -/// let a: InlineArray<4, Int> = [1, 2, 4, 8] -/// let b: InlineArray<_, Int> = [1, 2, 4, 8] -/// let c: InlineArray<4, _> = [1, 2, 4, 8] -/// let d: InlineArray = [1, 2, 4, 8] +/// An *empty* `InlineArray`'s size is zero. Its stride and alignment are both +/// one byte. @available(SwiftStdlib 6.2, *) @frozen @safe @@ -203,7 +257,7 @@ extension InlineArray where Element: ~Copyable { /// count of the array, to initialize every element by passing the closure /// the index of the current element being initialized. /// - /// InlineArray<4, Int> { 1 << $0 } //-> [1, 2, 4, 8] + /// InlineArray<4, Int> { $0 * 2 } // [0, 2, 4, 6] /// /// The closure is allowed to throw an error at any point during /// initialization at which point the array will stop initialization, @@ -242,7 +296,7 @@ extension InlineArray where Element: ~Copyable { /// count of the array, to initialize every element by passing the closure an /// immutable borrow reference to the preceding element. /// - /// InlineArray<4, Int>(first: 1) { $0 << 1 } //-> [1, 2, 4, 8] + /// InlineArray<4, Int>(first: 1) { $0 * 2 } // [1, 2, 4, 8] /// /// The closure is allowed to throw an error at any point during /// initialization at which point the array will stop initialization,