| // RUN: rm -rf %t |
| // RUN: mkdir -p %t |
| // RUN: %S/../../utils/gyb %s -o %t/FixedPointConversion.swift |
| // RUN: %S/../../utils/line-directive %t/FixedPointConversion.swift -- %target-build-swift %t/FixedPointConversion.swift -o %t/a.out_Debug |
| // RUN: %S/../../utils/line-directive %t/FixedPointConversion.swift -- %target-build-swift %t/FixedPointConversion.swift -o %t/a.out_Release -O |
| // |
| // RUN: %S/../../utils/line-directive %t/FixedPointConversion.swift -- %target-run %t/a.out_Debug |
| // RUN: %S/../../utils/line-directive %t/FixedPointConversion.swift -- %target-run %t/a.out_Release |
| // REQUIRES: executable_test |
| |
| %{ |
| import gyb |
| }% |
| |
| import StdlibUnittest |
| |
| var FixedPointConversionTraps = TestSuite("FixedPointToFixedPointConversionTraps") |
| var FixedPointConversionFailure = TestSuite("FixedPointToFixedPointConversionFailures") |
| |
| %{ |
| |
| int_to_int_conversion_template = gyb.parse_template("int_to_int_conversion", |
| """ |
| %{ |
| from SwiftIntTypes import all_integer_types |
| |
| def intMax(bits, signed): |
| bits = bits - 1 if signed else bits |
| return (1 << bits) - 1 |
| |
| def intMin(bits, signed): |
| return -1 * intMax(bits, signed) - 1 if signed else 0 |
| |
| }% |
| |
| % for self_ty in all_integer_types(word_bits): |
| % selfBits = self_ty.bits |
| % selfSigned = self_ty.is_signed |
| % selfMin = intMin(selfBits, selfSigned) |
| % selfMax = intMax(selfBits, selfSigned) |
| % Self = self_ty.stdlib_name |
| |
| % for other_ty in all_integer_types(word_bits): |
| % otherBits = other_ty.bits |
| % otherSigned = other_ty.is_signed |
| % otherMin = intMin(otherBits, otherSigned) |
| % otherMax = intMax(otherBits, otherSigned) |
| % Other = other_ty.stdlib_name |
| |
| % for testValue in [selfMin, selfMax, selfMin - 1, selfMax + 1, otherMin, otherMax]: |
| |
| % if testValue < otherMin or testValue > otherMax: |
| % # Can't construct `other` value, do nothing and continue. |
| |
| % elif testValue >= selfMin and testValue <= selfMax: |
| |
| /// Always-safe conversion from ${Other}(${testValue}) to ${Self}. |
| FixedPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}") { |
| // Test that nothing interesting happens and we end up with the same result after converting. |
| let input = get${Other}(${testValue}) |
| let result = ${Self}(input) |
| expectEqual(${testValue}, result) |
| _blackHole(result) |
| } |
| |
| /// Never-nil failable conversion from ${Other}(${testValue}) to ${Self}. |
| FixedPointConversionFailure.test("${Other}To${Self}FailableConversion/dest=${testValue}") { |
| // Test that nothing interesting happens and we end up with a non-nil, identical result. |
| let input = get${Other}(${testValue}) |
| var result = ${Self}(exactly: input) |
| expectNotEqual(result, nil) |
| expectEqual(${testValue}, result) |
| _blackHole(result) |
| } |
| |
| % else: |
| |
| /// Always-failing conversion from ${Other}(${testValue}) to ${Self}. |
| FixedPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}") { |
| // Test that we check if we fail and crash when an integer would be truncated in conversion. |
| let input = get${Other}(${testValue}) |
| expectCrashLater() |
| var result = ${Self}(input) |
| _blackHole(result) |
| } |
| |
| /// Always-nil failable conversion from ${Other}(${testValue}) to ${Self}. |
| FixedPointConversionFailure.test("${Other}To${Self}Conversion/dest=${testValue}") { |
| // Test that we check if we return nil when an integer would be truncated in conversion. |
| let input = get${Other}(${testValue}) |
| var result = ${Self}(exactly: input) |
| expectEqual(nil, result) |
| _blackHole(result) |
| } |
| % end |
| |
| % end # for testValue in ... |
| % end # for in all_integer_types (Other) |
| % end # for in all_integer_types (Self) |
| """) |
| |
| }% |
| |
| #if arch(i386) || arch(arm) |
| |
| ${gyb.execute_template( |
| int_to_int_conversion_template, |
| word_bits=32)} |
| |
| #elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) |
| |
| ${gyb.execute_template( |
| int_to_int_conversion_template, |
| word_bits=64)} |
| |
| #else |
| |
| _UnimplementedError() |
| |
| #endif |
| |
| runAllTests() |