diff --git a/Runtimes/Core/core/CMakeLists.txt b/Runtimes/Core/core/CMakeLists.txt index 023c23fe9e433..e5364160dfe9d 100644 --- a/Runtimes/Core/core/CMakeLists.txt +++ b/Runtimes/Core/core/CMakeLists.txt @@ -21,9 +21,6 @@ gyb_expand(UnsafeBufferPointer.swift.gyb UnsafeBufferPointer.swift gyb_expand(UnsafeRawBufferPointer.swift.gyb UnsafeRawBufferPointer.swift FLAGS "-DCMAKE_SIZEOF_VOID_P=${SwiftCore_SIZEOF_POINTER}") -gyb_expand(Tuple.swift.gyb Tuple.swift - FLAGS "-DCMAKE_SIZEOF_VOID_P=${SwiftCore_SIZEOF_POINTER}") - # These sources are not strictly sorted alphabetically because the compiler # crashes if they are. add_library(swiftCore @@ -194,6 +191,7 @@ add_library(swiftCore SwiftNativeNSArray.swift TemporaryAllocation.swift ThreadLocalStorage.swift + Tuple.swift UIntBuffer.swift UnavailableStringAPIs.swift UnicodeData.swift diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt index 935c86843bedc..0cf3e28a0c0d0 100644 --- a/stdlib/public/core/CMakeLists.txt +++ b/stdlib/public/core/CMakeLists.txt @@ -248,6 +248,7 @@ split_embedded_sources( NORMAL CommandLine.swift EMBEDDED SliceBuffer.swift EMBEDDED StaticBigInt.swift + EMBEDDED Tuple.swift EMBEDDED UInt128.swift EMBEDDED UnfoldSequence.swift EMBEDDED UnsafeBufferPointerSlice.swift @@ -268,7 +269,6 @@ split_embedded_sources( EMBEDDED LegacyInt128.swift.gyb EMBEDDED UnsafeBufferPointer.swift.gyb EMBEDDED UnsafeRawBufferPointer.swift.gyb - EMBEDDED Tuple.swift.gyb ) if(SWIFT_STDLIB_ENABLE_VECTOR_TYPES) diff --git a/stdlib/public/core/Tuple.swift b/stdlib/public/core/Tuple.swift new file mode 100644 index 0000000000000..6afc0f285c139 --- /dev/null +++ b/stdlib/public/core/Tuple.swift @@ -0,0 +1,373 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2025 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 +// +//===----------------------------------------------------------------------===// + +// Variadic functions for comparison operations on tuple types. + +/// Returns a Boolean value indicating whether the corresponding components of +/// two tuples are equal. +/// +/// For two tuples to compare as equal, each corresponding pair of components +/// must be equal. The following example compares tuples made up of 4 +/// components: +/// +/// let a = ("a", 1, 2, 3) +/// let b = ("a", 1, 2, 3) +/// print(a == b) +/// // Prints "true" +/// +/// let c = ("a", 1, 2, 4) +/// print(a == c) +/// // Prints "false" +/// +/// - Parameters: +/// - lhs: A tuple of `Equatable` elements. +/// - rhs: Another tuple of elements of the same type as `lhs`. +@_alwaysEmitIntoClient +public func ==(lhs: (repeat each B), rhs: (repeat each B)) -> Bool { + for (lhs, rhs) in repeat (each lhs, each rhs) { + if lhs != rhs { + return false + } + } + return true +} + +/// Returns a Boolean value indicating whether any corresponding components of +/// the two tuples are not equal. +/// +/// For two tuples to compare as equal, each corresponding pair of components +/// must be equal. The following example compares tuples made up of 4 +/// components: +/// +/// let a = ("a", 1, 2, 3) +/// let b = ("a", 1, 2, 3) +/// print(a != b) +/// // Prints "false" +/// +/// let c = ("a", 1, 2, 4) +/// print(a != c) +/// // Prints "true" +/// +/// - Parameters: +/// - lhs: A tuple of `Equatable` elements. +/// - rhs: Another tuple of elements of the same type as `lhs`. +@_alwaysEmitIntoClient +public func !=(lhs: (repeat each B), rhs: (repeat each B)) -> Bool { + for (lhs, rhs) in repeat (each lhs, each rhs) { + if lhs == rhs { + return false + } + } + return true +} + +/// Returns a Boolean value indicating whether the first tuple is ordered +/// before the second in a lexicographical ordering. +/// +/// Given two tuples `(a1, a2, ..., aN)` and `(b1, b2, ..., bN)`, the first +/// tuple is before the second tuple if and only if +/// `a1 < b1` or (`a1 == b1` and +/// `(a2, ..., aN) < (b2, ..., bN)`). +/// +/// - Parameters: +/// - lhs: A tuple of `Comparable` elements. +/// - rhs: Another tuple of elements of the same type as `lhs`. +@_alwaysEmitIntoClient +public func < (lhs: (repeat each B), rhs: (repeat each B)) -> Bool { + for (lhs, rhs) in repeat (each lhs, each rhs) { + if lhs >= rhs { + return false + } + } + return true +} + +/// Returns a Boolean value indicating whether the first tuple is ordered +/// before or the same as the second in a lexicographical ordering. +/// +/// Given two tuples `(a1, a2, ..., aN)` and `(b1, b2, ..., bN)`, the first +/// tuple is before or the same as the second tuple if and only if +/// `a1 < b1` or (`a1 == b1` and +/// `(a2, ..., aN) <= (b2, ..., bN)`). +/// +/// - Parameters: +/// - lhs: A tuple of `Comparable` elements. +/// - rhs: Another tuple of elements of the same type as `lhs`. +@_alwaysEmitIntoClient +public func <= (lhs: (repeat each B), rhs: (repeat each B)) -> Bool { + for (lhs, rhs) in repeat (each lhs, each rhs) { + if lhs > rhs { + return false + } + } + return true +} + +/// Returns a Boolean value indicating whether the first tuple is ordered +/// after the second in a lexicographical ordering. +/// +/// Given two tuples `(a1, a2, ..., aN)` and `(b1, b2, ..., bN)`, the first +/// tuple is after the second tuple if and only if +/// `a1 > b1` or (`a1 == b1` and +/// `(a2, ..., aN) > (b2, ..., bN)`). +/// +/// - Parameters: +/// - lhs: A tuple of `Comparable` elements. +/// - rhs: Another tuple of elements of the same type as `lhs`. +@_alwaysEmitIntoClient +public func > (lhs: (repeat each B), rhs: (repeat each B)) -> Bool { + for (lhs, rhs) in repeat (each lhs, each rhs) { + if lhs <= rhs { + return false + } + } + return true +} + +/// Returns a Boolean value indicating whether the first tuple is ordered +/// after or the same as the second in a lexicographical ordering. +/// +/// Given two tuples `(a1, a2, ..., aN)` and `(b1, b2, ..., bN)`, the first +/// tuple is after or the same as the second tuple if and only if +/// `a1 > b1` or (`a1 == b1` and +/// `(a2, ..., aN) >= (b2, ..., bN)`). +/// +/// - Parameters: +/// - lhs: A tuple of `Comparable` elements. +/// - rhs: Another tuple of elements of the same type as `lhs`. +@_alwaysEmitIntoClient +public func >= (lhs: (repeat each B), rhs: (repeat each B)) -> Bool { + for (lhs, rhs) in repeat (each lhs, each rhs) { + if lhs < rhs { + return false + } + } + return true +} + +// MARK: - Old vestigial ABI symbols for old variadic tuple methods. + +@usableFromInline +@_disfavoredOverload +internal func == (lhs: (), rhs: ()) -> Bool { + return true +} + +@usableFromInline +@_disfavoredOverload +internal func != (lhs: (), rhs: ()) -> Bool { + return false +} + +@usableFromInline +@_disfavoredOverload +internal func < (lhs: (), rhs: ()) -> Bool { + return false +} + +@usableFromInline +@_disfavoredOverload +internal func <= (lhs: (), rhs: ()) -> Bool { + return true +} + +@usableFromInline +@_disfavoredOverload +internal func > (lhs: (), rhs: ()) -> Bool { + return false +} + +@usableFromInline +@_disfavoredOverload +internal func >=(lhs: (), rhs: ()) -> Bool { + return true +} + +@usableFromInline +@_disfavoredOverload +internal func == (lhs: (A,B), rhs: (A,B)) -> Bool { + lhs == rhs +} + +@usableFromInline +@_disfavoredOverload +internal func != (lhs: (A,B), rhs: (A,B)) -> Bool { + lhs != rhs +} + +@usableFromInline +@_disfavoredOverload +internal func < (lhs: (A,B), rhs: (A,B)) -> Bool { + lhs < rhs +} + +@usableFromInline +@_disfavoredOverload +internal func <= (lhs: (A,B), rhs: (A,B)) -> Bool { + lhs <= rhs +} + +@usableFromInline +@_disfavoredOverload +internal func > (lhs: (A,B), rhs: (A,B)) -> Bool { + lhs > rhs +} + +@usableFromInline +@_disfavoredOverload +internal func >= (lhs: (A,B), rhs: (A,B)) -> Bool { + lhs >= rhs +} + +@usableFromInline +@_disfavoredOverload +internal func == (lhs: (A,B,C), rhs: (A,B,C)) -> Bool { + lhs == rhs +} + +@usableFromInline +@_disfavoredOverload +internal func != (lhs: (A,B,C), rhs: (A,B,C)) -> Bool { + lhs != rhs +} + +@usableFromInline +@_disfavoredOverload +internal func < (lhs: (A,B,C), rhs: (A,B,C)) -> Bool { + lhs < rhs +} + +@usableFromInline +@_disfavoredOverload +internal func <= (lhs: (A,B,C), rhs: (A,B,C)) -> Bool { + lhs <= rhs +} + +@usableFromInline +@_disfavoredOverload +internal func > (lhs: (A,B,C), rhs: (A,B,C)) -> Bool { + lhs > rhs +} + +@usableFromInline +@_disfavoredOverload +internal func >= (lhs: (A,B,C), rhs: (A,B,C)) -> Bool { + lhs >= rhs +} + +@usableFromInline +@_disfavoredOverload +internal func == (lhs: (A,B,C,D), rhs: (A,B,C,D)) -> Bool { + lhs == rhs +} + +@usableFromInline +@_disfavoredOverload +internal func != (lhs: (A,B,C,D), rhs: (A,B,C,D)) -> Bool { + lhs != rhs +} + +@usableFromInline +@_disfavoredOverload +internal func < (lhs: (A,B,C,D), rhs: (A,B,C,D)) -> Bool { + lhs < rhs +} + +@usableFromInline +@_disfavoredOverload +internal func <= (lhs: (A,B,C,D), rhs: (A,B,C,D)) -> Bool { + lhs <= rhs +} + +@usableFromInline +@_disfavoredOverload +internal func > (lhs: (A,B,C,D), rhs: (A,B,C,D)) -> Bool { + lhs > rhs +} + +@usableFromInline +@_disfavoredOverload +internal func >= (lhs: (A,B,C,D), rhs: (A,B,C,D)) -> Bool { + lhs >= rhs +} + +@usableFromInline +@_disfavoredOverload +internal func == (lhs: (A,B,C,D,E), rhs: (A,B,C,D,E)) -> Bool { + lhs == rhs +} + +@usableFromInline +@_disfavoredOverload +internal func != (lhs: (A,B,C,D,E), rhs: (A,B,C,D,E)) -> Bool { + lhs != rhs +} + +@usableFromInline +@_disfavoredOverload +internal func < (lhs: (A,B,C,D,E), rhs: (A,B,C,D,E)) -> Bool { + lhs < rhs +} + +@usableFromInline +@_disfavoredOverload +internal func <= (lhs: (A,B,C,D,E), rhs: (A,B,C,D,E)) -> Bool { + lhs <= rhs +} + +@usableFromInline +@_disfavoredOverload +internal func > (lhs: (A,B,C,D,E), rhs: (A,B,C,D,E)) -> Bool { + lhs > rhs +} + +@usableFromInline +@_disfavoredOverload +internal func >= (lhs: (A,B,C,D,E), rhs: (A,B,C,D,E)) -> Bool { + lhs >= rhs +} + +@usableFromInline +@_disfavoredOverload +internal func == (lhs: (A,B,C,D,E,F), rhs: (A,B,C,D,E,F)) -> Bool { + lhs == rhs +} + +@usableFromInline +@_disfavoredOverload +internal func != (lhs: (A,B,C,D,E,F), rhs: (A,B,C,D,E,F)) -> Bool { + lhs != rhs +} + +@usableFromInline +@_disfavoredOverload +internal func < (lhs: (A,B,C,D,E,F), rhs: (A,B,C,D,E,F)) -> Bool { + lhs < rhs +} + +@usableFromInline +@_disfavoredOverload +internal func <= (lhs: (A,B,C,D,E,F), rhs: (A,B,C,D,E,F)) -> Bool { + lhs <= rhs +} + +@usableFromInline +@_disfavoredOverload +internal func > (lhs: (A,B,C,D,E,F), rhs: (A,B,C,D,E,F)) -> Bool { + lhs > rhs +} + +@usableFromInline +@_disfavoredOverload +internal func >= (lhs: (A,B,C,D,E,F), rhs: (A,B,C,D,E,F)) -> Bool { + lhs >= rhs +} diff --git a/stdlib/public/core/Tuple.swift.gyb b/stdlib/public/core/Tuple.swift.gyb deleted file mode 100644 index 63d7ee25f0c96..0000000000000 --- a/stdlib/public/core/Tuple.swift.gyb +++ /dev/null @@ -1,201 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2017 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 -// -//===----------------------------------------------------------------------===// - -// Generate comparison functions for tuples up to some reasonable arity. - -%{ - -comparableOperators = [ - ('<', 'before'), - ('<=', 'before or the same as'), - ('>', 'after'), - ('>=', 'after or the same as') -] - -}% - -/// Returns a Boolean value indicating whether the corresponding components of -/// two tuples are equal. -/// -/// All arity zero tuples are equal. -/// -/// - Parameters: -/// - lhs: An empty tuple. -/// - rhs: An empty tuple. -@inlinable // trivial-implementation -public func ==(lhs: (), rhs: ()) -> Bool { - return true -} - -/// Returns a Boolean value indicating whether any corresponding components of -/// the two tuples are not equal. -/// -/// All arity zero tuples are equal. -/// -/// - Parameters: -/// - lhs: An empty tuple. -/// - rhs: An empty tuple. -@inlinable // trivial-implementation -public func !=(lhs: (), rhs: ()) -> Bool { - return false -} - -/// Returns a Boolean value indicating whether the first tuple is ordered -/// before the second in a lexicographical ordering. -/// -/// An arity zero tuple is never strictly before another arity zero tuple in a -/// lexicographical ordering. -/// -/// - Parameters: -/// - lhs: An empty tuple. -/// - rhs: An empty tuple. -@inlinable // trivial-implementation -public func <(lhs: (), rhs: ()) -> Bool { - return false -} - -/// Returns a Boolean value indicating whether the first tuple is ordered -/// before or the same as the second in a lexicographical ordering. -/// -/// An arity zero tuple is always before or the same as another arity zero tuple -/// in a lexicographical ordering. -/// -/// - Parameters: -/// - lhs: An empty tuple. -/// - rhs: An empty tuple. -@inlinable // trivial-implementation -public func <=(lhs: (), rhs: ()) -> Bool { - return true -} - -/// Returns a Boolean value indicating whether the first tuple is ordered -/// after the second in a lexicographical ordering. -/// -/// An arity zero tuple is never strictly after another arity zero tuple in a -/// lexicographical ordering. -/// -/// - Parameters: -/// - lhs: An empty tuple. -/// - rhs: An empty tuple. -@inlinable // trivial-implementation -public func >(lhs: (), rhs: ()) -> Bool { - return false -} - -/// Returns a Boolean value indicating whether the first tuple is ordered -/// after or the same as the second in a lexicographical ordering. -/// -/// An arity zero tuple is always after or the same as another arity zero tuple -/// in a lexicographical ordering. -/// -/// - Parameters: -/// - lhs: An empty tuple. -/// - rhs: An empty tuple. -@inlinable // trivial-implementation -public func >=(lhs: (), rhs: ()) -> Bool { - return true -} - -% for arity in range(2,7): -% typeParams = [chr(ord("A") + i) for i in range(arity)] -% tupleT = "({})".format(",".join(typeParams)) -% equatableTypeParams = ", ".join(["{}: Equatable".format(c) for c in typeParams]) - -% originalTuple = "(\"a\", {})".format(", ".join(map(str, range(1, arity)))) -% greaterTuple = "(\"a\", {})".format(", ".join(map(str, list(range(1, arity - 1)) + [arity]))) - -/// Returns a Boolean value indicating whether the corresponding components of -/// two tuples are equal. -/// -/// For two tuples to compare as equal, each corresponding pair of components -/// must be equal. The following example compares tuples made up of ${arity} -/// components: -/// -/// let a = ${originalTuple} -/// let b = ${originalTuple} -/// print(a == b) -/// // Prints "true" -/// -/// let c = ${greaterTuple} -/// print(a == c) -/// // Prints "false" -/// -/// - Parameters: -/// - lhs: A tuple of `Equatable` elements. -/// - rhs: Another tuple of elements of the same type as `lhs`. -@inlinable // trivial-implementation -public func == <${equatableTypeParams}>(lhs: ${tupleT}, rhs: ${tupleT}) -> Bool { - guard lhs.0 == rhs.0 else { return false } - /*tail*/ return ( - ${", ".join("lhs.{}".format(i) for i in range(1, arity))} - ) == ( - ${", ".join("rhs.{}".format(i) for i in range(1, arity))} - ) -} - -/// Returns a Boolean value indicating whether any corresponding components of -/// the two tuples are not equal. -/// -/// For two tuples to compare as equal, each corresponding pair of components -/// must be equal. The following example compares tuples made up of ${arity} -/// components: -/// -/// let a = ${originalTuple} -/// let b = ${originalTuple} -/// print(a != b) -/// // Prints "false" -/// -/// let c = ${greaterTuple} -/// print(a != c) -/// // Prints "true" -/// -/// - Parameters: -/// - lhs: A tuple of `Equatable` elements. -/// - rhs: Another tuple of elements of the same type as `lhs`. -@inlinable // trivial-implementation -public func != <${equatableTypeParams}>(lhs: ${tupleT}, rhs: ${tupleT}) -> Bool { - guard lhs.0 == rhs.0 else { return true } - /*tail*/ return ( - ${", ".join("lhs.{}".format(i) for i in range(1, arity))} - ) != ( - ${", ".join("rhs.{}".format(i) for i in range(1, arity))} - ) -} - -% comparableTypeParams = ", ".join(["{}: Comparable".format(c) for c in typeParams]) -% for op, phrase in comparableOperators: -/// Returns a Boolean value indicating whether the first tuple is ordered -/// ${phrase} the second in a lexicographical ordering. -/// -/// Given two tuples `(a1, a2, ..., aN)` and `(b1, b2, ..., bN)`, the first -/// tuple is ${phrase} the second tuple if and only if -/// `a1 ${op.replace('=', '')} b1` or (`a1 == b1` and -/// `(a2, ..., aN) ${op} (b2, ..., bN)`). -/// -/// - Parameters: -/// - lhs: A tuple of `Comparable` elements. -/// - rhs: Another tuple of elements of the same type as `lhs`. -@inlinable // trivial-implementation -public func ${op} <${comparableTypeParams}>(lhs: ${tupleT}, rhs: ${tupleT}) -> Bool { - if lhs.0 != rhs.0 { return lhs.0 ${op} rhs.0 } - /*tail*/ return ( - ${", ".join("lhs.{}".format(i) for i in range(1, arity))} - ) ${op} ( - ${", ".join("rhs.{}".format(i) for i in range(1, arity))} - ) -} -% end -% end - -// ${'Local Variables'}: -// eval: (read-only-mode 1) -// End: