class TestCase::Module::Fn {
  use Fn;
  use TestCase::Minimal;
  use TestCase::Simple;
  use TestCase::Empty;
  use Complex_2d;
  use Array;
  use Point;
  use TestCase::Pointer;
  use Hash;
  use Sort;
  use Native;
  use TestCase::Examples;
  
  static method BYTE_MAX : int () {
    
    unless (Fn->BYTE_MAX isa int) {
      return 0;
    }
    unless (Fn->BYTE_MAX == Fn->INT8_MAX) {
      return 0;
    }
    return 1;
  }
  
  static method BYTE_MIN : int () {
    unless (Fn->BYTE_MIN isa int) {
      return 0;
    }
    unless (Fn->BYTE_MIN == Fn->INT8_MIN) {
      return 0;
    }
    return 1;
  }
  
  static method DBL_MAX : int () {
    unless (Fn->DBL_MAX isa double) {
      return 0;
    }
    return 1;
  }
  
  static method DBL_MIN : int () {
    unless (Fn->DBL_MIN isa double) {
      return 0;
    }
    return 1;
  }
  
  static method DOUBLE_MAX : int () {
    unless (Fn->DOUBLE_MAX isa double) {
      return 0;
    }
    unless (Fn->DOUBLE_MAX == Fn->DBL_MAX) {
      return 0;
    }
    return 1;
  }
  
  static method DOUBLE_MIN : int () {
    unless (Fn->DOUBLE_MIN isa double) {
      return 0;
    }
    unless (Fn->DOUBLE_MIN == Fn->DBL_MIN) {
      return 0;
    }
    return 1;
  }
  
  static method FLOAT_MAX : int () {
    unless (Fn->FLOAT_MAX isa float) {
      return 0;
    }
    unless (Fn->FLOAT_MAX == Fn->FLT_MAX) {
      return 0;
    }
    return 1;
  }
  
  static method FLOAT_MIN : int () {
    unless (Fn->FLOAT_MIN isa float) {
      return 0;
    }
    unless (Fn->FLOAT_MIN == Fn->FLT_MIN) {
      return 0;
    }
    return 1;
  }
  
  static method FLT_MAX : int () {
    unless (Fn->FLT_MAX isa float) {
      return 0;
    }
    return 1;
  }
  
  static method FLT_MIN : int () {
    unless (Fn->FLT_MIN isa float) {
      return 0;
    }
    return 1;
  }
  
  static method INT16_MAX : int () {
    unless (Fn->INT16_MAX  isa int) {
      return 0;
    }
    unless (Fn->INT16_MAX == 32767) {
      return 0;
    }
    
    return 1;
  }
  
  static method INT16_MIN : int () {
    unless (Fn->INT16_MIN  isa int) {
      return 0;
    }
    unless (Fn->INT16_MIN == -32768) {
      return 0;
    }
    
    return 1;
  }
  
  static method INT32_MIN : int () {
    unless (Fn->INT32_MIN  isa int) {
      return 0;
    }
    unless (Fn->INT32_MIN == -2147483648) {
      return 0;
    }
    
    return 1;
  }
  
  static method INT32_MAX : int () {
    unless (Fn->INT32_MAX  isa int) {
      return 0;
    }
    unless (Fn->INT32_MAX == 2147483647) {
      return 0;
    }
    
    return 1;
  }
  
  static method INT64_MIN : int () {
    unless (Fn->INT64_MIN  isa long) {
      return 0;
    }
    unless (Fn->INT64_MIN == -9223372036854775808L) {
      return 0;
    }
    
    return 1;
  }
  
  static method INT64_MAX : int () {
    unless (Fn->INT64_MAX  isa long) {
      return 0;
    }
    unless (Fn->INT64_MAX == 9223372036854775807L) {
      return 0;
    }
    
    return 1;
  }
  
  static method INT8_MIN : int () {
    unless (Fn->INT8_MIN  isa int) {
      return 0;
    }
    unless (Fn->INT8_MIN == -128) {
      return 0;
    }
    
    return 1;
  }
  
  static method INT8_MAX : int () {
    unless (Fn->INT8_MAX  isa int) {
      return 0;
    }
    
    unless (Fn->INT8_MAX == 127) {
      return 0;
    }
    
    return 1;
  }
  
  static method INT_MAX : int () {
    unless (Fn->INT_MAX isa int) {
      return 0;
    }
    unless (Fn->INT_MAX == Fn->INT32_MAX) {
      return 0;
    }
    return 1;
  }
  
  static method INT_MIN : int () {
    unless (Fn->INT_MIN isa int) {
      return 0;
    }
    unless (Fn->INT_MIN == Fn->INT32_MIN) {
      return 0;
    }
    return 1;
  }
  
  static method LONG_MAX : int () {
    unless (Fn->LONG_MAX isa long) {
      return 0;
    }
    unless (Fn->LONG_MAX == Fn->INT64_MAX) {
      return 0;
    }
    return 1;
  }
  
  static method LONG_MIN : int () {
    unless (Fn->LONG_MIN isa long) {
      return 0;
    }
    unless (Fn->LONG_MIN == Fn->INT64_MIN) {
      return 0;
    }
    return 1;
  }
  
  static method RAND_MAX : int () {
    
    unless (Fn->RAND_MAX == 2147483647) {
      return 0;
    }
    
    return 1;
  }
  
  static method SHORT_MAX : int () {
    unless (Fn->SHORT_MAX isa int) {
      return 0;
    }
    unless (Fn->SHORT_MAX == Fn->INT16_MAX) {
      return 0;
    }
    return 1;
  }
  
  static method SHORT_MIN : int () {
    unless (Fn->SHORT_MIN isa int) {
      return 0;
    }
    unless (Fn->SHORT_MIN == Fn->INT16_MIN) {
      return 0;
    }
    return 1;
  }
  
  static method UINT16_MAX : int () {
    unless (Fn->UINT16_MAX isa int) {
      return 0;
    }
    
    unless (Fn->UINT16_MAX == -1) {
      return 0;
    }
    
    return 1;
  }
  
  static method UINT32_MAX : int () {
    unless (Fn->UINT32_MAX isa int) {
      return 0;
    }
    
    unless (Fn->UINT32_MAX == -1) {
      return 0;
    }
    
    return 1;
  }
  
  static method UINT64_MAX : int () {
    unless (Fn->UINT64_MAX isa long) {
      return 0;
    }
    
    unless (Fn->UINT64_MAX == -1) {
      return 0;
    }
    
    return 1;
  }
  
  static method UINT8_MAX : int () {
    unless (Fn->UINT8_MAX isa int) {
      return 0;
    }
    
    unless (Fn->UINT8_MAX == -1) {
      return 0;
    }
    
    return 1;
  }
  
  static method UBYTE_MAX : int () {
    unless (Fn->UBYTE_MAX isa int) {
      return 0;
    }
    unless (Fn->UBYTE_MAX == Fn->UINT8_MAX) {
      return 0;
    }
    return 1;
  }
  
  static method UINT_MAX : int () {
    unless (Fn->UINT_MAX isa int) {
      return 0;
    }
    unless (Fn->UINT_MAX == Fn->UINT32_MAX) {
      return 0;
    }
    return 1;
  }
  
  static method ULONG_MAX : int () {
    unless (Fn->ULONG_MAX isa long) {
      return 0;
    }
    unless (Fn->ULONG_MAX == Fn->UINT64_MAX) {
      return 0;
    }
    return 1;
  }
  
  static method USHORT_MAX : int () {
    unless (Fn->USHORT_MAX isa int) {
      return 0;
    }
    unless (Fn->USHORT_MAX == Fn->UINT16_MAX) {
      return 0;
    }
    return 1;
  }
  
  static method abs : int () {
    
    # Positive values
    {
      my $num = 3;
      my $ret = Fn->abs($num);
      unless ($ret isa int) {
        return 0;
      }
      unless ($ret == 3) {
        return 0;
      }
    }
    
    # Negative values
    {
      my $num = -3;
      my $ret = Fn->abs($num);
      unless ($ret == 3) {
        return 0;
      }
      
    }
    
    # Zeros
    {
      my $num = 0;
      my $ret = Fn->abs($num);
      unless ($ret == 0) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method chomp : int () {
    
    # Basic
    {
      my $line = copy "abc\n";
      Fn->chomp((mutable string)$line);
      
      unless ($line eq "abc") {
        return 0;
      }
    }

    {
      my $line = copy "abc\r\n";
      Fn->chomp((mutable string)$line);
      
      unless ($line eq "abc") {
        return 0;
      }
    }

    {
      my $line = copy "a";
      Fn->chomp((mutable string)$line);
      
      unless ($line eq "a") {
        return 0;
      }
    }

    {
      my $line = copy "ab";
      Fn->chomp((mutable string)$line);
      
      unless ($line eq "ab") {
        return 0;
      }
    }

    {
      my $line = copy "\n";
      Fn->chomp((mutable string)$line);
      
      unless ($line eq "") {
        return 0;
      }
    }

    {
      my $line = copy "\r\n";
      Fn->chomp((mutable string)$line);
      
      unless ($line eq "") {
        return 0;
      }
    }
    
    # Non basic cases
    {
      # no new line
      {
        my $line = copy "abc";
        Fn->chomp((mutable string)$line);
        
        unless ($line eq "abc") {
          return 0;
        }
      }
      
      # The length is zero
      {
        my $line = copy "";
        Fn->chomp((mutable string)$line);
        
        unless ($line eq "") {
          return 0;
        }
      }
    }
    
    # Exception
    {
      {
        my $line = (string)undef;
        eval { Fn->chomp((mutable string)$line); };
        unless (Fn->contains($@, "The string \$string must be defined")) {
          return 0;
        }
      }
    }
    
    return 1;
  }
  
  static method chompr : int () {
    {
      my $string = "abc\n";
      my $ret = Fn->chompr($string);
      unless ($ret eq "abc") {
        return 0;
      }
    }

    {
      my $string = "abc\r\n";
      my $ret = Fn->chompr($string);
      unless ($ret eq "abc") {
        return 0;
      }
    }
    {
      my $string = "abc";
      my $ret = Fn->chompr($string);
      unless ($ret eq "abc") {
        return 0;
      }
    }
    {
      my $string = "";
      my $ret = Fn->chompr($string);
      unless ($ret eq "") {
        return 0;
      }
    }
    
    # Exception
    {
      {
        my $line = (string)undef;
        eval { Fn->chompr((mutable string)$line); };
        unless (Fn->contains($@, "The string \$string must be defined")) {
          return 0;
        }
      }
    }
    return 1;
  }
  
  static method chr : int () {
    
    {
      unless (Fn->chr(0) eq "\0") {
        return 0;
      }
      
      unless (Fn->chr('0') eq "0") {
        return 0;
      }
      
      unless (Fn->chr('a') eq "a") {
        return 0;
      }
      
      unless (Fn->chr(0x3042) eq "あ") {
        return 0;
      }
      
      if (Fn->chr(-1)) {
        return 0;
      }
      
      unless (Fn->chr(0xD800 - 1)) {
        return 0;
      }
      
      if (Fn->chr(0xD800)) {
        return 0;
      }
      
      if (Fn->chr(0xDFFF)) {
        return 0;
      }
      
      unless (Fn->chr(0xDFFF + 1)) {
        return 0;
      }
      
      unless (Fn->chr(0x10FFFF)) {
        return 0;
      }
      
      if (Fn->chr(0x10FFFF + 1)) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method contains : int () {
    {
      my $string = "abcde";
      my $substring = "";
      my $found = Fn->contains($string, $substring);
      unless ($found == 1) {
        return 0;
      }
    }
    {
      my $string = "";
      my $substring = "";
      my $found = Fn->contains($string, $substring);
      unless ($found == 1) {
        return 0;
      }
    }
    {
      my $string = "abcde";
      my $substring = "bcd";
      my $found = Fn->contains($string, $substring);
      unless ($found == 1) {
        return 0;
      }
    }
    {
      my $string = "abcde";
      my $substring = "abcde";
      my $found = Fn->contains($string, $substring);
      unless ($found == 1) {
        return 0;
      }
    }
    {
      my $string = "abcde";
      my $substring = "p";
      my $found = Fn->contains($string, $substring);
      unless ($found == 0) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        {
          my $string = (string)undef;
          my $substring = "p";
          eval { Fn->contains($string, $substring); };
          
          unless (Fn->contains($@, "The string \$string must be defined")) {
            return 0;
          }
        }
      }
      
      {
        {
        my $string = "abcde";
        my $substring = (string)undef;
          eval {Fn->contains($string, $substring); };
          unless (Fn->contains($@, "The substring \$substring must be defined")) {
            return 0;
          }
        }
      }
    }
    return 1;
  }
  
  static method copy_string : int () {
    # copy string
    {
      my $string = "abc";
      my $string_out = Fn->copy_string($string);
      
      # Equals the value
      unless ($string_out eq "abc") {
        return 0;
      }
      
      # Not equals address
      if ($string == $string_out) {
        return 0;
      }
    }
    
    # undef
    {
      my $string_out = Fn->copy_string(undef);
      
      # Equals the value
      unless ($string_out == undef) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method crand : int ($seed : int) {
    
    my $founds_plus = new int[10];
    my $founds_minus = new int[10];
    my $rand = 0;
    for (my $i = 0; $i < 100000; $i++) {
      $rand = Fn->crand(\$seed);
      my $dig0 = $rand % 10;
      $founds_plus->[$dig0] = 1;
    }
    
    unless (Array->equals_int($founds_plus, [1, 1, 1, 1, 1, 1, 1, 1, 1, 1])) {
      return 0;
    }
    
    return 1;
  }
  
  static method equals_string_range : int () {
    
    {
      my $string1 = "abc";
      my $string1_offset = 0;
      my $string2 = "abc";
      my $string2_offset = 0;
      my $length = 3;
      my $match = Fn->equals_string_range($string1, $string1_offset, $string2, $string2_offset, $length);
      
      unless ($match) {
        return 0;
      }
    }

    {
      my $string1 = "abc";
      my $string1_offset = 0;
      my $string2 = "ab";
      my $string2_offset = 0;
      my $length = 3;
      my $match = Fn->equals_string_range($string1, $string1_offset, $string2, $string2_offset, $length);
      
      if ($match) {
        return 0;
      }
    }

    {
      my $string1 = "abc";
      my $string1_offset = 0;
      my $string2 = "ab";
      my $string2_offset = 0;
      my $length = 2;
      my $match = Fn->equals_string_range($string1, $string1_offset, $string2, $string2_offset, $length);
      
      unless ($match) {
        return 0;
      }
    }
    
    {
      my $string1 = "ab";
      my $string1_offset = 0;
      my $string2 = "abc";
      my $string2_offset = 0;
      my $length = 3;
      my $match = Fn->equals_string_range($string1, $string1_offset, $string2, $string2_offset, $length);
      
      if ($match) {
        return 0;
      }
    }

    {
      my $string1 = "ab";
      my $string1_offset = 0;
      my $string2 = "abc";
      my $string2_offset = 0;
      my $length = 2;
      my $match = Fn->equals_string_range($string1, $string1_offset, $string2, $string2_offset, $length);
      
      unless ($match) {
        return 0;
      }
    }

    {
      my $string1 = "ab";
      my $string1_offset = 0;
      my $string2 = "xy";
      my $string2_offset = 0;
      my $length = 0;
      my $match = Fn->equals_string_range($string1, $string1_offset, $string2, $string2_offset, $length);
      
      unless ($match) {
        return 0;
      }
    }

    {
      my $string1 = "abc";
      my $string1_offset = 1;
      my $string2 = "abc";
      my $string2_offset = 1;
      my $length = 3;
      my $match = Fn->equals_string_range($string1, $string1_offset, $string2, $string2_offset, $length);
      
      if ($match) {
        return 0;
      }
    }
    
    {
      my $string1 = "abc";
      my $string1_offset = 1;
      my $string2 = "abc";
      my $string2_offset = 1;
      my $length = 2;
      my $match = Fn->equals_string_range($string1, $string1_offset, $string2, $string2_offset, $length);
      
      unless ($match) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        my $string1 = "abc";
        my $string1_offset = 1;
        my $string2 = "abc";
        my $string2_offset = 1;
        my $length = 2;
        eval { Fn->equals_string_range($string1, $string1_offset, $string2, $string2_offset, $length); };
        if ($@) {
          return 0;
        }
      }
      {
        my $string1 = (string)undef;
        my $string1_offset = 1;
        my $string2 = "abc";
        my $string2_offset = 1;
        my $length = 2;
        eval { Fn->equals_string_range($string1, $string1_offset, $string2, $string2_offset, $length); };
        unless (Fn->contains($@, "The string1 \$string1 must be defined")) {
          return 0;
        }
      }
      {
        my $string1 = "abc";
        my $string1_offset = 1;
        my $string2 = (string)undef;
        my $string2_offset = 1;
        my $length = 2;
        eval { Fn->equals_string_range($string1, $string1_offset, $string2, $string2_offset, $length); };
        unless (Fn->contains($@, "The string2 \$string2 must be defined")) {
          return 0;
        }
      }
      {
        my $string1 = "abc";
        my $string1_offset = -1;
        my $string2 = "abc";
        my $string2_offset = 1;
        my $length = 2;
        eval { Fn->equals_string_range($string1, $string1_offset, $string2, $string2_offset, $length); };
        unless (Fn->contains($@, "The string1 offset \$string1_offset must be greater than or equal to 0")) {
          return 0;
        }
      }
      {
        my $string1 = "abc";
        my $string1_offset = 1;
        my $string2 = "abc";
        my $string2_offset = -1;
        my $length = 2;
        eval { Fn->equals_string_range($string1, $string1_offset, $string2, $string2_offset, $length); };
        unless (Fn->contains($@, "The string2 offset \$string2_offset must be greater than or equal to 0")) {
          return 0;
        }
      }
    }
    
    return 1;
  }
  
  static method get_code_point : int () {
    
    {
      my $string = "あaい";
      
      my $offset = 0;
      
      # あ
      {
        my $code_point = Fn->get_code_point($string, \$offset);
        
        unless ($code_point == 0x3042) {
          return 0;
        }
        
        unless ($offset == 3) {
          return 0;
        }
      }
      
      # a
      {
        my $code_point = Fn->get_code_point($string, \$offset);
        
        unless ($code_point == 'a') {
          return 0;
        }
        
        unless ($offset == 4) {
          return 0;
        }
      }
      
      # い
      {
        my $code_point = Fn->get_code_point($string, \$offset);
       
        unless ($code_point == 0x3044) {
          return 0;
        }
        
        unless ($offset == 7) {
          return 0;
        }
      }
      
      # End - exception
      {
        eval { Fn->get_code_point($string, \$offset); }
        
        unless (Fn->contains($@, "The value of the offset \$offset must be less than the length of the string \$string.")) {
          return 0;
        }
        
      }
    }
    
    {
      my $string = "あaい";
      my $code_points = [0x3042, 'a', 0x3044];
      
      my $offset = 0;
      my $i = 0;
      while (1) {
        
        if ($offset >= length $string) {
          last;
        }
        
        my $code_point = Fn->get_code_point($string, \$offset);
        
        unless ($code_point == $code_points->[$i]) {
          return 0;
        }
        
        $i++;
      }
    }
    
    # Exceptions
    {
      # 0xFF - Invalid UTF-8
      {
        my $string = "\xFF";
        my $offset = 0;
        eval { Fn->get_code_point($string, \$offset); }
        unless (Fn->contains($@, "An invalid UTF-8 is gotten.")) {
          return 0;
        }
        
        unless (eval_error_id is_error Error::Unicode::InvalidUTF8) {
          return 0;
        }
      }
      {
        my $string = (string)undef;
        my $offset = 0;
        eval { Fn->get_code_point($string, \$offset); };
        unless (Fn->contains($@, "The string \$string must be defined")) {
          return 0;
        }
      }
      {
        my $string = "あaい";
        my $offset = -1;
        eval { Fn->get_code_point($string, \$offset); };
        unless (Fn->contains($@, "The offset \$\$offset_ref must be greater than or equal to 0")) {
          return 0;
        }
      }
    }
    
    $@ = undef;
    return 1;
  }
  
  static method hex : int () {
    # 0
    {
      my $hex_string = (string)"0";
      my $hex_num = Fn->hex($hex_string);
      unless ($hex_num isa int) {
        return 0;
      }
      unless ($hex_num == 0) {
        return 0;
      }
    }
    
    # 1-9
    {
      unless (Fn->hex("1") == 1) { return 0; }
      unless (Fn->hex("2") == 2) { return 0; }
      unless (Fn->hex("3") == 3) { return 0; }
      unless (Fn->hex("4") == 4) { return 0; }
      unless (Fn->hex("5") == 5) { return 0; }
      unless (Fn->hex("6") == 6) { return 0; }
      unless (Fn->hex("7") == 7) { return 0; }
      unless (Fn->hex("8") == 8) { return 0; }
      unless (Fn->hex("9") == 9) { return 0; }
    }
    
    # a-z
    {
      unless (Fn->hex("a") == 10) { return 0; }
      unless (Fn->hex("b") == 11) { return 0; }
      unless (Fn->hex("c") == 12) { return 0; }
      unless (Fn->hex("d") == 13) { return 0; }
      unless (Fn->hex("e") == 14) { return 0; }
      unless (Fn->hex("f") == 15) { return 0; }
    }
    
    # A-Z
    {
      unless (Fn->hex("A") == 10) { return 0; }
      unless (Fn->hex("B") == 11) { return 0; }
      unless (Fn->hex("C") == 12) { return 0; }
      unless (Fn->hex("D") == 13) { return 0; }
      unless (Fn->hex("E") == 14) { return 0; }
      unless (Fn->hex("F") == 15) { return 0; }
    }
    
    # 19afAF25
    {
      unless (Fn->hex("19afAF25") == 430944037) { return 0; }
      unless (Fn->hex("19afAF25") == 430944037) { return 0; }
    }
    
    # FFFFFFFF
    {
      unless (Fn->hex("FFFFFFFF") == 0xFFFFFFFF) { return 0; }
    }
    
    # Exception - undef
    {
      eval { Fn->hex(undef); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Empty String
    {
      eval { Fn->hex(""); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Invalid hex string
    {
      eval { Fn->hex("g"); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Too long
    {
      eval { Fn->hex("111111111"); };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }

  static method index : int () {
    {
      my $string = "abcde";
      my $substring = "";
      my $found_offset = Fn->index($string, $substring, 0);
      unless ($found_offset == 0) {
        return 0;
      }
    }
    {
      my $string = "abcde";
      my $substring = "";
      my $found_offset = Fn->index($string, $substring);
      unless ($found_offset == 0) {
        return 0;
      }
    }
    {
      my $string = "";
      my $substring = "";
      my $found_offset = Fn->index($string, $substring, 0);
      unless ($found_offset == 0) {
        return 0;
      }
    }
    
    {
      my $string = "abc";
      my $substring = "";
      my $found_offset = Fn->index($string, $substring);
      unless ($found_offset == 0) {
        return 0;
      }
    }
    
    {
      my $string = "abc";
      my $substring = "";
      my $begin = 1;
      my $found_offset = Fn->index($string, $substring, $begin);
      unless ($found_offset == 1) {
        return 0;
      }
    }
    {
      my $string = "abc";
      my $substring = "";
      my $begin = 3;
      my $found_offset = Fn->index($string, $substring, $begin);
      unless ($found_offset == 3) {
        return 0;
      }
    }
    
    {
      my $string = "abcde";
      my $substring = "bcd";
      my $found_offset = Fn->index($string, $substring, 0);
      unless ($found_offset == 1) {
        return 0;
      }
    }
    {
      my $string = "abcde";
      my $substring = "bcd";
      my $found_offset = Fn->index($string, $substring, 1);
      unless ($found_offset == 1) {
        return 0;
      }
    }
    
    {
      my $string = "abcde";
      my $substring = "bcd";
      my $found_offset = Fn->index($string, $substring, 2);
      unless ($found_offset == -1) {
        return 0;
      }
    }
    
    {
      my $string = "abcde";
      my $substring = "pq";
      my $found_offset = Fn->index($string, $substring, 2);
      unless ($found_offset == -1) {
        return 0;
      }
    }

    {
      my $string = "abcde";
      my $substring = "bcd";
      my $found_offset = Fn->index($string, $substring, 0, length $string - 1);
      unless ($found_offset == 1) {
        return 0;
      }
    }
    {
      my $string = "abcde";
      my $substring = "bcd";
      my $found_offset = Fn->index($string, $substring, 0);
      unless ($found_offset == 1) {
        return 0;
      }
    }
    
    {
      my $string = "abcde";
      my $substring = "";
      my $found_offset = Fn->index($string, $substring, 0);
      unless ($found_offset == 0) {
        return 0;
      }
    }
    
    {
      my $string = "abcde";
      my $substring = "";
      my $found_offset = Fn->index($string, $substring, 1);
      unless ($found_offset == 1) {
        return 0;
      }
    }
    {
      my $string = "abcde";
      my $substring = "bcd";
      my $found_offset = Fn->index($string, $substring, 0, 3);
      unless ($found_offset == 1) {
        return 0;
      }
    }
    {
      my $string = "abcde";
      my $substring = "bcd";
      my $found_offset = Fn->index($string, $substring, 0, 2);
      unless ($found_offset == -1) {
        return 0;
      }
    }
    {
      my $string = "foo,bar,baz,,";
      my $substring = ",";
      my $offset = 8;
      my $found_offset = Fn->index($string, $substring, $offset);
      unless ($found_offset == 11) {
        return 0;
      }
    }
    
    # Exception
    {
      {
        my $string = (string)undef;
        my $substring = "bcd";
        eval { Fn->index(undef, $substring); };
        unless (Fn->contains($@, "The string \$string must be defined")) {
          return 0;
        }
      }
      
      {
        my $string = "abcde";
        my $substring = (string)undef;
        eval { Fn->index($string, $substring); };
        unless (Fn->contains($@, "The substring \$substring must be defined")) {
          return 0;
        }
      }
      
      {
        my $string = "abcde";
        my $substring = "bcd";
        eval { Fn->index($string, $substring, -1); };
        unless (Fn->contains($@, "The begin \$begin must be between 0 and the length of the string \$string")) {
          return 0;
        }
      }
      
      {
        my $string = "abcde";
        my $substring = "bcd";
        eval { Fn->index($string, $substring, length $string + 1); };
        unless (Fn->contains($@, "The begin \$begin must be between 0 and the length of the string \$string")) {
          return 0;
        }
      }
      
      {
        my $string = "abcde";
        my $substring = "bcd";
        eval { Fn->index($string, $substring, 0, length $string + 1); };
        unless (Fn->contains($@, "The end \$end must be less than or equal to the length of the string \$string")) {
          return 0;
        }
      }
      
      {
        my $string = "abcde";
        my $substring = "bcd";
        my $begin = 2;
        my $end = 1;
        eval { Fn->index($string, $substring, $begin, $end); };
        unless (Fn->contains($@, "The end \$end must be greater than or equal to the begin \$begin")) {
          return 0;
        }
      }
    }
    
    return 1;
  }

  static method init_string : int () {
    {
      my $string = (mutable string)copy "abc";
      Fn->init_string($string);
      
      unless ($string eq "\0\0\0") {
        return 0;
      }
    }

    {
      my $string = (mutable string)copy "abc";
      my $ascii_code = 'd';
      Fn->init_string($string, $ascii_code);
      
      unless ($string eq "ddd") {
        return 0;
      }
    }
    
    {
      my $string = (mutable string)copy "abc";
      my $ascii_code = 0;
      my $offset = 1;
      Fn->init_string($string, $ascii_code, $offset);
      
      unless ($string eq "a\0\0") {
        return 0;
      }
    }
    
    {
      my $string = (mutable string)copy "abc";
      my $ascii_code = 0;
      my $offset = 1;
      my $length = 1;
      Fn->init_string($string, $ascii_code, $offset, $length);
      
      unless ($string eq "a\0c") {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        eval { Fn->init_string(undef); };
        
        unless (Fn->contains($@, "The string \$string must be defined")) {
          return 0;
        }
      }
      {
        my $string = (mutable string)copy "abc";
        eval { Fn->init_string($string, '\0', 1, 3); };
        
        unless (Fn->contains($@, "The offset \$offset + the length \$length must be less than or equal to the length of the string \$string")) {
          return 0;
        }
      }
    }
    return 1;
  }

  static method is_alnum : int () {

    my $ok = 1;
    for (my $i = 0; $i < 128; $i++) {
      my $char = $i;

      if (($char >= 'A' && $char <= 'Z') || ($char >= 'a' && $char <= 'z') || ($char >= '0' && $char <= '9')) {
        my $ret = Fn->is_alnum($char);
        unless ($ret == 1) {
          $ok = 0;
        }
      }
      else {
        my $ret = Fn->is_alnum($char);
        unless ($ret == 0) {
          $ok = 0;
        }
      }
    }

    unless ($ok) {
      return 0;
    }

    return 1;
  }

  static method is_alpha : int () {

    my $ok = 1;
    for (my $i = 0; $i < 128; $i++) {
      my $char = $i;

      if (($char >= 'A' && $char <= 'Z') || ($char >= 'a' && $char <= 'z')) {
        my $ret = Fn->is_alpha($char);
        unless ($ret == 1) {
          $ok = 0;
        }
      }
      else {
        my $ret = Fn->is_alpha($char);
        unless ($ret == 0) {
          $ok = 0;
        }
      }
    }

    unless ($ok) {
      return 0;
    }

    return 1;
  }

  static method is_array : int () {
    
    # Array
    {
      my $array = new byte[3];
      
      unless (Fn->is_array($array)) {
        return 0;
      }
    }
    
    # string
    {
      my $string = "abc";
      
      if (Fn->is_array($string)) {
        return 0;
      }
    }
    
    # Object
    {
      my $minimal = TestCase::Minimal->new;
      
      if (Fn->is_array($minimal)) {
        return 0;
      }
    }
    
    # undef
    {
      if (Fn->is_array(undef)) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method is_blank : int () {
    
    my $ok = 1;
    for (my $i = 0; $i < 128; $i++) {
      my $char = $i;
      
      if ($char >= ' ' ||  $char <= '\t') {
        my $ret = Fn->is_blank($char);
        unless ($ret == 1) {
          $ok = 0;
        }
      }
      else {
        my $ret = Fn->is_blank($char);
        unless ($ret == 0) {
          $ok = 0;
        }
      }
    }

    unless ($ok) {
      return 0;
    }

    return 1;
  }

  static method is_class : int () {
    
    # Class
    {
      my $object = Point->new;
      
      unless (Fn->is_class($object)) {
        return 0;
      }
    }

    # Class
    {
      my $object = (Stringable)Point->new;
      
      unless (Fn->is_class($object)) {
        return 0;
      }
    }
    
    # Array
    {
      my $object = new byte[3];
      
      if (Fn->is_class($object)) {
        return 0;
      }
    }
    
    # string
    {
      my $string = "abc";
      
      if (Fn->is_class($string)) {
        return 0;
      }
    }
    
    # undef
    {
      if (Fn->is_class(undef)) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method is_cntrl : int () {

    my $ok = 1;
    for (my $i = 0; $i < 128; $i++) {
      my $char = $i;

      if (($char >= 0x00 && $char <= 0x1f) || $char == 0x7f) {
        my $ret = Fn->is_cntrl($char);
        unless ($ret == 1) {
          $ok = 0;
        }
      }
      else {
        my $ret = Fn->is_cntrl($char);
        unless ($ret == 0) {
          $ok = 0;
        }
      }
    }

    unless ($ok) {
      return 0;
    }

    return 1;
  }

  static method is_digit : int () {

    my $ok = 1;
    for (my $i = 0; $i < 128; $i++) {
      my $char = $i;

      if ($char >= '0' && $char <= '9') {
        my $ret = Fn->is_digit($char);
        unless ($ret == 1) {
          $ok = 0;
        }
      }
      else {
        my $ret = Fn->is_digit($char);
        unless ($ret == 0) {
          $ok = 0;
        }
      }
    }

    unless ($ok) {
      return 0;
    }

    return 1;
  }

  static method is_graph : int () {

    my $ok = 1;
    for (my $i = 0; $i < 128; $i++) {
      my $char = $i;

      if ($char >= 0x21 && $char <= 0x7E) {
        my $ret = Fn->is_graph($char);
        unless ($ret == 1) {
          $ok = 0;
        }
      }
      else {
        my $ret = Fn->is_graph($char);
        unless ($ret == 0) {
          $ok = 0;
        }
      }
    }

    unless ($ok) {
      return 0;
    }

    return 1;
  }

  static method is_hex_digit : int () {

    my $ok = 1;
    for (my $i = 0; $i < 128; $i++) {
      my $char = $i;

      if ($char >= '0' && $char <= '9') {
        my $ret = Fn->is_hex_digit($char);
        unless ($ret == 1) {
          $ok = 0;
        }
      }
      elsif ($char >= 'a' && $char <= 'f') {
        my $ret = Fn->is_hex_digit($char);
        unless ($ret == 1) {
          $ok = 0;
        }
      }
      elsif ($char >= 'A' && $char <= 'F') {
        my $ret = Fn->is_hex_digit($char);
        unless ($ret == 1) {
          $ok = 0;
        }
      }
      else {
        my $ret = Fn->is_hex_digit($char);
        unless ($ret == 0) {
          $ok = 0;
        }
      }
    }

    unless ($ok) {
      return 0;
    }

    return 1;
  }

  static method is_lower : int () {

    my $ok = 1;
    for (my $i = 0; $i < 128; $i++) {
      my $char = $i;

    if ($char >= 'a' && $char <= 'z') {
        my $ret = Fn->is_lower($char);
        unless ($ret == 1) {
          $ok = 0;
        }
      }
      else {
        my $ret = Fn->is_lower($char);
        unless ($ret == 0) {
          $ok = 0;
        }
      }
    }

    unless ($ok) {
      return 0;
    }

    return 1;
  }

  static method is_mulnum_array : int () {
    
    # Numeric Array
    {
      if (Fn->is_mulnum_array(new byte[3])) {
        return 0;
      }
      
      if (Fn->is_mulnum_array(new double[3])) {
        return 0;
      }
    }
    
    # Multi Numeric Array
    {
      unless (Fn->is_mulnum_array(new Complex_2d[3])) {
        return 0;
      }
    }
    
    # string
    {
      my $string = "abc";
      
      if (Fn->is_mulnum_array($string)) {
        return 0;
      }
    }
    
    # Object
    {
      my $minimal = TestCase::Minimal->new;
      
      if (Fn->is_mulnum_array($minimal)) {
        return 0;
      }
    }
    
    # undef
    {
      if (Fn->is_mulnum_array(undef)) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method is_numeric_array : int () {

    # Numeric Array
    {
      unless (Fn->is_numeric_array(new byte[3])) {
        return 0;
      }

      unless (Fn->is_numeric_array(new double[3])) {
        return 0;
      }
    }

    # Multi Numeric Array
    {
      if (Fn->is_numeric_array(new Complex_2d[3])) {
        return 0;
      }
    }
    
    # string
    {
      my $string = "abc";
      
      if (Fn->is_numeric_array($string)) {
        return 0;
      }
    }
    
    # Object
    {
      my $minimal = TestCase::Minimal->new;
      
      if (Fn->is_numeric_array($minimal)) {
        return 0;
      }
    }

    # undef
    {
      if (Fn->is_numeric_array(undef)) {
        return 0;
      }
    }
    
    return 1;
  }

  static method is_object_array : int () {

    # Numeric Array
    {
      if (Fn->is_object_array(new byte[3])) {
        return 0;
      }

      if (Fn->is_object_array(new double[3])) {
        return 0;
      }
    }

    # Multi Numeric Array
    {
      if (Fn->is_object_array(new Complex_2d[3])) {
        return 0;
      }
    }
    
    # string
    {
      my $string = "abc";
      
      if (Fn->is_object_array($string)) {
        return 0;
      }
    }
    
    # Object
    {
      my $minimal = TestCase::Minimal->new;
      
      if (Fn->is_object_array($minimal)) {
        return 0;
      }
    }

    # Object array
    {
      my $minimals = new TestCase::Minimal[3];
      
      unless (Fn->is_object_array($minimals)) {
        return 0;
      }
    }

    # undef
    {
      if (Fn->is_object_array(undef)) {
        return 0;
      }
    }
    
    return 1;
  }

  static method is_perl_space : int () {
    {
      my $ok = 1;
      for (my $i = 0; $i < 128; $i++) {
        my $char = $i;
        
        if ($char == ' ' || $char == '\r' || $char == '\n' || $char == '\t' || $char == '\f') {
          my $ret = Fn->is_perl_space($char);
          unless ($ret == 1) {
            $ok = 0;
          }
        }
        else {
          my $ret = Fn->is_perl_space($char);
          unless ($ret == 0) {
            $ok = 0;
          }
        }
      }
      
      unless ($ok) {
        return 0;
      }
    }
    
    {
      my $ok = 1;
      for (my $i = 0; $i < 128; $i++) {
        my $char = $i;
        
        if ($char == 0x20 || $char == 0x0D || $char == 0x0A || $char == 0x09 || $char == 0x0C) {
          my $ret = Fn->is_perl_space($char);
          unless ($ret == 1) {
            $ok = 0;
          }
        }
        else {
          my $ret = Fn->is_perl_space($char);
          unless ($ret == 0) {
            $ok = 0;
          }
        }
      }
      
      unless ($ok) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method is_perl_word : int () {

    my $ok = 1;
    for (my $i = 0; $i < 128; $i++) {
      my $char = $i;

      if ($char >= 'a' && $char <= 'z' || $char >= 'A' && $char <= 'Z' || $char == '_' || $char >= '0' && $char <= '9') {
        my $ret = Fn->is_perl_word($char);
        unless ($ret == 1) {
          $ok = 0;
        }
      }
      else {
        my $ret = Fn->is_perl_word($char);
        unless ($ret == 0) {
          $ok = 0;
        }
      }
    }

    unless ($ok) {
      return 0;
    }

    return 1;
  }

  static method is_pointer_class : int () {
    
    # Class
    {
      my $object = TestCase::Pointer->new(3);
      
      unless (Fn->is_pointer_class($object)) {
        return 0;
      }
    }
    
    # Class
    {
      my $object = Point->new;
      
      if (Fn->is_pointer_class($object)) {
        return 0;
      }
    }

    # Interface
    {
      my $object = (Stringable)Point->new;
      
      if (Fn->is_pointer_class($object)) {
        return 0;
      }
    }
    
    # Array
    {
      my $object = new byte[3];
      
      if (Fn->is_pointer_class($object)) {
        return 0;
      }
    }
    
    # string
    {
      my $string = "abc";
      
      if (Fn->is_pointer_class($string)) {
        return 0;
      }
    }
    
    # undef
    {
      if (Fn->is_pointer_class(undef)) {
        return 0;
      }
    }
    
    return 1;
  }

  static method is_print : int () {

    my $ok = 1;
    for (my $i = 0; $i < 128; $i++) {
      my $char = $i;

      if ($char >= 0x20 && $char <= 0x7E) {
        my $ret = Fn->is_print($char);
        unless ($ret == 1) {
          $ok = 0;
        }
      }
      else {
        my $ret = Fn->is_print($char);
        unless ($ret == 0) {
          $ok = 0;
        }
      }
    }

    unless ($ok) {
      return 0;
    }

    return 1;
  }

  static method is_punct : int () {

    my $ok = 1;
    for (my $i = 0; $i < 128; $i++) {
      my $char = $i;

      if (($char >= 0x21 && $char <= 0x2F) || ($char >= 0x3A && $char <= 0x40) || ($char >= 0x5B && $char <= 0x60) || ($char >= 0x7B && $char <= 0x7E)) {
        my $ret = Fn->is_punct($char);
        unless ($ret == 1) {
          $ok = 0;
        }
      }
      else {
        my $ret = Fn->is_punct($char);
        unless ($ret == 0) {
          $ok = 0;
        }
      }
    }

    unless ($ok) {
      return 0;
    }

    return 1;
  }

  static method is_space : int () {

    my $ok = 1;
    for (my $i = 0; $i < 128; $i++) {
      my $char = $i;

      if (($char >= 0x09 && $char <= 0x0D) || $char == 0x20) {
        my $ret = Fn->is_space($char);
        unless ($ret == 1) {
          $ok = 0;
        }
      }
      else {
        my $ret = Fn->is_space($char);
        unless ($ret == 0) {
          $ok = 0;
        }
      }
    }

    unless ($ok) {
      return 0;
    }

    return 1;
  }

  static method is_upper : int () {

    my $ok = 1;
    for (my $i = 0; $i < 128; $i++) {
      my $char = $i;

      if ($char >= 'A' && $char <= 'Z') {
        my $ret = Fn->is_upper($char);
        unless ($ret == 1) {
          $ok = 0;
        }
      }
      else {
        my $ret = Fn->is_upper($char);
        unless ($ret == 0) {
          $ok = 0;
        }
      }
    }

    unless ($ok) {
      return 0;
    }

    return 1;
  }

  static method is_xdigit : int () {

    my $ok = 1;
    for (my $i = 0; $i < 128; $i++) {
      my $char = $i;

      if (($char >= 'A' && $char <= 'F') || ($char >= 'a' && $char <= 'f') || ($char >= '0' && $char <= '9')) {
        my $ret = Fn->is_xdigit($char);
        unless ($ret == 1) {
          $ok = 0;
        }
      }
      else {
        my $ret = Fn->is_xdigit($char);
        unless ($ret == 0) {
          $ok = 0;
        }
      }
    }

    unless ($ok) {
      return 0;
    }

    return 1;
  }

  static method join : int () {
    my $strings = ["abc", "def", "hij"];

    my $dump = Fn->join(",", $strings);

    if ($dump eq "abc,def,hij") {
      return 1;
    }

    return 0;
  }

  static method labs : int () {
    
    # Positive values
    {
      my $num = 3L;
      my $ret = Fn->labs($num);
      unless ($ret isa long) {
        return 0;
      }
      unless ($ret == 3) {
        return 0;
      }
    }
    
    # Negative values
    {
      my $num = -3L;
      my $ret = Fn->labs($num);
      unless ($ret == 3) {
        return 0;
      }
      
    }

    # Zeros
    {
      my $num = 0;
      my $ret = Fn->labs($num);
      unless ($ret == 0) {
        return 0;
      }
    }
    
    return 1;
  }

  static method lc : int () {
    {
      my $string = "@[APZ[";
      my $result_str = Fn->lc($string);
      unless ($result_str eq "@[apz[") {
        return 0;
      }
    }
    return 1;
  }

  static method lcfirst : int () {
    {
      my $string = "@ABC";
      my $result_str = Fn->lcfirst($string);
      unless ($result_str eq "@ABC") {
        return 0;
      }
    }
    {
      my $string = "[ABC";
      my $result_str = Fn->lcfirst($string);
      unless ($result_str eq "[ABC") {
        return 0;
      }
    }

    {
      my $string = "AABC";
      my $result_str = Fn->lcfirst($string);
      unless ($result_str eq "aABC") {
        return 0;
      }
    }

    {
      my $string = "PABC";
      my $result_str = Fn->lcfirst($string);
      unless ($result_str eq "pABC") {
        return 0;
      }
    }

    {
      my $string = "ZABC";
      my $result_str = Fn->lcfirst($string);
      unless ($result_str eq "zABC") {
        return 0;
      }
    }
    return 1;
  }

  static method look_code_point : int () {
    
    {
      my $string = "あaい";
      
      my $found_offset = 0;
      
      # あ
      {
        my $code_point = Fn->look_code_point($string, \$found_offset);
        
        unless ($code_point == 0x3042) {
          return 0;
        }
        
        unless ($found_offset == 0) {
          return 0;
        }
      }
    }
    
    return 1;
  }
  
  static method memcpy : int () {
    
    # Basic
    {
      # Copy numeric array
      {
        # byte
        {
          my $dist = [(byte)1, 2, 3, 4];
          my $source = [(byte)10, 11, 12, 13];
          
          Fn->memcpy($dist, 0, $source, 0, 4);
          
          my $dist_expected = [(byte)10, 11, 12, 13];
          unless (Array->equals_byte($dist, $dist_expected)) {
            return 0;
          }
        }

        # double
        {
          my $dist = [(double)1, 2, 3, 4];
          my $source = [(double)10, 11, 12, 13];
          
          Fn->memcpy($dist, 0, $source, 0, 8 * 4);
          
          my $dist_expected = [(double)10, 11, 12, 13];
          unless (Array->equals_double($dist, $dist_expected)) {
            return 0;
          }
        }
      }

      # Copy string
      {
        my $dist = (string)[(byte)1, 2, 3, 4];
        my $source = (string)[(byte)10, 11, 12, 13];
        
        Fn->memcpy($dist, 0, $source, 0, 4);
        
        my $dist_expected = (string)[(byte)10, 11, 12, 13];
        unless ($dist eq $dist_expected) {
          return 0;
        }
      }

      # Copy multi numeric array
      {
        my $dist = new Complex_2d[4];
        my $source = new Complex_2d[4];
        $source->[0]{re} = 1;
        $source->[0]{im} = 2;
        $source->[2]{re} = 3;
        $source->[2]{im} = 4;
        
        Fn->memcpy($dist, 0, $source, 0, 2 * 8 * 4);
        
        unless ($dist->[0]{re} == 1) {
          return 0;
        }
        unless ($dist->[0]{im} == 2) {
          return 0;
        }
        unless ($dist->[2]{re} == 3) {
          return 0;
        }
        unless ($dist->[2]{im} == 4) {
          return 0;
        }
      }

      # Copy string to bytes
      {
        my $dist = [(byte)1, 2, 3, 4];
        my $source = (string)[(byte)10, 11, 12, 13];
        
        Fn->memcpy($dist, 0, $source, 0, 4);
        
        my $dist_expected = [(byte)10, 11, 12, 13];
        unless ($dist eq $dist_expected) {
          return 0;
        }
      }
    }

    # Copy offset + length
    {
      # int
      {
        my $dist = [(int)1, 2, 3, 4];
        my $source = [(int)10, 11, 12, 13];
        
        Fn->memcpy($dist, 1 * 4, $source, 1 * 4, 2 * 4);
        
        my $dist_expected = [(int)1, 11, 12, 4];
        unless (Array->equals_int($dist, $dist_expected)) {
          return 0;
        }
      }
    }
    
    # Exception
    {
      # Exception - Destnation must be defined
      {
        my $source = [(byte)1, 3, 5];
        eval { Fn->memcpy(undef, 0, $source, 0, 3); };
        unless ($@) {
          return 0;
        }
      }

      # Exception - Source must be defined
      {
        my $dest = new byte[4];
        eval { Fn->memcpy($dest, 0, undef, 0, 3); };
        unless ($@) {
          return 0;
        }
      }
      
      # Exception - Length must be more than or equals to 0
      {
        my $dest = new byte[4];
        my $source = [(byte)1, 3, 5];
        eval { Fn->memcpy($dest, 0, $source, 0, -1); };
        unless ($@) {
          return 0;
        }
      }
      
      # Exception - Destnation offset + length must be within the range of the destination array
      {
        my $dest = new byte[4];
        my $source = [(byte)1, 3, 5];
        eval { Fn->memcpy($dest, 2, $source, 0, 3); };
        unless ($@) {
          return 0;
        }
      }

      # Exception - Source offset + length must be within the range of the source array
      {
        my $dest = new byte[4];
        my $source = [(byte)1, 3, 5];
        eval { Fn->memcpy($dest, 0, $source, 1, 3); };
        unless ($@) {
          return 0;
        }
      }
    }
    
    $@ = undef;

    
    return 1;
  }

  static method memmove : int () {
    
    # Basic
    {
      # Copy numeric array
      {
        # byte
        {
          my $dist = [(byte)1, 2, 3, 4];
          my $source = [(byte)10, 11, 12, 13];
          
          Fn->memmove($dist, 0, $source, 0, 4);
          
          my $dist_expected = [(byte)10, 11, 12, 13];
          unless (Array->equals_byte($dist, $dist_expected)) {
            return 0;
          }
        }

        # double
        {
          my $dist = [(double)1, 2, 3, 4];
          my $source = [(double)10, 11, 12, 13];
          
          Fn->memmove($dist, 0, $source, 0, 8 * 4);
          
          my $dist_expected = [(double)10, 11, 12, 13];
          unless (Array->equals_double($dist, $dist_expected)) {
            return 0;
          }
        }
      }

      # Copy string
      {
        my $dist = (string)[(byte)1, 2, 3, 4];
        my $source = (string)[(byte)10, 11, 12, 13];
        
        Fn->memmove($dist, 0, $source, 0, 4);
        
        my $dist_expected = (string)[(byte)10, 11, 12, 13];
        unless ($dist eq $dist_expected) {
          return 0;
        }
      }

      # Copy multi numeric array
      {
        my $dist = new Complex_2d[4];
        my $source = new Complex_2d[4];
        $source->[0]{re} = 1;
        $source->[0]{im} = 2;
        $source->[2]{re} = 3;
        $source->[2]{im} = 4;
        
        Fn->memmove($dist, 0, $source, 0, 2 * 8 * 4);
        
        unless ($dist->[0]{re} == 1) {
          return 0;
        }
        unless ($dist->[0]{im} == 2) {
          return 0;
        }
        unless ($dist->[2]{re} == 3) {
          return 0;
        }
        unless ($dist->[2]{im} == 4) {
          return 0;
        }
      }

      # Copy string to bytes
      {
        my $dist = [(byte)1, 2, 3, 4];
        my $source = (string)[(byte)10, 11, 12, 13];
        
        Fn->memmove($dist, 0, $source, 0, 4);
        
        my $dist_expected = [(byte)10, 11, 12, 13];
        unless ($dist eq $dist_expected) {
          return 0;
        }
      }
    }

    # Copy offset + length
    {
      # int
      {
        my $dist = [(int)1, 2, 3, 4];
        my $source = [(int)10, 11, 12, 13];
        
        Fn->memmove($dist, 1 * 4, $source, 1 * 4, 2 * 4);
        
        my $dist_expected = [(int)1, 11, 12, 4];
        unless (Array->equals_int($dist, $dist_expected)) {
          return 0;
        }
      }
    }
    
    # Exception
    {
      # Exception - Destnation must be defined
      {
        my $source = [(byte)1, 3, 5];
        eval { Fn->memmove(undef, 0, $source, 0, 3); };
        unless ($@) {
          return 0;
        }
      }

      # Exception - Source must be defined
      {
        my $dest = new byte[4];
        eval { Fn->memmove($dest, 0, undef, 0, 3); };
        unless ($@) {
          return 0;
        }
      }
      
      # Exception - Length must be more than or equals to 0
      {
        my $dest = new byte[4];
        my $source = [(byte)1, 3, 5];
        eval { Fn->memmove($dest, 0, $source, 0, -1); };
        unless ($@) {
          return 0;
        }
      }
      
      # Exception - Destnation offset + length must be within the range of the destination array
      {
        my $dest = new byte[4];
        my $source = [(byte)1, 3, 5];
        eval { Fn->memmove($dest, 2, $source, 0, 3); };
        unless ($@) {
          return 0;
        }
      }

      # Exception - Source offset + length must be within the range of the source array
      {
        my $dest = new byte[4];
        my $source = [(byte)1, 3, 5];
        eval { Fn->memmove($dest, 0, $source, 1, 3); };
        unless ($@) {
          return 0;
        }
      }
    }
    
    $@ = undef;

    
    return 1;
  }
  static method ord : int () {
    
    unless (Fn->ord("a") == 97) {
      return 0;
    }
    unless (Fn->ord("ab") == 97) {
      return 0;
    }
    unless (Fn->ord("\x00") == 0) {
      return 0;
    }
    
    unless (Fn->ord("\x01") == 1) {
      return 0;
    }

    unless (Fn->ord("\x7F") == 127) {
      return 0;
    }

    unless (Fn->ord("あ") == 12354) {
      return 0;
    }
    
    # Unicode max scalar value
    unless (Fn->ord(Fn->chr(0x10FFFF)) == 0x10FFFF) {
      return 0;
    }
    
    # End
    {
      eval { Fn->ord(""); }
      unless (Fn->contains($@, "The value of the offset \$offset must be less than the length of the string \$string.")) {
        return 0;
      }
      
    }
    
    # Error
    {
      eval { Fn->ord(undef); };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }

  static method rand : int ($seed : int) {
    
    # 0 <= random_number < 1
    {
      my $rand = 0.0;
      my $invalid_range = 0;
      for (my $i = 0; $i < 100000; $i++) {
        $rand = Fn->rand(\$seed);
        
        unless ($rand >= 0 && $rand < 1) {
          $invalid_range = 1;
          last;
        }
      }
      
      if ($invalid_range) {
        return 0;
      }
    }
    
    # Apper random numbers
    {
      my $founds_plus = new int[10];
      my $founds_minus = new int[10];
      my $rand = 0.0;
      for (my $i = 0; $i < 100000; $i++) {
        $rand = Fn->rand(\$seed);
        
        # 0-9
        my $dig0 = (int)($rand * 10);
        $founds_plus->[$dig0] = 1;
      }
      
      unless (Array->equals_int($founds_plus, [1, 1, 1, 1, 1, 1, 1, 1, 1, 1])) {
        return 0;
      }
    }
    

    # Apper random numbers
    {
      my $founds_plus = new int[10];
      my $founds_minus = new int[10];
      my $rand = 0.0;
      for (my $i = 0; $i < 100000; $i++) {
        $rand = Fn->rand(\$seed, 10);
        
        # 0-9
        my $dig0 = (int)($rand);
        $founds_plus->[$dig0] = 1;
      }
      
      unless (Array->equals_int($founds_plus, [1, 1, 1, 1, 1, 1, 1, 1, 1, 1])) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        my $seed = 1;
        eval { Fn->rand(\$seed, 0); }
        
        unless ($@) {
          return 0;
        }
        
      }
    }
    
    return 1;
  }
  
  static method repeat : int () {
    
    unless (Fn->repeat("abc", 3) eq "abcabcabc") {
      return 0;
    }
    
    {
      my $ret = Fn->repeat("abc", 0);
      unless ($ret eq "") {
        return 0;
      }
    }
    
    # Exception
    {
      eval { Fn->repeat(undef, 1); };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }

  static method replace_chars : int () {
    
    my $string = (mutable string)copy "abacad";
    Fn->replace_chars($string, 'a', 'A');
    
    unless ($string eq "AbAcAd") {
      return 0;
    }
    
    # Exception
    {
      eval { Fn->replace_chars(undef, 'a', 'A'); };
      unless (Fn->contains($@, "The string \$string must be defined")) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method rindex : int () {
    
    {
      my $string = "abab";
      my $substring = "ab";
      my $begin = 0;
      my $found_offset = Fn->rindex($string, $substring, -1, $begin);
      unless ($found_offset == 2) {
        return 0;
      }
    }
    
    {
      my $string = "abab";
      my $substring = "ab";
      my $begin = 1;
      my $found_offset = Fn->rindex($string, $substring, -1, 1);
      unless ($found_offset == 2) {
        return 0;
      }
    }
    
    {
      my $string = "abab";
      my $substring = "ab";
      my $begin = 2;
      my $found_offset = Fn->rindex($string, $substring, -1, $begin);
      unless ($found_offset == 2) {
        return 0;
      }
    }
    
    {
      my $string = "abab";
      my $substring = "ab";
      my $begin = 3;
      my $found_offset = Fn->rindex($string, $substring, -1, $begin);
      unless ($found_offset == -1) {
        return 0;
      }
    }
    
    {
      my $string = "abc";
      my $substring = "";
      my $found_offset = Fn->rindex($string, $substring);
      unless ($found_offset == 3) {
        return 0;
      }
    }
    
    {
      my $string = "abc";
      my $substring = "";
      my $end = 3;
      my $found_offset = Fn->rindex($string, $substring, $end);
      unless ($found_offset == 3) {
        return 0;
      }
    }
    
    {
      my $string = "abc";
      my $substring = "";
      my $end = 2;
      my $found_offset = Fn->rindex($string, $substring, $end);
      unless ($found_offset == 2) {
        return 0;
      }
    }
    
    {
      my $string = "abab";
      my $substring = "pq";
      my $begin = 2;
      my $found_offset = Fn->rindex($string, $substring, -1, $begin);
      unless ($found_offset == -1) {
        return 0;
      }
    }
    
    {
      my $string = "abcab";
      my $substring = "bca";
      my $begin = 0;
      my $found_offset = Fn->rindex($string, $substring, -1, $begin);
      unless ($found_offset == 1) {
        return 0;
      }
    }
    
    {
      my $string = "abab";
      my $substring = "ab";
      my $begin = 0;
      my $found_offset = Fn->rindex($string, $substring, length $string - 1, $begin);
      unless ($found_offset == 2) {
        return 0;
      }
    }
    {
      my $string = "abab";
      my $substring = "ab";
      my $found_offset = Fn->rindex($string, $substring);
      unless ($found_offset == 2) {
        return 0;
      }
    }
    
    {
      my $string = "abab";
      my $substring = "ab";
      my $begin = 1;
      my $found_offset = Fn->rindex($string, $substring, length $string - 1, 1);
      unless ($found_offset == 2) {
        return 0;
      }
    }
    {
      my $string = "abab";
      my $substring = "ab";
      my $begin = 1;
      my $found_offset = Fn->rindex($string, $substring, -1, 1);
      unless ($found_offset == 2) {
        return 0;
      }
    }
    
    {
      my $string = "abab";
      my $substring = "ab";
      my $begin = 2;
      my $found_offset = Fn->rindex($string, $substring, length $string - 1, $begin);
      unless ($found_offset == 2) {
        return 0;
      }
    }
    {
      my $string = "abab";
      my $substring = "ab";
      my $begin = 2;
      my $found_offset = Fn->rindex($string, $substring, -1, $begin);
      unless ($found_offset == 2) {
        return 0;
      }
    }
    
    {
      my $string = "abab";
      my $substring = "ab";
      my $begin = 3;
      my $found_offset = Fn->rindex($string, $substring, length $string - 1, $begin);
      unless ($found_offset == -1) {
        return 0;
      }
    }
    {
      my $string = "abab";
      my $substring = "ab";
      my $begin = 3;
      my $found_offset = Fn->rindex($string, $substring, -1, $begin);
      unless ($found_offset == -1) {
        return 0;
      }
    }
    
    {
      my $string = "abab";
      my $substring = "pq";
      my $begin = 2;
      my $found_offset = Fn->rindex($string, $substring, length $string - 1, $begin);
      unless ($found_offset == -1) {
        return 0;
      }
    }
    {
      my $string = "abab";
      my $substring = "pq";
      my $begin = 2;
      my $found_offset = Fn->rindex($string, $substring, -1, $begin);
      unless ($found_offset == -1) {
        return 0;
      }
    }
    
    {
      my $string = "abcab";
      my $substring = "bca";
      my $begin = 0;
      my $found_offset = Fn->rindex($string, $substring, length $string - 1, $begin);
      unless ($found_offset == 1) {
        return 0;
      }
    }
    {
      my $string = "abcab";
      my $substring = "bca";
      my $begin = 0;
      my $found_offset = Fn->rindex($string, $substring, -1, $begin);
      unless ($found_offset == 1) {
        return 0;
      }
    }

    {
      my $string = "abcab";
      my $substring = "bca";
      my $begin = 0;
      my $end = 3;
      my $found_offset = Fn->rindex($string, $substring, $end, $begin);
      unless ($found_offset == 1) {
        return 0;
      }
    }

    {
      my $string = "abcab";
      my $substring = "bca";
      my $begin = 1;
      my $end = 3;
      my $found_offset = Fn->rindex($string, $substring, $end, $begin);
      unless ($found_offset == 1) {
        return 0;
      }
    }

    {
      my $string = "abcab";
      my $substring = "bca";
      my $begin = 2;
      my $end = 2;
      my $found_offset = Fn->rindex($string, $substring, $end, $begin);
      unless ($found_offset == -1) {
        return 0;
      }
    }
    
    {
      my $string = "abcab";
      my $substring = "bca";
      my $begin = 2;
      my $found_offset = Fn->rindex($string, $substring, length $string - 1, $begin);
      unless ($found_offset == -1) {
        return 0;
      }
    }
    
    # Exception
    {
      {
        my $string = (string)undef;
        my $substring = "bcd";
        eval { Fn->rindex(undef, $substring); };
        unless (Fn->contains($@, "The string \$string must be defined")) {
          return 0;
        }
      }
      
      {
        my $string = "abcde";
        my $substring = (string)undef;
        eval { Fn->rindex($string, $substring); };
        unless (Fn->contains($@, "The substring \$substring must be defined")) {
          return 0;
        }
      }
      
      {
        my $string = "abcde";
        my $substring = "bcd";
        eval { Fn->rindex($string, $substring, -1, -1); };
        unless (Fn->contains($@, "The begin \$begin must be between 0 and the length of the string \$string")) {
          return 0;
        }
      }
      
      {
        my $string = "abcde";
        my $substring = "bcd";
        eval { Fn->rindex($string, $substring, length $string, -1); };
        unless (Fn->contains($@, "The begin \$begin must be between 0 and the length of the string \$string")) {
          return 0;
        }
      }
      
      {
        my $string = "abcde";
        my $substring = "bcd";
        eval { Fn->rindex($string, $substring, length $string + 1, 0); };
        unless (Fn->contains($@, "The end \$end must be less than or equal to the length of the string \$string")) {
          return 0;
        }
      }
      
      {
        my $string = "abcde";
        my $substring = "bcd";
        my $begin = 2;
        my $end = 1;
        eval { Fn->rindex($string, $substring, $end, $begin); };
        unless (Fn->contains($@, "The end \$end must be greater than or equal to the begin \$begin")) {
          return 0;
        }
      }
      
    }
    
    return 1;
  }
  
  static method sizeof_native_int : int () {
    
    my $value = Fn->sizeof_native_int;
    
    unless ($value == 4) {
      return 0;
    }
    
    return 1;
  }
  
  static method shorten : int () {
    
    # Basic
    {
      my $string = copy "abc";
      
      Fn->shorten((mutable string)$string, 2);
      
      unless ($string eq "ab") {
        return 0;
      }
      
      Fn->shorten((mutable string)$string, 0);
      
      unless ($string eq "") {
        return 0;
      }
    }
    
    {
      my $string = copy "";
      
      Fn->shorten((mutable string)$string, 0);
      
      unless ($string eq "") {
        return 0;
      }
    }
    
    {
      my $string = copy "";
      
      Fn->shorten((mutable string)$string, 1);
      
      unless ($string eq "") {
        return 0;
      }
    }
    
    # Bad cases
    {
      my $string = copy "abc";
      
      Fn->shorten((mutable string)$string, 4);
      
      unless ($string eq "abc") {
        return 0;
      }
      
      eval { Fn->shorten((mutable string)$string, -1); };
      
      unless ($@) {
        return 0;
      }
    }
    
    # undef
    {
      my $string = (string)undef;
      
      eval { Fn->shorten((mutable string)$string, 2); };
      
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }

  static method shorten_null_char : int () {
    
    # Contain \0
    {
      my $string = copy "abc\0def";
      
      Fn->shorten_null_char((mutable string)$string);
      
      unless ($string eq "abc") {
        return 0;
      }
    }
    {
      my $string = copy "abc\0def\0ghi";
      
      Fn->shorten_null_char((mutable string)$string);
      
      unless ($string eq "abc") {
        return 0;
      }
    }
    {
      my $string = copy "\0";
      
      Fn->shorten_null_char((mutable string)$string);
      
      unless ($string eq "") {
        return 0;
      }
    }
    
    # Don't contain \0
    {
      my $string = copy "abc";
      
      Fn->shorten_null_char((mutable string)$string);
      
      unless ($string eq "abc") {
        return 0;
      }
    }
    {
      my $string = copy "";
      
      Fn->shorten_null_char((mutable string)$string);
      
      unless ($string eq "") {
        return 0;
      }
    }
    
    # Exception
    {
      my $string = (string)undef;
      
      eval { Fn->shorten_null_char((mutable string)$string); };
      
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method split : int () {
    
    {
      my $string = "foo,bar,baz";
      my $splited_strings = Fn->split(",", $string);
      unless (Array->equals_string($splited_strings, ["foo", "bar", "baz"])) {
        return 0;
      }
    }
    
    {
      my $string = "foo,bar,";
      my $splited_strings = Fn->split(",", $string);
      unless (Array->equals_string($splited_strings, ["foo", "bar"])) {
        return 0;
      }
    }
    
    {
      my $string = ",foo,,bar,,";
      my $splited_strings = Fn->split(",", $string);
      unless (Array->equals_string($splited_strings, ["", "foo", "", "bar"])) {
        return 0;
      }
    }
    
    {
      my $string = "foo : bar : baz";
      my $splited_strings = Fn->split(" : ", $string);
      unless (Array->equals_string($splited_strings, ["foo", "bar", "baz"])) {
        return 0;
      }
    }
    {
      my $string = "foo : bar : ";
      my $splited_strings = Fn->split(" : ", $string);
      unless (Array->equals_string($splited_strings, ["foo", "bar"])) {
        return 0;
      }
    }
    {
      my $string = " : foo :  : bar :  : ";
      my $splited_strings = Fn->split(" : ", $string);
      unless (Array->equals_string($splited_strings, ["", "foo", "", "bar"])) {
        return 0;
      }
    }
    
    {
      my $string = "foo---bar---baz";
      my $splited_strings = Fn->split("---", $string);
      unless (Array->equals_string($splited_strings, ["foo", "bar", "baz"])) {
        return 0;
      }
    }
    {
      my $string = "foo---bar---";
      my $splited_strings = Fn->split("---", $string);
      unless (Array->equals_string($splited_strings, ["foo", "bar"])) {
        return 0;
      }
    }
    {
      my $string = "---foo------bar------";
      my $splited_strings = Fn->split("---", $string);
      unless (Array->equals_string($splited_strings, ["", "foo", "", "bar"])) {
        return 0;
      }
    }
    
    {
      my $string = "foo--!bar---baz";
      my $splited_strings = Fn->split("---", $string);
      unless (Array->equals_string($splited_strings, ["foo--!bar", "baz"])) {
        return 0;
      }
    }

    {
      my $string = "foo,bar,baz";
      my $splited_strings = Fn->split(",", $string, -1);
      unless (Array->equals_string($splited_strings, ["foo", "bar", "baz"])) {
        return 0;
      }
    }
    {
      my $string = "foo,bar,baz";
      my $splited_strings = Fn->split(",", $string);
      unless (Array->equals_string($splited_strings, ["foo", "bar", "baz"])) {
        return 0;
      }
    }
    
    {
      my $string = "foo,bar,";
      my $splited_strings = Fn->split(",", $string, -1);
      unless (Array->equals_string($splited_strings, ["foo", "bar", ""])) {
        return 0;
      }
    }
    
    {
      my $string = ",foo,,bar,,";
      my $splited_strings = Fn->split(",", $string, -1);
      unless (Array->equals_string($splited_strings, ["", "foo", "", "bar", "", ""])) {
        return 0;
      }
    }
    
    {
      my $string = "foo : bar : baz";
      my $splited_strings = Fn->split(" : ", $string, -1);
      unless (Array->equals_string($splited_strings, ["foo", "bar", "baz"])) {
        return 0;
      }
    }
    {
      my $string = "foo : bar : ";
      my $splited_strings = Fn->split(" : ", $string, -1);
      unless (Array->equals_string($splited_strings, ["foo", "bar", ""])) {
        return 0;
      }
    }
    {
      my $string = " : foo :  : bar :  : ";
      my $splited_strings = Fn->split(" : ", $string, -1);
      unless (Array->equals_string($splited_strings, ["", "foo", "", "bar", "", ""])) {
        return 0;
      }
    }
    
    {
      my $string = "foo---bar---baz";
      my $splited_strings = Fn->split("---", $string, -1);
      unless (Array->equals_string($splited_strings, ["foo", "bar", "baz"])) {
        return 0;
      }
    }
    {
      my $string = "foo---bar---";
      my $splited_strings = Fn->split("---", $string, -1);
      unless (Array->equals_string($splited_strings, ["foo", "bar", ""])) {
        return 0;
      }
    }
    {
      my $string = "---foo------bar------";
      my $splited_strings = Fn->split("---", $string, -1);
      unless (Array->equals_string($splited_strings, ["", "foo", "", "bar", "", ""])) {
        return 0;
      }
    }
    
    {
      my $string = "foo--!bar---baz";
      my $splited_strings = Fn->split("---", $string, -1);
      unless (Array->equals_string($splited_strings, ["foo--!bar", "baz"])) {
        return 0;
      }
    }
    
    {
      my $string = "foo,bar,baz";
      my $splited_strings = Fn->split(",", $string, 1);
      unless (Array->equals_string($splited_strings, ["foo,bar,baz"])) {
        return 0;
      }
    }
    
    {
      my $string = "foo,bar,baz";
      my $splited_strings = Fn->split(",", $string, 2);
      unless (Array->equals_string($splited_strings, ["foo", "bar,baz"])) {
        return 0;
      }
    }
    
    {
      my $string = "foo,bar,baz";
      my $splited_strings = Fn->split(",", $string, 3);
      unless (Array->equals_string($splited_strings, ["foo", "bar", "baz"])) {
        return 0;
      }
    }
    
    {
      my $string = "foo,bar,baz";
      my $splited_strings = Fn->split(",", $string, 4);
      unless (Array->equals_string($splited_strings, ["foo", "bar", "baz"])) {
        return 0;
      }
    }
    
    {
      my $string = "";
      my $splited_strings = Fn->split(",", $string);
      unless (Array->equals_string($splited_strings, new string[0])) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        my $sep = (string)undef;
        my $string = "foo,bar,baz";
        my $limit = -1;
        eval {
          Fn->split($sep, $string, $limit);
        };
        unless (Fn->contains($@, "The separator \$separator must be defined")) {
          return 0;
        }
      }
      
      {
        my $sep = ",";
        my $string = (string)undef;
        my $limit = -1;
        eval {
          Fn->split($sep, $string, $limit);
        };
        unless (Fn->contains($@, "The string \$string must be defined")) {
          return 0;
        }
      }
      
      {
        my $sep = "";
        my $string = "foo,bar,baz";
        my $limit = -1;
        eval {
          Fn->split($sep, $string, $limit);
        };
        unless (Fn->contains($@, "The length of the separator \$separator must be greater than 0")) {
          return 0;
        }
      }
    }

    return 1;
  }
  
  static method substr : int () {
    
    {
      my $string = "abcde";
      my $substring = Fn->substr($string, 0, 5);
      unless ($substring eq "abcde") {
        return 0;
      }
    }
    
    {
      my $string = "abcde";
      my $substring = Fn->substr($string, 2, 3);
      unless ($substring eq "cde") {
        return 0;
      }
    }

    {
      my $string = "abcde";
      my $substring = Fn->substr($string, 2, -1);
      unless ($substring eq "cde") {
        return 0;
      }
    }

    {
      my $string = "abcde";
      my $substring = Fn->substr($string, 2);
      unless ($substring eq "cde") {
        return 0;
      }
    }
    
    {
      my $string = "abcde";
      my $replaced = Fn->substr($string, 1, 2, "XYZ");
      
      unless ($replaced eq "aXYZde") {
        return 0;
      }
    }
    
    {
      eval { Fn->substr(undef, 0); };
      unless (Fn->contains($@, "The string \$string must be defined")) {
        return 0;
      }
    }
    
    {
      eval { Fn->substr("a", -1); };
      unless (Fn->contains($@, "The offset \$offset must be greater than or equal to 0")) {
        return 0;
      }
    }
    
    {
      eval { Fn->substr("abc", 1, 3); };
      unless (Fn->contains($@, "The offset \$offset + the length \$length must be less than or equal to the length of the string \$string")) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method to_utf8_chars : int () {
    {
      my $string = "あいうa";
      my $utf8_chars = Fn->to_utf8_chars($string);
      unless (Array->equals_string($utf8_chars, ["あ", "い", "う", "a"])) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method to_double : int () {
    # 10 digit minimal and return type is int
    {
      my $string = "1.25";
      my $num = Fn->to_double($string);
      unless ($num isa double) {
        return 0;
      }
      
      unless ($num == 1.25) {
        return 0;
      }
    }
   
    # Exceptions
    {
      {
        eval {
          Fn->to_double(undef);
        };
        unless (Fn->contains($@, "The string \$string must be defined")) {
          return 0;
        }
      }
      
      # Invalid string format
      {
        my $string = "10oppp";
        eval {
          Fn->to_double($string);
        };
        unless (Fn->contains($@, "The string \$string must be the string that can be parsed as a double number")) {
          return 0;
        }
      }
      
      # Invalid digit
      {
        my $string = "A";
        eval {
          Fn->to_double($string);
        };
        unless (Fn->contains($@, "The string \$string must be the string that can be parsed as a double number")) {
          return 0;
        }
      }
    }
    
    # Extra
    {
      unless (Fn->to_double("1.000") == 1.000) {
        return 0;
      }
      
      unless (Fn->to_double("2.000") == 2) {
        return 0;
      }
      unless (Fn->to_double("1.001") == 1.001) {
        return 0;
      }
      unless (Fn->to_double("1.100") == 1.100) {
        return 0;
      }
      unless (Fn->to_double("1.100") == 1.1) {
        return 0;
      }
      unless (Fn->to_double("1.1") == 1.100) {
        return 0;
      }
      unless (Fn->to_double("1.999") == 1.999) {
        return 0;
      }
      unless (Fn->to_double("1.001002") > 1.001) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method to_float : int () {
    # 10 digit minimal and return type is int
    {
      my $string = "1.25";
      my $num = Fn->to_float($string);
      unless ($num isa float) {
        return 0;
      }
      
      unless ($num == 1.25) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        eval {
          Fn->to_float(undef);
        };
        unless (Fn->contains($@, "The string \$string must be defined")) {
          return 0;
        }
      }
      
      # Invalid string format
      {
        my $string = "10oppp";
        eval {
          Fn->to_float($string);
        };
        unless (Fn->contains($@, "The string \$string must be the string that can be parsed as a float number")) {
          return 0;
        }
      }
      
      # Invalid digit
      {
        my $string = "A";
        eval {
          Fn->to_float($string);
        };
        unless (Fn->contains($@, "The string \$string must be the string that can be parsed as a float number")) {
          return 0;
        }
      }
    }
    
    $@ = undef;
    return 1;
  }
  
  static method to_int : int () {
    # 10 digit minimal and return type is int
    {
      my $string = "-2147483648";
      my $num = Fn->to_int($string);
      unless ($num isa int) {
        return 0;
      }
      
      unless ($num == -2147483648) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method to_int_with_base : int () {
    # 10 digit minimal and return type is int
    {
      my $string = "-2147483648";
      my $num = Fn->to_int_with_base($string, 10);
      unless ($num isa int) {
        return 0;
      }
      
      unless ($num == -2147483648) {
        return 0;
      }
    }
    
    # 10 digit max
    {
      my $string = "2147483647";
      my $num = Fn->to_int_with_base($string, 10);
      unless ($num isa int) {
        return 0;
      }
      
      unless ($num == 2147483647) {
        return 0;
      }
    }
    
    # 2 digit
    {
      my $string = "11";
      my $num = Fn->to_int_with_base($string, 2);
      
      unless ($num == 3) {
        return 0;
      }
    }
    
    # 8 digit
    {
      my $string = "11";
      my $num = Fn->to_int_with_base($string, 8);
      
      unless ($num == 9) {
        return 0;
      }
    }
    
    # 16 digit
    {
      my $string = "FF";
      my $num = Fn->to_int_with_base($string, 16);
      
      unless ($num == 255) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        eval {
          Fn->to_int_with_base(undef, 10);
        };
        unless (Fn->contains($@, "The string \$string must be defined")) {
          return 0;
        }
      }
      
      {
        my $string = "10";
        eval {
          Fn->to_int_with_base($string, 9);
        };
        unless (Fn->contains($@, "The digit \$digit must be one of 2, 8, 10, or 16")) {
          return 0;
        }
      }
      
      # Invalid string format
      {
        my $string = "10oppp";
        eval {
          Fn->to_int_with_base($string, 10);
        };
        unless (Fn->contains($@, "The string \$string must be the string that can be parsed as a 10-digit 32-bit integer")) {
          return 0;
        }
      }
      
      # Invalid digit
      {
        my $string = "A";
        eval {
          Fn->to_int_with_base($string, 10);
        };
        unless (Fn->contains($@, "The string \$string must be the string that can be parsed as a 10-digit 32-bit integer")) {
          return 0;
        }
      }
      
      # Out of range max + 1
      {
        my $string = "2147483648";
        eval {
          Fn->to_int_with_base($string, 10);
        };
        unless (Fn->contains($@, "The string \$string must be a 32-bit integer in correct range")) {
          return 0;
        }
      }
      
      # Out of range min - 1
      {
        my $string = "-2147483649";
        eval {
          Fn->to_int_with_base($string, 10);
        };
        unless (Fn->contains($@, "The string \$string must be a 32-bit integer in correct range")) {
          return 0;
        }
      }
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method to_long : int () {
    # 10 digit minimal and return type is int
    {
      my $string = "-9223372036854775808";
      my $num = Fn->to_long($string);
      unless ($num isa long) {
        return 0;
      }
      
      unless ($num == -9223372036854775808L) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method to_long_with_base : int () {
    # 10 digit minimal and return type is int
    {
      my $string = "-9223372036854775808";
      my $num = Fn->to_long_with_base($string, 10);
      unless ($num isa long) {
        return 0;
      }
      
      unless ($num == -9223372036854775808L) {
        return 0;
      }
    }
    
    # 10 digit max
    {
      my $string = "9223372036854775807";
      my $num = Fn->to_long_with_base($string, 10);
      
      unless ($num == 9223372036854775807L) {
        return 0;
      }
    }
    
    # 2 digit
    {
      my $string = "11";
      my $num = Fn->to_long_with_base($string, 2);
      
      unless ($num == 3) {
        return 0;
      }
    }
    
    # 8 digit
    {
      my $string = "11";
      my $num = Fn->to_long_with_base($string, 8);
      
      unless ($num == 9) {
        return 0;
      }
    }
    
    # 16 digit
    {
      my $string = "FF";
      my $num = Fn->to_long_with_base($string, 16);
      
      unless ($num == 255) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        eval {
          Fn->to_long_with_base(undef, 10);
        };
        unless (Fn->contains($@, "The string \$string must be defined")) {
          return 0;
        }
      }
      
      {
        my $string = "10";
        eval {
          Fn->to_long_with_base($string, 9);
        };
        unless (Fn->contains($@, "The digit \$digit must be one of 2, 8, 10, or 16")) {
          return 0;
        }
      }
      
      # Invalid string format
      {
        my $string = "10oppp";
        eval {
          Fn->to_long_with_base($string, 10);
        };
        unless (Fn->contains($@, "The string \$string must be the string that can be parsed as a 10-digit 64-bit integer")) {
          return 0;
        }
      }
      
      # Invalid digit
      {
        my $string = "A";
        eval {
          Fn->to_long_with_base($string, 10);
        };
        unless (Fn->contains($@, "The string \$string must be the string that can be parsed as a 10-digit 64-bit integer")) {
          return 0;
        }
      }
      
      # Out of range max + 1
      {
        my $string = "9223372036854775808";
        eval {
          Fn->to_long_with_base($string, 10);
        };
        unless (Fn->contains($@, "The string \$string must be a 64-bit integer in correct range")) {
          return 0;
        }
      }
      
      # Out of range min - 1
      {
        my $string = "-9223372036854775809";
        eval {
          Fn->to_long_with_base($string, 10);
        };
        unless (Fn->contains($@, "The string \$string must be a 64-bit integer in correct range")) {
          return 0;
        }
      }
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method to_lower : int () {
    
    my $ok = 1;
    for (my $i = 0; $i < 128; $i++) {
      my $char = $i;
      
      if ($char >= 'A' && $char <= 'Z') {
        my $ret = Fn->to_lower($char);
        unless ($ret == $char + 0x20) {
          $ok = 0;
        }
      }
      else {
        my $ret = Fn->to_lower($char);
        unless ($ret == $char) {
          $ok = 0;
        }
      }
    }
    
    unless ($ok) {
      return 0;
    }
    
    return 1;
  }
  
  static method to_upper : int () {
   
    my $ok = 1;
    for (my $i = 0; $i < 128; $i++) {
      my $char = $i;
      
      if ($char >= 'a' && $char <= 'z') {
        my $ret = Fn->to_upper($char);
        unless ($ret == $char - 0x20) {
          $ok = 0;
        }
      }
      else {
        my $ret = Fn->to_upper($char);
        unless ($ret == $char) {
          $ok = 0;
        }
      }
    }
    
    unless ($ok) {
      return 0;
    }
    
    return 1;
  }
  
  static method to_code_points : int () {
   
    {
      my $string = "あいうa";
      my $code_points = Fn->to_code_points($string);
      unless (Array->equals_int($code_points, [12354, 12356, 12358, 97])) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method tr : int () {

    {
      my $string = "a";
      my $pattern = "a";
      my $replace = "b";
      
      my $ret = Fn->tr($string, $pattern, $replace);
      unless ($ret eq "b") {
        return 0;
      }
    }
    
    {
      my $string = "a";
      my $pattern = "c";
      my $replace = "b";
      
      my $ret = Fn->tr($string, $pattern, $replace);
      unless ($ret eq "a") {
        return 0;
      }
    }

    {
      my $string = "ab";
      my $pattern = "a-b";
      my $replace = "x-y";
      
      my $ret = Fn->tr($string, $pattern, $replace);
      unless ($ret eq "xy") {
        return 0;
      }
    }

    {
      my $string = "-";
      my $pattern = "---";
      my $replace = "b";
      
      my $ret = Fn->tr($string, $pattern, $replace);
      
      unless ($ret eq "b") {
        return 0;
      }
    }

    {
      my $string = "aa";
      my $pattern = "a";
      my $replace = "b";
      
      my $ret = Fn->tr($string, $pattern, $replace);
      unless ($ret eq "bb") {
        return 0;
      }
    }

    {
      my $string = "";
      my $pattern = "a";
      my $replace = "b";
      
      my $ret = Fn->tr($string, $pattern, $replace);
      unless ($ret eq "") {
        return 0;
      }
    }

    {
      my $string = "abcd";
      my $pattern = "a-c";
      my $replace = "x-z";
      
      my $ret = Fn->tr($string, $pattern, $replace);
      
      unless ($ret eq "xyzd") {
        return 0;
      }
    }

    {
      my $string = "0123456789";
      my $pattern = "0-9";
      my $replace = "0-9";
      
      my $ret = Fn->tr($string, $pattern, $replace);
      
      unless ($ret eq "0123456789") {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method trim : int () {
    
    # no left and right spaces
    {
      my $string = (string)"ab  c";
      my $trimed_string = Fn->trim($string);
      unless ($trimed_string eq "ab  c") {
        return 0;
      }
    }
    
    # left spaces
    {
      my $string = (string)"  \t  \nab  c";
      my $trimed_string = Fn->trim($string);
      unless ($trimed_string eq "ab  c") {
        return 0;
      }
    }
    
    # right spaces
    {
      my $string = (string)"ab  c  \t  \n";
      my $trimed_string = Fn->trim($string);
      unless ($trimed_string eq "ab  c") {
        return 0;
      }
    }
    
    # left and right spaces
    {
      my $string = (string)"  \t  \nab  c  \t  \n";
      my $trimed_string = Fn->trim($string);
      unless ($trimed_string eq "ab  c") {
        return 0;
      }
    }
    
    # Exception
    {
      eval { Fn->trim(undef); };
      unless (Fn->contains($@, "The string \$string must be defined")) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method uc : int () {
    {
      my $string = "@[apz[";
      my $result_str = Fn->uc($string);
      unless ($result_str eq "@[APZ[") {
        return 0;
      }
    }
    
    # Exception
    {
      eval { Fn->uc(undef); };
      unless (Fn->contains($@, "The string \$string must be defined")) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method ucfirst : int () {
    {
      my $string = "@abc";
      my $result_str = Fn->ucfirst($string);
      unless ($result_str eq "@abc") {
        return 0;
      }
    }
    {
      my $string = "[abc";
      my $result_str = Fn->ucfirst($string);
      unless ($result_str eq "[abc") {
        return 0;
      }
    }
    
    {
      my $string = "aabc";
      my $result_str = Fn->ucfirst($string);
      unless ($result_str eq "Aabc") {
        return 0;
      }
    }
    
    {
      my $string = "pabc";
      my $result_str = Fn->ucfirst($string);
      unless ($result_str eq "Pabc") {
        return 0;
      }
    }
    
    {
      my $string = "zabc";
      my $result_str = Fn->ucfirst($string);
      unless ($result_str eq "Zabc") {
        return 0;
      }
    }
    
    # Exception
    {
      eval { Fn->ucfirst(undef); };
      unless (Fn->contains($@, "The string \$string must be defined")) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }

  static method utf8_length : int () {
    {
      my $string = "あいうa";
      my $utf8_length = Fn->utf8_length($string);
      unless ($utf8_length == 4) {
        return 0;
      }
    }
    
    return 1;
  }

  static method utf8_substr : int () {
    
    {
      my $string = "あいうえお";
      my $utf8_substring = Fn->utf8_substr($string, 0, 5);
      unless ($utf8_substring eq "あいうえお") {
        return 0;
      }
    }
    
    {
      my $string = "あいうえお";
      my $utf8_substring = Fn->utf8_substr($string, 2, 3);
      unless ($utf8_substring eq "うえお") {
        return 0;
      }
    }

    {
      my $string = "あいうえお";
      my $utf8_substring = Fn->utf8_substr($string, 2, -1);
      unless ($utf8_substring eq "うえお") {
        return 0;
      }
    }

    {
      my $string = "あいうえお";
      my $utf8_substring = Fn->utf8_substr($string, 2);
      unless ($utf8_substring eq "うえお") {
        return 0;
      }
    }
    {
      eval { Fn->utf8_substr(undef, 0); };
      unless (Fn->contains($@, "The string \$string must be defined")) {
        return 0;
      }
    }
    
    {
      eval { Fn->utf8_substr("あ", -1); };
      unless (Fn->contains($@, "The offset \$utf8_offset must be greater than or equal to 0")) {
        return 0;
      }
    }
    {
      eval { Fn->utf8_substr("あいう", 1, 3); };
      unless (Fn->contains($@, "The offset \$utf8_offset + the length \$utf8_length must be less than or equal to the UTF-8 length of the string \$string")) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }

  static method merge_options : int () {
    
    {
      my $merged_options = Fn->merge_options({key1 => 1, key2 => 2}, {key3 => "abc", key4 => "def"});
      unless (@$merged_options == 8) {
        return 0;
      }
      
      Sort->sort_options_asc($merged_options);
      
      unless ($merged_options->[0]->(string) eq "key1") {
        return 0;
      }
      
      unless ($merged_options->[1]->(int) == 1) {
        return 0;
      }
      unless ($merged_options->[2]->(string) eq "key2") {
        return 0;
      }
      unless ($merged_options->[3]->(int) == 2) {
        return 0;
      }
      unless ($merged_options->[4]->(string) eq "key3") {
        return 0;
      }
      unless ($merged_options->[5]->(string) eq "abc") {
        return 0;
      }
      unless ($merged_options->[6]->(string) eq "key4") {
        return 0;
      }
      unless ($merged_options->[7]->(string) eq "def") {
        return 0;
      }
    }
    
    {
      my $merged_options = Fn->merge_options({key1 => 1, key2 => 2}, {key2 => "abc", key4 => "def"});
      unless (@$merged_options == 8) {
        return 0;
      }
      
      Sort->sort_options_asc($merged_options);
      
      unless ($merged_options->[0]->(string) eq "key1") {
        return 0;
      }
      
      unless ($merged_options->[1]->(int) == 1) {
        return 0;
      }
      unless ($merged_options->[2]->(string) eq "key2") {
        return 0;
      }
      unless ($merged_options->[3]->(int) == 2) {
        return 0;
      }
      unless ($merged_options->[4]->(string) eq "key2") {
        return 0;
      }
      unless ($merged_options->[5]->(string) eq "abc") {
        return 0;
      }
      unless ($merged_options->[6]->(string) eq "key4") {
        return 0;
      }
      unless ($merged_options->[7]->(string) eq "def") {
        return 0;
      }
    }
    
    {
      my $merged_options = Fn->merge_options(undef, undef);
      
      unless (@$merged_options == 0) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        eval { Fn->merge_options(["a"], {}); };
        unless (Fn->contains($@, "The length of the options1 \$options1 must be an even number")) {
          return 0;
        }
      }
      {
        eval { Fn->merge_options({}, ["a"]); };
        unless (Fn->contains($@, "The length of the options2 \$options2 must be an even number")) {
          return 0;
        }
      }
    }
    
    $@ = undef;
    
    return 1;
  }

  static method object_to_int : int () {
    
    {
      my $int = Fn->object_to_int(Int->new(1));
      unless ($int isa int) {
        return 0;
      }
      if ($int == 0) {
        return 0;
      }
    }
    
    {
      my $int = Fn->object_to_int(undef);
      
      unless ($int == 0) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method object_to_long : int () {
    
    {
      my $long = Fn->object_to_long(Int->new(1));
      unless ($long isa long) {
        return 0;
      }
      if ($long == 0) {
        return 0;
      }
    }
    
    {
      my $long = Fn->object_to_long(undef);
      unless ($long == 0) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method get_version_string : int () {
    
    {
      my $version_string = Fn->get_version_string("TestCase::Minimal");
      unless ($version_string eq "1.001") {
        return 0;
      }
    }
    
    {
      my $version_string = Fn->get_version_string("TestCase::Simple");
      unless ($version_string eq "1.001009000") {
        return 0;
      }
    }
    
    {
      my $version_string = Fn->get_version_string("TestCase::Empty");
      
      if ($version_string) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        eval { Fn->get_version_string(undef); };
        unless (Fn->contains($@, "The basic type name \$basic_type_name must be defined")) {
          return 0;
        }
      }
      {
        eval { Fn->get_version_string("NotFoundClass"); };
        unless (Fn->contains($@, "The class specified by the basic type name \$basic_type_name must be loaded")) {
          return 0;
        }
      }
      
      $@ = undef;
    }
    
    # Extra
    {
      {
        unless (Fn->get_version_string("SPVM") eq Fn->get_spvm_version_string) {
          return 0;
        }
      }
    }
    
    return 1;
  }
  
  static method get_version_number : int () {
    
    {
      my $version_number = Fn->get_version_number("TestCase::Minimal");
      unless ($version_number == 1.001) {
        return 0;
      }
    }
    
    {
      my $version_number = Fn->get_version_number("TestCase::Simple");
      unless ($version_number == 1.001009) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method defer : int () {
    
    # Executing the callback at the end of the scope
    {
      my $string = (mutable string)copy "abc";
      {
        my $callback = [has string : mutable string = $string] method : void () {
          my $string = $self->{string};
          
          $string->[0] = 'A';
          $string->[1] = 'B';
        };
        my $guard = Fn->defer($callback);
        
        unless ($callback == $guard->callback) {
          return 0;
        }
        
        $string->[0] = 'P';
      }
      
      unless ($string eq "ABc") {
        return 0;
      }
    }
    
    # Executing the callback at the end of the scope
    {
      my $string = (mutable string)copy "abc";
      
      {
        # Temporary local variable is created if the instance is not assigned to a local variable.
        Fn->defer([has string : mutable string = $string] method : void () {
          my $string = $self->{string};
          
          $string->[0] = 'A';
          $string->[1] = 'B';
        });
        
        $string->[0] = 'P';
      }
      
      unless ($string eq "ABc") {
        return 0;
      }
    }
    
    # Exceptions
    {
      my $callback : Callback;
      eval { Fn->defer($callback); } ;
      unless (Fn->contains($@, "The callback \$callback must be defined")) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method get_memory_blocks_count : int () {
    
    my $memory_blocks_count_start = Fn->get_memory_blocks_count;
    {
      my $point = Point->new;
      
      
      my $memory_blocks_count_current = Fn->get_memory_blocks_count;
      
      unless ($memory_blocks_count_current > $memory_blocks_count_start) {
        return 0;
      }
    }
    
    my $memory_blocks_count_end = Fn->get_memory_blocks_count;
    
    unless ($memory_blocks_count_end == $memory_blocks_count_start) {
      return 0;
    }
    
    return 1;
  }
  
  static method to_address : int () {
    
    {
      my $point = Point->new;
      
      unless (Fn->to_address($point) eq Format->sprintf("%p", [(object)$point])) {
        return 0;
      }
      
    }
    
    {
      my $point = (Point)undef;
      
      unless (Fn->to_address($point) eq Format->sprintf("%p", [(object)$point])) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method check_option_names : int () {
    
    {
      my $available_option_names = ["foo", "bar", "baz"];
      
      Fn->check_option_names(undef, $available_option_names);
    }
    
    {
      my $options = {foo => undef, bar => undef};
      
      my $available_option_names = ["foo", "bar", "baz"];
      
      Fn->check_option_names($options, $available_option_names);
    }
    
    {
      my $options = {foo => 1, bar => 2};
      
      my $available_option_names = ["foo"];
      
      eval { Fn->check_option_names($options, $available_option_names); }
      
      unless (Fn->contains($@, "The \"bar\" option is not available.")) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method get_basic_type_id : int () {
    
    {
      my $basic_type_name = "Error";
      my $basic_type_id = Fn->get_basic_type_id($basic_type_name);
      
      unless ($basic_type_id == 18) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        eval { Fn->get_basic_type_id(undef); }
        
        unless (Fn->contains($@, "The basic type name \$basic_type_name must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { Fn->get_basic_type_id("NotExists::XXXXXXXXX"); }
        
        unless (Fn->contains($@, "The basic type \"NotExists::XXXXXXXXX\" is not found.")) {
          return 0;
        }
      }
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method memset_char : int () {
    
    # Basic
    {
      my $string = (mutable string)copy "abcd";
      my $offset = 1;
      my $length = 2;
      my $new_char = 'e';
      Fn->memset_char($string, $new_char, $offset, $length);
      unless ($string eq "aeed") {
        return 0;
      }
    }
    
    # Zero length
    {
      my $string = (mutable string)copy "abcd";
      my $offset = 1;
      my $length = 0;
      my $new_char = 'e';
      Fn->memset_char($string, $new_char, $offset, $length);
      unless ($string eq "abcd") {
        return 0;
      }
    }
    
    # All
    {
      my $string = (mutable string)copy "abcd";
      my $offset = 0;
      my $length = length $string;
      my $new_char = 'e';
      Fn->memset_char($string, $new_char, $offset, $length);
      unless ($string eq "eeee") {
        return 0;
      }
    }
    
    {
      my $string = (mutable string)copy "abcd";
      my $offset = 0;
      my $length = -1;
      my $new_char = 'e';
      Fn->memset_char($string, $new_char, $offset, $length);
      unless ($string eq "eeee") {
        return 0;
      }
    }
    
    {
      my $string = (mutable string)copy "abcd";
      my $offset = 0;
      my $new_char = 'e';
      Fn->memset_char($string, $new_char, $offset);
      unless ($string eq "eeee") {
        return 0;
      }
    }
    
    {
      my $string = (mutable string)copy "abcd";
      my $new_char = 'e';
      Fn->memset_char($string, $new_char);
      unless ($string eq "eeee") {
        return 0;
      }
    }
    
    # Exception
    {
      {
        eval { Fn->memset_char(undef, 0, 0, 3); };
        unless (Fn->contains($@, "The string \$string must be defined")) {
          return 0;
        }
      }
      
      {
        my $dest = (mutable string)copy "abcd";
        eval { Fn->memset_char($dest, 0, -1, 3); };
        unless (Fn->contains($@, "The offset \$offset must be greater than or equal to 0")) {
          return 0;
        }
      }
      
      {
        my $dest = (mutable string)copy "abcd";
        eval { Fn->memset_char($dest, 0, 2, 3); };
        unless (Fn->contains($@, "The offset \$offset + the length \$length must be less than or equal to the length of the string \$string")) {
          return 0;
        }
      }
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method or : int () {
    
    {
      my $left = "a";
      my $right = "b";
      
      my $ret = Fn->or($left, $right);
      
      unless ($ret is_compile_type object) {
        return 0;
      }
    }
    
    {
      my $left = "a";
      my $right = "b";
      
      my $ret = Fn->or($left, $right);
      
      unless ($ret == $left) {
        return 0;
      }
    }
    
    {
      my $left = (string)undef;
      my $right = "b";
      
      my $ret = Fn->or($left, $right);
      
      unless ($ret == $right) {
        return 0;
      }
    }
    
    return 1;
  }

  static method if : int () {
    
    {
      my $left = "a";
      my $right = "b";
      
      my $ret = Fn->if(1, $left, $right);
      
      unless ($ret is_compile_type object) {
        return 0;
      }
    }
    
    {
      my $left = "a";
      my $right = "b";
      
      my $ret = Fn->if(1, $left, $right);
      
      unless ($ret == $left) {
        return 0;
      }
    }
    
    {
      my $left = "a";
      my $right = "b";
      
      my $ret = Fn->if(0, $left, $right);
      
      unless ($ret == $right) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method grep : int () {
    
    {
      my $array = ["a", "b", "c"];
      
      my $array_out = (string[])Fn->grep(method : int ($element : object) {
        if ($element->(string) eq "c") {
          return 1;
        }
        else {
          return 0;
        }
      }, $array);
      
      unless (Array->equals_string($array_out, ["c"])) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        eval { Fn->grep(method : int ($array : object) {}, undef); };
        unless (Fn->contains($@, "The array \$array must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { Fn->grep(undef, ["a"]); };
        unless (Fn->contains($@, "The callback \$callback must be defined.")) {
          return 0;
        }
      }
      
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method map : int () {
    
    {
      my $array = ["a", "b", "c"];
      
      my $array_out = (string[])Fn->map(method : object ($element : object) {
        return "a" . $element->(string);
      }, $array);
      
      unless (Array->equals_string($array_out, ["aa", "ab", "ac"])) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        eval { Fn->map(method : object ($array : object) {}, undef); };
        unless (Fn->contains($@, "The array \$array must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { Fn->map(undef, ["a"]); };
        unless (Fn->contains($@, "The callback \$callback must be defined.")) {
          return 0;
        }
      }
      
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method map_expand : int () {
    
    {
      my $array = ["a", "b", "c"];
      
      my $array_out = (string[])Fn->map_expand(method : object[] ($element : object) {
        return ["a" . $element->(string), "b" . $element->(string)];
      }, $array);
      
      unless (Array->equals_string($array_out, ["aa", "ba", "ab", "bb", "ac", "bc"])) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        eval { Fn->map_expand(method : object[] ($array : object) {}, undef); };
        unless (Fn->contains($@, "The array \$array must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { Fn->map_expand(undef, ["a"]); };
        unless (Fn->contains($@, "The callback \$callback must be defined.")) {
          return 0;
        }
      }
      
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method get_compile_type_name : int () {
    
    {
      {
        my $compile_type_name = Fn->get_compile_type_name("int", 2, 0);
        
        unless ($compile_type_name eq "int[][]") {
          return 0;
        }
      }
      
      {
        my $compile_type_name = Fn->get_compile_type_name("int", 0, 1);
        
        unless ($compile_type_name eq "int*") {
          return 0;
        }
      }
      
      {
        my $compile_type_name = Fn->get_compile_type_name("string", 0, 2);
        
        unless ($compile_type_name eq "mutable string") {
          return 0;
        }
      }
      
    }
    
    # Exceptions
    {
      {
        eval { Fn->get_compile_type_name(undef, 0, 0); }
        unless (Fn->contains($@, "The basic type name \$basic_type_name must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { Fn->get_compile_type_name("int", -1, 0); }
        unless (Fn->contains($@, "The type dimension \$type_dimension must be grether than or equal to 0 and less than or equal to 255.")) {
          return 0;
        }
      }
      
      {
        eval { Fn->get_compile_type_name("int", 256, 0); }
        unless (Fn->contains($@, "The type dimension \$type_dimension must be grether than or equal to 0 and less than or equal to 255.")) {
          return 0;
        }
      }
      
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method is_any_numeric_array : int () {
    
    # Numeric Array
    {
      unless (Fn->is_any_numeric_array(new byte[3])) {
        return 0;
      }
      
      unless (Fn->is_any_numeric_array(new double[3])) {
        return 0;
      }
    }
    
    # Multi Numeric Array
    {
      unless (Fn->is_any_numeric_array(new Complex_2d[3])) {
        return 0;
      }
    }
    
    # string
    {
      my $string = "abc";
      
      if (Fn->is_any_numeric_array($string)) {
        return 0;
      }
    }
    
    # Object
    {
      my $minimal = TestCase::Minimal->new;
      
      if (Fn->is_any_numeric_array($minimal)) {
        return 0;
      }
    }
    
    # undef
    {
      if (Fn->is_any_numeric_array(undef)) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method array_length : int () {
    
    {
      my $array = new int[3];
      
      my $ret = Fn->array_length($array);
      
      unless ($ret == 3) {
        return 0;
      }
    }
    
    {
      my $array = (object)new int[3];
      
      my $ret = Fn->array_length($array);
      
      unless ($ret == 3) {
        return 0;
      }
    }
    
    {
      my $array = new object[3];
      
      my $ret = Fn->array_length($array);
      
      unless ($ret == 3) {
        return 0;
      }
    }
    
    {
      my $array = new Point[3];
      
      my $ret = Fn->array_length($array);
      
      unless ($ret == 3) {
        return 0;
      }
    }
    
    {
      my $array = new Complex_2d[3];
      
      my $ret = Fn->array_length($array);
      
      unless ($ret == 3) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        my $array = new int[3];
        
        eval { Fn->array_length(undef); }
        
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $array = Point->new;
        
        eval { Fn->array_length($array); }
        
        unless ($@) {
          return 0;
        }
      }
      
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method get_elem_size : int () {
    
    {
      my $array = new byte[3];
      
      my $ret = Fn->get_elem_size($array);
      
      unless ($ret == 1) {
        return 0;
      }
    }
    
    {
      my $array = new short[3];
      
      my $ret = Fn->get_elem_size($array);
      
      unless ($ret == 2) {
        return 0;
      }
    }
    
    {
      my $array = new int[3];
      
      my $ret = Fn->get_elem_size($array);
      
      unless ($ret == 4) {
        return 0;
      }
    }
    
    {
      my $array = new long[3];
      
      my $ret = Fn->get_elem_size($array);
      
      unless ($ret == 8) {
        return 0;
      }
    }
    
    {
      my $array = new float[3];
      
      my $ret = Fn->get_elem_size($array);
      
      unless ($ret == 4) {
        return 0;
      }
    }
    
    {
      my $array = new double[3];
      
      my $ret = Fn->get_elem_size($array);
      
      unless ($ret == 8) {
        return 0;
      }
    }
    
    {
      my $array = (object)new int[3];
      
      my $ret = Fn->get_elem_size($array);
      
      unless ($ret == 4) {
        return 0;
      }
    }
    
    {
      my $array = new object[3];
      
      my $ret = Fn->get_elem_size($array);
      
      unless ($ret == Fn->sizeof_native_pointer) {
        return 0;
      }
    }
    
    {
      my $array = new Point[3];
      
      my $ret = Fn->get_elem_size($array);
      
      unless ($ret == Fn->sizeof_native_pointer) {
        return 0;
      }
    }
    
    {
      my $array = new Complex_2d[3];
      
      my $ret = Fn->get_elem_size($array);
      
      unless ($ret == 16) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        my $array = new int[3];
        
        eval { Fn->get_elem_size(undef); }
        
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $array = Point->new;
        
        eval { Fn->get_elem_size($array); }
        
        unless ($@) {
          return 0;
        }
      }
      
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method get_elem_type_name : int () {
    
    {
      my $array = new int[3];
      
      my $ret = Fn->get_elem_type_name($array);
      
      unless ($ret eq "int") {
        return 0;
      }
    }
    
    {
      my $array = (object)new int[3];
      
      my $ret = Fn->get_elem_type_name($array);
      
      unless ($ret eq "int") {
        return 0;
      }
    }
    
    {
      my $array = new object[3];
      
      my $ret = Fn->get_elem_type_name($array);
      
      unless ($ret eq "object") {
        return 0;
      }
    }
    
    {
      my $array = new Point[3];
      
      my $ret = Fn->get_elem_type_name($array);
      
      unless ($ret eq "Point") {
        return 0;
      }
    }
    
    {
      my $array = new Complex_2d[3];
      
      my $ret = Fn->get_elem_type_name($array);
      
      unless ($ret eq "Complex_2d") {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        my $array = new int[3];
        
        eval { Fn->get_elem_type_name(undef); }
        
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $array = Point->new;
        
        eval { Fn->get_elem_type_name($array); }
        
        unless ($@) {
          return 0;
        }
      }
      
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method memcmp : int () {
    
    {
      # Numeric array
      {
        # byte
        {
          {
            my $data1 = [(byte)1, 2, 3, 5];
            my $data2 = [(byte)1, 2, 3, 4];
            
            my $ret = Fn->memcmp($data1, 0, $data2, 0, 4);
            
            unless ($ret > 0) {
              return 0;
            }
          }
          
          {
            my $data1 = [(byte)1, 2, 3, 4];
            my $data2 = [(byte)1, 2, 3, 4];
            
            my $ret = Fn->memcmp($data1, 0, $data2, 0, 4);
            
            unless ($ret == 0) {
              return 0;
            }
          }
          
          {
            my $data1 = [(byte)1, 2, 3, 3];
            my $data2 = [(byte)1, 2, 3, 4];
            
            my $ret = Fn->memcmp($data1, 0, $data2, 0, 4);
            
            unless ($ret < 0) {
              return 0;
            }
          }
          
          {
            my $data1 = [(byte)5];
            my $data2 = [(byte)4];
            
            my $ret = Fn->memcmp($data1, 0, $data2, 0, 0);
            
            unless ($ret == 0) {
              return 0;
            }
          }
          
        }
        
        # double
        {
          {
            my $data1 = [(double)1, 2, 3, 5];
            my $data2 = [(double)1, 2, 3, 4];
            
            my $ret = Fn->memcmp($data1, 0, $data2, 0, 8 * 4);
            
            unless ($ret > 0) {
              return 0;
            }
          }
          
          {
            my $data1 = [(double)1, 2, 3, 4];
            my $data2 = [(double)1, 2, 3, 4];
            
            my $ret = Fn->memcmp($data1, 0, $data2, 0, 8 * 4);
            
            unless ($ret == 0) {
              return 0;
            }
          }
          
          {
            my $data1 = [(double)1, 2, 3, 3];
            my $data2 = [(double)1, 2, 3, 4];
            
            my $ret = Fn->memcmp($data1, 0, $data2, 0, 8 * 4);
            
            unless ($ret < 0) {
              return 0;
            }
          }
          
        }
      }

      # string
      {
        {
          my $data1 = (string)[(byte)1, 2, 3, 5];
          my $data2 = (string)[(byte)1, 2, 3, 4];
          
          my $ret = Fn->memcmp($data1, 0, $data2, 0, 4);
          
          unless ($ret > 0) {
            return 0;
          }
        }
        
        {
          my $data1 = (string)[(byte)1, 2, 3, 4];
          my $data2 = (string)[(byte)1, 2, 3, 4];
          
          my $ret = Fn->memcmp($data1, 0, $data2, 0, 4);
          
          unless ($ret == 0) {
            return 0;
          }
        }
        
        {
          my $data1 = (string)[(byte)1, 2, 3, 3];
          my $data2 = (string)[(byte)1, 2, 3, 4];
          
          my $ret = Fn->memcmp($data1, 0, $data2, 0, 4);
          
          unless ($ret < 0) {
            return 0;
          }
        }
        
      }
      
      # Multi numeric array
      {
        {
          my $data1 = new Complex_2d[4];
          $data1->[0]{re} = 1;
          $data1->[0]{im} = 2;
          $data1->[2]{re} = 3;
          $data1->[2]{im} = 5;
          
          my $data2 = new Complex_2d[4];
          $data2->[0]{re} = 1;
          $data2->[0]{im} = 2;
          $data2->[2]{re} = 3;
          $data2->[2]{im} = 4;
          
          my $ret = Fn->memcmp($data1, 0, $data2, 0, 2 * 8 * 4);
          
          unless ($ret > 0) {
            return 0;
          }
        }
        
        {
          my $data1 = new Complex_2d[4];
          $data1->[0]{re} = 1;
          $data1->[0]{im} = 2;
          $data1->[2]{re} = 3;
          $data1->[2]{im} = 4;
          
          my $data2 = new Complex_2d[4];
          $data2->[0]{re} = 1;
          $data2->[0]{im} = 2;
          $data2->[2]{re} = 3;
          $data2->[2]{im} = 4;
          
          my $ret = Fn->memcmp($data1, 0, $data2, 0, 2 * 8 * 4);
          
          unless ($ret == 0) {
            return 0;
          }
        }
        
        {
          my $data1 = new Complex_2d[4];
          $data1->[0]{re} = 1;
          $data1->[0]{im} = 2;
          $data1->[2]{re} = 3;
          $data1->[2]{im} = 4;
          
          my $data2 = new Complex_2d[4];
          $data2->[0]{re} = 1;
          $data2->[0]{im} = 2;
          $data2->[2]{re} = 3;
          $data2->[2]{im} = 5;
          
          my $ret = Fn->memcmp($data1, 0, $data2, 0, 2 * 8 * 4);
          
          unless ($ret < 0) {
            return 0;
          }
        }
        
      }
    }
    
    # Copy offset + length
    {
      # int
      {
        {
          my $data1 = [(int)0, 1, 2, 4, 4];
          my $data2 = [(int)0, -1, 1, 2, 3, 4];
          
          my $ret = Fn->memcmp($data1, 1 * 4, $data2, 2 * 4, 3 * 4);
          
          unless ($ret > 0) {
            return 0;
          }
        }
        
        {
          my $data1 = [(int)0, 1, 2, 3, 4];
          my $data2 = [(int)0, -1, 1, 2, 3, 5];
          
          my $ret = Fn->memcmp($data1, 1 * 4, $data2, 2 * 4, 3 * 4);
          
          unless ($ret == 0) {
            return 0;
          }
        }
        
        {
          my $data1 = [(int)0, 1, 2, 3, 3];
          my $data2 = [(int)0, -1, 1, 2, 4, 4];
          
          my $ret = Fn->memcmp($data1, 1 * 4, $data2, 2 * 4, 3 * 4);
          
          unless ($ret < 0) {
            return 0;
          }
        }
      }
    }
    
    # Exception
    {
      # Exception - Destnation must be defined
      {
        my $data2 = [(byte)1, 3, 5];
        eval { my $ret = Fn->memcmp(undef, 0, $data2, 0, 3); };
        unless ($@) {
          return 0;
        }
      }

      # Exception - Source must be defined
      {
        my $data1 = new byte[4];
        eval { my $ret = Fn->memcmp($data1, 0, undef, 0, 3); };
        unless ($@) {
          return 0;
        }
      }
      
      # Exception - Length must be more than or equals to 0
      {
        my $data1 = new byte[4];
        my $data2 = [(byte)1, 3, 5];
        eval { my $ret = Fn->memcmp($data1, 0, $data2, 0, -1); };
        unless ($@) {
          return 0;
        }
      }
      
      # Exception - Destnation offset + length must be within the range of the destination array
      {
        my $data1 = new byte[4];
        my $data2 = [(byte)1, 3, 5];
        eval { my $ret = Fn->memcmp($data1, 2, $data2, 0, 3); };
        unless ($@) {
          return 0;
        }
      }

      # Exception - Source offset + length must be within the range of the source array
      {
        my $data1 = new byte[4];
        my $data2 = [(byte)1, 3, 5];
        eval { my $ret = Fn->memcmp($data1, 0, $data2, 1, 3); };
        unless ($@) {
          return 0;
        }
      }
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method reverse_inplace : int () {
    
    # Numeric array
    {
      {
        my $array = [1, 3, 2];
        
        Fn->reverse_inplace($array);
        
        unless (Array->equals_int($array, [2, 3, 1])) {
          return 0;
        }
        
      }
      
      {
        my $array = [1, 3, 2, 4];
        
        Fn->reverse_inplace($array);
        
        unless (Array->equals_int($array, [4, 2, 3, 1])) {
          return 0;
        }
        
      }
    }
    
    # Multi-numeric array
    {
      {
        my $array = new Complex_2d[3];
        
        $array->[0]{re} = 1;
        $array->[0]{im} = 11;
        $array->[1]{re} = 3;
        $array->[1]{im} = 33;
        $array->[2]{re} = 2;
        $array->[2]{im} = 22;
        
        Fn->reverse_inplace($array);
        
        unless ($array->[0]{re} == 2) {
          return 0;
        }
        
        unless ($array->[0]{im} == 22) {
          return 0;
        }
        unless ($array->[1]{re} == 3) {
          return 0;
        }
        unless ($array->[1]{im} == 33) {
          return 0;
        }
        unless ($array->[2]{re} == 1) {
          return 0;
        }
        unless ($array->[2]{im} == 11) {
          return 0;
        }
        
      }
    }
    
    # String
    {
      {
        my $string = (mutable string)copy "abc";
        
        Fn->reverse_inplace($string);
        
        unless ($string eq "cba") {
          return 0;
        }
        
      }
      
      {
        my $string = (mutable string)copy "abcd";
        
        Fn->reverse_inplace($string);
        
        unless ($string eq "dcba") {
          return 0;
        }
        
      }
      
    }
    
    # Object array
    {
      {
        my $array = [(string)1, 3, 2];
        
        Fn->reverse_inplace($array);
        
        unless (Array->equals_string($array, [(string)2, 3, 1])) {
          return 0;
        }
        
      }
      
      {
        my $array = [(string)1, 3, 2, 4];
        
        Fn->reverse_inplace($array);
        
        unless (Array->equals_string($array, [(string)4, 2, 3, 1])) {
          return 0;
        }
        
      }
    }
    
    # Exceptions
    {
      {
        my $array = [(string)1, 3, 2];
        
        eval { Fn->reverse_inplace(undef); }
        
        unless ($@) {
          return 0;
        }
        
      }
      
      {
        my $array = Int->new(1);
        
        eval { Fn->reverse_inplace($array); }
        
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $array = "abc";
        
        eval { Fn->reverse_inplace($array); }
        
        unless ($@) {
          return 0;
        }
      }
      
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method is_string_array : int () {
    
    # Array
    {
      my $array = new byte[3];
      
      if (Fn->is_string_array($array)) {
        return 0;
      }
    }
    
    # string
    {
      my $string = "abc";
      
      if (Fn->is_string_array($string)) {
        return 0;
      }
    }
    
    # string[]
    {
      my $string = ["abc"];
      
      unless (Fn->is_string_array($string)) {
        return 0;
      }
    }
    
    # string[]. Cast to object[]
    {
      my $string = (object[])["abc"];
      
      unless (Fn->is_string_array($string)) {
        return 0;
      }
    }
    
    # object[]
    {
      my $string = [(object)"abc"];
      
      if (Fn->is_string_array($string)) {
        return 0;
      }
    }
    
    # Object
    {
      my $minimal = TestCase::Minimal->new;
      
      if (Fn->is_string_array($minimal)) {
        return 0;
      }
    }
    
    # undef
    {
      if (Fn->is_string_array(undef)) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method length : int () {
    
    {
      my $array = new int[3];
      
      my $ret = Fn->length($array);
      
      unless ($ret == 3) {
        return 0;
      }
    }
    
    {
      my $array = (object)new int[3];
      
      my $ret = Fn->length($array);
      
      unless ($ret == 3) {
        return 0;
      }
    }
    
    {
      my $array = new object[3];
      
      my $ret = Fn->length($array);
      
      unless ($ret == 3) {
        return 0;
      }
    }
    
    {
      my $array = new Point[3];
      
      my $ret = Fn->length($array);
      
      unless ($ret == 3) {
        return 0;
      }
    }
    
    {
      my $array = new Complex_2d[3];
      
      my $ret = Fn->length($array);
      
      unless ($ret == 3) {
        return 0;
      }
    }
    
    {
      my $string = "abc";;
      
      my $ret = Fn->length($string);
      
      unless ($ret == 3) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        my $array = new int[3];
        
        eval { Fn->length(undef); }
        
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $array = Point->new;
        
        eval { Fn->length($array); }
        
        unless ($@) {
          return 0;
        }
      }
      
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method get_elem_or_char_size : int () {
    
    {
      my $array = new byte[3];
      
      my $ret = Fn->get_elem_or_char_size($array);
      
      unless ($ret == 1) {
        return 0;
      }
    }
    
    {
      my $array = new short[3];
      
      my $ret = Fn->get_elem_or_char_size($array);
      
      unless ($ret == 2) {
        return 0;
      }
    }
    
    {
      my $array = new int[3];
      
      my $ret = Fn->get_elem_or_char_size($array);
      
      unless ($ret == 4) {
        return 0;
      }
    }
    
    {
      my $array = new long[3];
      
      my $ret = Fn->get_elem_or_char_size($array);
      
      unless ($ret == 8) {
        return 0;
      }
    }
    
    {
      my $array = new float[3];
      
      my $ret = Fn->get_elem_or_char_size($array);
      
      unless ($ret == 4) {
        return 0;
      }
    }
    
    {
      my $array = new double[3];
      
      my $ret = Fn->get_elem_or_char_size($array);
      
      unless ($ret == 8) {
        return 0;
      }
    }
    
    {
      my $array = (object)new int[3];
      
      my $ret = Fn->get_elem_or_char_size($array);
      
      unless ($ret == 4) {
        return 0;
      }
    }
    
    {
      my $array = new object[3];
      
      my $ret = Fn->get_elem_or_char_size($array);
      
      unless ($ret == Fn->sizeof_native_pointer) {
        return 0;
      }
    }
    
    {
      my $array = new Point[3];
      
      my $ret = Fn->get_elem_or_char_size($array);
      
      unless ($ret == Fn->sizeof_native_pointer) {
        return 0;
      }
    }
    
    {
      my $array = new Complex_2d[3];
      
      my $ret = Fn->get_elem_or_char_size($array);
      
      unless ($ret == 16) {
        return 0;
      }
    }
    
    {
      my $string = "abc";
      
      my $ret = Fn->get_elem_or_char_size($string);
      
      unless ($ret == 1) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        my $array = new int[3];
        
        eval { Fn->get_elem_or_char_size(undef); }
        
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $array = Point->new;
        
        eval { Fn->get_elem_or_char_size($array); }
        
        unless ($@) {
          return 0;
        }
      }
      
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method copy : int () {
    
    {
      my $array = [1, 2, 3];
      my $array_out = Fn->copy($array);
      
      unless ($array_out is_compile_type object) {
        return 0;
      }
    }
    
    # copy numeric array
    {
      my $array = [1, 2, 3];
      my $array_out = (int[])Fn->copy($array);
      
      unless (Array->equals($array_out, $array)) {
        return 0;
      }
      
      if ($array == $array_out) {
        return 0;
      }
    }
    
    # copy numeric array
    {
      my $array = [1, 2, 3];
      my $array_out = (int[])Fn->copy($array);
      
      unless (Array->equals($array_out, $array)) {
        return 0;
      }
      
      if ($array == $array_out) {
        return 0;
      }
    }
    
    # copy multi numeric array
    {
      my $array = Complex_2d->new_array_from_pairs([(double)1,2,  3,4]);
      my $array_out = (Complex_2d[])Fn->copy($array);
      
      unless (Array->equals($array_out, $array)) {
        return 0;
      }
      
      if ($array == $array_out) {
        return 0;
      }
    }
    
    # copy object array
    {
      my $array = [Point->new(1, 2), Point->new(3, 4), undef];
      my $array_out = (Point[])Fn->copy($array);
      
      unless ($array_out->[0]->x == $array->[0]->x) {
        return 0;
      }
      
      unless ($array_out->[0]->y == $array->[0]->y) {
        return 0;
      }
      
      if ($array_out->[0] == $array->[0]) {
        return 0;
      }
      
      unless ($array_out->[1]->x == $array->[1]->x) {
        return 0;
      }
      
      unless ($array_out->[1]->y == $array->[1]->y) {
        return 0;
      }
      
      if ($array_out->[1] == $array->[1]) {
        return 0;
      }
      
      unless ($array_out->[2] == undef) {
        return 0;
      }
      
      if ($array == $array_out) {
        return 0;
      }
    }
    
    # copy object array
    {
      my $array = [Point->new, Point->new, Point->new];
      my $shallow = 1;
      my $array_out = (Point[])Fn->copy($array, $shallow);
      
      unless (Array->equals_object_address($array_out, $array)) {
        return 0;
      }
      
      if ($array == $array_out) {
        return 0;
      }
    }
    
    # copy string array
    {
      my $array = ["a", "b", "c"];
      my $array_out = (string[])Fn->copy($array);
      
      unless (Array->equals_string($array_out, $array)) {
        return 0;
      }
      
      if (Array->equals_string_address($array_out, $array)) {
        return 0;
      }
      
      if ($array == $array_out) {
        return 0;
      }
    }
    
    # copy string array - shallow
    {
      my $array = ["a", "b", "c"];
      my $shallow = 1;
      my $array_out = (string[])Fn->copy($array, $shallow);
      
      unless (Array->equals_string_address($array_out, $array)) {
        return 0;
      }
      
      if ($array == $array_out) {
        return 0;
      }
    }
    
    # copy string
    {
      my $string = "abc";
      my $string_out = (string)Fn->copy($string);
      
      # Equals the value
      unless ($string_out eq "abc") {
        return 0;
      }
      
      # Not equals address
      if ($string == $string_out) {
        return 0;
      }
    }
    
    # undef
    {
      my $string_out = Fn->copy(undef);
      
      # Equals the value
      unless ($string_out == undef) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method reverse : int () {
    
    # Numeric array
    {
      {
        my $array = [1, 3, 2];
        
        my $ret = (int[])Fn->reverse($array);
        
        unless (Array->equals_int($ret, [2, 3, 1])) {
          return 0;
        }
        
        if ($ret == $array) {
          return 0;
        }
      }
      
      {
        my $array = [1, 3, 2, 4];
        
        my $ret = (int[])Fn->reverse($array);
        
        unless (Array->equals_int($ret, [4, 2, 3, 1])) {
          return 0;
        }
        
      }
    }
    
    # Multi-numeric array
    {
      {
        my $array = new Complex_2d[3];
        
        $array->[0]{re} = 1;
        $array->[0]{im} = 11;
        $array->[1]{re} = 3;
        $array->[1]{im} = 33;
        $array->[2]{re} = 2;
        $array->[2]{im} = 22;
        
        my $ret = (Complex_2d[])Fn->reverse($array);
        
        unless ($ret->[0]{re} == 2) {
          return 0;
        }
        
        unless ($ret->[0]{im} == 22) {
          return 0;
        }
        unless ($ret->[1]{re} == 3) {
          return 0;
        }
        unless ($ret->[1]{im} == 33) {
          return 0;
        }
        unless ($ret->[2]{re} == 1) {
          return 0;
        }
        unless ($ret->[2]{im} == 11) {
          return 0;
        }
        
      }
    }
    
    # String
    {
      {
        my $string = "abc";
        
        my $ret = (string)Fn->reverse($string);
        
        unless ($ret eq "cba") {
          return 0;
        }
        
      }
      
      {
        my $string = "abcd";
        
        my $ret = (string)Fn->reverse($string);
        
        unless ($ret eq "dcba") {
          return 0;
        }
        
      }
      
    }
    
    # Object array
    {
      {
        my $array = [(string)1, 3, 2];
        
        my $ret = (string[])Fn->reverse($array);
        
        unless (Array->equals_string($ret, [(string)2, 3, 1])) {
          return 0;
        }
        
      }
      
      {
        my $array = [(string)1, 3, 2, 4];
        
        my $ret = (string[])Fn->reverse($array);
        
        unless (Array->equals_string($ret, [(string)4, 2, 3, 1])) {
          return 0;
        }
        
      }
    }
    
    # Exceptions
    {
      {
        my $array = [(string)1, 3, 2];
        
        eval { Fn->reverse(undef); }
        
        unless ($@) {
          return 0;
        }
        
      }
      
      {
        my $array = Int->new(1);
        
        eval { Fn->reverse($array); }
        
        unless ($@) {
          return 0;
        }
      }
      
    }
    
    $@ = undef;
    
    return 1;
  }
  
  static method slice : int () {
    
    # Copy with offset and length
    {
      my $point0 = Point->new(1, 1);
      my $point1 = Point->new(3, 3);
      my $point2 = Point->new(5, 5);
      my $source = [$point0, $point1, $point2];
      my $dest = (Point[])Fn->slice($source, 1, 2);
      
      unless (@$dest == 2) {
      
      }
      unless ($dest->[0] == $point1) {
        return 0;
      }
      unless ($dest->[1] == $point2) {
        return 0;
      }
    }
    
    # Copy with offset and length
    {
      my $source = [(int)1, 3, 5, 9];
      my $dest = (int[])Fn->slice($source, 1, 2);
      unless (Array->equals_int($dest, [(int)3, 5])) {
        return 0;
      }
    }
    
    # Exception
    {
      {
        my $source = [(string)1, 3, 5];
        eval { Fn->slice(undef, 0, 3); };
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $source = [(string)1, 3, 5];
        eval { Fn->slice(Int->new(1), 0, 3); };
        unless ($@) {
          return 0;
        }
      }
      
    }
    
    return 1;
  }
  
  static method sprintf : int () {
    {
      unless (Fn->sprintf("%d", [(object)123]) eq "123") {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method sort_asc : int () {
    
    {
      my $array = [(byte)2, 3, 1];
      
      my $ret = (byte[])Fn->sort_asc($array);
      
      unless (Array->equals($ret, [(byte)1, 2, 3])) {
        return 0;
      }
      
      if ($array == $ret) {
        return 0;
      }
    }
    
    {
      my $array = [(short)2, 3, 1];
      
      my $ret = (short[])Fn->sort_asc($array);
      
      unless (Array->equals($ret, [(short)1, 2, 3])) {
        return 0;
      }
      
      if ($array == $ret) {
        return 0;
      }
    }
    
    {
      my $array = [(int)2, 3, 1];
      
      my $ret = (int[])Fn->sort_asc($array);
      
      unless (Array->equals($ret, [(int)1, 2, 3])) {
        return 0;
      }
      
      if ($array == $ret) {
        return 0;
      }
    }
    
    {
      my $array = [(long)2, 3, 1];
      
      my $ret = (long[])Fn->sort_asc($array);
      
      unless (Array->equals($ret, [(long)1, 2, 3])) {
        return 0;
      }
      
      if ($array == $ret) {
        return 0;
      }
    }
    
    {
      my $array = [(float)2, 3, 1];
      
      my $ret = (float[])Fn->sort_asc($array);
      
      unless (Array->equals($ret, [(float)1, 2, 3])) {
        return 0;
      }
      
      if ($array == $ret) {
        return 0;
      }
    }
    
    {
      my $array = [(double)2, 3, 1];
      
      my $ret = (double[])Fn->sort_asc($array);
      
      unless (Array->equals($ret, [(double)1, 2, 3])) {
        return 0;
      }
      
      if ($array == $ret) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        my $array = [(byte)2, 3, 1];
        
        eval { my $ret = (byte[])Fn->sort_asc(undef); }
        
        unless ($@) {
          return 0;
        }
        
      }
      
      {
        my $array = [(object)2, 3, 1];
        
        eval { my $ret = (byte[])Fn->sort_asc($array); }
        
        unless ($@) {
          return 0;
        }
        
      }
    }
    
    return 1;
  }
  
  static method sort_desc : int () {
    
    {
      my $array = [(byte)2, 3, 1];
      
      my $ret = (byte[])Fn->sort_desc($array);
      
      unless (Array->equals($ret, [(byte)3, 2, 1])) {
        return 0;
      }
      
      if ($array == $ret) {
        return 0;
      }
    }
    
    {
      my $array = [(short)2, 3, 1];
      
      my $ret = (short[])Fn->sort_desc($array);
      
      unless (Array->equals($ret, [(short)3, 2, 1])) {
        return 0;
      }
      
      if ($array == $ret) {
        return 0;
      }
    }
    
    {
      my $array = [(int)2, 3, 1];
      
      my $ret = (int[])Fn->sort_desc($array);
      
      unless (Array->equals($ret, [(int)3, 2, 1])) {
        return 0;
      }
      
      if ($array == $ret) {
        return 0;
      }
    }
    
    {
      my $array = [(long)2, 3, 1];
      
      my $ret = (long[])Fn->sort_desc($array);
      
      unless (Array->equals($ret, [(long)3, 2, 1])) {
        return 0;
      }
      
      if ($array == $ret) {
        return 0;
      }
    }
    
    {
      my $array = [(float)2, 3, 1];
      
      my $ret = (float[])Fn->sort_desc($array);
      
      unless (Array->equals($ret, [(float)3, 2, 1])) {
        return 0;
      }
      
      if ($array == $ret) {
        return 0;
      }
    }
    
    {
      my $array = [(double)2, 3, 1];
      
      my $ret = (double[])Fn->sort_desc($array);
      
      unless (Array->equals($ret, [(double)3, 2, 1])) {
        return 0;
      }
      
      if ($array == $ret) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        my $array = [(byte)2, 3, 1];
        
        eval { my $ret = (byte[])Fn->sort_desc(undef); }
        
        unless ($@) {
          return 0;
        }
        
      }
      
      {
        my $array = [(object)2, 3, 1];
        
        eval { my $ret = (byte[])Fn->sort_desc($array); }
        
        unless ($@) {
          return 0;
        }
        
      }
    }
    
    return 1;
  }
  
  static method sort : int () {
    
    {
      my $array = [&new_minimal(2, 0), &new_minimal(3, 0), &new_minimal(1, 0)];
      
      Fn->sort($array, method : int ($a : object, $b : object) {
        return $a->(TestCase::Minimal)->x <=> $b->(TestCase::Minimal)->x;
      });
      
      my $is_equals = Array->equals_object($array, [&new_minimal(1, 0), &new_minimal(2, 0), &new_minimal(3, 0)], method : int ($a : object, $b : object) {
        return $a->(TestCase::Minimal)->x == $b->(TestCase::Minimal)->x;
      });
      
      unless ($is_equals) {
        return 0;
      }
    }
    
    return 1;
  }
  
  private static method new_minimal : TestCase::Minimal ($x : int, $y : int) {
    my $minimal = TestCase::Minimal->new;
    $minimal->set_x($x);
    $minimal->set_y($y);
    
    return $minimal;
  }
  
  static method change_endian : int () {
    
    {
      my $size = 8;
      
      my $values = [(double)1, 2];
      
      my $buffer = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer, 0, $values, 0, $size);
      
      my $buffer_ret = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer_ret, 0, $values, 0, $size);
      
      Fn->change_endian($buffer_ret, $size);
      
      unless ($buffer_ret->[7] == $buffer->[0]) {
        return 0;
      }
      
      unless ($buffer_ret->[6] == $buffer->[1]) {
        return 0;
      }
      
      unless ($buffer_ret->[5] == $buffer->[2]) {
        return 0;
      }
      
      unless ($buffer_ret->[4] == $buffer->[3]) {
        return 0;
      }
      
      unless ($buffer_ret->[3] == $buffer->[4]) {
        return 0;
      }
      
      unless ($buffer_ret->[2] == $buffer->[5]) {
        return 0;
      }
      
      unless ($buffer_ret->[1] == $buffer->[6]) {
        return 0;
      }
      
      unless ($buffer_ret->[0] == $buffer->[7]) {
        return 0;
      }
      
      unless ($buffer_ret->[8 + 0] == $buffer->[8 + 0]) {
        return 0;
      }
      
      unless ($buffer_ret->[8 + 1] == $buffer->[8 + 1]) {
        return 0;
      }
      
      unless ($buffer_ret->[8 + 2] == $buffer->[8 + 2]) {
        return 0;
      }
      
      unless ($buffer_ret->[8 + 3] == $buffer->[8 + 3]) {
        return 0;
      }
      
      unless ($buffer_ret->[8 + 4] == $buffer->[8 + 4]) {
        return 0;
      }
      
      unless ($buffer_ret->[8 + 5] == $buffer->[8 + 5]) {
        return 0;
      }
      
      unless ($buffer_ret->[8 + 6] == $buffer->[8 + 6]) {
        return 0;
      }
      
      unless ($buffer_ret->[8 + 7] == $buffer->[8 + 7]) {
        return 0;
      }
      
    }
    
    {
      my $size = 1;
      
      my $values = [(byte)1, 2];
      
      my $buffer = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer, 0, $values, 0, $size);
      
      my $buffer_ret = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer_ret, 0, $values, 0, $size);
      
      Fn->change_endian($buffer_ret, $size);
      
      unless ($buffer_ret->[0] == $buffer->[0]) {
        return 0;
      }
      
      unless ($buffer_ret->[1] == $buffer->[1]) {
        return 0;
      }
      
      unless ($buffer_ret->[2] == $buffer->[2]) {
        return 0;
      }
      
      unless ($buffer_ret->[3] == $buffer->[3]) {
        return 0;
      }
    }
    
    {
      my $size = 8;
      
      my $values = [(double)1, 2];
      
      my $buffer = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer, 0, $values, 0, $size);
      
      my $buffer_ret = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer_ret, 0, $values, 0, $size);
      
      my $offset = 8;
      Fn->change_endian($buffer_ret, $size, $offset);
      
      unless ($buffer_ret->[0] == $buffer->[0]) {
        return 0;
      }
      
      unless ($buffer_ret->[1] == $buffer->[1]) {
        return 0;
      }
      
      unless ($buffer_ret->[2] == $buffer->[2]) {
        return 0;
      }
      
      unless ($buffer_ret->[3] == $buffer->[3]) {
        return 0;
      }
      
      unless ($buffer_ret->[4] == $buffer->[4]) {
        return 0;
      }
      
      unless ($buffer_ret->[5] == $buffer->[5]) {
        return 0;
      }
      
      unless ($buffer_ret->[6] == $buffer->[6]) {
        return 0;
      }
      
      unless ($buffer_ret->[7] == $buffer->[7]) {
        return 0;
      }
      
      unless ($buffer_ret->[8 + 7] == $buffer->[8 + 0]) {
        return 0;
      }
      
      unless ($buffer_ret->[8 + 6] == $buffer->[8 + 1]) {
        return 0;
      }
      
      unless ($buffer_ret->[8 + 5] == $buffer->[8 + 2]) {
        return 0;
      }
      
      unless ($buffer_ret->[8 + 4] == $buffer->[8 + 3]) {
        return 0;
      }
      
      unless ($buffer_ret->[8 + 3] == $buffer->[8 + 4]) {
        return 0;
      }
      
      unless ($buffer_ret->[8 + 2] == $buffer->[8 + 5]) {
        return 0;
      }
      
      unless ($buffer_ret->[8 + 1] == $buffer->[8 + 6]) {
        return 0;
      }
      
      unless ($buffer_ret->[8 + 0] == $buffer->[8 + 7]) {
        return 0;
      }
      
    }
    
    # Exceptions
    {
      {
        my $binary = (mutable string)new_string_len 256;
        
        my $size = 4;
        
        eval { Fn->change_endian(undef, $size); }
        
        unless ($@) {
          return 0;
        }
        
      }
      
      {
        my $binary = (mutable string)new_string_len 256;
        my $size = 256;
        
        Fn->change_endian($binary, $size);
      }
      
      {
        my $binary = (mutable string)new_string_len 256;
        my $size = 257;
        
        eval { Fn->change_endian($binary, $size); }
        
        unless ($@) {
          return 0;
        }
        
      }
      
      {
        my $binary = (mutable string)new_string_len 256;
        my $size = 256;
        my $offset = -1;
        eval { Fn->change_endian($binary, $size, $offset); }
        
        unless ($@) {
          return 0;
        }
        
      }
      
      {
        my $binary = (mutable string)new_string_len 256;
        my $size = 256;
        my $offset = 1;
        eval { Fn->change_endian($binary, $size, $offset); }
        
        unless ($@) {
          return 0;
        }
        
      }
      
    }
    
    return 1;
  }
  
  static method big_endian_to_system_endian : int () {
    
    {
      my $size = 8;
      
      my $values = [(double)1, 2];
      
      my $buffer = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer, 0, $values, 0, $size);
      
      my $buffer_ret = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer_ret, 0, $values, 0, $size);
      
      Fn->big_endian_to_system_endian($buffer_ret, $size);
      
      if (Fn->system_is_little_endian) {
        
        unless ($buffer_ret->[7] == $buffer->[0]) {
          return 0;
        }
        
        unless ($buffer_ret->[6] == $buffer->[1]) {
          return 0;
        }
        
        unless ($buffer_ret->[5] == $buffer->[2]) {
          return 0;
        }
        
        unless ($buffer_ret->[4] == $buffer->[3]) {
          return 0;
        }
        
        unless ($buffer_ret->[3] == $buffer->[4]) {
          return 0;
        }
        
        unless ($buffer_ret->[2] == $buffer->[5]) {
          return 0;
        }
        
        unless ($buffer_ret->[1] == $buffer->[6]) {
          return 0;
        }
        
        unless ($buffer_ret->[0] == $buffer->[7]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 7] == $buffer->[8 + 0]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 6] == $buffer->[8 + 1]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 5] == $buffer->[8 + 2]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 4] == $buffer->[8 + 3]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 3] == $buffer->[8 + 4]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 2] == $buffer->[8 + 5]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 1] == $buffer->[8 + 6]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 0] == $buffer->[8 + 7]) {
          return 0;
        }
      }
      else {
        unless ($buffer_ret eq $buffer) {
          return 0;
        }
      }
    }
    
    {
      my $size = 8;
      
      my $values = [(double)1, 2];
      
      my $buffer = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer, 0, $values, 0, $size);
      
      my $buffer_ret = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer_ret, 0, $values, 0, $size);
      
      my $offset = 8;
      Fn->big_endian_to_system_endian($buffer_ret, $size, $offset);
      
      if (Fn->system_is_little_endian) {
        unless ($buffer_ret->[0] == $buffer->[0]) {
          return 0;
        }
        
        unless ($buffer_ret->[1] == $buffer->[1]) {
          return 0;
        }
        
        unless ($buffer_ret->[2] == $buffer->[2]) {
          return 0;
        }
        
        unless ($buffer_ret->[3] == $buffer->[3]) {
          return 0;
        }
        
        unless ($buffer_ret->[4] == $buffer->[4]) {
          return 0;
        }
        
        unless ($buffer_ret->[5] == $buffer->[5]) {
          return 0;
        }
        
        unless ($buffer_ret->[6] == $buffer->[6]) {
          return 0;
        }
        
        unless ($buffer_ret->[7] == $buffer->[7]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 7] == $buffer->[8 + 0]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 6] == $buffer->[8 + 1]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 5] == $buffer->[8 + 2]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 4] == $buffer->[8 + 3]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 3] == $buffer->[8 + 4]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 2] == $buffer->[8 + 5]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 1] == $buffer->[8 + 6]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 0] == $buffer->[8 + 7]) {
          return 0;
        }
        
      }
      else {
        unless ($buffer_ret eq $buffer) {
          return 0;
        }
      }
    }
    return 1;
  }
  
  static method system_endian_to_big_endian : int () {
    
    {
      my $size = 8;
      
      my $values = [(double)1, 2];
      
      my $buffer = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer, 0, $values, 0, $size);
      
      my $buffer_ret = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer_ret, 0, $values, 0, $size);
      
      Fn->system_endian_to_big_endian($buffer_ret, $size);
      
      if (Fn->system_is_little_endian) {
        
        unless ($buffer_ret->[7] == $buffer->[0]) {
          return 0;
        }
        
        unless ($buffer_ret->[6] == $buffer->[1]) {
          return 0;
        }
        
        unless ($buffer_ret->[5] == $buffer->[2]) {
          return 0;
        }
        
        unless ($buffer_ret->[4] == $buffer->[3]) {
          return 0;
        }
        
        unless ($buffer_ret->[3] == $buffer->[4]) {
          return 0;
        }
        
        unless ($buffer_ret->[2] == $buffer->[5]) {
          return 0;
        }
        
        unless ($buffer_ret->[1] == $buffer->[6]) {
          return 0;
        }
        
        unless ($buffer_ret->[0] == $buffer->[7]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 7] == $buffer->[8 + 0]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 6] == $buffer->[8 + 1]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 5] == $buffer->[8 + 2]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 4] == $buffer->[8 + 3]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 3] == $buffer->[8 + 4]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 2] == $buffer->[8 + 5]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 1] == $buffer->[8 + 6]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 0] == $buffer->[8 + 7]) {
          return 0;
        }
      }
      else {
        unless ($buffer_ret eq $buffer) {
          return 0;
        }
      }
    }
    
    {
      my $size = 8;
      
      my $values = [(double)1, 2];
      
      my $buffer = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer, 0, $values, 0, $size);
      
      my $buffer_ret = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer_ret, 0, $values, 0, $size);
      
      my $offset = 8;
      Fn->system_endian_to_big_endian($buffer_ret, $size, $offset);
      
      if (Fn->system_is_little_endian) {
        
        unless ($buffer_ret->[0] == $buffer->[0]) {
          return 0;
        }
        
        unless ($buffer_ret->[1] == $buffer->[1]) {
          return 0;
        }
        
        unless ($buffer_ret->[2] == $buffer->[2]) {
          return 0;
        }
        
        unless ($buffer_ret->[3] == $buffer->[3]) {
          return 0;
        }
        
        unless ($buffer_ret->[4] == $buffer->[4]) {
          return 0;
        }
        
        unless ($buffer_ret->[5] == $buffer->[5]) {
          return 0;
        }
        
        unless ($buffer_ret->[6] == $buffer->[6]) {
          return 0;
        }
        
        unless ($buffer_ret->[7] == $buffer->[7]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 7] == $buffer->[8 + 0]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 6] == $buffer->[8 + 1]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 5] == $buffer->[8 + 2]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 4] == $buffer->[8 + 3]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 3] == $buffer->[8 + 4]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 2] == $buffer->[8 + 5]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 1] == $buffer->[8 + 6]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 0] == $buffer->[8 + 7]) {
          return 0;
        }
      
      }
      else {
        unless ($buffer_ret eq $buffer) {
          return 0;
        }
      }
    }
    
    return 1;
  }
  
  static method little_endian_to_system_endian : int () {
    
    {
      my $size = 8;
      
      my $values = [(double)1, 2];
      
      my $buffer = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer, 0, $values, 0, $size);
      
      my $buffer_ret = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer_ret, 0, $values, 0, $size);
      
      Fn->little_endian_to_system_endian($buffer_ret, $size);
      
      if (!Fn->system_is_little_endian) {
        
        unless ($buffer_ret->[7] == $buffer->[0]) {
          return 0;
        }
        
        unless ($buffer_ret->[6] == $buffer->[1]) {
          return 0;
        }
        
        unless ($buffer_ret->[5] == $buffer->[2]) {
          return 0;
        }
        
        unless ($buffer_ret->[4] == $buffer->[3]) {
          return 0;
        }
        
        unless ($buffer_ret->[3] == $buffer->[4]) {
          return 0;
        }
        
        unless ($buffer_ret->[2] == $buffer->[5]) {
          return 0;
        }
        
        unless ($buffer_ret->[1] == $buffer->[6]) {
          return 0;
        }
        
        unless ($buffer_ret->[0] == $buffer->[7]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 7] == $buffer->[8 + 0]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 6] == $buffer->[8 + 1]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 5] == $buffer->[8 + 2]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 4] == $buffer->[8 + 3]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 3] == $buffer->[8 + 4]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 2] == $buffer->[8 + 5]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 1] == $buffer->[8 + 6]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 0] == $buffer->[8 + 7]) {
          return 0;
        }
      }
      else {
        unless ($buffer_ret eq $buffer) {
          return 0;
        }
      }
    }
    
    {
      my $size = 8;
      
      my $values = [(double)1, 2];
      
      my $buffer = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer, 0, $values, 0, $size);
      
      my $buffer_ret = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer_ret, 0, $values, 0, $size);
      
      my $offset = 8;
      Fn->little_endian_to_system_endian($buffer_ret, $size, $offset);
      
      if (!Fn->system_is_little_endian) {
        unless ($buffer_ret->[0] == $buffer->[0]) {
          return 0;
        }
        
        unless ($buffer_ret->[1] == $buffer->[1]) {
          return 0;
        }
        
        unless ($buffer_ret->[2] == $buffer->[2]) {
          return 0;
        }
        
        unless ($buffer_ret->[3] == $buffer->[3]) {
          return 0;
        }
        
        unless ($buffer_ret->[4] == $buffer->[4]) {
          return 0;
        }
        
        unless ($buffer_ret->[5] == $buffer->[5]) {
          return 0;
        }
        
        unless ($buffer_ret->[6] == $buffer->[6]) {
          return 0;
        }
        
        unless ($buffer_ret->[7] == $buffer->[7]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 7] == $buffer->[8 + 0]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 6] == $buffer->[8 + 1]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 5] == $buffer->[8 + 2]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 4] == $buffer->[8 + 3]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 3] == $buffer->[8 + 4]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 2] == $buffer->[8 + 5]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 1] == $buffer->[8 + 6]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 0] == $buffer->[8 + 7]) {
          return 0;
        }
        
      }
      else {
        unless ($buffer_ret eq $buffer) {
          return 0;
        }
      }
    }
    return 1;
  }
  
  static method system_endian_to_little_endian : int () {
    
    {
      my $size = 8;
      
      my $values = [(double)1, 2];
      
      my $buffer = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer, 0, $values, 0, $size);
      
      my $buffer_ret = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer_ret, 0, $values, 0, $size);
      
      Fn->system_endian_to_little_endian($buffer_ret, $size);
      
      if (!Fn->system_is_little_endian) {
        
        unless ($buffer_ret->[7] == $buffer->[0]) {
          return 0;
        }
        
        unless ($buffer_ret->[6] == $buffer->[1]) {
          return 0;
        }
        
        unless ($buffer_ret->[5] == $buffer->[2]) {
          return 0;
        }
        
        unless ($buffer_ret->[4] == $buffer->[3]) {
          return 0;
        }
        
        unless ($buffer_ret->[3] == $buffer->[4]) {
          return 0;
        }
        
        unless ($buffer_ret->[2] == $buffer->[5]) {
          return 0;
        }
        
        unless ($buffer_ret->[1] == $buffer->[6]) {
          return 0;
        }
        
        unless ($buffer_ret->[0] == $buffer->[7]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 7] == $buffer->[8 + 0]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 6] == $buffer->[8 + 1]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 5] == $buffer->[8 + 2]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 4] == $buffer->[8 + 3]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 3] == $buffer->[8 + 4]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 2] == $buffer->[8 + 5]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 1] == $buffer->[8 + 6]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 0] == $buffer->[8 + 7]) {
          return 0;
        }
      }
      else {
        unless ($buffer_ret eq $buffer) {
          return 0;
        }
      }
    }
    
    {
      my $size = 8;
      
      my $values = [(double)1, 2];
      
      my $buffer = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer, 0, $values, 0, $size);
      
      my $buffer_ret = (mutable string)new_string_len 256;
      
      Fn->memcpy($buffer_ret, 0, $values, 0, $size);
      
      my $offset = 8;
      Fn->system_endian_to_little_endian($buffer_ret, $size, $offset);
      
      if (!Fn->system_is_little_endian) {
        
        unless ($buffer_ret->[0] == $buffer->[0]) {
          return 0;
        }
        
        unless ($buffer_ret->[1] == $buffer->[1]) {
          return 0;
        }
        
        unless ($buffer_ret->[2] == $buffer->[2]) {
          return 0;
        }
        
        unless ($buffer_ret->[3] == $buffer->[3]) {
          return 0;
        }
        
        unless ($buffer_ret->[4] == $buffer->[4]) {
          return 0;
        }
        
        unless ($buffer_ret->[5] == $buffer->[5]) {
          return 0;
        }
        
        unless ($buffer_ret->[6] == $buffer->[6]) {
          return 0;
        }
        
        unless ($buffer_ret->[7] == $buffer->[7]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 7] == $buffer->[8 + 0]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 6] == $buffer->[8 + 1]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 5] == $buffer->[8 + 2]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 4] == $buffer->[8 + 3]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 3] == $buffer->[8 + 4]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 2] == $buffer->[8 + 5]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 1] == $buffer->[8 + 6]) {
          return 0;
        }
        
        unless ($buffer_ret->[8 + 0] == $buffer->[8 + 7]) {
          return 0;
        }
      
      }
      else {
        unless ($buffer_ret eq $buffer) {
          return 0;
        }
      }
    }
    
    return 1;
  }
  static method pack : int () {
    
    # l
    {
      my $objects = [(object)Fn->INT_MIN];
      
      my $template = "l";
      
      my $binary = Fn->pack($template, $objects);
      
      unless (length $binary == 4) {
        return 0;
      }
      
      my $objects_again = Fn->unpack($template, $binary);
      
      unless (@$objects_again == 1) {
        return 0;
      }
      
      unless ($objects_again->[0] is_type Int) {
        return 0;
      }
      
      unless ($objects_again->[0]->(int) == Fn->INT_MIN) {
        return 0;
      }
      
    }
    
    return 1;
  }
  
  static method unpack : int () {
    
    # Tested in pack method.
    
    return 1;
  }
  
  static method no_free : int () {
    
    my $point = Point->new;
    
    {
      my $no_free = Fn->no_free($point);
      
      if ($no_free) {
        return 0;
      }
    }
    
    {
      &set_no_free_true($point);
      
      my $no_free = Fn->no_free($point);
      
      unless ($no_free) {
        return 0;
      }
      
      unless ($no_free == 1) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method set_no_free : int () {
    
    my $point = Point->new;
    
    {
      Fn->set_no_free($point, 1);
      
      my $no_free = Fn->no_free($point);
      
      unless ($no_free) {
        return 0;
      }
    }
    
    return 1;
  }
  
  native static method set_no_free_true : int ($object : object);
  
  static method get_pointer : int () {
    
    {
      my $point = Point->new;
      
      my $pointer = Fn->get_pointer($point);
      
      unless ($pointer is_type Address) {
        return 0;
      }
    }
    
    {
      my $point = Point->new;
      
      my $pointer = Fn->get_pointer($point);
      
      unless (Fn->has_null_pointer($pointer)) {
        return 0;
      }
    }
    
    {
      my $point = Native->get_current_compiler;
      
      my $pointer = Fn->get_pointer($point);
      
      if (Fn->has_null_pointer($pointer)) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        my $point = Point->new;
        
        eval { my $pointer = Fn->get_pointer($point); }
        
        unless (!$@) {
          return 0;
        }
      }
      
      {
        my $point = Point->new;
        
        eval { my $pointer = Fn->get_pointer(undef); }
        
        unless ($@) {
          return 0;
        }
      }
    }
    
    return 1;
  }
  
  static method set_pointer : int () {
    
    {
      my $compiler = Native->get_current_compiler;
      
      my $pointer = Fn->get_pointer($compiler);
      
      my $point = Point->new;
      
      Fn->set_pointer($point, $pointer);
      
      unless (Fn->eq_pointer(Fn->get_pointer($point), $pointer)) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        my $compiler = Native->get_current_compiler;
        
        my $pointer = Fn->get_pointer($compiler);
        
        my $point = Point->new;
        
        eval { Fn->set_pointer($point, $pointer); }
        
        unless (!$@) {
          return 0;
        }
      }
      
      {
        my $compiler = Native->get_current_compiler;
        
        my $pointer = Fn->get_pointer($compiler);
        
        my $point = Point->new;
        
        eval { Fn->set_pointer(undef, $pointer); }
        
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $compiler = Native->get_current_compiler;
        
        my $pointer = Fn->get_pointer($compiler);
        
        my $point = Point->new;
        
        eval { Fn->set_pointer($point, undef); }
        
        unless ($@) {
          return 0;
        }
      }
      
    }
    
    return 1;
  }
  
  static method has_null_pointer : int () {
    
    {
      my $point = Point->new;
      
      my $pointer = Fn->get_pointer($point);
      
      unless (Fn->has_null_pointer($pointer)) {
        return 0;
      }
    }
    
    {
      my $compiler = Native->get_current_compiler;
      
      my $pointer = Fn->get_pointer($compiler);
      
      if (Fn->has_null_pointer($pointer)) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        my $point = Point->new;
        
        eval { my $pointer = Fn->get_pointer($point); }
        
        unless (!$@) {
          return 0;
        }
      }
      
      {
        my $point = Point->new;
        
        eval { my $pointer = Fn->get_pointer(undef); }
        
        unless ($@) {
          return 0;
        }
      }
      
    }
    
    return 1;
  }
  
  static method eq_pointer : int () {
    
    {
      my $point = Point->new;
      
      my $pointer1 = Fn->get_pointer($point);
      
      my $pointer2 = Fn->get_pointer($point);
      
      my $ret = Fn->eq_pointer($pointer1, $pointer2);
      
      unless ($ret) {
        return 0;
      }
    }
    
    {
      my $point = Point->new;
      
      my $pointer1 = Fn->get_pointer($point);
      
      my $compiler = Native->get_current_compiler;
      
      my $pointer2 = Fn->get_pointer($compiler);
      
      my $ret = Fn->eq_pointer($pointer1, $pointer2);
      
      if ($ret) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        my $point = Point->new;
        
        my $pointer1 = Fn->get_pointer($point);
        
        my $pointer2 = Fn->get_pointer($point);
        
        eval { my $ret = Fn->eq_pointer($pointer1, $pointer2); }
        
        unless (!$@) {
          return 0;
        }
      }
      
      {
        my $point = Point->new;
        
        my $pointer1 = Fn->get_pointer($point);
        
        my $pointer2 = Fn->get_pointer($point);
        
        eval { my $ret = Fn->eq_pointer(undef, $pointer2); }
        
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $point = Point->new;
        
        my $pointer1 = Fn->get_pointer($point);
        
        my $pointer2 = Fn->get_pointer($point);
        
        eval { my $ret = Fn->eq_pointer($pointer1, undef); }
        
        unless ($@) {
          return 0;
        }
      }
      
    }
    
    return 1;
  }
  
  static method pointer_to_string : int () {
    
    {
      my $point = Point->new;
      
      my $pointer = Fn->get_pointer($point);
      
      my $ret = Fn->pointer_to_string($pointer);
      
      warn "[Test Output]$ret";
    }
    
    {
      my $compiler = Native->get_current_compiler;
      
      my $pointer = Fn->get_pointer($compiler);
      
      my $ret = Fn->pointer_to_string($pointer);
      
      warn "[Test Output]$ret";
    }
    
    # Exceptions
    {
      {
        my $point = Point->new;
        
        my $pointer = Fn->get_pointer($point);
        
        eval { my $ret = Fn->pointer_to_string($pointer); }
        
        unless (!$@) {
          return 0;
        }
      }
      
      {
        my $point = Point->new;
        
        my $pointer = Fn->get_pointer($point);
        
        eval { my $ret = Fn->pointer_to_string(undef); }
        
        unless ($@) {
          return 0;
        }
      }
      
    }
    
    return 1;
  }
  
  static method dump_object_internal : int () {
    
    {
      my $point = Point->new;
      my $dump = Fn->dump_object_internal($point);
      
      unless (Fn->contains($dump, "pointer:")) {
        return 0;
      }
      
      unless (Fn->contains($dump, "weaken_backrefs_length:0")) {
        return 0;
      }
      
      unless (Fn->contains($dump, "ref_count:1")) {
        return 0;
      }
      
      unless (Fn->contains($dump, "basic_type_name:Point")) {
        return 0;
      }
      
      unless (Fn->contains($dump, "flag:")) {
        return 0;
      }
      
    }
    
    {
      my $point = Point->new;
      
      Fn->set_no_free($point, 1);
      
      my $hash = Hash->new;
      $hash->set("point", $point);
      
      $hash->weaken("point");
      
      my $dump = Fn->dump_object_internal($point);
      
      unless (Fn->contains($dump, "weaken_backrefs_length:1")) {
        return 0;
      }
      
      unless (Fn->contains($dump, "no_free")) {
        return 0;
      }
    }
    
    {
      my $string = "abc";
      
      my $dump = Fn->dump_object_internal($string);
      
      unless (Fn->contains($dump, "is_read_only")) {
        return 0;
      }
      
    }
    
    {
      my $points = new Point[2];
      my $dump = Fn->dump_object_internal($points);
      
      unless (Fn->contains($dump, "type_dimension:1")) {
        return 0;
      }
      
      unless (Fn->contains($dump, "length:2")) {
        return 0;
      }
      
    }
    
    return 1;
  }
  
  # get_seed, set_seed, and seed_initialized
  static method get_seed : int () {
    
    {
      my $seed = Fn->get_seed;
      
      unless ($seed == 0) {
        return 0;
      }
    }
    
    {
      my $seed_initialized = Fn->seed_initialized;
      
      unless ($seed_initialized == 0) {
        return 0;
      }
    }
    
    {
      Fn->set_seed(Fn->INT_MAX);
      
      unless (Fn->seed_initialized == 1) {
        return 0;
      }
      
      unless (Fn->get_seed == Fn->INT_MAX) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method get_basic_type_name_in_version_from : int () {
    
    {
      my $basic_type_name_in_version_from = Fn->get_basic_type_name_in_version_from("TestCase::Examples");
      
      unless ($basic_type_name_in_version_from eq "TestCase") {
        return 0;
      }
    }
    
    {
      my $basic_type_name_in_version_from = Fn->get_basic_type_name_in_version_from("TestCase::Empty");
      if ($basic_type_name_in_version_from) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        eval { Fn->get_basic_type_name_in_version_from(undef); };
        unless (Fn->contains($@, "The basic type name \$basic_type_name must be defined")) {
          return 0;
        }
      }
      {
        eval { Fn->get_basic_type_name_in_version_from("NotFoundClass"); };
        unless (Fn->contains($@, "The class specified by the basic type name \$basic_type_name must be loaded")) {
          return 0;
        }
      }
      
      $@ = undef;
    }
    
    return 1;
  }
  
  static method destroy_cache_class_vars : int () {
    
    $TestCase::Simple::CACHE_POINT = Point->new;
    
    $TestCase::Simple::NOT_CACHE_POINT = Point->new;
    
    Fn->destroy_cache_class_vars;
    
    if ($TestCase::Simple::CACHE_POINT) {
      return 0;
    }
    
    unless ($TestCase::Simple::NOT_CACHE_POINT) {
      return 0;
    }
    
    $TestCase::Simple::NOT_CACHE_POINT = undef;
    
    return 1;
  }
  
  static method destroy_runtime_permanent_vars : int () {
    
    $TestCase::Simple::CACHE_POINT = Point->new;
    
    $TestCase::Simple::NOT_CACHE_POINT = Point->new;
    
    $@ = "Error";
    
    Fn->destroy_runtime_permanent_vars;
    
    if ($TestCase::Simple::CACHE_POINT) {
      return 0;
    }
    
    unless ($TestCase::Simple::NOT_CACHE_POINT) {
      return 0;
    }
    
    if ($@) {
      return 0;
    }
    
    $TestCase::Simple::NOT_CACHE_POINT = undef;
    
    return 1;
  }
  
}