// RUN: %empty-directory(%t)
// RUN: echo 'main()' >%t/main.swift
// RUN: %target-swiftc_driver -o %t/a.out %s %t/main.swift
// 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 comparedAsComparablesCount : Int = 0
public var comparedAsFauxtsCount : Int = 0

public protocol FauxtingPoint : Comparable {
  static var nan: Self { get }
  static var one: Self { get }
  static var two: Self { get }
}

public protocol BinaryFauxtingPoint: FauxtingPoint {
  var bitPattern: UInt8 { get }
}

public extension BinaryFauxtingPoint {
  // This version of < will be called in a context that only knows it has a Comparable.
  @_implements(Comparable, <(_:_:))
  static func _ComparableLessThan(_ lhs: Fauxt, _ rhs: Fauxt) -> Bool {
    print("compared as Comparables")
    comparedAsComparablesCount += 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 Comparable.< 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_Comparables<T:Comparable>(_ 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_Comparables(Fauxt.one, Fauxt.two))
  assert(comparedAsComparablesCount == 1)
  // CHECK: compared as Comparables
  assert(compare_Comparables(Fauxt.one, Fauxt.nan))
  assert(comparedAsComparablesCount == 2)
  // CHECK: compared as Comparables
  assert(!compare_Comparables(Fauxt.nan, Fauxt.one))
  assert(comparedAsComparablesCount == 3)
  // CHECK: compared as Comparables

  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
}
