// RUN: %empty-directory(%t)
// RUN: %gyb %s -o %t/FloatingPointConversion.swift
// RUN: %line-directive %t/FloatingPointConversion.swift -- %target-build-swift %t/FloatingPointConversion.swift -Xfrontend -disable-access-control -o %t/a.out_Debug -Onone
// RUN: %line-directive %t/FloatingPointConversion.swift -- %target-build-swift %t/FloatingPointConversion.swift -Xfrontend -disable-access-control -o %t/a.out_Release -O
//
// RUN: %line-directive %t/FloatingPointConversion.swift -- %target-run %t/a.out_Debug
// RUN: %line-directive %t/FloatingPointConversion.swift -- %target-run %t/a.out_Release
// REQUIRES: executable_test

import StdlibUnittest

%{
import gyb
from SwiftFloatingPointTypes import all_floating_point_types, getFtoIBounds
from SwiftIntTypes import all_integer_types
}%

var FixedPointConversionTruncations = TestSuite("FixedPointToFloatingPointConversionTruncations")
var FixedPointConversionFailures = TestSuite("FixedPointToFloatingPointConversionFailures")

var FloatingPointConversionTruncations = TestSuite("FloatingPointToFloatingPointConversionTruncations")
var FloatingPointConversionFailures = TestSuite("FloatingPointToFloatingPointConversionFailures")

%  for self_type in all_floating_point_types():
%   SelfSignificandBits = self_type.bits
%   Self = self_type.stdlib_name

%  if Self == 'Float80':
#if !os(Windows) && (arch(i386) || arch(x86_64))
%  end

%  for other_type in all_floating_point_types():
%   OtherSignificandBits = other_type.bits
%   OtherFloat = other_type.stdlib_name

%   if OtherFloat == 'Float80':
#if !os(Windows) && (arch(i386) || arch(x86_64))
%   end

%   if OtherSignificandBits <= SelfSignificandBits:

FloatingPointConversionTruncations.test("${OtherFloat}To${Self}Conversion")
  .forEach(in: [
     ${OtherFloat}.greatestFiniteMagnitude,
    -${OtherFloat}.greatestFiniteMagnitude,
     (1.0 as ${OtherFloat}).nextUp,
     (1.0 as ${OtherFloat}).nextDown,
    (-1.0 as ${OtherFloat}).nextUp,
    (-1.0 as ${OtherFloat}).nextDown,
  ]) {
  input in
  // FIXME: we should have a stronger postcondition here.
  let result = ${Self}(input)
  let resultConvertedBack = ${OtherFloat}(result)
  expectEqual(input, resultConvertedBack)
}

%   else:

FloatingPointConversionTruncations.test("${OtherFloat}To${Self}Conversion")
  .forEach(in: [
    ( ${OtherFloat}.greatestFiniteMagnitude,  ${Self}.infinity),
    (-${OtherFloat}.greatestFiniteMagnitude, -${Self}.infinity),
    ( (1.0 as ${OtherFloat}).nextUp,    1.0 as ${Self}),
    ( (1.0 as ${OtherFloat}).nextDown,  1.0 as ${Self}),
    ((-1.0 as ${OtherFloat}).nextUp,   -1.0 as ${Self}),
    ((-1.0 as ${OtherFloat}).nextDown, -1.0 as ${Self}),
  ]) {
  (input, expectedResult) in
  expectEqual(expectedResult, ${Self}(input))
}

%   end

FloatingPointConversionTruncations.test("${OtherFloat}To${Self}Conversion/special") {
  expectEqual( 1.0 as ${Self},   ${Self}(exactly:  1.0 as ${OtherFloat}))
  expectEqual(-1.0 as ${Self},   ${Self}(exactly: -1.0 as ${OtherFloat}))
  expectEqual( ${Self}.infinity, ${Self}( ${OtherFloat}.infinity))
  expectEqual(-${Self}.infinity, ${Self}(-${OtherFloat}.infinity))
  expectTrue(${Self}(${OtherFloat}.nan).isNaN)
}

FloatingPointConversionFailures.test("${OtherFloat}To${Self}FailableConversion")
  .forEach(in: [
    ${OtherFloat}.greatestFiniteMagnitude,
    -${OtherFloat}.greatestFiniteMagnitude,
    (1.0 as ${OtherFloat}).nextUp,
    (1.0 as ${OtherFloat}).nextDown,
    (-1.0 as ${OtherFloat}).nextUp,
    (-1.0 as ${OtherFloat}).nextDown,
  ]) {
  input in
  let result = ${Self}(exactly: input)
%   if OtherSignificandBits <= SelfSignificandBits:
  if let result = expectNotNil(result) {
    // FIXME: we should have a stronger postcondition here.
    expectEqual(input, ${OtherFloat}(result))
  }
%   else:
  expectNil(result)
%   end
}

FloatingPointConversionFailures.test("${OtherFloat}To${Self}Conversion/AlwaysSuccess") {
  expectEqual( 1.0 as ${Self},   ${Self}(exactly:  1.0 as ${OtherFloat}))
  expectEqual(-1.0 as ${Self},   ${Self}(exactly: -1.0 as ${OtherFloat}))
  expectEqual( ${Self}.infinity, ${Self}(exactly:  ${OtherFloat}.infinity))
  expectEqual(-${Self}.infinity, ${Self}(exactly: -${OtherFloat}.infinity))
  expectNil(${Self}(exactly: ${OtherFloat}.nan))
}

%   if OtherFloat == 'Float80':
#endif
%   end

%  end # for in all_floating_point_types (Other)

%{

float_to_int_conversion_template = gyb.parse_template("float_to_int_conversion",
"""
% for int_ty in all_integer_types(word_bits):
%  OtherInt = int_ty.stdlib_name
%  OtherMin = int_ty.min
%  OtherMax = int_ty.max
%  (FloatMin, FloatMax) = getFtoIBounds(self_type.bits, int_ty.bits, int_ty.is_signed)

%  for testValue in [0, FloatMin, FloatMax, FloatMin - 1, FloatMax + 1, OtherMin, OtherMax]:

%    if testValue < OtherMin or testValue > OtherMax: 
%          # Can't construct `other` value, do nothing and continue.

%    elif testValue >= FloatMin and testValue <= FloatMax:

FixedPointConversionTruncations.test("${OtherInt}to${Self}Conversion/${testValue}") {
  expectEqual(${Self}(${testValue} as ${OtherInt}), ${testValue})
}

FixedPointConversionFailures.test("${OtherInt}to${Self}FailableConversion/${testValue}") {
  expectEqual(${Self}(exactly: ${testValue} as ${OtherInt}), ${testValue})
}

%    else:

FixedPointConversionTruncations.test("${OtherInt}to${Self}Truncation/${testValue}") {
  let value: ${OtherInt} = ${testValue}
  let result = ${Self}(value)
  expectNotEqual(${OtherInt}(result), value)
}

FixedPointConversionFailures.test("${OtherInt}to${Self}Failure/${testValue}") {
  let value: ${OtherInt} = ${testValue}
  let result = ${Self}(exactly: value)
  expectEqual(result, ${OtherMin} as ${Self})
  expectEqual(${OtherInt}(result!), value)
}

%    end

%  end # testValue in testValues
%  end # for in all_integer_types (Other)
""")
}%

#if arch(i386) || arch(arm)

  ${gyb.execute_template(
      float_to_int_conversion_template,
      word_bits=32,
      **locals()
      )}

#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)

  ${gyb.execute_template(
      float_to_int_conversion_template,
      word_bits=64,
      **locals()
      )}

#else

_UnimplementedError()

#endif

%  if Self == 'Float80':
#endif
%  end

% end # for in all_floating_point_types (Self)

runAllTests()
