Permalink
Switch branches/tags
4.1-dont-hardcode-numbers-in-objc-block-sil 5.0-dont-hardcode-numbers-in-objc-block-sil Character-test-patch Compare-types-with-equal-equal SR-2545 TensorFlowLite UnicodeEncoding anotherdayanothercommit asyncawait bananaphone builtin-int128 cherr42 codable_test_comment_fix core-team-resolution-2017-05-10 dabrahams-append-contentsOf-replaceRange dcci-build-script-backend demangledmepatatino distributed-test dwa-where-clause-cleanup empty-collection-debugPrecondition external-swift-stdlib _fastCStringContents fix-macos-build-runtime fixmeSC generic-typealias-1-lldb gsb-superclass gyb-nested-expand hoist-to-stringprotocol hoist-to-stringprotocol.1 inhibit-implicit-conversions inline-ASCII-grapheme-fastpaths is-swift-bit-5 latest-emacs-fix-fix marcrasi-const-evaluator-part-1 marcrasi-const-evaluator-part-2 marcrasi-const-evaluator-part-3 marcrasi-last-irgen-attrs marcrasi-static-assert master-llvm-swift5-transition master-next master move-debugging-executables-into-its-own-section no-6-figure-benchmarks owned_fix patatinomio pr-66bbf1369684fc75517cfe6a12718d3cdf6a09d6 pr-94ee6e6c6e2d268f47f17dead77e4feb169c24e6 preservesugar rdar-43033749-fix-batch-mode-no-diags-swift-5.0-branch readme-add-tf-gpu remotemirrorsfixmacho remove-narrow-perf-hack revert-12818-cover-model revert-12843-force-on-named-lazy-member-loading revert-13168-large_type_lldb_workaround revert-13438-re-cover-model revert-13597-master revert-14840-concat_thin revert-14846-rdar-37790062-alt revert-15421-disable_autolinkextract revert-15602-deserialize-clang-importer-witness-tables-4.2 revert-16072-disable_failing_test revert-16149-rdar39629937-master revert-16188-assert-metadata-mangled-name-roundtrip revert-17271-DIOptWritePR revert-17370-raj-cp-allargs revert-17668-master revert-18066-sr8022-workaround revert-18156-generalized-accessors revert-18226-42480588 revert-18315-fix-argument-convention revert-18500-swift-syntax-dependency revert-18624-unbreak_unified_linux_builds revert-19006-error-bridging-integer-type revert-19050-revert-19006-error-bridging-integer-type revert-19097-fluctuation-of-the-pupil revert-19130-run-remote-run revert-19138-revert-19130-run-remote-run revert-19202-rework-type-checking-designated-protocol revert-19253-serialize-generic-typealias revert-19300-explicit-implicit-conversion revert-19447-fix-req-diagnstics-not-to-print-special-names revert-19500-updateValue-but-not-the-key revert-19689-keep-sourcekitd-response-alive-while-variant-lives revert-20129-make-nsobject-hashvalue-final revert-20187-another-42247881 revert-20191-revert-20190-rdar45708367 revert-20444-rdar-45659733-5.0 revert-20561-multi-payload-xi revert-20846-swift-5.0-default-to-gold-linker revert-20956-irgen-invariant-load revert-21199-14 rst-to-markdown runtime-fix-swift-error-box-comparison rxwei-patch-1 sequence=collection shahmishal-patch-1 shahmishal/swift-4.2-branch-update shahmishal/test-swift-4.2-branch silgen-tests-should-build-modules silgen-transform-null-context-3.0 stable static-rangereplaceable-plus stdlib-BidirectionalCollection.removeLast stdlib-default-RangeReplaceableCollection.SubSequence-3.0 stdlib-indexing stdlib-manual stdlib-swift4-build substring-views substring swift-2.2-branch swift-2.2-with-migration-attributes swift-2.3-branch swift-3.0-branch swift-3.0-preview-1-branch swift-3.0-preview-2-branch swift-3.0-preview-3-branch swift-3.0-preview-4-branch swift-3.0-preview-5-branch swift-3.0-preview-5-speculative swift-3.0.1-preview-2-branch swift-3.1-branch swift-4.0-branch-04-18-2017 swift-4.0-branch-06-02-2017 swift-4.0-branch-06-23-2017 swift-4.0-branch-07-11-2017 swift-4.0-branch-10-10-2017 swift-4.0-branch swift-4.1-branch swift-4.2-branch-03-26-2018 swift-4.2-branch-04-20-2018 swift-4.2-branch-04-30-2018 swift-4.2-branch-06-11-2018 swift-4.2-branch swift-4.2-xcode-10-beta-5 swift-5.0-branch-10-15-2018 swift-5.0-branch-11-16-2018 swift-5.0-branch-12-12-2018 swift-5.0-branch swift-master-xcode-10-beta-5 swiftstringview-specialization tensorflow-merge tensorflow the-runtime-stands-alone-5 typelist-existential unicode-rethink unioc update-checkout-swift-5
Nothing to show
Find file Copy path
350 lines (331 sloc) 11.6 KB
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 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
//
//===----------------------------------------------------------------------===//
// Bool Datatype and Supporting Operators
//===----------------------------------------------------------------------===//
/// A value type whose instances are either `true` or `false`.
///
/// `Bool` represents Boolean values in Swift. Create instances of `Bool` by
/// using one of the Boolean literals `true` or `false`, or by assigning the
/// result of a Boolean method or operation to a variable or constant.
///
/// var godotHasArrived = false
///
/// let numbers = 1...5
/// let containsTen = numbers.contains(10)
/// print(containsTen)
/// // Prints "false"
///
/// let (a, b) = (100, 101)
/// let aFirst = a < b
/// print(aFirst)
/// // Prints "true"
///
/// Swift uses only simple Boolean values in conditional contexts to help avoid
/// accidental programming errors and to help maintain the clarity of each
/// control statement. Unlike in other programming languages, in Swift, integers
/// and strings cannot be used where a Boolean value is required.
///
/// For example, the following code sample does not compile, because it
/// attempts to use the integer `i` in a logical context:
///
/// var i = 5
/// while i {
/// print(i)
/// i -= 1
/// }
/// // error: 'Int' is not convertible to 'Bool'
///
/// The correct approach in Swift is to compare the `i` value with zero in the
/// `while` statement.
///
/// while i != 0 {
/// print(i)
/// i -= 1
/// }
///
/// Using Imported Boolean values
/// =============================
///
/// The C `bool` and `Boolean` types and the Objective-C `BOOL` type are all
/// bridged into Swift as `Bool`. The single `Bool` type in Swift guarantees
/// that functions, methods, and properties imported from C and Objective-C
/// have a consistent type interface.
@_fixed_layout
public struct Bool {
@usableFromInline
internal var _value: Builtin.Int1
/// Creates an instance initialized to `false`.
///
/// Do not call this initializer directly. Instead, use the Boolean literal
/// `false` to create a new `Bool` instance.
@_transparent
public init() {
let zero: Int8 = 0
self._value = Builtin.trunc_Int8_Int1(zero._value)
}
@usableFromInline @_transparent
internal init(_ v: Builtin.Int1) { self._value = v }
/// Creates an instance equal to the given Boolean value.
///
/// - Parameter value: The Boolean value to copy.
@inlinable
public init(_ value: Bool) {
self = value
}
/// Returns a random Boolean value, using the given generator as a source for
/// randomness.
///
/// This method returns `true` and `false` with equal probability. Use this
/// method to generate a random Boolean value when you are using a custom
/// random number generator.
///
/// let flippedHeads = Bool.random(using: &myGenerator)
/// if flippedHeads {
/// print("Heads, you win!")
/// } else {
/// print("Maybe another try?")
/// }
///
/// - Note: The algorithm used to create random values may change in a future
/// version of Swift. If you're passing a generator that results in the
/// same sequence of Boolean values each time you run your program, that
/// sequence may change when your program is compiled using a different
/// version of Swift.
///
/// - Parameter generator: The random number generator to use when creating
/// the new random value.
/// - Returns: Either `true` or `false`, randomly chosen with equal
/// probability.
@inlinable
public static func random<T: RandomNumberGenerator>(
using generator: inout T
) -> Bool {
return (generator.next() >> 17) & 1 == 0
}
/// Returns a random Boolean value.
///
/// This method returns `true` and `false` with equal probability.
///
/// let flippedHeads = Bool.random()
/// if flippedHeads {
/// print("Heads, you win!")
/// } else {
/// print("Maybe another try?")
/// }
///
/// This method is equivalent to calling `Bool.random(using:)`, passing in
/// the system's default random generator.
///
/// - Returns: Either `true` or `false`, randomly chosen with equal
/// probability.
@inlinable
public static func random() -> Bool {
var g = SystemRandomNumberGenerator()
return Bool.random(using: &g)
}
}
extension Bool : _ExpressibleByBuiltinBooleanLiteral, ExpressibleByBooleanLiteral {
@_transparent
public init(_builtinBooleanLiteral value: Builtin.Int1) {
self._value = value
}
/// Creates an instance initialized to the specified Boolean literal.
///
/// Do not call this initializer directly. It is used by the compiler when
/// you use a Boolean literal. Instead, create a new `Bool` instance by
/// using one of the Boolean literals `true` or `false`.
///
/// var printedMessage = false
///
/// if !printedMessage {
/// print("You look nice today!")
/// printedMessage = true
/// }
/// // Prints "You look nice today!"
///
/// In this example, both assignments to the `printedMessage` variable call
/// this Boolean literal initializer behind the scenes.
///
/// - Parameter value: The value of the new instance.
@_transparent
public init(booleanLiteral value: Bool) {
self = value
}
}
extension Bool {
// This is a magic entry point known to the compiler.
@_transparent
public // COMPILER_INTRINSIC
func _getBuiltinLogicValue() -> Builtin.Int1 {
return _value
}
}
extension Bool : CustomStringConvertible {
/// A textual representation of the Boolean value.
@inlinable
public var description: String {
return self ? "true" : "false"
}
}
extension Bool: Equatable {
@_transparent
public static func == (lhs: Bool, rhs: Bool) -> Bool {
return Bool(Builtin.cmp_eq_Int1(lhs._value, rhs._value))
}
}
extension Bool: Hashable {
/// Hashes the essential components of this value by feeding them into the
/// given hasher.
///
/// - Parameter hasher: The hasher to use when combining the components
/// of this instance.
@inlinable
public func hash(into hasher: inout Hasher) {
hasher.combine((self ? 1 : 0) as UInt8)
}
}
extension Bool : LosslessStringConvertible {
/// Creates a new Boolean value from the given string.
///
/// If the `description` value is any string other than `"true"` or
/// `"false"`, the result is `nil`. This initializer is case sensitive.
///
/// - Parameter description: A string representation of the Boolean value.
@inlinable
public init?(_ description: String) {
if description == "true" {
self = true
} else if description == "false" {
self = false
} else {
return nil
}
}
}
//===----------------------------------------------------------------------===//
// Operators
//===----------------------------------------------------------------------===//
extension Bool {
/// Performs a logical NOT operation on a Boolean value.
///
/// The logical NOT operator (`!`) inverts a Boolean value. If the value is
/// `true`, the result of the operation is `false`; if the value is `false`,
/// the result is `true`.
///
/// var printedMessage = false
///
/// if !printedMessage {
/// print("You look nice today!")
/// printedMessage = true
/// }
/// // Prints "You look nice today!"
///
/// - Parameter a: The Boolean value to negate.
@_transparent
public static prefix func ! (a: Bool) -> Bool {
return Bool(Builtin.xor_Int1(a._value, true._value))
}
}
extension Bool {
/// Performs a logical AND operation on two Boolean values.
///
/// The logical AND operator (`&&`) combines two Boolean values and returns
/// `true` if both of the values are `true`. If either of the values is
/// `false`, the operator returns `false`.
///
/// This operator uses short-circuit evaluation: The left-hand side (`lhs`) is
/// evaluated first, and the right-hand side (`rhs`) is evaluated only if
/// `lhs` evaluates to `true`. For example:
///
/// let measurements = [7.44, 6.51, 4.74, 5.88, 6.27, 6.12, 7.76]
/// let sum = measurements.reduce(0, combine: +)
///
/// if measurements.count > 0 && sum / Double(measurements.count) < 6.5 {
/// print("Average measurement is less than 6.5")
/// }
/// // Prints "Average measurement is less than 6.5"
///
/// In this example, `lhs` tests whether `measurements.count` is greater than
/// zero. Evaluation of the `&&` operator is one of the following:
///
/// - When `measurements.count` is equal to zero, `lhs` evaluates to `false`
/// and `rhs` is not evaluated, preventing a divide-by-zero error in the
/// expression `sum / Double(measurements.count)`. The result of the
/// operation is `false`.
/// - When `measurements.count` is greater than zero, `lhs` evaluates to
/// `true` and `rhs` is evaluated. The result of evaluating `rhs` is the
/// result of the `&&` operation.
///
/// - Parameters:
/// - lhs: The left-hand side of the operation.
/// - rhs: The right-hand side of the operation.
@_transparent
@inline(__always)
public static func && (lhs: Bool, rhs: @autoclosure () throws -> Bool) rethrows
-> Bool {
return lhs ? try rhs() : false
}
/// Performs a logical OR operation on two Boolean values.
///
/// The logical OR operator (`||`) combines two Boolean values and returns
/// `true` if at least one of the values is `true`. If both values are
/// `false`, the operator returns `false`.
///
/// This operator uses short-circuit evaluation: The left-hand side (`lhs`) is
/// evaluated first, and the right-hand side (`rhs`) is evaluated only if
/// `lhs` evaluates to `false`. For example:
///
/// let majorErrors: Set = ["No first name", "No last name", ...]
/// let error = ""
///
/// if error.isEmpty || !majorErrors.contains(error) {
/// print("No major errors detected")
/// } else {
/// print("Major error: \(error)")
/// }
/// // Prints "No major errors detected"
///
/// In this example, `lhs` tests whether `error` is an empty string.
/// Evaluation of the `||` operator is one of the following:
///
/// - When `error` is an empty string, `lhs` evaluates to `true` and `rhs` is
/// not evaluated, skipping the call to `majorErrors.contains(_:)`. The
/// result of the operation is `true`.
/// - When `error` is not an empty string, `lhs` evaluates to `false` and
/// `rhs` is evaluated. The result of evaluating `rhs` is the result of the
/// `||` operation.
///
/// - Parameters:
/// - lhs: The left-hand side of the operation.
/// - rhs: The right-hand side of the operation.
@_transparent
@inline(__always)
public static func || (lhs: Bool, rhs: @autoclosure () throws -> Bool) rethrows
-> Bool {
return lhs ? true : try rhs()
}
}
extension Bool {
/// Toggles the Boolean variable's value.
///
/// Use this method to toggle a Boolean value from `true` to `false` or from
/// `false` to `true`.
///
/// var bools = [true, false]
///
/// bools[0].toggle()
/// // bools == [false, false]
@inlinable
public mutating func toggle() {
self = !self
}
}