// Exponentiation operator.
 
import Foundation
 
precedencegroup ExponentiationPrecedence {
    associativity: right
    higherThan: MultiplicationPrecedence
}
 
infix operator ** : ExponentiationPrecedence
 
func ** <T: BinaryFloatingPoint>(_ x: T, _ y: T) -> Double {
    return pow(Double
(x
), Double
(y
)) }
 
func ** <T: BinaryInteger>(_ x: T, _ y: T) -> Int {
    return Int
(pow(Double
(x
), Double
(y
))) }
 
// Test.
 
func check<T: Equatable>(_ f: () -> Any, _ expect: T) {
    let result = f()
    print(result, terminator: "\t")
    if let x = result as? T {
        if x == expect {
            print("Pass.")
        } else {
            print("Fail:", expect)
        }
    } else {
        let u = type(of: result)
        print("Fail:", u, "not", T.self)
    }
}
 
check({2 ** 0},          1)
check({2 ** Int8(1)},    2)
check({2.0 ** 2},        4.0)
check({2.0 ** Float(3)}, 8.0)
check({2 ** 4.0},        16.0)
check({2.0 ** 5.0},      32.0)
check({2 * 2 ** 4 * 2},  64)
				Ly8gRXhwb25lbnRpYXRpb24gb3BlcmF0b3IuCgppbXBvcnQgRm91bmRhdGlvbgoKcHJlY2VkZW5jZWdyb3VwIEV4cG9uZW50aWF0aW9uUHJlY2VkZW5jZSB7CiAgICBhc3NvY2lhdGl2aXR5OiByaWdodAogICAgaGlnaGVyVGhhbjogTXVsdGlwbGljYXRpb25QcmVjZWRlbmNlCn0KCmluZml4IG9wZXJhdG9yICoqIDogRXhwb25lbnRpYXRpb25QcmVjZWRlbmNlCgpmdW5jICoqIDxUOiBCaW5hcnlGbG9hdGluZ1BvaW50PihfIHg6IFQsIF8geTogVCkgLT4gRG91YmxlIHsKICAgIHJldHVybiBwb3coRG91YmxlKHgpLCBEb3VibGUoeSkpCn0KCmZ1bmMgKiogPFQ6IEJpbmFyeUludGVnZXI+KF8geDogVCwgXyB5OiBUKSAtPiBJbnQgewogICAgcmV0dXJuIEludChwb3coRG91YmxlKHgpLCBEb3VibGUoeSkpKQp9CgovLyBUZXN0LgoKZnVuYyBjaGVjazxUOiBFcXVhdGFibGU+KF8gZjogKCkgLT4gQW55LCBfIGV4cGVjdDogVCkgewogICAgbGV0IHJlc3VsdCA9IGYoKQogICAgcHJpbnQocmVzdWx0LCB0ZXJtaW5hdG9yOiAiXHQiKQogICAgaWYgbGV0IHggPSByZXN1bHQgYXM/IFQgewogICAgICAgIGlmIHggPT0gZXhwZWN0IHsKICAgICAgICAgICAgcHJpbnQoIlBhc3MuIikKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwcmludCgiRmFpbDoiLCBleHBlY3QpCiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBsZXQgdSA9IHR5cGUob2Y6IHJlc3VsdCkKICAgICAgICBwcmludCgiRmFpbDoiLCB1LCAibm90IiwgVC5zZWxmKQogICAgfQp9CgpjaGVjayh7MiAqKiAwfSwgICAgICAgICAgMSkKY2hlY2soezIgKiogSW50OCgxKX0sICAgIDIpCmNoZWNrKHsyLjAgKiogMn0sICAgICAgICA0LjApCmNoZWNrKHsyLjAgKiogRmxvYXQoMyl9LCA4LjApCmNoZWNrKHsyICoqIDQuMH0sICAgICAgICAxNi4wKQpjaGVjayh7Mi4wICoqIDUuMH0sICAgICAgMzIuMCkKY2hlY2soezIgKiAyICoqIDQgKiAyfSwgIDY0KQ==