class TestCase::Operator::ComparisonOperator {
  use TestCase::Minimal;
  use Point;
  
  static method numeric_eq  : int () {
    my $test_case : TestCase::Minimal = undef;
    
    # undef
    {
      unless (undef == undef) {
        return 0;
      }
      
      unless ($test_case == undef) {
        return 0;
      }
      
      unless (undef == $test_case) {
        return 0;
      }
    }
    
    # byte
    {
      unless ((byte)3 == (byte)3) {
        return 0;
      }
      
      if ((byte)3 == (byte)2) {
        return 0;
      }
    }
    
    # short
    {
      unless ((short)3 == (short)3) {
        return 0;
      }
      
      if ((short)3 == (short)2) {
        return 0;
      }
    }
    
    # int
    {
      unless (3 == 3) {
        return 0;
      }
      
      my $ret = 3 == 3;
      unless ($ret isa int && $ret == 1) {
        return 0;
      }
      
      if (3 == 2) {
        return 0;
      }
    }
    
    # long
    {
      unless ((long)3 == (long)3) {
        return 0;
      }
      
      if ((long)3 == (long)2) {
        return 0;
      }
    }
    
    # float
    {
      unless (0.5f == 0.5f) {
        return 0;
      }
      
      if (0.5f == 0.25f) {
        return 0;
      }
      
      my $nan = (float)0.0 / (float)0.0;
      if ($nan == $nan) {
        return 0;
      }
      
      if ($nan == (float)0.0) {
        return 0;
      }
      
      if ($nan == (float)1.0) {
        return 0;
      }
    }
    
    # double
    {
      unless (0.5 == 0.5) {
        return 0;
      }
      
      if (0.5 == 0.25) {
        return 0;
      }
      
      my $nan = (double)0.0 / (double)0.0;
      if ($nan == $nan) {
        return 0;
      }
      
      if ($nan == (double)0.0) {
        return 0;
      }
      
      if ($nan == (double)1.0) {
        return 0;
      }
    }
    
    # object
    {
      {
        my $object1 = TestCase::Minimal->new;
        
        unless ($object1 == $object1) {
          return 0;
        }
      }
      
      {
        my $object1 = TestCase::Minimal->new;
        my $object2 = TestCase::Minimal->new;
        
        if ($object1 == $object2) {
          return 0;
        }
      }
      
      {
        my $object1 = (TestCase::Minimal)undef;
        
        unless ($object1 == undef) {
          return 0;
        }
        
        unless (undef == $object1) {
          return 0;
        }
        
        if ($object1 != undef) {
          return 0;
        }
        
        if (undef != $object1) {
          return 0;
        }
        
      }
      
    }
    
    # reference
    {
      {
        my $ref1 = TestCase::Minimal->new;
        
        unless ($ref1 == $ref1) {
          return 0;
        }
      }
      
      {
        my $ref1 = TestCase::Minimal->new;
        my $ref2 = TestCase::Minimal->new;
        
        if ($ref1 == $ref2) {
          return 0;
        }
      }
      
      {
        my $ref1 = (int*)undef;
        
        unless ($ref1 == undef) {
          return 0;
        }
        
        unless (undef == $ref1) {
          return 0;
        }
        
        if ($ref1 != undef) {
          return 0;
        }
        
        if (undef != $ref1) {
          return 0;
        }
        
      }
      
    }
    
    return 1;
  }
  
  # If a != b
  static method numeric_ne  : int () {
    my $test_case : TestCase::Minimal = TestCase::Minimal->new;
    
    # undef
    {
      if (undef != undef) {
        return 0;
      }
      
      unless ($test_case != undef) {
        return 0;
      }
      
      unless (undef != $test_case) {
        return 0;
      }
    }
    
    # byte
    {
      if ((byte)3 != (byte)3) {
        return 0;
      }
      
      unless ((byte)3 != (byte)2) {
        return 0;
      }
    }
    
    # short
    {
      if ((int)(short)3 != (int)(short)3) {
        return 0;
      }
      
      unless ((int)(short)3 != (int)(short)2) {
        return 0;
      }
    }
    
    # int
    {
      if ((int)3 != (int)3) {
        return 0;
      }
      
      unless ((int)3 != (int)2) {
        return 0;
      }
    }
    
    # long
    {
      if ((long)3 != (long)3) {
        return 0;
      }
      
      unless ((long)3 != (long)2) {
        return 0;
      }
    }
    
    # float
    {
      if (0.5f != 0.5f) {
        return 0;
      }
      
      unless (0.5f != 0.25f) {
        return 0;
      }
      
      my $nan = (float)0.0 / (float)0.0;
      unless ($nan != $nan) {
        return 0;
      }
      
      unless ($nan != (float)0.0) {
        return 0;
      }
      
      unless ($nan != (float)1.0) {
        return 0;
      }
    }
    
    # double
    {
      if (0.5 != 0.5) {
        return 0;
      }
      
      unless (0.5 != 0.25) {
        return 0;
      }
      
      my $nan = (double)0.0 / (double)0.0;
      unless ($nan != $nan) {
        return 0;
      }
      
      unless ($nan != (double)0.0) {
        return 0;
      }
      
      unless ($nan != (double)1.0) {
        return 0;
      }
    }
    
    # object
    {
      {
        my $object1 = TestCase::Minimal->new;
        
        if ($object1 != $object1) {
          return 0;
        }
      }
      
      {
        my $object1 = TestCase::Minimal->new;
        my $object2 = TestCase::Minimal->new;
        
        unless ($object1 != $object2) {
          return 0;
        }
      }
    }
    
    # reference
    {
      {
        my $value = 1;
        my $ref1 : int* = \$value;
        
        if ($ref1 != $ref1) {
          return 0;
        }
      }
      
      {
        my $value1 = 1;
        my $ref1 = \$value1;
        my $value2 = 2;
        my $ref2 = \$value2;
        
        unless ($ref1 != $ref2) {
          return 0;
        }
      }
    }
    
    return 1;
  }
  
  # If a > b
  static method numeric_gt  : int () {
    
    # byte
    {
      unless ((byte)3 > (byte)1) {
        return 0;
      }
      
      if ((byte)3 > (byte)3) {
        return 0;
      }
      
      if ((byte)3 > (byte)4) {
        return 0;
      }
    }
    
    # short
    {
      unless ((int)(short)3 > (int)(short)1) {
        return 0;
      }
      
      if ((int)(short)3 > (int)(short)3) {
        return 0;
      }
      
      if ((int)(short)3 > (int)(short)4) {
        return 0;
      }
    }
    
    # int
    {
      unless (3 > 1) {
        return 0;
      }
      
      if (3 > 3) {
        return 0;
      }
      
      if (3 > 4) {
        return 0;
      }
    }
    
    # long
    {
      unless ((long)3 > (long)1) {
        return 0;
      }
      
      if ((long)3 > (long)3) {
        return 0;
      }
      
      if ((long)3 > (long)4) {
        return 0;
      }
    }
    
    # float
    {
      unless ((float)3 > (float)1) {
        return 0;
      }
      
      if ((float)3 > (float)3) {
        return 0;
      }
      
      if ((float)3 > (float)4) {
        return 0;
      }
      
      my $nan = (float)0.0 / (float)0.0;
      if ($nan > $nan) {
        return 0;
      }
      
      if ($nan > (float)0.0) {
        return 0;
      }
      
      if ($nan > (float)1.0) {
        return 0;
      }
    }
    
    # double
    {
      unless ((double)3 > (double)1) {
        return 0;
      }
      
      if ((double)3 > (double)3) {
        return 0;
      }
      
      if ((double)3 > (double)4) {
        return 0;
      }
      
      my $nan = (double)0.0 / (double)0.0;
      if ($nan > $nan) {
        return 0;
      }
      
      if ($nan > (double)0.0) {
        return 0;
      }
      
      if ($nan > (double)1.0) {
        return 0;
      }
    }
    
    return 1;
  }
  
  # If a >= b
  static method numeric_ge  : int () {
    
    # byte
    {
      unless ((byte)3 >= (byte)1) {
        return 0;
      }
      
      unless ((byte)3 >= (byte)3) {
        return 0;
      }
      
      if ((byte)3 >= (byte)4) {
        return 0;
      }
    }
    
    # short
    {
      unless ((int)(short)3 >= (int)(short)1) {
        return 0;
      }
      
      unless ((int)(short)3 >= (int)(short)3) {
        return 0;
      }
      
      if ((int)(short)3 >= (int)(short)4) {
        return 0;
      }
    }
    
    # int
    {
      unless (3 >= 1) {
        return 0;
      }
      
      unless (3 >= 3) {
        return 0;
      }
      
      if (3 >= 4) {
        return 0;
      }
    }
    
    # long
    {
      unless ((long)3 >= (long)1) {
        return 0;
      }
      
      unless ((long)3 >= (long)3) {
        return 0;
      }
      
      if ((long)3 >= (long)4) {
        return 0;
      }
    }
    
    # float
    {
      unless ((float)3 >= (float)1) {
        return 0;
      }
      
      unless ((float)3 >= (float)3) {
        return 0;
      }
      
      if ((float)3 >= (float)4) {
        return 0;
      }
      
      my $nan = (float)0.0 / (float)0.0;
      if ($nan >= $nan) {
        return 0;
      }
      
      if ($nan >= (float)0.0) {
        return 0;
      }
      
      if ($nan >= (float)1.0) {
        return 0;
      }
    }
    
    # double
    {
      unless ((double)3 >= (double)1) {
        return 0;
      }
      
      unless ((double)3 >= (double)3) {
        return 0;
      }
      
      if ((double)3 >= (double)4) {
        return 0;
      }
      
      my $nan = (double)0.0 / (double)0.0;
      if ($nan >= $nan) {
        return 0;
      }
      
      if ($nan >= (double)0.0) {
        return 0;
      }
      
      if ($nan >= (double)1.0) {
        return 0;
      }
    }
    
    return 1;
  }
  
  # If a < b
  static method numeric_lt  : int () {
    
    # byte
    {
      if ((byte)3 < (byte)1) {
        return 0;
      }
      
      if ((byte)3 < (byte)3) {
        return 0;
      }
      
      unless ((byte)3 < (byte)4) {
        return 0;
      }
    }
    
    # short
    {
      if ((int)(short)3 < (int)(short)1) {
        return 0;
      }
      
      if ((int)(short)3 < (int)(short)3) {
        return 0;
      }
      
      unless ((int)(short)3 < (int)(short)4) {
        return 0;
      }
    }
    
    # int
    {
      if (3 < 1) {
        return 0;
      }
      
      if (3 < 3) {
        return 0;
      }
      
      unless (3 < 4) {
        return 0;
      }
    }
    
    # long
    {
      if ((long)3 < (long)1) {
        return 0;
      }
      
      if ((long)3 < (long)3) {
        return 0;
      }
      
      unless ((long)3 < (long)4) {
        return 0;
      }
    }
    
    # float
    {
      if ((float)3 < (float)1) {
        return 0;
      }
      
      if ((float)3 < (float)3) {
        return 0;
      }
      
      unless ((float)3 < (float)4) {
        return 0;
      }
      
      my $nan = (float)0.0 / (float)0.0;
      if ($nan < $nan) {
        return 0;
      }
      
      if ($nan < (float)0.0) {
        return 0;
      }
      
      if ($nan < (float)1.0) {
        return 0;
      }
    }
    
    # double
    {
      if ((double)3 < (double)1) {
        return 0;
      }
      
      if ((double)3 < (double)3) {
        return 0;
      }
      
      unless ((double)3 < (double)4) {
        return 0;
      }
      
      my $nan = (double)0.0 / (double)0.0;
      if ($nan < $nan) {
        return 0;
      }
      
      if ($nan < (double)0.0) {
        return 0;
      }
      
      if ($nan < (double)1.0) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method numeric_le  : int () {
    
    # byte
    {
      if ((byte)3 <= (byte)1) {
        return 0;
      }
      
      unless ((byte)3 <= (byte)3) {
        return 0;
      }
      
      unless ((byte)3 <= (byte)4) {
        return 0;
      }
    }
    
    # short
    {
      if ((int)(short)3 <= (int)(short)1) {
        return 0;
      }
      
      unless ((int)(short)3 <= (int)(short)3) {
        return 0;
      }
      
      unless ((int)(short)3 <= (int)(short)4) {
        return 0;
      }
    }
    
    # int
    {
      if (3 <= 1) {
        return 0;
      }
      
      unless (3 <= 3) {
        return 0;
      }
      
      unless (3 <= 4) {
        return 0;
      }
    }
    
    # long
    {
      if ((long)3 <= (long)1) {
        return 0;
      }
      
      unless ((long)3 <= (long)3) {
        return 0;
      }
      
      unless ((long)3 <= (long)4) {
        return 0;
      }
    }
    
    # float
    {
      if ((float)3 <= (float)1) {
        return 0;
      }
      
      unless ((float)3 <= (float)3) {
        return 0;
      }
      
      unless ((float)3 <= (float)4) {
        return 0;
      }
      
      my $nan = (float)0.0 / (float)0.0;
      if ($nan <= $nan) {
        return 0;
      }
      
      if ($nan <= (float)0.0) {
        return 0;
      }
      
      if ($nan <= (float)1.0) {
        return 0;
      }
    }
    
    # double
    {
      if ((double)3 <= (double)1) {
        return 0;
      }
      
      unless ((double)3 <= (double)3) {
        return 0;
      }
      
      unless ((double)3 <= (double)4) {
        return 0;
      }
      
      my $nan = (double)0.0 / (double)0.0;
      if ($nan <= $nan) {
        return 0;
      }
      
      if ($nan <= (double)0.0) {
        return 0;
      }
      
      if ($nan <= (double)1.0) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method numeric_cmp  : int () {
    
    # byte
    {
      {
        my $ret = (byte)3 <=> (byte)1;
        unless ($ret == 1) {
          return 0;
        }
      }
      
      {
        my $ret = (byte)1 <=> (byte)3;
        unless ($ret == -1) {
          return 0;
        }
      }
      
      {
        my $ret = (byte)3 <=> (byte)3;
        unless ($ret == 0) {
          return 0;
        }
      }
    }
    
    # short
    {
      {
        my $ret = (short)3 <=> (short)1;
        unless ($ret == 1) {
          return 0;
        }
      }
      
      {
        my $ret = (short)1 <=> (short)3;
        unless ($ret == -1) {
          return 0;
        }
      }
      
      {
        my $ret = (short)3 <=> (short)3;
        unless ($ret == 0) {
          return 0;
        }
      }
    }
    
    # int
    {
      {
        my $ret = (int)3 <=> (int)1;
        unless ($ret == 1) {
          return 0;
        }
      }
      
      {
        my $ret = (int)1 <=> (int)3;
        unless ($ret == -1) {
          return 0;
        }
      }
      
      {
        my $ret = (int)3 <=> (int)3;
        unless ($ret == 0) {
          return 0;
        }
      }
    }
    
    # long
    {
      {
        my $ret = (long)3 <=> (long)1;
        unless ($ret == 1) {
          return 0;
        }
      }
      
      {
        my $ret = (long)1 <=> (long)3;
        unless ($ret == -1) {
          return 0;
        }
      }
      
      {
        my $ret = (long)3 <=> (long)3;
        unless ($ret == 0) {
          return 0;
        }
      }
    }
    
    # float
    {
      {
        my $ret = (float)3 <=> (float)1;
        unless ($ret == 1) {
          return 0;
        }
      }
      
      {
        my $ret = (float)1 <=> (float)3;
        unless ($ret == -1) {
          return 0;
        }
      }
      
      {
        my $ret = (float)3 <=> (float)3;
        unless ($ret == 0) {
          return 0;
        }
      }
      
      my $nan = (float)0.0 / (float)0.0;
      if ($nan <=> $nan) {
        return 0;
      }
      
      if ($nan <=> (float)0.0) {
        return 0;
      }
      
      if ($nan <=> (float)1.0) {
        return 0;
      }
    }
    
    # double
    {
      {
        my $ret = (double)3 <=> (double)1;
        unless ($ret == 1) {
          return 0;
        }
      }
      
      {
        my $ret = (double)1 <=> (double)3;
        unless ($ret == -1) {
          return 0;
        }
      }
      
      {
        my $ret = (double)3 <=> (double)3;
        unless ($ret == 0) {
          return 0;
        }
      }
      
      my $nan = (double)0.0 / (double)0.0;
      if ($nan <=> $nan) {
        return 0;
      }
      
      if ($nan <=> (double)0.0) {
        return 0;
      }
      
      if ($nan <=> (double)1.0) {
        return 0;
      }
    }
    
    return 1;
  }
  static method string_eq : int () {
    my $string = "abc";
    my $string_same = "abc";
    my $string_short = "ab";
    my $string_long = "abcd";
    my $string_different_short= "ad";
    my $string_different_long= "adcd";
    my $string_empty = "";
    my $string_undef : string;
    
    # eq
    my $ok = 0;
    unless ($string eq $string_same) {
      return 0;
    }
    unless ($string eq (byte[])$string_same) {
      return 0;
    }
    unless ((byte[])$string eq $string_same) {
      return 0;
    }
    unless (!($string eq $string_short)) {
      return 0;
    }
    unless (!($string eq $string_long)) {
      return 0;
    }
    unless (!($string eq $string_different_short)) {
      return 0;
    }
    unless (!($string eq $string_different_long)) {
      return 0;
    }
    unless (!($string eq $string_empty)) {
      return 0;
    }
    
    {
      my $ret = $string eq $string_same;
      unless ($ret == 1) {
        return 0;
      }
    }
    {
      my $ret = $string eq $string_short;
      unless ($ret == 0) {
        return 0;
      }
    }
    
    if ($string_undef eq $string_undef) {
      # OK
    } else {
      return 0;
    }

    if ($string_undef eq $string_empty) {
      return 0;
    }
    else {
      # OK
    }

    if ($string_empty eq $string_undef) {
      return 0;
    }
    else {
      # OK
    }

    
    return 1;
  }

  static method string_ne : int () {
    my $string = "abc";
    my $string_same = "abc";
    my $string_short = "ab";
    my $string_long = "abcd";
    my $string_different_short= "ad";
    my $string_different_long= "adcd";
    my $string_empty = "";
    my $string_undef : string;
    
    # ne
    unless (!($string ne $string_same)) {
      return 0;
    }
    unless (!($string ne (byte[])$string_same)) {
      return 0;
    }
    unless (!((byte[])$string ne $string_same)) {
      return 0;
    }
    unless (($string ne $string_short)) {
      return 0;
    }
    unless (($string ne $string_long)) {
      return 0;
    }
    unless (($string ne $string_different_short)) {
      return 0;
    }
    unless (($string ne $string_different_long)) {
      return 0;
    }
    unless (($string ne $string_empty)) {
      return 0;
    }
    
    if ($string_undef ne $string_undef) {
      return 0;
    } else {
      # OK
    }

    if ($string_undef ne $string_empty) {
      # OK
    }
    else {
      return 0;
    }

    if ($string_empty ne $string_undef) {
      # OK
    }
    else {
      return 0;
    }

    return 1;
  }

  static method string_gt : int () {
    my $string = "abc";
    my $string_same = "abc";
    my $string_short = "ab";
    my $string_long = "abcd";
    my $string_different_short= "ad";
    my $string_different_long= "adcd";
    my $string_empty = "";
    my $string_undef : string;
    
    # gt
    unless (!($string gt $string_same)) {
      return 0;
    }
    unless (!($string gt (byte[])$string_same)) {
      return 0;
    }
    unless (!((byte[])$string gt $string_same)) {
      return 0;
    }
    unless ($string gt $string_short) {
      return 0;
    }
    unless (!($string gt $string_long)) {
      return 0;
    }
    unless (!($string gt $string_different_short)) {
      return 0;
    }
    unless (!($string gt $string_different_long)) {
      return 0;
    }
    unless ($string gt $string_empty) {
      return 0;
    }
    
    if ($string_undef gt $string_undef) {
      return 0;
    } else {
      # OK
    }

    if ($string_undef gt $string_empty) {
      return 0;
    }
    else {
      # OK
    }

    if ($string_empty gt $string_undef) {
      # OK
    }
    else {
      return 0;
    }

    return 1;
  }

  static method string_ge : int () {
    my $string = "abc";
    my $string_same = "abc";
    my $string_short = "ab";
    my $string_long = "abcd";
    my $string_different_short= "ad";
    my $string_different_long= "adcd";
    my $string_empty = "";
    my $string_undef : string;
    
    # ge
    unless ($string ge $string_same) {
      return 0;
    }
    unless ($string ge (byte[])$string_same) {
      return 0;
    }
    unless ((byte[])$string ge $string_same) {
      return 0;
    }
    unless ($string ge $string_short) {
      return 0;
    }
    unless (!($string ge $string_long)) {
      return 0;
    }
    unless (!($string ge $string_different_short)) {
      return 0;
    }
    unless (!($string ge $string_different_long)) {
      return 0;
    }
    unless ($string ge $string_empty) {
      return 0;
    }
    
    if ($string_undef ge $string_undef) {
      # OK
    } else {
      return 0;
    }

    if ($string_undef ge $string_empty) {
      return 0;
    }
    else {
      # OK
    }

    if ($string_empty ge $string_undef) {
      # OK
    }
    else {
      return 0;
    }

    return 1;
  }

  static method string_lt : int () {
    my $string = "abc";
    my $string_same = "abc";
    my $string_short = "ab";
    my $string_long = "abcd";
    my $string_different_short= "ad";
    my $string_different_long= "adcd";
    my $string_empty = "";
    my $string_undef : string;
    
    # lt
    if ($string lt $string_same) {
      return 0;
    }
    
    if ($string lt (byte[])$string_same) {
      return 0;
    }
    
    if ((byte[])$string lt $string_same) {
      return 0;
    }
    
    unless (!($string lt $string_short)) {
      return 0;
    }
    
    unless ($string lt $string_long) {
      return 0;
    }
    
    unless ($string lt $string_different_short) {
      return 0;
    }
    
    unless ($string lt $string_different_long) {
      return 0;
    }
    
    unless (!($string lt $string_empty)) {
      return 0;
    }

    
    if ($string_undef lt $string_undef) {
      return 0;
    } else {
      # OK
    }

    if ($string_undef lt $string_empty) {
      # OK
    }
    else {
      return 0;
    }

    if ($string_empty lt $string_undef) {
      return 0;
    }
    else {
      # OK
    }

    return 1;
  }

  static method string_le : int () {
    my $string = "abc";
    my $string_same = "abc";
    my $string_short = "ab";
    my $string_long = "abcd";
    my $string_different_short= "ad";
    my $string_different_long= "adcd";
    my $string_empty = "";
    my $string_undef : string;
    
    # le
    my $ok = 0;
    unless ($string le $string_same) {
      return 0;
    }
    unless ($string le (byte[])$string_same) {
      return 0;
    }
    unless ((byte[])$string le $string_same) {
      return 0;
    }
    unless (!($string le $string_short)) {
      return 0;
    }
    unless ($string le $string_long) {
      return 0;
    }
    unless ($string le $string_different_short) {
      return 0;
    }
    unless ($string le $string_different_long) {
      return 0;
    }
    unless (!($string le $string_empty)) {
      return 0;
    }
    
    if ($string_undef le $string_undef) {
      # OK
    } else {
      return 0;
    }

    if ($string_undef le $string_empty) {
      # OK
    }
    else {
      return 0;
    }

    if ($string_empty le $string_undef) {
      return 0;
    }
    else {
      # OK
    }

    return 1;
  }

  static method string_cmp  : int () {
    my $string_empty = "";
    my $string_undef : string;
    
    {
      my $ret = "abd" cmp "abc";
      unless ($ret == 1) {
        return 0;
      }
    }

    {
      my $ret = "abcd" cmp "abc";
      unless ($ret == 1) {
        return 0;
      }
    }

    {
      my $ret = "abb" cmp "abc";
      unless ($ret == -1) {
        return 0;
      }
    }

    {
      my $ret = "abc" cmp "abcd";
      unless ($ret == -1) {
        return 0;
      }
    }

    {
      my $ret = "abc" cmp "abc";
      unless ($ret == 0) {
        return 0;
      }
    }

    {
      my $ret = "abc" cmp (byte[])"abc";
      unless ($ret == 0) {
        return 0;
      }
    }

    {
      my $ret = (byte[])"abc" cmp "abc";
      unless ($ret == 0) {
        return 0;
      }
    }

    {
      my $ret = $string_undef cmp $string_undef;
      unless ($ret == 0) {
        return 0;
      }
    }

    {
      my $ret = $string_undef cmp $string_empty;
      unless ($ret == -1) {
        return 0;
      }
    }

    {
      my $ret = $string_empty cmp $string_undef;
      unless ($ret == 1) {
        return 0;
      }
    }
    
    return 1;
  }
  
}
