|
| 1 | +//===----------------------------------------------------------------------===// |
| 2 | +// |
| 3 | +// This source file is part of the Swift.org open source project |
| 4 | +// |
| 5 | +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors |
| 6 | +// Licensed under Apache License v2.0 with Runtime Library Exception |
| 7 | +// |
| 8 | +// See http://swift.org/LICENSE.txt for license information |
| 9 | +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| 10 | +// |
| 11 | +//===----------------------------------------------------------------------===// |
| 12 | + |
| 13 | +/// A type that can be compared using the relational operators `<`, `<=`, `>=`, |
| 14 | +/// and `>`. |
| 15 | +/// |
| 16 | +/// The `Comparable` protocol is used for types that have an inherent order, |
| 17 | +/// such as numbers and strings. Many types in the standard library already |
| 18 | +/// conform to the `Comparable` protocol. Add `Comparable` conformance to your |
| 19 | +/// own custom types when you want to be able to compare instances using |
| 20 | +/// relational operators or use standard library methods that are designed for |
| 21 | +/// `Comparable` types. |
| 22 | +/// |
| 23 | +/// The most familiar use of relational operators is to compare numbers, as in |
| 24 | +/// the following example: |
| 25 | +/// |
| 26 | +/// let currentTemp = 73 |
| 27 | +/// |
| 28 | +/// if currentTemp >= 90 { |
| 29 | +/// print("It's a scorcher!") |
| 30 | +/// } else if currentTemp < 65 { |
| 31 | +/// print("Might need a sweater today.") |
| 32 | +/// } else { |
| 33 | +/// print("Seems like picnic weather!") |
| 34 | +/// } |
| 35 | +/// // Prints "Seems like picnic weather!" |
| 36 | +/// |
| 37 | +/// You can use special versions of some sequence and collection operations |
| 38 | +/// when working with a `Comparable` type. For example, if your array's |
| 39 | +/// elements conform to `Comparable`, you can call the `sort()` method without |
| 40 | +/// using arguments to sort the elements of your array in ascending order. |
| 41 | +/// |
| 42 | +/// var measurements = [1.1, 1.5, 2.9, 1.2, 1.5, 1.3, 1.2] |
| 43 | +/// measurements.sort() |
| 44 | +/// print(measurements) |
| 45 | +/// // Prints "[1.1, 1.2, 1.2, 1.3, 1.5, 1.5, 2.9]" |
| 46 | +/// |
| 47 | +/// Conforming to the Comparable Protocol |
| 48 | +/// ===================================== |
| 49 | +/// |
| 50 | +/// Types with Comparable conformance implement the less-than operator (`<`) |
| 51 | +/// and the is-equal-to operator (`==`). These two operations impose a strict |
| 52 | +/// total order on the values of a type, in which exactly one of the following |
| 53 | +/// must be true for any two values `a` and `b`: |
| 54 | +/// |
| 55 | +/// - `a == b` |
| 56 | +/// - `a < b` |
| 57 | +/// - `b < a` |
| 58 | +/// |
| 59 | +/// In addition, the following conditions must hold: |
| 60 | +/// |
| 61 | +/// - `a < a` is always `false` (Irreflexivity) |
| 62 | +/// - `a < b` implies `!(b < a)` (Asymmetry) |
| 63 | +/// - `a < b` and `b < c` implies `a < c` (Transitivity) |
| 64 | +/// |
| 65 | +/// To add `Comparable` conformance to your custom types, define the `<` and |
| 66 | +/// `==` operators. The `==` operator is a requirement of the `Equatable` |
| 67 | +/// protocol, which `Comparable` extends---see that protocol's documentation |
| 68 | +/// for more information about equality in Swift. Because default |
| 69 | +/// implementations of the remainder of the relational operators are provided |
| 70 | +/// by the standard library, you'll be able to use `!=`, `>`, `<=`, and `>=` |
| 71 | +/// with instances of your type without any further code. |
| 72 | +/// |
| 73 | +/// As an example, here's an implementation of a `Date` structure that stores |
| 74 | +/// the year, month, and day of a date: |
| 75 | +/// |
| 76 | +/// struct Date { |
| 77 | +/// let year: Int |
| 78 | +/// let month: Int |
| 79 | +/// let day: Int |
| 80 | +/// } |
| 81 | +/// |
| 82 | +/// To add `Comparable` conformance to `Date`, first declare conformance to |
| 83 | +/// `Comparable` and implement the `<` operator function. |
| 84 | +/// |
| 85 | +/// extension Date: Comparable { } |
| 86 | +/// |
| 87 | +/// func <(lhs: Date, rhs: Date) -> Bool { |
| 88 | +/// if lhs.year != rhs.year { |
| 89 | +/// return lhs.year < rhs.year |
| 90 | +/// } else if lhs.month != rhs.month { |
| 91 | +/// return lhs.month < rhs.month |
| 92 | +/// } else { |
| 93 | +/// return lhs.day < rhs.day |
| 94 | +/// } |
| 95 | +/// } |
| 96 | +/// |
| 97 | +/// This function uses the least specific nonmatching property of the date to |
| 98 | +/// determine the result of the comparison. For example, if the two `year` |
| 99 | +/// properties are equal but the two `month` properties are not, the date with |
| 100 | +/// the lesser value for `month` is the lesser of the two dates. |
| 101 | +/// |
| 102 | +/// Next, implement the `==` operator function, the requirement inherited from |
| 103 | +/// the `Equatable` protocol. |
| 104 | +/// |
| 105 | +/// func ==(lhs: Date, rhs: Date) -> Bool { |
| 106 | +/// return lhs.year == rhs.year && lhs.month == rhs.month |
| 107 | +/// && lhs.day == rhs.day |
| 108 | +/// } |
| 109 | +/// |
| 110 | +/// Two `Date` instances are equal if each of their corresponding properties is |
| 111 | +/// equal. |
| 112 | +/// |
| 113 | +/// Now that `Date` conforms to `Comparable`, you can compare instances of the |
| 114 | +/// type with any of the relational operators. The following example compares |
| 115 | +/// the date of the first moon landing with the release of David Bowie's song |
| 116 | +/// "Space Oddity": |
| 117 | +/// |
| 118 | +/// let spaceOddity = Date(year: 1969, month: 7, day: 11) // July 11, 1969 |
| 119 | +/// let moonLanding = Date(year: 1969, month: 7, day: 20) // July 20, 1969 |
| 120 | +/// if moonLanding > spaceOddity { |
| 121 | +/// print("Major Tom stepped through the door first.") |
| 122 | +/// } else { |
| 123 | +/// print("David Bowie was following in Neil Armstrong's footsteps.") |
| 124 | +/// } |
| 125 | +/// // Prints "Major Tom stepped through the door first." |
| 126 | +/// |
| 127 | +/// Note that the `>` operator provided by the standard library is used in this |
| 128 | +/// example, not the `<` operator implemented above. |
| 129 | +/// |
| 130 | +/// - Note: A conforming type may contain a subset of values which are treated |
| 131 | +/// as exceptional---that is, values that are outside the domain of |
| 132 | +/// meaningful arguments for the purposes of the `Comparable` protocol. For |
| 133 | +/// example, the special not-a-number (`FloatingPoint.nan`) value for |
| 134 | +/// floating-point types compares as neither less than, greater than, nor |
| 135 | +/// equal to any normal floating-point value. Exceptional values need not |
| 136 | +/// take part in the strict total order. |
| 137 | +public protocol Comparable : Equatable { |
| 138 | + /// Returns a Boolean value indicating whether the value of the first |
| 139 | + /// argument is less than that of the second argument. |
| 140 | + /// |
| 141 | + /// This function is the only requirement of the `Comparable` protocol. The |
| 142 | + /// remainder of the relational operator functions are implemented by the |
| 143 | + /// standard library for any type that conforms to `Comparable`. |
| 144 | + /// |
| 145 | + /// - Parameters: |
| 146 | + /// - lhs: A value to compare. |
| 147 | + /// - rhs: Another value to compare. |
| 148 | + func < (lhs: Self, rhs: Self) -> Bool |
| 149 | + |
| 150 | + /// Returns a Boolean value indicating whether the value of the first |
| 151 | + /// argument is less than or equal to that of the second argument. |
| 152 | + /// |
| 153 | + /// - Parameters: |
| 154 | + /// - lhs: A value to compare. |
| 155 | + /// - rhs: Another value to compare. |
| 156 | + func <= (lhs: Self, rhs: Self) -> Bool |
| 157 | + |
| 158 | + /// Returns a Boolean value indicating whether the value of the first |
| 159 | + /// argument is greater than or equal to that of the second argument. |
| 160 | + /// |
| 161 | + /// - Parameters: |
| 162 | + /// - lhs: A value to compare. |
| 163 | + /// - rhs: Another value to compare. |
| 164 | + func >= (lhs: Self, rhs: Self) -> Bool |
| 165 | + |
| 166 | + /// Returns a Boolean value indicating whether the value of the first |
| 167 | + /// argument is greater than that of the second argument. |
| 168 | + /// |
| 169 | + /// - Parameters: |
| 170 | + /// - lhs: A value to compare. |
| 171 | + /// - rhs: Another value to compare. |
| 172 | + func > (lhs: Self, rhs: Self) -> Bool |
| 173 | +} |
| 174 | + |
| 175 | +/// Returns a Boolean value indicating whether the value of the first argument |
| 176 | +/// is greater than that of the second argument. |
| 177 | +/// |
| 178 | +/// This is the default implementation of the greater-than operator (`>`) for |
| 179 | +/// any type that conforms to `Comparable`. |
| 180 | +/// |
| 181 | +/// - Parameters: |
| 182 | +/// - lhs: A value to compare. |
| 183 | +/// - rhs: Another value to compare. |
| 184 | +public func > <T : Comparable>(lhs: T, rhs: T) -> Bool { |
| 185 | + return rhs < lhs |
| 186 | +} |
| 187 | + |
| 188 | +/// Returns a Boolean value indicating whether the value of the first argument |
| 189 | +/// is less than or equal to that of the second argument. |
| 190 | +/// |
| 191 | +/// This is the default implementation of the less-than-or-equal-to |
| 192 | +/// operator (`<=`) for any type that conforms to `Comparable`. |
| 193 | +/// |
| 194 | +/// - Parameters: |
| 195 | +/// - lhs: A value to compare. |
| 196 | +/// - rhs: Another value to compare. |
| 197 | +public func <= <T : Comparable>(lhs: T, rhs: T) -> Bool { |
| 198 | + return !(rhs < lhs) |
| 199 | +} |
| 200 | + |
| 201 | +/// Returns a Boolean value indicating whether the value of the first argument |
| 202 | +/// is greater than or equal to that of the second argument. |
| 203 | +/// |
| 204 | +/// This is the default implementation of the greater-than-or-equal-to operator |
| 205 | +/// (`>=`) for any type that conforms to `Comparable`. |
| 206 | +/// |
| 207 | +/// - Parameters: |
| 208 | +/// - lhs: A value to compare. |
| 209 | +/// - rhs: Another value to compare. |
| 210 | +/// - Returns: `true` if `lhs` is greater than or equal to `rhs`; otherwise, |
| 211 | +/// `false`. |
| 212 | +public func >= <T : Comparable>(lhs: T, rhs: T) -> Bool { |
| 213 | + return !(lhs < rhs) |
| 214 | +} |
| 215 | + |
0 commit comments