Skip to content

Commit 6e27491

Browse files
committed
[stdlib] Revise documentation for Array- and Set-related types.
This adds and expands documentation for sequences, collections, and the array types as well as `Set` and its related protocols.
1 parent 77b4931 commit 6e27491

22 files changed

+5376
-1031
lines changed

stdlib/public/core/ArrayType.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ protocol _ArrayProtocol
5555
///
5656
/// - Complexity: O(`self.count`).
5757
///
58-
/// - Precondition: `i <= count`.
58+
/// - Precondition: `startIndex <= i`, `i <= endIndex`.
5959
mutating func insert(_ newElement: Iterator.Element, at i: Int)
6060

6161
/// Remove and return the element at the given index.

stdlib/public/core/Arrays.swift.gyb

Lines changed: 818 additions & 207 deletions
Large diffs are not rendered by default.

stdlib/public/core/Collection.swift

Lines changed: 660 additions & 129 deletions
Large diffs are not rendered by default.

stdlib/public/core/CollectionAlgorithms.swift.gyb

Lines changed: 357 additions & 69 deletions
Large diffs are not rendered by default.

stdlib/public/core/CompilerProtocols.swift

Lines changed: 254 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,35 +26,160 @@ public protocol Boolean {
2626
var boolValue: Bool { get }
2727
}
2828

29-
/// A type that can be converted to an associated "raw" type, then
30-
/// converted back to produce an instance equivalent to the original.
29+
/// A type that can be converted to and from an associated raw value.
30+
///
31+
/// With a `RawRepresentable` type, you can switch back and forth between a
32+
/// custom type and an associated `RawValue` type without losing the value of
33+
/// the original `RawRepresentable` type. Using the raw value of a conforming
34+
/// type streamlines interoperation with Objective-C and legacy APIs and
35+
/// simplifies conformance to other protocols, such as `Equatable`,
36+
/// `Comparable`, and `Hashable`.
37+
///
38+
/// The `RawRepresentable` protocol is seen mainly in two categories of types:
39+
/// enumerations with raw value types and option sets.
40+
///
41+
/// Enumerations with Raw Values
42+
/// ============================
43+
///
44+
/// For any enumeration with a string, integer, or floating-point raw type, the
45+
/// Swift compiler automatically adds `RawRepresentable` conformance. When
46+
/// defining your own custom enumeration, you give it a raw type by specifying
47+
/// the raw type as the first item in the enumeration's type inheritance list.
48+
/// You can also use literals to specify values for one or more cases.
49+
///
50+
/// For example, the `Counter` enumeration defined here has an `Int` raw value
51+
/// type and gives the first case a raw value of `1`:
52+
///
53+
/// enum Counter: Int {
54+
/// case one = 1, two, three, four, five
55+
/// }
56+
///
57+
/// You can create a `Counter` instance from an integer value between 1 and 5
58+
/// by using the `init?(rawValue:)` initializer declared in the
59+
/// `RawRepresentable` protocol. This initializer is failable because although
60+
/// every case of the `Counter` type has a corresponding `Int` value, there
61+
/// are many `Int` values that *don't* correspond to a case of `Counter`.
62+
///
63+
/// for i in 3...6 {
64+
/// print(Counter(rawValue: i))
65+
/// }
66+
/// // Prints "Optional(Counter.three)"
67+
/// // Prints "Optional(Counter.four)"
68+
/// // Prints "Optional(Counter.five)"
69+
/// // Prints "nil"
70+
///
71+
/// Option Sets
72+
/// ===========
73+
///
74+
/// Option sets all conform to `RawRepresentable` by inheritance using the
75+
/// `OptionSet` protocol. Whether using an option set or creating your own,
76+
/// you use the raw value of an option set instance to store the instance's
77+
/// bitfield. The raw value must therefore be of a type that conforms to the
78+
/// `BitwiseOperations` protocol, such as `UInt8` or `Int`. For example, the
79+
/// `Direction` type defines an option set for the four directions you can
80+
/// move in a game.
81+
///
82+
/// struct Directions: OptionSet {
83+
/// let rawValue: UInt8
84+
///
85+
/// static let up = Directions(rawValue: 1 << 0)
86+
/// static let down = Directions(rawValue: 1 << 1)
87+
/// static let left = Directions(rawValue: 1 << 2)
88+
/// static let right = Directions(rawValue: 1 << 3)
89+
/// }
90+
///
91+
/// Unlike enumerations, option sets provide a nonfailable `init(rawValue:)`
92+
/// initializer to convert from a raw value, because option sets don't have an
93+
/// enumerated list of all possible cases. Option set values have
94+
/// a one-to-one correspondence with their associated raw values.
95+
///
96+
/// In the case of the `Directions` option set, an instance can contain zero,
97+
/// one, or more of the four defined directions. This example declares a
98+
/// constant with three currently allowed moves. The raw value of the
99+
/// `allowedMoves` instance is the result of the bitwise `OR` of its three
100+
/// members' raw values:
101+
///
102+
/// let allowedMoves: Directions = [.up, .down, .left]
103+
/// print(allowedMoves.rawValue)
104+
/// // Prints "7"
105+
///
106+
/// Option sets use bitwise operations on their associated raw values to
107+
/// implement their mathematical set operations. For example, the `contains()`
108+
/// method on `allowedMoves` performs a bitwise `AND` operation to check
109+
/// whether the option set contains an element.
110+
///
111+
/// print(allowedMoves.contains(.right))
112+
/// // Prints "false"
113+
/// print(allowedMoves.rawValue & Directions.right.rawValue)
114+
/// // Prints "0"
115+
///
116+
/// - SeeAlso: `OptionSet`, `BitwiseOperations`
31117
public protocol RawRepresentable {
32-
/// The "raw" type that can be used to represent all values of `Self`.
118+
/// The raw type that can be used to represent all values of the conforming
119+
/// type.
33120
///
34-
/// Every distinct value of `self` has a corresponding unique
35-
/// value of `RawValue`, but `RawValue` may have representations
36-
/// that do not correspond to a value of `Self`.
121+
/// Every distinct value of the conforming type has a corresponding unique
122+
/// value of the `RawValue` type, but there may be values of the `RawValue`
123+
/// type that don't have a corresponding value of the conforming type.
37124
associatedtype RawValue
38125

39-
/// Convert from a value of `RawValue`, yielding `nil` iff
40-
/// `rawValue` does not correspond to a value of `Self`.
126+
/// Creates a new instance with the specified raw value.
127+
///
128+
/// If there is no value of the type that corresponds with the specified raw
129+
/// value, this initializer returns `nil`. For example:
130+
///
131+
/// enum PaperSize: String {
132+
/// case A4, A5, Letter, Legal
133+
/// }
134+
///
135+
/// print(PaperSize(rawValue: "Legal"))
136+
/// // Prints "Optional("PaperSize.Legal")"
137+
///
138+
/// print(PaperSize(rawValue: "Tabloid"))
139+
/// // Prints "nil"
140+
///
141+
/// - Parameter rawValue: The raw value to use for the new instance.
41142
init?(rawValue: RawValue)
42143

43-
/// The corresponding value of the "raw" type.
144+
/// The corresponding value of the raw type.
145+
///
146+
/// A new instance initialized with `rawValue` will be equivalent to this
147+
/// instance. For example:
148+
///
149+
/// enum PaperSize: String {
150+
/// case A4, A5, Letter, Legal
151+
/// }
44152
///
45-
/// `Self(rawValue: self.rawValue)!` is equivalent to `self`.
153+
/// let selectedSize = PaperSize.Letter
154+
/// print(selectedSize.rawValue)
155+
/// // Prints "Letter"
156+
///
157+
/// print(selectedSize == PaperSize(rawValue: selectedSize.rawValue)!)
158+
/// // Prints "true"
46159
var rawValue: RawValue { get }
47160
}
48161

49-
/// Returns `true` iff `lhs.rawValue == rhs.rawValue`.
162+
/// Returns a Boolean value indicating whether the two operands are equal.
163+
///
164+
/// - Parameters:
165+
/// - lhs: A raw-representable instance.
166+
/// - rhs: A second raw-representable instance.
167+
/// - Returns: `true` if the two operands have equal raw values; otherwise,
168+
/// `false`.
50169
@warn_unused_result
51170
public func == <
52171
T : RawRepresentable where T.RawValue : Equatable
53172
>(lhs: T, rhs: T) -> Bool {
54173
return lhs.rawValue == rhs.rawValue
55174
}
56175

57-
/// Returns `true` iff `lhs.rawValue != rhs.rawValue`.
176+
/// Returns a Boolean value indicating whether the two operands are not equal.
177+
///
178+
/// - Parameters:
179+
/// - lhs: A raw-representable instance.
180+
/// - rhs: A second raw-representable instance.
181+
/// - Returns: `true` if the two operands have unequal raw values; otherwise,
182+
/// `false`.
58183
@warn_unused_result
59184
public func != <
60185
T : RawRepresentable where T.RawValue : Equatable
@@ -64,7 +189,13 @@ public func != <
64189

65190
// This overload is needed for ambiguity resolution against the
66191
// implementation of != for T : Equatable
67-
/// Returns `true` iff `lhs.rawValue != rhs.rawValue`.
192+
/// Returns a Boolean value indicating whether the two operands are not equal.
193+
///
194+
/// - Parameters:
195+
/// - lhs: A raw-representable instance.
196+
/// - rhs: A second raw-representable instance.
197+
/// - Returns: `true` if the two operands have unequal raw values; otherwise,
198+
/// `false`.
68199
@warn_unused_result
69200
public func != <
70201
T : Equatable where T : RawRepresentable, T.RawValue : Equatable
@@ -172,10 +303,118 @@ public protocol StringLiteralConvertible
172303
init(stringLiteral value: StringLiteralType)
173304
}
174305

175-
/// Conforming types can be initialized with array literals.
306+
/// A type that can be initialized using an array literal.
307+
///
308+
/// An array literal is a simple way of expressing a list of values. Simply
309+
/// surround a comma-separated list of values, instances, or literals with
310+
/// square brackets to create an array literal. You can use an array literal
311+
/// anywhere an instance of an `ArrayLiteralConvertible` type is expected: as
312+
/// a value assigned to a variable or constant, as a parameter to a method or
313+
/// initializer, or even as the subject of a nonmutating operation like
314+
/// `map(_:)` or `filter(_:)`.
315+
///
316+
/// Arrays, sets, and option sets all conform to `ArrayLiteralConvertible`, and
317+
/// your own custom types can as well. Here's an example of creating a set and
318+
/// an array using array literals:
319+
///
320+
/// let employeesSet: Set<String> = ["Amir", "Jihye", "Dave", "Alessia", "Dave"]
321+
/// print(employeesSet)
322+
/// // Prints "["Amir", "Dave", "Jihye", "Alessia"]"
323+
///
324+
/// let employeesArray: [String] = ["Amir", "Jihye", "Dave", "Alessia", "Dave"]
325+
/// print(employeesArray)
326+
/// // Prints "["Amir", "Jihye", "Dave", "Alessia", "Dave"]"
327+
///
328+
/// The `Set` and `Array` types each handle array literals in their own way to
329+
/// create new instances. In this case, the newly created set drops the
330+
/// duplicate value ("Dave") and doesn't maintain the order of the array
331+
/// literal's elements. The new array, on the other hand, matches the order
332+
/// and number of elements provided.
333+
///
334+
/// - Note: An array literal is not the same as an `Array` instance. You can't
335+
/// initialize a type that conforms to `ArrayLiteralConvertible` simply by
336+
/// assigning an existing array.
337+
///
338+
/// let anotherSet: Set = employeesArray
339+
/// // error: cannot convert value of type '[String]' to specified type 'Set'
340+
///
341+
/// Type Inference of Array Literals
342+
/// ================================
343+
///
344+
/// Whenever possible, Swift's compiler infers the full intended type of your
345+
/// array literal. Because `Array` is the default type for an array literal,
346+
/// without writing any other code, you can declare an array with a particular
347+
/// element type by providing one or more values.
348+
///
349+
/// In this example, the compiler infers the full type of each array literal.
350+
///
351+
/// let integers = [1, 2, 3]
352+
/// // 'integers' has type '[Int]'
353+
///
354+
/// let strings = ["a", "b", "c"]
355+
/// // 'strings' has type '[String]'
356+
///
357+
/// An empty array literal alone doesn't provide enough information for the
358+
/// compiler to infer the intended type of the `Array` instance. When using an
359+
/// empty array literal, specify the type of the variable or constant.
360+
///
361+
/// var emptyArray: [Bool] = []
362+
/// // 'emptyArray' has type '[Bool]'
363+
///
364+
/// Because many functions and initializers fully specify the types of their
365+
/// parameters, you can often use an array literal with or without elements as
366+
/// a parameter. For example, the `sum(_:)` function shown here takes an `Int`
367+
/// array as a parameter:
368+
///
369+
/// func sum(values: [Int]) -> Int {
370+
/// return values.reduce(0, combine: +)
371+
/// }
372+
///
373+
/// let sumOfFour = sum([5, 10, 15, 20])
374+
/// // 'sumOfFour' == 50
375+
///
376+
/// let sumOfNone = sum([])
377+
/// // 'sumOfNone' == 0
378+
///
379+
/// When you call a function that does not fully specify its parameters' types,
380+
/// use the type-cast operator (`as`) to specify the type of an array literal.
381+
/// For example, the `log(name:value:)` function shown here has an
382+
/// unconstrained generic `value` parameter.
383+
///
384+
/// func log<T>(name name: String, value: T) {
385+
/// print("\(name): \(value)")
386+
/// }
387+
///
388+
/// log(name: "Four integers", value: [5, 10, 15, 20])
389+
/// // Prints "Four integers: [5, 10, 15, 20]"
390+
///
391+
/// log(name: "Zero integers", value: [] as [Int])
392+
/// // Prints "Zero integers: []"
393+
///
394+
/// Conforming to ArrayLiteralConvertible
395+
/// =====================================
396+
///
397+
/// Add the capability to be initialized with an array literal to your own
398+
/// custom types by declaring an `init(arrayLiteral:)` initializer. The
399+
/// following example shows the array literal initializer for a hypothetical
400+
/// `OrderedSet` type, which has setlike semantics but maintains the order of
401+
/// its elements.
402+
///
403+
/// struct OrderedSet<Element: Hashable>: Collection, SetAlgebra {
404+
/// // implementation details
405+
/// }
406+
///
407+
/// extension OrderedSet: ArrayLiteralConvertible {
408+
/// init(arrayLiteral: Element...) {
409+
/// self.init()
410+
/// for element in arrayLiteral {
411+
/// self.append(element)
412+
/// }
413+
/// }
414+
/// }
176415
public protocol ArrayLiteralConvertible {
177416
associatedtype Element
178-
/// Create an instance initialized with `elements`.
417+
/// Creates an instance initialized with the given elements.
179418
init(arrayLiteral elements: Element...)
180419
}
181420

stdlib/public/core/ExistentialCollection.swift.gyb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -887,7 +887,7 @@ public func !== <
887887
/// same `Element` type, hiding the specifics of the underlying
888888
/// `Collection`.
889889
///
890-
/// - SeeAlso: ${', '.join('`Any%s`' % collectionForTraversal(t) for t in (2 * TRAVERSALS)[ti + 1 : ti + 3]) }
890+
/// - SeeAlso: ${', '.join('`Any%sCollection`' % t for t in (2 * TRAVERSALS)[ti + 1 : ti + 3]) }
891891
public struct ${Self}<Element>
892892
: AnyCollectionProtocol, ${SelfProtocol} {
893893

0 commit comments

Comments
 (0)