class TestCase::Operator::Modulo {
  use Fn;
  use Array;
  
  #
  # Spec tests
  #
  static method modulo_byte_byte : int () {
    my $mod = (byte)7 % (byte)3;
    
    unless ($mod == 1) {
      return 0;
    }
    
    unless ($mod isa int) {
      return 0;
    }
    
    return 1;
  }

  static method modulo_short_short : int () {
    my $mod = (short)10 % (short)2;
    
    unless ($mod == 0) {
      return 0;
    }
    
    unless ($mod isa int) {
      return 0;
    }
    
    return 1;
  }

  static method modulo_int_byte : int () {
    my $mod = 12 % (byte)5;
    
    unless ($mod == 2) {
      return 0;
    }
    
    unless ($mod isa int) {
      return 0;
    }
    
    return 1;
  }

  static method modulo_int_short : int () {
    my $mod = 7 % (short)3;
    
    unless ($mod == 1) {
      return 0;
    }
    
    unless ($mod isa int) {
      return 0;
    }
    
    return 1;
  }

  static method modulo_byte_int : int () {
    my $mod = (byte)-5 % 3;
    
    unless ($mod == 1) {
      return 0;
    }
    
    unless ($mod isa int) {
      return 0;
    }
    
    return 1;
  }

  static method modulo_short_int : int () {
    my $mod = (short)5 % -3;
    
    unless ($mod == -1) {
      return 0;
    }
    
    unless ($mod isa int) {
      return 0;
    }
    
    return 1;
  }

  static method modulo_int_int : int () {
    {
      my $mod1 = 1000000000 % 2;
      
      unless ($mod1 == 0) {
        return 0;
      }
      
      unless ($mod1 isa int) {
        return 0;
      }
    }
    
    {
      my $mod = 17 % 3;
      
      unless ($mod == 2) {
        return 0;
      }
    }
    
    {
      my $mod = 17 % -3;
      
      unless ($mod == -1) {
        return 0;
      }
    }
    
    {
      my $mod = -17 % 3;
      
      unless ($mod == 1) {
        return 0;
      }
    }
    
    {
      my $mod = -17 % -3;
      
      unless ($mod == -2) {
        return 0;
      }
    }
    
    {
      my $mod = 17 % 17;
      
      unless ($mod == 0) {
        return 0;
      }
    }
    
    {
      my $mod = 17 % -17;
      
      unless ($mod == 0) {
        return 0;
      }
    }
    
    {
      my $mod = -17 % 17;
      
      unless ($mod == 0) {
        return 0;
      }
    }
    
    {
      my $mod = -17 % -17;
      
      unless ($mod == 0) {
        return 0;
      }
    }
    
    return 1;
  }

  static method modulo_long_long : int () {
    my $mod1 = 100000000001L % 2L;
    
    unless ($mod1 == 1) {
      return 0;
    }
    
    unless ($mod1 isa long) {
      return 0;
    }
    
    {
      my $mod = 17L % 3L;
      
      unless ($mod == 2) {
        return 0;
      }
    }
    
    {
      my $mod = 17L % -3L;
      
      unless ($mod == -1) {
        return 0;
      }
    }
    
    {
      my $mod = -17L % 3L;
      
      unless ($mod == 1) {
        return 0;
      }
    }
    
    {
      my $mod = -17L % -3L;
      
      unless ($mod == -2) {
        return 0;
      }
    }
    
    {
      my $mod = 17L % 17L;
      
      unless ($mod == 0) {
        return 0;
      }
    }
    
    {
      my $mod = 17L % -17L;
      
      unless ($mod == 0) {
        return 0;
      }
    }
    
    {
      my $mod = -17L % 17L;
      
      unless ($mod == 0) {
        return 0;
      }
    }
    
    {
      my $mod = -17L % -17L;
      
      unless ($mod == 0) {
        return 0;
      }
    }
    
    return 1;
  }

  static method modulo_unsigned_int : int () {
    {
      my $x = Fn->UINT32_MAX;

      # 0 = -1 % 3
      my $ret_rem = $x % 3;
      
      # 1431655765 = 4,294,967,295 mod_uint 3
      my $ret_remui = $x mod_uint 3;
      
      unless ($ret_remui isa int) {
        return 0;
      }
      
      unless ($ret_rem == 2) {
        return 0;
      }
      
      unless ($ret_remui == 0) {
        return 0;
      }
    }
    
    return 1;
  }

  static method modulo_unsigned_long : int () {
    {
      my $x = Fn->UINT64_MAX;

      # 0 = -1 % 3
      my $ret_rem = $x % 3L;
      
      # 6,148,914,691,236,517,205 = 18,446,744,073,709,551,615 mod_ulong 3
      my $ret_remul = $x mod_ulong 3L;

      unless ($ret_remul isa long) {
        return 0;
      }
      
      unless ($ret_rem == 2) {
        return 0;
      }
      
      unless ($ret_remul == 0) {
        return 0;
      }
    }
    
    return 1;
  }

  #
  # Optional tests
  #
  static method modulo : int () {
    my $num1 = (byte)((byte)5 % (byte)3);
    my $num2 = (byte)((byte)-3 % (byte)5);
    my $num3 = (short)((int)(short)5 % (int)(short)3);
    my $num4 = (short)((int)(short)-3 % (int)(short)5);
    my $num5 = 5 % 3;
    my $num6 = -3 % 5;
    my $num7 = 5L % 3L;
    my $num8 = -3L % 5L;
    
    unless ($num1 == 2) {
      return 0;
    }
    
    unless ($num2 == 2) {
      return 0;
    }
    
    unless ($num3 == 2) {
      return 0;
    }
    
    unless ($num4 == 2) {
      return 0;
    }
    
    unless ($num5 == 2) {
      return 0;
    }
    
    unless ($num6 == 2) {
      return 0;
    }
    
    unless ($num7 == 2L) {
      return 0;
    }
    
    unless ($num8 == 2L) {
      return 0;
    }
    
    return 1;
  }
}
