mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
154 lines
4.5 KiB
Swift
154 lines
4.5 KiB
Swift
// RUN: %empty-directory(%t)
|
|
// RUN: echo 'main()' >%t/main.swift
|
|
// RUN: %target-swiftc_driver -o %t/a.out %s %t/main.swift -Xfrontend -enable-operator-designated-types -Xfrontend -solver-enable-operator-designated-types
|
|
// RUN: %target-codesign %t/a.out
|
|
// RUN: %target-run %t/a.out | %FileCheck %s
|
|
// REQUIRES: executable_test
|
|
|
|
// This is a more-thorough and explicit test for rdar://43804798 that uses @_implements to
|
|
// achieve "Comparable Floating Point values are FP-like when known to be FP, Comparable-like
|
|
// when only known to be comparable".
|
|
|
|
// Could calls to the different comparison operators.
|
|
public var comparedAsCauxmparablesCount : Int = 0
|
|
public var comparedAsFauxtsCount : Int = 0
|
|
|
|
infix operator .< : ComparisonPrecedence, BinaryFauxtingPoint, Cauxmparable
|
|
|
|
public protocol Cauxmparable {
|
|
static func .< (lhs: Self, rhs: Self) -> Bool
|
|
}
|
|
|
|
public protocol FauxtingPoint : Cauxmparable {
|
|
static var nan: Self { get }
|
|
static var one: Self { get }
|
|
static var two: Self { get }
|
|
}
|
|
|
|
public protocol BinaryFauxtingPoint: FauxtingPoint {
|
|
@_nonoverride static func .< (lhs: Self, rhs: Self) -> Bool
|
|
|
|
var bitPattern: UInt8 { get }
|
|
}
|
|
|
|
public extension BinaryFauxtingPoint {
|
|
// This version of .< will be called in a context that only knows it has a Cauxmparable.
|
|
@_implements(Cauxmparable, .<(_:_:))
|
|
static func _CauxmparableLessThan(_ lhs: Fauxt, _ rhs: Fauxt) -> Bool {
|
|
print("compared as Cauxmparables")
|
|
comparedAsCauxmparablesCount += 1
|
|
return lhs.bitPattern < rhs.bitPattern
|
|
}
|
|
}
|
|
|
|
public enum State {
|
|
case Nan
|
|
case One
|
|
case Two
|
|
}
|
|
|
|
public struct Fauxt {
|
|
let state: State
|
|
init(_ s: State) {
|
|
state = s
|
|
}
|
|
public static var nan: Fauxt {
|
|
return Fauxt(State.Nan)
|
|
}
|
|
public static var one: Fauxt {
|
|
return Fauxt(State.One)
|
|
}
|
|
public static var two: Fauxt {
|
|
return Fauxt(State.Two)
|
|
}
|
|
}
|
|
|
|
extension Fauxt: BinaryFauxtingPoint {
|
|
// Requirement from BinaryFauxtingPoint
|
|
public var bitPattern: UInt8 {
|
|
switch state {
|
|
case .One:
|
|
return 1
|
|
case .Two:
|
|
return 2
|
|
case .Nan:
|
|
return 0xff
|
|
}
|
|
}
|
|
}
|
|
|
|
public extension Fauxt {
|
|
// This version of .< will be called in a context that knows it has a Fauxt.
|
|
// It is inside an extension of Fauxt rather than the declaration of Fauxt
|
|
// itself in order to avoid a warning about near-matches with the defaulted
|
|
// requirement from Cauxmparable..< up above.
|
|
static func .<(_ lhs: Fauxt, _ rhs: Fauxt) -> Bool {
|
|
print("compared as Fauxts")
|
|
comparedAsFauxtsCount += 1
|
|
if lhs.state == .Nan || rhs.state == .Nan {
|
|
return false
|
|
} else {
|
|
return lhs.bitPattern < rhs.bitPattern
|
|
}
|
|
}
|
|
}
|
|
|
|
public func compare_Cauxmparables<T:Cauxmparable>(_ x: T, _ y: T) -> Bool {
|
|
return x .< y
|
|
}
|
|
|
|
public func compare_FauxtingPoint<T:FauxtingPoint>(_ x: T, _ y: T) -> Bool {
|
|
return x .< y
|
|
}
|
|
|
|
public func compare_BinaryFauxtingPoint<T:BinaryFauxtingPoint>(_ x: T, _ y: T) -> Bool {
|
|
return x .< y
|
|
}
|
|
|
|
public func compare_Fauxts(_ x: Fauxt, _ y: Fauxt) -> Bool {
|
|
return x .< y
|
|
}
|
|
|
|
public func main() {
|
|
assert(compare_Cauxmparables(Fauxt.one, Fauxt.two))
|
|
assert(comparedAsCauxmparablesCount == 1)
|
|
// CHECK: compared as Cauxmparables
|
|
assert(compare_Cauxmparables(Fauxt.one, Fauxt.nan))
|
|
assert(comparedAsCauxmparablesCount == 2)
|
|
// CHECK: compared as Cauxmparables
|
|
assert(!compare_Cauxmparables(Fauxt.nan, Fauxt.one))
|
|
assert(comparedAsCauxmparablesCount == 3)
|
|
// CHECK: compared as Cauxmparables
|
|
|
|
assert(compare_FauxtingPoint(Fauxt.one, Fauxt.two))
|
|
assert(comparedAsCauxmparablesCount == 4)
|
|
// CHECK: compared as Cauxmparables
|
|
assert(compare_FauxtingPoint(Fauxt.one, Fauxt.nan))
|
|
assert(comparedAsCauxmparablesCount == 5)
|
|
// CHECK: compared as Cauxmparables
|
|
assert(!compare_FauxtingPoint(Fauxt.nan, Fauxt.one))
|
|
assert(comparedAsCauxmparablesCount == 6)
|
|
// CHECK: compared as Cauxmparables
|
|
|
|
assert(compare_Fauxts(Fauxt.one, Fauxt.two))
|
|
assert(comparedAsFauxtsCount == 1)
|
|
// CHECK: compared as Fauxts
|
|
assert(!compare_Fauxts(Fauxt.one, Fauxt.nan))
|
|
assert(comparedAsFauxtsCount == 2)
|
|
// CHECK: compared as Fauxts
|
|
assert(!compare_Fauxts(Fauxt.nan, Fauxt.one))
|
|
assert(comparedAsFauxtsCount == 3)
|
|
// CHECK: compared as Fauxts
|
|
|
|
assert(compare_BinaryFauxtingPoint(Fauxt.one, Fauxt.two))
|
|
assert(comparedAsFauxtsCount == 4)
|
|
// CHECK: compared as Fauxts
|
|
assert(!compare_BinaryFauxtingPoint(Fauxt.one, Fauxt.nan))
|
|
assert(comparedAsFauxtsCount == 5)
|
|
// CHECK: compared as Fauxts
|
|
assert(!compare_BinaryFauxtingPoint(Fauxt.nan, Fauxt.one))
|
|
assert(comparedAsFauxtsCount == 6)
|
|
// CHECK: compared as Fauxts
|
|
|
|
}
|