Skip to content

Commit 55be501

Browse files
committed
Merge pull request #2429 from natecook1000/nc-revise-core
[stdlib] Revise documentation for core types and protocols
2 parents 5345128 + dfa8915 commit 55be501

12 files changed

+947
-100
lines changed

stdlib/public/core/Bool.swift

Lines changed: 88 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,53 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
/// A value type whose instances are either `true` or `false`.
16+
///
17+
/// `Bool` is the default type for Boolean values in Swift. Create instances of
18+
/// `Bool` by using one of the Boolean literals `true` and `false` or by
19+
/// assigning the result of a Boolean method or operation to a variable or
20+
/// constant.
21+
///
22+
/// var godotHasArrived = false
23+
///
24+
/// let numbers = 1...5
25+
/// let containsTen = numbers.contains(10)
26+
/// print(containsTen)
27+
/// // Prints "false"
28+
///
29+
/// let (a, b) == (100, 101)
30+
/// let aFirst = a < b
31+
/// print(aFirst)
32+
/// // Prints "true"
33+
///
34+
/// Swift uses only simple Boolean values in conditional contexts to help avoid
35+
/// accidental programming errors and to help maintain the clarity of each
36+
/// control statement. Unlike other programming languages, in Swift integers
37+
/// and strings cannot be used where a Boolean value is expected.
38+
///
39+
/// For example, the following code sample does not compile, because it
40+
/// attempts to use the integer `i` in a logical context:
41+
///
42+
/// var i = 5
43+
/// while i {
44+
/// print(i)
45+
/// i -= 1
46+
/// }
47+
///
48+
/// The correct approach in Swift is to compare the `i` value with zero in the
49+
/// `while` statement.
50+
///
51+
/// while i != 0 {
52+
/// print(i)
53+
/// i -= 1
54+
/// }
1655
@_fixed_layout
1756
public struct Bool {
1857
internal var _value: Builtin.Int1
1958

20-
/// Default-initialize Boolean value to `false`.
59+
/// Creates an instance initialized to `false`.
60+
///
61+
/// Don't call this initializer directly. Instead, use the Boolean literal
62+
/// `false` to create a new `Bool` instance.
2163
@_transparent
2264
public init() {
2365
let zero: Int8 = 0
@@ -35,7 +77,24 @@ extension Bool : _BuiltinBooleanLiteralConvertible, BooleanLiteralConvertible {
3577
self._value = value
3678
}
3779

38-
/// Create an instance initialized to `value`.
80+
/// Creates an instance initialized to the specified Boolean literal.
81+
///
82+
/// Don't directly call this initializer, which is used by the compiler when
83+
/// you use a Boolean literal. Instead, create a new `Bool` instance by
84+
/// using one of the Boolean literals `true` and `false`.
85+
///
86+
/// var printedMessage = false
87+
///
88+
/// if !printedMessage {
89+
/// print("You look nice today!")
90+
/// printedMessage = true
91+
/// }
92+
/// // Prints "You look nice today!"
93+
///
94+
/// In this example, both assignments to the `printedMessage` variable call
95+
/// this Boolean literal initializer behind the scenes.
96+
///
97+
/// - Parameter value: The value of the new instance.
3998
@_transparent
4099
public init(booleanLiteral value: Bool) {
41100
self = value
@@ -49,18 +108,20 @@ extension Bool : Boolean {
49108
return _value
50109
}
51110

52-
/// Identical to `self`.
111+
/// This value expressed as a `Bool` instance; its value is identical to that
112+
/// of the current instance.
53113
@_transparent public var boolValue: Bool { return self }
54114

55-
/// Construct an instance representing the same logical value as
56-
/// `value`.
115+
/// Creates an instance representing the given logical value.
116+
///
117+
/// - Parameter value: The logical value for the new instance.
57118
public init<T : Boolean>(_ value: T) {
58119
self = value.boolValue
59120
}
60121
}
61122

62123
extension Bool : CustomStringConvertible {
63-
/// A textual representation of `self`.
124+
/// A textual representation of the Boolean value.
64125
public var description: String {
65126
return self ? "true" : "false"
66127
}
@@ -73,13 +134,14 @@ func _getBool(_ v: Builtin.Int1) -> Bool { return Bool(v) }
73134

74135
@_transparent
75136
extension Bool : Equatable, Hashable {
76-
/// The hash value.
137+
/// The hash value for the Boolean value.
77138
///
78-
/// **Axiom:** `x == y` implies `x.hashValue == y.hashValue`.
139+
/// Two values that are equal always have equal hash values.
79140
///
80-
/// - Note: the hash value is not guaranteed to be stable across
81-
/// different invocations of the same program. Do not persist the
82-
/// hash value across program runs.
141+
/// - Note: The hash value is not guaranteed to be stable across different
142+
/// invocations of the same program. Do not persist the hash value across
143+
/// program runs.
144+
/// - SeeAlso: `Hashable`
83145
public var hashValue: Int {
84146
return self ? 1 : 0
85147
}
@@ -89,7 +151,21 @@ extension Bool : Equatable, Hashable {
89151
// Operators
90152
//===----------------------------------------------------------------------===//
91153

92-
// Unary logical complement.
154+
/// Performs a logical NOT operation on a Boolean value.
155+
///
156+
/// The `!` (logical NOT) operator inverts a Boolean value. If the value is
157+
/// `true`, the result of the operation is `false`; if the value is `false`,
158+
/// the result is `true`.
159+
///
160+
/// var printedMessage = false
161+
///
162+
/// if !printedMessage {
163+
/// print("You look nice today!")
164+
/// printedMessage = true
165+
/// }
166+
/// // Prints "You look nice today!"
167+
///
168+
/// - Parameter a: The Boolean value to negate.
93169
@_transparent
94170
@warn_unused_result
95171
public prefix func !(a: Bool) -> Bool {

stdlib/public/core/Boolean.swift

Lines changed: 145 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,58 @@
1212
// Boolean
1313
//===----------------------------------------------------------------------===//
1414

15-
/// Returns the result of inverting `a`'s logic value.
15+
/// Performs a logical NOT operation on a Boolean value.
16+
///
17+
/// The `!` (logical NOT) operator inverts a Boolean value. If the value is
18+
/// `true`, the result of the operation is `false`; if the value is `false`,
19+
/// the result is `true`. For example:
20+
///
21+
/// var printedMessage = false
22+
///
23+
/// if !printedMessage {
24+
/// print("You look nice today!")
25+
/// printedMessage = true
26+
/// }
27+
/// // Prints "You look nice today!"
28+
///
29+
/// - Parameter a: The Boolean value to negate.
1630
@warn_unused_result
1731
public prefix func !<T : Boolean>(a: T) -> Bool {
1832
return !a.boolValue
1933
}
2034

21-
/// If `lhs` is `false`, return it. Otherwise, evaluate `rhs` and
22-
/// return its `boolValue`.
35+
/// Performs a logical AND operation on two Boolean values.
36+
///
37+
/// The `&&` (logical AND) operator combines two Boolean values and returns
38+
/// `true` if both of the values are `true`. If either of the values is
39+
/// `false`, the operator returns `false`.
40+
///
41+
/// This operator uses short-circuit evaluation: The left-hand side (`lhs`) is
42+
/// evaluated first, and the right-hand side (`rhs`) is evaluated only if
43+
/// `lhs` evaluates to `true`. For example:
44+
///
45+
/// let measurements = [7.44, 6.51, 4.74, 5.88, 6.27, 6.12, 7.76]
46+
/// let sum = measurements.reduce(0, combine: +)
47+
///
48+
/// if measurements.count > 0 && sum / Double(measurements.count) < 6.5 {
49+
/// print("Average measurement is less than 6.5")
50+
/// }
51+
/// // Prints "Average measurement is less than 6.5"
52+
///
53+
/// In this example, `lhs` tests whether `measurements.count` is greater than
54+
/// zero. Evaluation of the `&&` operator is one of the following:
55+
///
56+
/// - When `measurements.count` is equal to zero, `lhs` evaluates to `false`
57+
/// and `rhs` is not evaluated, preventing a divide-by-zero error in the
58+
/// expression `sum / Double(measurements.count)`. The result of the
59+
/// operation is `false`.
60+
/// - When `measurements.count` is greater than zero, `lhs` evaluates to `true`
61+
/// and `rhs` is evaluated. The result of evaluating `rhs` is the result of
62+
/// the `&&` operation.
63+
///
64+
/// - Parameters:
65+
/// - lhs: The left-hand side of the operation.
66+
/// - rhs: The right-hand side of the operation.
2367
@inline(__always)
2468
@warn_unused_result
2569
public func && <T : Boolean, U : Boolean>(
@@ -28,8 +72,39 @@ public func && <T : Boolean, U : Boolean>(
2872
return lhs.boolValue ? try rhs().boolValue : false
2973
}
3074

31-
/// If `lhs` is `true`, return it. Otherwise, evaluate `rhs` and
32-
/// return its `boolValue`.
75+
/// Performs a logical OR operation on two Boolean values.
76+
///
77+
/// The `||` (logical OR) operator combines two Boolean values and returns
78+
/// `true` if at least one of the values is `true`. If both values are
79+
/// `false`, the operator returns `false`.
80+
///
81+
/// This operator uses short-circuit evaluation: The left-hand side (`lhs`) is
82+
/// evaluated first, and the right-hand side (`rhs`) is evaluated only if
83+
/// `lhs` evaluates to `false`. For example:
84+
///
85+
/// let majorErrors: Set = ["No first name", "No last name", ...]
86+
/// let error = ""
87+
///
88+
/// if error.isEmpty || !majorErrors.contains(error) {
89+
/// print("No major errors detected")
90+
/// } else {
91+
/// print("Major error: \(error)")
92+
/// }
93+
/// // Prints "No major errors detected")
94+
///
95+
/// In this example, `lhs` tests whether `error` is an empty string. Evaluation
96+
/// of the `||` operator is one of the following:
97+
///
98+
/// - When `error` is an empty string, `lhs` evaluates to `true` and `rhs` is
99+
/// not evaluated, skipping the call to `majorErrors.contains(_:)`. The
100+
/// result of the operation is `true`.
101+
/// - When `error` is not an empty string, `lhs` evaluates to `false` and `rhs`
102+
/// is evaluated. The result of evaluating `rhs` is the result of the `||`
103+
/// operation.
104+
///
105+
/// - Parameters:
106+
/// - lhs: The left-hand side of the operation.
107+
/// - rhs: The right-hand side of the operation.
33108
@inline(__always)
34109
@warn_unused_result
35110
public func || <T : Boolean, U : Boolean>(
@@ -38,6 +113,38 @@ public func || <T : Boolean, U : Boolean>(
38113
return lhs.boolValue ? true : try rhs().boolValue
39114
}
40115

116+
/// Performs a logical AND operation on two Boolean values.
117+
///
118+
/// The `&&` (logical AND) operator combines two Boolean values and returns
119+
/// `true` if both of the values are `true`. If either of the values is
120+
/// `false`, the operator returns `false`.
121+
///
122+
/// This operator uses short-circuit evaluation: The left-hand side (`lhs`) is
123+
/// evaluated first, and the right-hand side (`rhs`) is evaluated only if
124+
/// `lhs` evaluates to `true`. For example:
125+
///
126+
/// let measurements = [7.44, 6.51, 4.74, 5.88, 6.27, 6.12, 7.76]
127+
/// let sum = measurements.reduce(0, combine: +)
128+
///
129+
/// if measurements.count > 0 && sum / Double(measurements.count) < 6.5 {
130+
/// print("Average measurement is less than 6.5")
131+
/// }
132+
/// // Prints "Average measurement is less than 6.5"
133+
///
134+
/// In this example, `lhs` tests whether `measurements.count` is greater than
135+
/// zero. Evaluation of the `&&` operator is one of the following:
136+
///
137+
/// - When `measurements.count` is equal to zero, `lhs` evaluates to `false`
138+
/// and `rhs` is not evaluated, preventing a divide-by-zero error in the
139+
/// expression `sum / Double(measurements.count)`. The result of the
140+
/// operation is `false`.
141+
/// - When `measurements.count` is greater than zero, `lhs` evaluates to `true`
142+
/// and `rhs` is evaluated. The result of evaluating `rhs` is the result of
143+
/// the `&&` operation.
144+
///
145+
/// - Parameters:
146+
/// - lhs: The left-hand side of the operation.
147+
/// - rhs: The right-hand side of the operation.
41148
// FIXME: We can't make the above @_transparent due to
42149
// rdar://problem/19418937, so here are some @_transparent overloads
43150
// for Bool. We've done the same for ObjCBool.
@@ -49,6 +156,39 @@ public func && <T : Boolean>(
49156
return lhs.boolValue ? try rhs().boolValue : false
50157
}
51158

159+
/// Performs a logical OR operation on two Boolean values.
160+
///
161+
/// The `||` (logical OR) operator combines two Boolean values and returns
162+
/// `true` if at least one of the values is `true`. If both values are
163+
/// `false`, the operator returns `false`.
164+
///
165+
/// This operator uses short-circuit evaluation: The left-hand side (`lhs`) is
166+
/// evaluated first, and the right-hand side (`rhs`) is evaluated only if
167+
/// `lhs` evaluates to `false`. For example:
168+
///
169+
/// let majorErrors: Set = ["No first name", "No last name", ...]
170+
/// let error = ""
171+
///
172+
/// if error.isEmpty || !majorErrors.contains(error) {
173+
/// print("No major errors detected")
174+
/// } else {
175+
/// print("Major error: \(error)")
176+
/// }
177+
/// // Prints "No major errors detected")
178+
///
179+
/// In this example, `lhs` tests whether `error` is an empty string. Evaluation
180+
/// of the `||` operator is one of the following:
181+
///
182+
/// - When `error` is an empty string, `lhs` evaluates to `true` and `rhs` is
183+
/// not evaluated, skipping the call to `majorErrors.contains(_:)`. The
184+
/// result of the operation is `true`.
185+
/// - When `error` is not an empty string, `lhs` evaluates to `false` and `rhs`
186+
/// is evaluated. The result of evaluating `rhs` is the result of the `||`
187+
/// operation.
188+
///
189+
/// - Parameters:
190+
/// - lhs: The left-hand side of the operation.
191+
/// - rhs: The right-hand side of the operation.
52192
@_transparent
53193
@warn_unused_result
54194
public func || <T : Boolean>(

0 commit comments

Comments
 (0)