package TestCase::UnaryMinus {

  sub unary_minus_byte : int () {
    my $value = -(byte)INT8_MAX();
    
    unless ($value isa int) {
      return 0;
    }
    
    unless ($value == -INT8_MAX()) {
      return 0;
    }
    
    return 1;
  }

  sub unary_minus_short : int () {
    my $value = -(short)INT16_MAX();
    
    unless ($value isa int) {
      return 0;
    }
    
    unless ($value == -INT16_MAX()) {
      return 0;
    }
    
    return 1;
  }
  
  sub unary_minus_int : int () {
    my $value = -INT32_MAX();
    
    unless ($value isa int) {
      return 0;
    }
    
    unless ($value == -INT32_MAX()) {
      return 0;
    }
    
    return 1;
  }

  sub unary_minus_long : int () {
    my $value = -INT64_MAX();
    
    unless ($value isa long) {
      return 0;
    }
    
    unless ($value == -INT64_MAX()) {
      return 0;
    }
    
    return 1;
  }

  sub unary_minus_float : int () {
    my $value = -FLT_MAX();
    
    unless ($value isa float) {
      return 0;
    }
    
    unless ($value == -FLT_MAX()) {
      return 0;
    }
    
    return 1;
  }
  sub unary_minus_double : int () {
    my $value = -DBL_MAX();
    
    unless ($value isa double) {
      return 0;
    }
    
    unless ($value == -DBL_MAX()) {
      return 0;
    }
    
    return 1;
  }

  #
  # Integral type overflow is not defined in C99
  #
  sub unary_minus_int_overflow : int () {
    my $value = -INT32_MIN();
    
    unless ($value isa int) {
      return 0;
    }
    
    unless ($value == INT32_MIN()) {
      return 0;
    }
    
    return 1;
  }
  sub unary_minus_long_overflow : int () {
    my $value = -INT64_MIN();
    
    unless ($value isa long) {
      return 0;
    }
    
    unless ($value == INT64_MIN()) {
      return 0;
    }
    
    return 1;
  }

  #
  # Nan, Inf, sign operation is not defined in C99
  #
  sub unary_minus_float_inf : int () {
    {
      my $value = -INFINITYF();
      
      unless ($value isa float) {
        return 0;
      }
      
      unless ($value == -INFINITYF()) {
        return 0;
      }

      unless (-$value == INFINITYF()) {
        return 0;
      }
    }
    return 1;
  }

  sub unary_minus_float_zero : int () {
    my $zero_plus = 0.0f;

    if (signbitf($zero_plus)) {
      return 0;
    }
    
    my $zero_minus = -$zero_plus;
    
    unless ($zero_minus isa float) {
      return 0;
    }
    
    
    unless ($zero_minus == 0.0f) {
      return 0;
    }

    unless ($zero_minus == -0.0f) {
      return 0;
    }
    
    unless(signbitf($zero_minus)) {
      return 0;
    }
    
    return 1;
  }

  sub unary_minus_float_nan : int () {
    my $value = -NANF();
     
    unless ($value isa float) {
      return 0;
    }
    
    unless (isnanf($value)) {
      return 0;
    }
    
    return 1;
  }

  sub unary_minus_double_inf : int () {
    my $value = -INFINITY();
    
    unless ($value isa double) {
      return 0;
    }
    
    unless ($value == -INFINITY()) {
      return 0;
    }
    
    unless (-$value == INFINITY()) {
      return 0;
    }
    
    return 1;
  }

  sub unary_minus_double_zero : int () {
    my $zero_plus = 0.0;

    if (signbit($zero_plus)) {
      return 0;
    }
    
    my $zero_minus = -$zero_plus;
    
    unless ($zero_minus isa double) {
      return 0;
    }
    
    unless ($zero_minus == 0.0) {
      return 0;
    }

    unless ($zero_minus == -0.0) {
      return 0;
    }
    
    unless(signbit($zero_minus)) {
      return 0;
    }
    
    return 1;
  }

  sub unary_minus_double_nan : int () {
    my $value = -NAN();
     
    unless ($value isa double) {
      return 0;
    }
    
    unless (isnan($value)) {
      return 0;
    }
    
    return 1;
  }
}
