class Fn : precompile {
use Cloner;
use EqualityChecker;
use Comparator::Byte;
use Comparator::Short;
use Comparator::Int;
use Comparator::Long;
use Comparator::Float;
use Comparator::Double;
use Comparator::String;
use Comparator;
use Stringer;
use Cloner;
use EqualityChecker;
use StringBuffer;
use StringList;
use Unicode;
use Regex;
native static method DBL_MAX : double ();
native static method DBL_MIN : double ();
native static method FLT_MAX : float ();
native static method FLT_MIN : float();
static method INT16_MAX : short () { return 32767; }
static method INT16_MIN : short () { return -32768; }
static method INT32_MAX : int () { return 2147483647; }
static method INT32_MIN : int () { return -2147483648; }
static method INT64_MAX : long () { return 9223372036854775807L; }
static method INT64_MIN : long () { return -9223372036854775808L; }
static method INT8_MAX : byte () { return 127; }
static method INT8_MIN : byte () { return -128; }
native static method RAND_MAX : int ();
static method UINT16_MAX : short () { return (short)0xFFFF; }
static method UINT32_MAX : int () { return 0xFFFFFFFF; }
static method UINT64_MAX : long () { return 0xFFFFFFFFFFFFFFFFL; }
static method UINT8_MAX : byte () { return (byte)0xFF; }
static method abs : int ($x : int) {
my $ret = 0;
if ($x > 0) {
$ret = $x;
}
else {
$ret = -$x;
}
return $ret;
}
static method chomp : void ($string : mutable string) {
unless ($string) {
return;
}
my $length = length $string;
if ($length > 0) {
if ($string->[$length - 1] == '\n') {
&shorten($string, $length - 1);
}
}
}
static method chompr : string ($string : string) {
unless ($string) {
return undef;
}
my $new_string : string;
my $length = length $string;
if ($length == 0) {
$new_string = copy $string;
}
else {
if ($string->[$length - 1] == '\n') {
$new_string = &substr($string, 0, $length - 1);
}
else {
$new_string = copy $string;
}
}
return $new_string;
}
static method chr : string ($unicode_code_point : int) {
my $is_unicode_scalar_value = Unicode->is_unicode_scalar_value($unicode_code_point);
my $utf8_char = (string)undef;
if ($is_unicode_scalar_value) {
$utf8_char = Unicode->uchar_to_utf8($unicode_code_point);
}
return $utf8_char;
}
static method copy_array_byte : byte[] ($nums : byte[]) {
return copy $nums;
}
static method copy_array_double : double[] ($nums : double[]) {
return copy $nums;
}
static method copy_array_float : float[] ($nums : float[]) {
return copy $nums;
}
static method copy_array_int : int[] ($nums : int[]) {
return copy $nums;
}
static method copy_array_long : long[] ($nums : long[]) {
return copy $nums;
}
static method copy_array_object : object[] ($objects : object[], $cloner : Cloner) {
if ($objects == undef) {
return undef;
}
my $length = @$objects;
my $new_objects = new object[$length];
for (my $i = 0; $i < $length; $i++) {
$new_objects->[$i] = $cloner->($objects->[$i]);
}
return $new_objects;
}
static method copy_array_range_byte : byte[] ($nums : byte[], $offset : int, $length : int) {
if ($nums == undef) {
die "The argument array must be defined";
}
my $array_length = @$nums;
if ($offset < 0 || $offset > $array_length - 1) {
die "Offset must be in the array range";
}
if ($length < 0) {
die "Length must be more than or equals to 0";
}
if ($offset + $length > $array_length) {
die "Offset + length must be in the array range";
}
my $range = new byte[$length];
my $pos = 0;
for (my $i = $offset; $i < $offset + $length; $i++) {
$range->[$pos] = $nums->[$i];
$pos++;
}
return $range;
}
static method copy_array_range_double : double[] ($nums : double[], $offset : int, $length : int) {
if ($nums == undef) {
die "The argument array must be defined";
}
my $array_length = @$nums;
if ($offset < 0 || $offset > $array_length - 1) {
die "Offset must be in the array range";
}
if ($length < 0) {
die "Length must be more than or equals to 0";
}
if ($offset + $length > $array_length) {
die "Offset + length must not be in the array range";
}
my $range = new double[$length];
my $pos = 0;
for (my $i = $offset; $i < $offset + $length; $i++) {
$range->[$pos] = $nums->[$i];
$pos++;
}
return $range;
}
static method copy_array_range_float : float[] ($nums : float[], $offset : int, $length : int) {
if ($nums == undef) {
die "The argument array must be defined";
}
my $array_length = @$nums;
if ($offset < 0 || $offset > $array_length - 1) {
die "Offset must be in the array range";
}
if ($length < 0) {
die "Length must be more than or equals to 0";
}
if ($offset + $length > $array_length) {
die "Offset + length must not be in the array range";
}
my $range = new float[$length];
my $pos = 0;
for (my $i = $offset; $i < $offset + $length; $i++) {
$range->[$pos] = $nums->[$i];
$pos++;
}
return $range;
}
static method copy_array_range_int : int[] ($nums : int[], $offset : int, $length : int) {
if ($nums == undef) {
die "The argument array must be defined";
}
my $array_length = @$nums;
if ($offset < 0 || $offset > $array_length - 1) {
die "Offset must be in the array range";
}
if ($length < 0) {
die "Length must be more than or equals to 0";
}
if ($offset + $length > $array_length) {
die "Offset + length must be in the array range";
}
my $range = new int[$length];
my $pos = 0;
for (my $i = $offset; $i < $offset + $length; $i++) {
$range->[$pos] = $nums->[$i];
$pos++;
}
return $range;
}
static method copy_array_range_long : long[] ($nums : long[], $offset : int, $length : int) {
if ($nums == undef) {
die "The argument array must be defined";
}
my $array_length = @$nums;
if ($offset < 0 || $offset > $array_length - 1) {
die "Offset must be in the array range";
}
if ($length < 0) {
die "Length must be more than or equals to 0";
}
if ($offset + $length > $array_length) {
die "Offset + length must not be in the array range";
}
my $range = new long[$length];
my $pos = 0;
for (my $i = $offset; $i < $offset + $length; $i++) {
$range->[$pos] = $nums->[$i];
$pos++;
}
return $range;
}
static method copy_array_range_object : object[] ($objects : object[], $offset : int, $length : int) {
if ($objects == undef) {
die "The argument array must be defined";
}
my $array_length = @$objects;
if ($offset < 0 || $offset > $array_length - 1) {
die "Offset must be in the array range";
}
if ($length < 0) {
die "Length must be more than or equals to 0";
}
if ($offset + $length > $array_length) {
die "Offset + length must not be in the array range";
}
my $range = Fn->new_array_proto($objects, $length);
my $pos = 0;
for (my $i = $offset; $i < $offset + $length; $i++) {
$range->[$pos] = $objects->[$i];
$pos++;
}
return $range;
}
static method copy_array_range_short : short[] ($nums : short[], $offset : int, $length : int) {
if ($nums == undef) {
die "The argument array must be defined";
}
my $array_length = @$nums;
if ($offset < 0 || $offset > $array_length - 1) {
die "Offset must be in the array range";
}
if ($length < 0) {
die "Length must be more than or equals to 0";
}
if ($offset + $length > $array_length) {
die "Offset + length must be in the array range";
}
my $range = new short[$length];
my $pos = 0;
for (my $i = $offset; $i < $offset + $length; $i++) {
$range->[$pos] = $nums->[$i];
$pos++;
}
return $range;
}
static method copy_array_range_string : string[] ($strings : string[], $offset : int, $length : int) {
if ($strings == undef) {
die "The argument array must be defined";
}
my $array_length = @$strings;
if ($offset < 0 || $offset > $array_length - 1) {
die "Offset must be in the array range";
}
if ($length < 0) {
die "Length must be more than or equals to 0";
}
if ($offset + $length > $array_length) {
die "Offset + length must not be in the array range";
}
my $range = new string[$length];
my $pos = 0;
for (my $i = $offset; $i < $offset + $length; $i++) {
$range->[$pos] = $strings->[$i];
$pos++;
}
return $range;
}
static method copy_array_short : short[] ($nums : short[]) {
return copy $nums;
}
static method copy_array_string : string[] ($strings : string[]) {
if ($strings == undef) {
return undef;
}
my $length = @$strings;
my $new_strings = new string[$length];
for (my $i = 0; $i < $length; $i++) {
$new_strings->[$i] = copy $strings->[$i];
}
return $new_strings;
}
static method copy_string : string ($string : string) {
return copy $string;
}
native static method crand : int ($seed : int*);
static method dump_array_byte : string ($nums : byte[]) {
if ($nums == undef) {
return undef;
}
my $dump = "[\n";
for (my $i = 0; $i < @$nums; $i++) {
my $string = (string)$nums->[$i];
$dump .= " $string";
if ($i != @$nums - 1) {
$dump .= ",\n";
}
else {
$dump .= "\n";
}
}
$dump .= "]";
return $dump;
}
static method dump_array_double : string ($nums : double[]) {
if ($nums == undef) {
return undef;
}
my $dump = "[\n";
for (my $i = 0; $i < @$nums; $i++) {
my $string = (string)$nums->[$i];
$dump .= " $string";
if ($i != @$nums - 1) {
$dump .= ",\n";
}
else {
$dump .= "\n";
}
}
$dump .= "]";
return $dump;
}
static method dump_array_float : string ($nums : float[]) {
if ($nums == undef) {
return undef;
}
my $dump = "[\n";
for (my $i = 0; $i < @$nums; $i++) {
my $string = (string)$nums->[$i];
$dump .= " $string";
if ($i != @$nums - 1) {
$dump .= ",\n";
}
else {
$dump .= "\n";
}
}
$dump .= "]";
return $dump;
}
static method dump_array_int : string ($nums : int[]) {
if ($nums == undef) {
return undef;
}
my $dump = "[\n";
for (my $i = 0; $i < @$nums; $i++) {
my $string = (string)$nums->[$i];
$dump .= " $string";
if ($i != @$nums - 1) {
$dump .= ",\n";
}
else {
$dump .= "\n";
}
}
$dump .= "]";
return $dump;
}
static method dump_array_long : string ($nums : long[]) {
if ($nums == undef) {
return undef;
}
my $dump = "[\n";
for (my $i = 0; $i < @$nums; $i++) {
my $string = (string)$nums->[$i];
$dump .= " $string";
if ($i != @$nums - 1) {
$dump .= ",\n";
}
else {
$dump .= "\n";
}
}
$dump .= "]";
return $dump;
}
static method dump_array_object : string ($objects : object[], $stringer : Stringer) {
if ($objects == undef) {
return undef;
}
my $dump = "[\n";
for (my $i = 0; $i < @$objects; $i++) {
my $string = $stringer->($objects->[$i]);
$dump .= " $string";
if ($i != @$objects - 1) {
$dump .= ",\n";
}
else {
$dump .= "\n";
}
}
$dump .= "]";
return $dump;
}
static method dump_array_short : string ($nums : short[]) {
if ($nums == undef) {
return undef;
}
my $dump = "[\n";
for (my $i = 0; $i < @$nums; $i++) {
my $string = (string)$nums->[$i];
$dump .= " $string";
if ($i != @$nums - 1) {
$dump .= ",\n";
}
else {
$dump .= "\n";
}
}
$dump .= "]";
return $dump;
}
static method dump_array_string : string ($strings : string[]) {
if ($strings == undef) {
return undef;
}
my $dump = "[\n";
for (my $i = 0; $i < @$strings; $i++) {
my $string = $strings->[$i];
$dump .= " $string";
if ($i != @$strings - 1) {
$dump .= ",\n";
}
else {
$dump .= "\n";
}
}
$dump .= "]";
return $dump;
}
static method dump_array_unsigned_byte : string ($nums : byte[]) {
if ($nums == undef) {
return undef;
}
my $dump = "[\n";
for (my $i = 0; $i < @$nums; $i++) {
my $string = Fn->sprintf("%u", (int)$nums->[$i] & 0xFF);
$dump .= " $string";
if ($i != @$nums - 1) {
$dump .= ",\n";
}
else {
$dump .= "\n";
}
}
$dump .= "]";
return $dump;
}
static method dump_array_unsigned_int : string ($nums : int[]) {
if ($nums == undef) {
return undef;
}
my $dump = "[\n";
for (my $i = 0; $i < @$nums; $i++) {
my $string = Fn->sprintf("%u", $nums->[$i]);
$dump .= " $string";
if ($i != @$nums - 1) {
$dump .= ",\n";
}
else {
$dump .= "\n";
}
}
$dump .= "]";
return $dump;
}
static method dump_array_unsigned_long : string ($nums : long[]) {
if ($nums == undef) {
return undef;
}
my $dump = "[\n";
for (my $i = 0; $i < @$nums; $i++) {
my $string = Fn->sprintf("%lu", $nums->[$i]);
$dump .= " $string";
if ($i != @$nums - 1) {
$dump .= ",\n";
}
else {
$dump .= "\n";
}
}
$dump .= "]";
return $dump;
}
static method dump_array_unsigned_short : string ($nums : short[]) {
if ($nums == undef) {
return undef;
}
my $dump = "[\n";
for (my $i = 0; $i < @$nums; $i++) {
my $string = Fn->sprintf("%u", (int)$nums->[$i] & 0xFFFF);
$dump .= " $string";
if ($i != @$nums - 1) {
$dump .= ",\n";
}
else {
$dump .= "\n";
}
}
$dump .= "]";
return $dump;
}
static method equals_array_byte : int ($nums1 : byte[], $nums2 : byte[]) {
if ($nums1 == undef && $nums2 == undef) {
return 1;
}
elsif ($nums1 != undef && $nums2 == undef) {
return 0;
}
elsif ($nums1 == undef && $nums2 != undef) {
return 0;
}
my $is_equals = 1;
if (@$nums1 == @$nums2) {
for (my $i = 0; $i < @$nums1; $i++) {
if ($nums1->[$i] != $nums2->[$i]) {
$is_equals = 0;
last;
}
}
}
else {
$is_equals = 0;
}
return $is_equals;
}
static method equals_array_double : int ($nums1 : double[], $nums2 : double[]) {
if ($nums1 == undef && $nums2 == undef) {
return 1;
}
elsif ($nums1 != undef && $nums2 == undef) {
return 0;
}
elsif ($nums1 == undef && $nums2 != undef) {
return 0;
}
my $is_equals = 1;
if (@$nums1 == @$nums2) {
for (my $i = 0; $i < @$nums1; $i++) {
if ($nums1->[$i] != $nums2->[$i]) {
$is_equals = 0;
last;
}
}
}
else {
$is_equals = 0;
}
return $is_equals;
}
static method equals_array_float : int ($nums1 : float[], $nums2 : float[]) {
if ($nums1 == undef && $nums2 == undef) {
return 1;
}
elsif ($nums1 != undef && $nums2 == undef) {
return 0;
}
elsif ($nums1 == undef && $nums2 != undef) {
return 0;
}
my $is_equals = 1;
if (@$nums1 == @$nums2) {
for (my $i = 0; $i < @$nums1; $i++) {
if ($nums1->[$i] != $nums2->[$i]) {
$is_equals = 0;
last;
}
}
}
else {
$is_equals = 0;
}
return $is_equals;
}
static method equals_array_int : int ($nums1 : int[], $nums2 : int[]) {
if ($nums1 == undef && $nums2 == undef) {
return 1;
}
elsif ($nums1 != undef && $nums2 == undef) {
return 0;
}
elsif ($nums1 == undef && $nums2 != undef) {
return 0;
}
my $is_equals = 1;
if (@$nums1 == @$nums2) {
for (my $i = 0; $i < @$nums1; $i++) {
if ($nums1->[$i] != $nums2->[$i]) {
$is_equals = 0;
last;
}
}
}
else {
$is_equals = 0;
}
return $is_equals;
}
static method equals_array_long : int ($nums1 : long[], $nums2 : long[]) {
if ($nums1 == undef && $nums2 == undef) {
return 1;
}
elsif ($nums1 != undef && $nums2 == undef) {
return 0;
}
elsif ($nums1 == undef && $nums2 != undef) {
return 0;
}
my $is_equals = 1;
if (@$nums1 == @$nums2) {
for (my $i = 0; $i < @$nums1; $i++) {
if ($nums1->[$i] != $nums2->[$i]) {
$is_equals = 0;
last;
}
}
}
else {
$is_equals = 0;
}
return $is_equals;
}
static method equals_array_object : int ($objects1 : object[], $objects2 : object[], $equality_checker : EqualityChecker) {
if ($objects1 == undef && $objects2 == undef) {
return 1;
}
elsif ($objects1 != undef && $objects2 == undef) {
return 0;
}
elsif ($objects1 == undef && $objects2 != undef) {
return 0;
}
my $is_equals = 1;
if (@$objects1 == @$objects2) {
for (my $i = 0; $i < @$objects1; $i++) {
if (!$equality_checker->($objects1->[$i], $objects2->[$i])) {
$is_equals = 0;
last;
}
}
}
else {
$is_equals = 0;
}
return $is_equals;
}
static method equals_array_short : int ($nums1 : short[], $nums2 : short[]) {
if ($nums1 == undef && $nums2 == undef) {
return 1;
}
elsif ($nums1 != undef && $nums2 == undef) {
return 0;
}
elsif ($nums1 == undef && $nums2 != undef) {
return 0;
}
my $is_equals = 1;
if (@$nums1 == @$nums2) {
for (my $i = 0; $i < @$nums1; $i++) {
if ($nums1->[$i] != $nums2->[$i]) {
$is_equals = 0;
last;
}
}
}
else {
$is_equals = 0;
}
return $is_equals;
}
static method equals_array_string : int ($strings1 : string[], $strings2 : string[]) {
if ($strings1 == undef && $strings2 == undef) {
return 1;
}
elsif ($strings1 != undef && $strings2 == undef) {
return 0;
}
elsif ($strings1 == undef && $strings2 != undef) {
return 0;
}
my $is_equals = 1;
if (@$strings1 == @$strings2) {
for (my $i = 0; $i < @$strings1; $i++) {
if ($strings1->[$i] ne $strings2->[$i]) {
$is_equals = 0;
last;
}
}
}
else {
$is_equals = 0;
}
return $is_equals;
}
static method hex : int ($hex_string : string) {
unless ($hex_string) {
die "the hex string must be defined";
}
my $re = Regex->new("^([0-9a-fA-F]{1,8})$");
my $hex_value = 0;
my $digit = 0;
my $value = 0;
if ($re->match($hex_string, 0)) {
my $length = length $hex_string;
for (my $i = $length - 1; $i >= 0; $i--) {
my $ascii_code = $hex_string->[$i];
my $digit_value = 0;
if ($ascii_code >= '0' && $ascii_code <= '9') {
$digit_value = $ascii_code - 48;
}
elsif ($ascii_code >= 'a' && $ascii_code <= 'f') {
$digit_value = $ascii_code - 87;
}
elsif ($ascii_code >= 'A' && $ascii_code <= 'F') {
$digit_value = $ascii_code - 55;
}
$value += $digit_value * Fn->powi(16, $digit);
$digit += 1;
}
}
else {
die "the hex string must be a valid expression";
}
return $value;
}
static method index : int ($string : string, $sub_string : string, $start_pos : int) {
return &index_len($string, $sub_string, $start_pos, length $string);
}
static method index_len : int ($string : string, $sub_string : string, $start_pos : int, $max_string_length : int) {
my $sub_string_length = length $sub_string;
if ($max_string_length > length $string) {
$max_string_length = length $string;
}
if ($start_pos >= $max_string_length) {
my $ret : int;
if ($sub_string_length == 0) {
$ret = $max_string_length;
}
else {
$ret = -1;
}
return $ret;
}
if ($start_pos < 0) {
$start_pos = 0;
}
if ($sub_string_length == 0) {
return $start_pos;
}
my $first : byte = $sub_string->[0];
my $max : int = ($max_string_length - $sub_string_length);
for (my $i = $start_pos; $i <= $max; $i++) {
if ($string->[$i] != $first) {
while (++$i <= $max && $string->[$i] != $first) {}
}
if ($i <= $max) {
my $j = $i + 1;
my $end = $j + $sub_string_length - 1;
for (my $k = 01; $j < $end && $string->[$j] == $sub_string->[$k]; ($j++, $k++)) {}
if ($j == $end) {
return $i;
}
}
}
return -1;
}
# The argument type of following charcter checking functions are int, not byte. This is intentinal.
# ASCII code is represented by byte type.
# On the other hand, Unicode Code Point can be represented by int tyep.
# Unicode Code Point is upper compatibility of ASCII code.
# So the following character check functions receive int type argument.
static method is_alnum : int ($code_point : int) {
if (($code_point >= 'A' && $code_point <= 'Z') || ($code_point >= 'a' && $code_point <= 'z') || ($code_point >= '0' && $code_point <= '9')) {
return 1;
}
else {
return 0;
}
}
static method is_alpha : int ($code_point : int) {
if (($code_point >= 'A' && $code_point <= 'Z') || ($code_point >= 'a' && $code_point <= 'z')) {
return 1;
}
else {
return 0;
}
}
native static method is_array : int ($object : object);
static method is_blank : int ($code_point : int) {
if ($code_point >= ' ' || $code_point <= '\t') {
return 1;
}
else {
return 0;
}
}
static method is_cntrl : int ($code_point : int) {
if (($code_point >= 0x00 && $code_point <= 0x1f) || $code_point == 0x7f) {
return 1;
}
else {
return 0;
}
}
static method is_digit : int ($code_point : int) {
if ($code_point >= '0' && $code_point <= '9') {
return 1;
}
else {
return 0;
}
}
static method is_graph : int ($code_point : int) {
if ($code_point >= 0x21 && $code_point <= 0x7e) {
return 1;
}
else {
return 0;
}
}
static method is_lower : int ($code_point : int) {
if ($code_point >= 'a' && $code_point <= 'z') {
return 1;
}
else {
return 0;
}
}
native static method is_mulnum_array : int ($object : object);
native static method is_numeric_array : int ($object : object);
native static method is_object_array : int ($object : object);
# This is same as Perl \s
static method is_perl_space : int ($code_point : int) {
my $ispspace = 0;
switch ($code_point) {
case ' ':
case '\r':
case '\n':
case '\t':
case '\f':
{
$ispspace = 1;
break;
}
}
return $ispspace;
}
static method is_perl_word : int ($code_point : int) {
my $ispword = 0;
if ($code_point >= 'a' && $code_point <= 'z') {
$ispword = 1;
}
elsif ($code_point >= 'A' && $code_point <= 'Z') {
$ispword = 1;
}
elsif ($code_point == '_') {
$ispword = 1;
}
elsif ($code_point >= '0' && $code_point <= '9') {
$ispword = 1;
}
return $ispword;
}
static method is_print : int ($code_point : int) {
if ($code_point >= 0x20 && $code_point <= 0x7e) {
return 1;
}
else {
return 0;
}
}
static method is_punct : int ($code_point : int) {
if (($code_point >= 0x21 && $code_point <= 0x2f) || ($code_point >= 0x3a && $code_point <= 0x40) || ($code_point >= 0x5b && $code_point <= 0x60) || ($code_point >= 0x7b && $code_point <= 0x7e)) {
return 1;
}
else {
return 0;
}
}
static method is_space : int ($code_point : int) {
if (($code_point >= 0x09 && $code_point <= 0x0d) || $code_point == 0x20) {
return 1;
}
else {
return 0;
}
}
static method is_upper : int ($code_point : int) {
if ($code_point >= 'A' && $code_point <= 'Z') {
return 1;
}
else {
return 0;
}
}
static method is_xdigit : int ($code_point : int) {
if (($code_point >= 'A' && $code_point <= 'F') || ($code_point >= 'a' && $code_point <= 'f') || ($code_point >= '0' && $code_point <= '9')) {
return 1;
}
else {
return 0;
}
}
static method join : string ($sep : string, $strings : string[]) {
my $join = "";
for (my $i = 0; $i < @$strings; $i++) {
my $string = $strings->[$i];
$join .= $string;
if ($i != @$strings - 1) {
$join .= $sep;
}
}
return $join;
}
static method labs : long ($x : long) {
my $ret = 0L;
if ($x > 0) {
$ret = $x;
}
else {
$ret = -$x;
}
return $ret;
}
static method lc : string ($string : string) {
unless ($string) { die "String must be defined"; }
my $length = length $string;
my $new_string = (mutable string)new_string_len($length);
for (my $i = 0; $i < $length; $i++) {
my $char = $string->[$i];
if ($char >= 'A' && $char <= 'Z') {
$new_string->[$i] = (byte)($string->[$i] + 32);
}
else {
$new_string->[$i] = $string->[$i];
}
}
return (string)$new_string;
}
static method lcfirst : string ($string : string) {
unless ($string) { die "String must be defined"; }
my $length = length $string;
my $new_string = (mutable string)new_string_len($length);
if ($length > 0) {
my $char = $string->[0];
if ($char >= 'A' && $char <= 'Z') {
$new_string->[0] = (byte)($char + 32);
}
else {
$new_string->[0] = $char;
}
}
for (my $i = 1; $i < $length; ++$i) {
$new_string->[$i] = $string->[$i];
}
return (string)$new_string;
}
static method match : Regex ($string : string, $regex_string : string, $regex_options_opt : string[]...) {
my $regex_options = (string)undef;
if (@$regex_options_opt > 0) {
$regex_options = $regex_options_opt->[0];
}
my $regex = (Regex)undef;
if ($regex_options) {
$regex = Regex->new_with_options($regex_string, $regex_options);
}
else {
$regex = Regex->new($regex_string);
}
my $match = $regex->match($string, 0);
if ($match) {
return $regex;
}
else {
return undef;
}
}
native static method memcpy : void ($dest : object, $dest_byte_offset : int, $source : object, $source_byte_offset : int, $byte_length : int);
native static method memcpy_byte : void ($dest : byte[], $dest_offset : int, $source : byte[], $source_offset : int, $length : int);
native static method memcpy_double : void ($dest : double[], $dest_offset : int, $source : double[], $source_offset : int, $length : int);
native static method memcpy_float : void ($dest : float[], $dest_offset : int, $source : float[], $source_offset : int, $length : int);
native static method memcpy_int : void ($dest : int[], $dest_offset : int, $source : int[], $source_offset : int, $length : int);
native static method memcpy_long : void ($dest : long[], $dest_offset : int, $source : long[], $source_offset : int, $length : int);
native static method memcpy_short : void ($dest : short[], $dest_offset : int, $source : short[], $source_offset : int, $length : int);
native static method memmove : void ($dest : object, $dest_byte_offset : int, $source : object, $source_byte_offset : int, $byte_length : int);
native static method memmove_byte : void ($dest : byte[], $dest_offset : int, $source : byte[], $source_offset : int, $length : int);
native static method memmove_double : void ($dest : double[], $dest_offset : int, $source : double[], $source_offset : int, $length : int);
native static method memmove_float : void ($dest : float[], $dest_offset : int, $source : float[], $source_offset : int, $length : int);
native static method memmove_int : void ($dest : int[], $dest_offset : int, $source : int[], $source_offset : int, $length : int);
native static method memmove_long : void ($dest : long[], $dest_offset : int, $source : long[], $source_offset : int, $length : int);
native static method memmove_short : void ($dest : short[], $dest_offset : int, $source : short[], $source_offset : int, $length : int);
native static method new_array_proto : object[] ($proto_array : object[], $length : int);
static method ord : int ($utf8_character : string) {
unless ($utf8_character) {
return -1;
}
if (length $utf8_character == 0) {
return -1;
}
my $offset = 0;
my $unicode_code_point = Unicode->uchar($utf8_character, \$offset);
return $unicode_code_point;
}
static method powi : int ($x : int, $y : int) {
my $p = 1;
for (my $i = 0; $i < $y; $i++) {
$p = $p * $x;
}
return $p;
}
static method powl : long ($x : long, $y : long) {
my $p = 1L;
for (my $i = 0; $i < $y; $i++) {
$p = $p * $x;
}
return $p;
}
static method rand : double ($seed : int*) {
# 0 <= random_number < 1
my $random_number = (double)Fn->crand($seed) / ((double)Fn->RAND_MAX() + 1);
return $random_number;
}
static method repeat : string ($string : string, $count : int) {
unless ($string) {
die "The string must be defined";
}
unless ($count > 0) {
die "The repeat count must be more than 0";
}
my $buffer = StringBuffer->new;
for (my $i = 0; $i < $count; $i++) {
$buffer->push($string);
}
my $repeat_string = $buffer->to_string;
return $repeat_string;
}
static method replace : string ($string : string, $regex_string : string, $replace_string_or_replacer : object, $regex_options_opt : string[]...) {
my $regex_options = (string)undef;
if (@$regex_options_opt > 0) {
$regex_options = $regex_options_opt->[0];
}
my $regex = (Regex)undef;
my $replace_all = 0;
if ($regex_options) {
$regex = Regex->new_with_options($regex_string, $regex_options);
if (Fn->index($regex_options, "g", 0) > -1) {
$replace_all = 1;
}
}
else {
$regex = Regex->new($regex_string);
}
my $replace_string = (string)undef;
my $replacer = (Regex::Replacer)undef;
if ($replace_string_or_replacer isa string) {
$replace_string = (string)$replace_string_or_replacer;
}
elsif ($replace_string_or_replacer isa Regex::Replacer) {
$replacer = (Regex::Replacer)$replace_string_or_replacer;
}
else {
die "The sencond argument must be a object that type is the string type or Regex::Replacer";
}
my $result = (string)undef;
if ($replace_all) {
if ($replace_string) {
$result = $regex->replace_all($string, 0, $replace_string);
}
else {
$result = $regex->replace_all_cb($string, 0, $replacer);
}
}
else {
if ($replace_string) {
$result = $regex->replace($string, 0, $replace_string);
}
else {
$result = $regex->replace_cb($string, 0, $replacer);
}
}
return $result;
}
static method rindex : int ($string : string, $sub_string : string, $start_pos : int) {
return &rindex_len($string, $sub_string, $start_pos, length $string);
}
static method rindex_len : int ($string : string, $sub_string : string, $start_pos : int, $max_string_length : int) {
my $sub_string_length = length $sub_string;
if ($max_string_length > length $string) {
$max_string_length = length $string;
}
my $sub_string_len = length $sub_string;
if ($start_pos > $max_string_length - $sub_string_length) {
$start_pos = $max_string_length - $sub_string_len;
}
for (my $i = $start_pos; $i >= 0; --$i) {
my $match = 1;
for (my $j = 0; $j < $sub_string_len; ++$j) {
if ($string->[$i + $j] != $sub_string->[$j]) {
$match = 0;
last;
}
}
if ($match) {
return $i;
}
}
return -1;
}
static method sort_byte : void ($nums : byte[], $offset : int, $length : int, $comparator : Comparator::Byte) {
if ($nums == undef) {
die "Array must be not undef";
}
my $nums_length = @$nums;
if ($offset < 0) {
die "Offset must be more than or equals to 0";
}
if ($length < 0) {
die "Length must be more than or equals to 0";
}
if ($offset + $length > $nums_length) {
die "Offset + Length must be in the array range";
}
if ($length == 0) {
return;
}
my $b = new byte[$length];
Fn->_sort_byte_merge_sort($nums, $b, $offset, $offset + $length - 1, $length - 1, $comparator);
}
native static method shorten : void ($string : mutable string, $length : int);
static method sort_double : void ($nums : double[], $offset : int, $length : int, $comparator : Comparator::Double) {
if ($nums == undef) {
die "Array must be not undef";
}
my $nums_length = @$nums;
if ($offset < 0) {
die "Offset must be more than or equals to 0";
}
if ($length < 0) {
die "Length must be more than or equals to 0";
}
if ($offset + $length > $nums_length) {
die "Offset + Length must be in the array range";
}
if ($length == 0) {
return;
}
my $b = new double[$length];
Fn->_sort_double_merge_sort($nums, $b, $offset, $offset + $length - 1, $length - 1, $comparator);
}
static method sort_float : void ($nums : float[], $offset : int, $length : int, $comparator : Comparator::Float) {
if ($nums == undef) {
die "Array must be not undef";
}
my $nums_length = @$nums;
if ($offset < 0) {
die "Offset must be more than or equals to 0";
}
if ($length < 0) {
die "Length must be more than or equals to 0";
}
if ($offset + $length > $nums_length) {
die "Offset + Length must be in the array range";
}
if ($length == 0) {
return;
}
my $b = new float[$length];
Fn->_sort_float_merge_sort($nums, $b, $offset, $offset + $length - 1, $length - 1, $comparator);
}
static method sort_int : void ($nums : int[], $offset : int, $length : int, $comparator : Comparator::Int) {
if ($nums == undef) {
die "Array must be not undef";
}
my $nums_length = @$nums;
if ($offset < 0) {
die "Offset must be more than or equals to 0";
}
if ($length < 0) {
die "Length must be more than or equals to 0";
}
if ($offset + $length > $nums_length) {
die "Offset + Length must be in the array range";
}
if ($length == 0) {
return;
}
my $b = new int[$length];
Fn->_sort_int_merge_sort($nums, $b, $offset, $offset + $length - 1, $length - 1, $comparator);
}
static method sort_long : void ($nums : long[], $offset : int, $length : int, $comparator : Comparator::Long) {
if ($nums == undef) {
die "Array must be not undef";
}
my $nums_length = @$nums;
if ($offset < 0) {
die "Offset must be more than or equals to 0";
}
if ($length < 0) {
die "Length must be more than or equals to 0";
}
if ($offset + $length > $nums_length) {
die "Offset + Length must be in the array range";
}
if ($length == 0) {
return;
}
my $b = new long[$length];
Fn->_sort_long_merge_sort($nums, $b, $offset, $offset + $length - 1, $length - 1, $comparator);
}
static method sort_object : void ($objects : object[], $offset : int, $length : int, $comparator : Comparator) {
if ($objects == undef) {
die "Array must be not undef";
}
my $objects_length = @$objects;
if ($offset < 0) {
die "Offset must be more than or equals to 0";
}
if ($length < 0) {
die "Length must be more than or equals to 0";
}
if ($offset + $length > $objects_length) {
die "Offset + Length must be in the array range";
}
my $b = Fn->new_array_proto($objects, $length);
Fn->_sort_object_merge_sort($objects, $b, $offset, $offset + $length - 1, $length - 1, $comparator);
}
static method sort_short : void ($nums : short[], $offset : int, $length : int, $comparator : Comparator::Short) {
if ($nums == undef) {
die "Array must be not undef";
}
my $nums_length = @$nums;
if ($offset < 0) {
die "Offset must be more than or equals to 0";
}
if ($length < 0) {
die "Length must be more than or equals to 0";
}
if ($offset + $length > $nums_length) {
die "Offset + Length must be in the array range";
}
if ($length == 0) {
return;
}
my $b = new short[$length];
Fn->_sort_short_merge_sort($nums, $b, $offset, $offset + $length - 1, $length - 1, $comparator);
}
static method sort_string : void ($strings : string[], $offset : int, $length : int, $comparator : Comparator::String) {
if ($strings == undef) {
die "Array must be not undef";
}
my $strings_length = @$strings;
if ($offset < 0) {
die "Offset must be more than or equals to 0";
}
if ($length < 0) {
die "Length must be more than or equals to 0";
}
if ($offset + $length > $strings_length) {
die "Offset + Length must be in the array range";
}
my $b = new string[$length];
Fn->_sort_string_merge_sort($strings, $b, $offset, $offset + $length - 1, $length - 1, $comparator);
}
static method split : string[] ($sep : string, $string : string) {
my $string_length = length $string;
my $sep_length = length $sep;
if ($sep_length == 0) {
die "Separator must not be empty string";
}
my $separated_strings_list = StringList->new_len(0);
my $match_start = 0;
my $string_base = 0;
for (my $string_index = 0; $string_index < $string_length; $string_index++) {
if ($string->[$string_index] == $sep->[0]) {
$match_start = 1;
}
if ($match_start) {
my $match = 1;
for (my $sep_index = 0; $sep_index < $sep_length; $sep_index++) {
if ($string_index + $sep_index > $string_length - 1) {
$match = 0;
last;
}
else {
unless ($string->[$string_index + $sep_index] == $sep->[$sep_index]) {
$match = 0;
last;
}
}
}
if ($match) {
my $separated_string = Fn->substr($string, $string_base, $string_index - $string_base);
$separated_strings_list->push($separated_string);
$string_base = $string_index + $sep_length;
$string_index += $sep_length - 1;
}
}
}
if ($string_base == $string_length) {
$separated_strings_list->push("");
}
else {
my $separated_string = Fn->substr($string, $string_base, $string_length - $string_base);
$separated_strings_list->push($separated_string);
}
my $separated_strings = $separated_strings_list->to_array;
return $separated_strings;
}
static method sprintf : string ($format : string, $args : object[]...) {
my $format_length = length $format;
my $index = 0;
my $buffer = StringBuffer->new;
my $arg_count = 0;
my $constant_string_length = 0;
while ($index + $constant_string_length < $format_length) {
if ($format->[$index + $constant_string_length] != '%') {
# Read constant string
++$constant_string_length;
}
elsif ($index + $constant_string_length + 1 < $format_length &&
$format->[$index + $constant_string_length + 1] == '%') {
# Read %%
++$constant_string_length;
# Add constant string
if ($constant_string_length > 0) {
my $format_part = Fn->substr($format, $index, $constant_string_length);
$buffer->push($format_part);
$index += $constant_string_length;
$constant_string_length = 0;
}
# Skip second %
++$index;
}
elsif ($index + $constant_string_length + 1 >= $format_length) {
die "Invalid conversion in sprintf: end of string";
}
else {
# Add constant string
if ($constant_string_length > 0) {
my $format_part = Fn->substr($format, $index, $constant_string_length);
$buffer->push($format_part);
$index += $constant_string_length;
$constant_string_length = 0;
}
# Read format string
# Check the next element of @$args corresponding to the specifier
unless ($arg_count < @$args) {
die "Missing argument in sprintf";
}
# Read specifier %[flags][width][.precision][length]type
my $specifier_base_index = $index;
++$index; # '%'
# Read `flags`
my $pad_char = ' ';
my $plus_sign = 0;
my $left_justified = 0;
while ($index < $format_length) {
my $flag = (int)($format->[$index]);
switch($flag) {
case '0': {
++$index;
$pad_char = '0';
break;
}
case '+': {
++$index;
$plus_sign = 1;
break;
}
case '-': {
++$index;
$left_justified = 1;
break;
}
default: {
last;
break;
}
}
}
if ($left_justified) {
$pad_char = ' ';
}
# Width
my $width = 0;
while ($index < $format_length) {
my $c = $format->[$index];
if ($c < '0' || '9' < $c) {
last;
}
$width = $width * 10 + $c - '0';
++$index;
}
# Precision
my $precision = 0;
my $has_precision = 0;
if ($index < $format_length && $format->[$index] == '.') {
++$index;
while ($index < $format_length) {
my $c = $format->[$index];
if ($c < '0' || '9' < $c) {
last;
}
$has_precision = 1;
$precision = $precision * 10 + $c - '0';
++$index;
}
}
unless ($has_precision) {
$precision = -1;
}
unless ($index < $format_length) {
die "Invalid conversion in sprintf: \""
. Fn->substr($format, $specifier_base_index, $index - $specifier_base_index) . "\"";
}
my $specifier_first_char = $format->[$index];
$index++;
my $specifier = (string)"";
switch ((int) $specifier_first_char) {
case 'c' : {
$specifier = "c";
break;
}
case 's' : {
$specifier = "s";
break;
}
case 'd' : {
$specifier = "d";
break;
}
case 'u' : {
$specifier = "u";
break;
}
case 'l' : {
if ($index < length $format) {
if ($format->[$index] == 'd') {
$index++;
$specifier = "ld";
}
elsif ($format->[$index] == 'u') {
$index++;
$specifier = "lu";
}
elsif ($format->[$index] == 'x') {
$index++;
$specifier = "lx";
}
elsif ($format->[$index] == 'X') {
$index++;
$specifier = "lX";
}
}
break;
}
case 'f' : {
$specifier = "f";
break;
}
case 'g' : {
$specifier = "g";
break;
}
case 'U' : {
$specifier = "U";
break;
}
case 'x' : {
$specifier = "x";
break;
}
case 'X' : {
$specifier = "X";
break;
}
default: {
}
}
if ($specifier eq "c") {
my $arg_value : int;
my $arg = $args->[$arg_count];
if ($arg isa Byte) {
$arg_value = $arg->(Byte)->value;
}
else {
$arg_value = $arg->(Int)->value;
}
my $formatted_value = Fn->chr($arg_value);
&_push_formatted_string_unsigned($buffer, $formatted_value, $width, $pad_char, $left_justified);
}
elsif ($specifier eq "s") {
my $arg = (string)$args->[$arg_count];
my $formatted_value = $arg;
&_push_formatted_string_unsigned($buffer, $formatted_value, $width, $pad_char, $left_justified);
}
elsif ($specifier eq "d") {
my $arg = (Int)$args->[$arg_count];
my $formatted_value = &_native_snprintf_d($arg);
&_push_formatted_string_signed($buffer, $formatted_value, $width, $pad_char, $left_justified, $plus_sign);
}
elsif ($specifier eq "u") {
my $arg = (Int)$args->[$arg_count];
my $formatted_value = &_native_snprintf_u($arg);
&_push_formatted_string_unsigned($buffer, $formatted_value, $width, $pad_char, $left_justified);
}
elsif ($specifier eq "ld") {
my $arg = (Long)$args->[$arg_count];
my $formatted_value = &_native_snprintf_ld($arg);
&_push_formatted_string_signed($buffer, $formatted_value, $width, $pad_char, $left_justified, $plus_sign);
}
elsif ($specifier eq "lu") {
my $arg = (Long)$args->[$arg_count];
my $formatted_value = &_native_snprintf_lu($arg);
&_push_formatted_string_unsigned($buffer, $formatted_value, $width, $pad_char, $left_justified);
}
elsif ($specifier eq "f") {
my $arg_value : double;
my $arg = $args->[$arg_count];
if ($arg isa Float) {
$arg_value = $arg->(Float)->value;
}
else {
$arg_value = $arg->(Double)->value;
}
my $formatted_value = &_native_snprintf_f($arg_value, $precision);
&_push_formatted_string_signed($buffer, $formatted_value, $width, $pad_char, $left_justified, $plus_sign);
}
elsif ($specifier eq "g") {
my $arg_value : double;
my $arg = $args->[$arg_count];
if ($arg isa Float) {
$arg_value = $arg->(Float)->value;
}
else {
$arg_value = $arg->(Double)->value;
}
my $formatted_value = &_native_snprintf_g($arg_value, $precision);
&_push_formatted_string_signed($buffer, $formatted_value, $width, $pad_char, $left_justified, $plus_sign);
}
elsif ($specifier eq "x" || $specifier eq "X") {
my $arg = (Int)$args->[$arg_count];
my $formatted_value = &_native_snprintf_x($arg);
if ($specifier eq "X") {
$formatted_value = Fn->uc($formatted_value);
}
&_push_formatted_string_unsigned($buffer, $formatted_value, $width, $pad_char, $left_justified);
}
elsif ($specifier eq "lx" || $specifier eq "lX") {
my $arg = (Long)$args->[$arg_count];
my $formatted_value = &_native_snprintf_lx($arg);
if ($specifier eq "lX") {
$formatted_value = Fn->uc($formatted_value);
}
&_push_formatted_string_unsigned($buffer, $formatted_value, $width, $pad_char, $left_justified);
}
else {
die "Invalid specifier \"%$specifier\"";
}
++$arg_count;
}
}
# Add constant string
if ($constant_string_length > 0) {
my $format_part = Fn->substr($format, $index, $constant_string_length);
$buffer->push($format_part);
$index += $constant_string_length;
$constant_string_length = 0;
}
my $result = $buffer->to_string;
return $result;
}
native static method _native_snprintf_d : string ($value : int);
native static method _native_snprintf_ld : string ($value : long);
native static method _native_snprintf_lu : string ($value : long);
native static method _native_snprintf_u : string ($value : int);
native static method _native_snprintf_x : string ($value : int);
native static method _native_snprintf_lx : string ($value : long);
native static method _native_snprintf_f : string ($value : double, $precision : int);
native static method _native_snprintf_g : string ($value : double, $precision : int);
static method _push_formatted_string_unsigned : void($buffer : StringBuffer, $formatted_value : string, $width : int, $pad_char : byte, $left_justified : int) {
# "+" sign is always ignored.
my $plus_sign = 0;
&_push_formatted_string_signed($buffer, $formatted_value, $width, $pad_char, $left_justified, $plus_sign);
}
static method _push_formatted_string_signed : void($buffer : StringBuffer, $formatted_value : string, $width : int, $pad_char : byte, $left_justified : int, $plus_sign : int) {
my $is_minus = 0;
if ($formatted_value->[0] == '-') {
$is_minus = 1;
}
my $space_count = $width - length $formatted_value;
if (!$is_minus && $plus_sign) {
--$space_count;
}
if ($left_justified) {
if (!$is_minus && $plus_sign) {
$buffer->push_char('+');
}
$buffer->push($formatted_value);
if ($space_count > 0) {
for (; $space_count > 0; --$space_count) {
$buffer->push_char($pad_char);
}
}
}
else {
if ($space_count > 0) {
for (; $space_count > 0; --$space_count) {
$buffer->push_char($pad_char);
}
}
if (!$is_minus && $plus_sign) {
$buffer->push_char('+');
}
$buffer->push($formatted_value);
}
}
static method substr : string ($string : string, $offset : int, $length : int) {
if ($string == undef) {
die "String must be defined";
}
my $string_length = length $string;
if ($offset < 0 || $offset > $string_length - 1) {
die "Invalid offset $offset";
}
if ($length < 0) {
die "Length must be non-zero value";
}
if ($offset + $length > $string_length) {
die "Offset + length must not be over array length";
}
my $slice = (mutable string)new_string_len($length);
my $pos = 0;
for (my $i = $offset; $i < $offset + $length; $i++) {
$slice->[$pos] = $string->[$i];
$pos++;
}
return $slice;
}
native static method to_double : double ($string : string);
native static method to_float : float ($string : string);
static method to_int : int ($string : string) {
return Fn->to_int_with_base($string, 10);
}
native static method to_int_with_base : int ($string : string, $digit : int);
static method to_long : long ($string : string) {
return Fn->to_long_with_base($string, 10);
}
native static method to_long_with_base : long ($string : string, $digit : int);
static method to_lower : int ($code_point : int) {
if ($code_point >= 'A' && $code_point <= 'Z') {
$code_point = $code_point + 0x20;
}
return $code_point;
}
static method to_upper : int ($code_point : int) {
if ($code_point >= 'a' && $code_point <= 'z') {
$code_point = $code_point - 0x20;
}
return $code_point;
}
static method trim_ascii_space : string ($string : string) {
unless ($string) {
return undef;
}
my $length = length $string;
my $start_string_index = -1;
my $end_string_index = -1;
for (my $i = 0; $i < $length; $i++) {
if ($start_string_index == -1) {
if (Fn->is_space($string->[$i])) {
# Skip
}
else {
$start_string_index = $i;
last;
}
}
}
for (my $i = $length - 1; $i >= 0; $i--) {
if ($end_string_index == -1) {
if (Fn->is_space($string->[$i])) {
# Skip
}
else {
$end_string_index = $i;
last;
}
}
}
my $trimed_string : string;
if ($start_string_index == -1 && $end_string_index == -1) {
return "";
}
elsif ($end_string_index == -1) {
$trimed_string = Fn->substr($string, $start_string_index, $length - $start_string_index);
}
elsif ($end_string_index == -1) {
$trimed_string = Fn->substr($string, 0, $end_string_index + 1);
}
else {
$trimed_string = Fn->substr($string, $start_string_index, $end_string_index - $start_string_index + 1);
}
return $trimed_string;
}
static method uc : string ($string : string) {
unless ($string) { die "String must be defined"; }
my $length = length $string;
my $new_string = (mutable string)new_string_len($length);
for (my $i = 0; $i < $length; $i++) {
my $char = $string->[$i];
if ($char >= 'a' && $char <= 'z') {
$new_string->[$i] = (byte)($string->[$i] - 32);
}
else {
$new_string->[$i] = $string->[$i];
}
}
return $new_string;
}
static method ucfirst : string ($string : string) {
unless ($string) { die "String must be defined"; }
my $length = length $string;
my $new_string = (mutable string)new_string_len($length);
if ($length > 0) {
my $char = $string->[0];
if ($char >= 'a' && $char <= 'z') {
$new_string->[0] = (byte)($char - 32);
}
else {
$new_string->[0] = $char;
}
}
for (my $i = 1; $i < $length; ++$i) {
$new_string->[$i] = $string->[$i];
}
return $new_string;
}
native static method _snsprintf_double : string ($format : string, $value : double);
private static method _sort_byte_merge : void($a : byte[], $b : byte[], $left : int, $mid : int, $right : int, $n : int, $comparator : Comparator::Byte) {
my $i = $left;
my $j = $mid + 1;
my $k = 0;
while ($i <= $mid && $j <= $right) {
$i = $left;
$j = $mid + 1;
$k = 0;
while ($i <= $mid && $j <= $right) {
if ($comparator->($a->[$i], $a->[$j]) <= 0) {
$b->[$k] = $a->[$i];
$i++;
} else {
$b->[$k] = $a->[$j];
$j++;
}
$k++;
}
if ($i == $mid + 1) {
while ($j <= $right) {
$b->[$k] = $a->[$j];
$j++;
$k++;
}
} else {
while($i <= $mid) {
$b->[$k] = $a->[$i];
$i++;
$k++;
}
}
}
for ($i = 0; $i < $k; $i++) {
$a->[$i + $left] = $b->[$i];
}
}
private static method _sort_byte_merge_sort : void($a : byte[], $b : byte[], $left : int, $right : int, $n : int, $comparator : Comparator::Byte){
if ($left >= $right) {
return;
}
my $mid = ($left + $right) / 2;
Fn->_sort_byte_merge_sort($a, $b, $left, $mid, $n, $comparator);
Fn->_sort_byte_merge_sort($a, $b, $mid + 1, $right, $n, $comparator);
Fn->_sort_byte_merge($a, $b, $left, $mid, $right, $n, $comparator);
}
private static method _sort_short_merge : void($a : short[], $b : short[], $left : int, $mid : int, $right : int, $n : int, $comparator : Comparator::Short) {
my $i = $left;
my $j = $mid + 1;
my $k = 0;
while ($i <= $mid && $j <= $right) {
$i = $left;
$j = $mid + 1;
$k = 0;
while ($i <= $mid && $j <= $right) {
if ($comparator->($a->[$i], $a->[$j]) <= 0) {
$b->[$k] = $a->[$i];
$i++;
} else {
$b->[$k] = $a->[$j];
$j++;
}
$k++;
}
if ($i == $mid + 1) {
while ($j <= $right) {
$b->[$k] = $a->[$j];
$j++;
$k++;
}
} else {
while($i <= $mid) {
$b->[$k] = $a->[$i];
$i++;
$k++;
}
}
}
for ($i = 0; $i < $k; $i++) {
$a->[$i + $left] = $b->[$i];
}
}
private static method _sort_short_merge_sort : void($a : short[], $b : short[], $left : int, $right : int, $n : int, $comparator : Comparator::Short){
if ($left >= $right) {
return;
}
my $mid = ($left + $right) / 2;
Fn->_sort_short_merge_sort($a, $b, $left, $mid, $n, $comparator);
Fn->_sort_short_merge_sort($a, $b, $mid + 1, $right, $n, $comparator);
Fn->_sort_short_merge($a, $b, $left, $mid, $right, $n, $comparator);
}
private static method _sort_int_merge : void($a : int[], $b : int[], $left : int, $mid : int, $right : int, $n : int, $comparator : Comparator::Int) {
my $i = $left;
my $j = $mid + 1;
my $k = 0;
while ($i <= $mid && $j <= $right) {
$i = $left;
$j = $mid + 1;
$k = 0;
while ($i <= $mid && $j <= $right) {
if ($comparator->($a->[$i], $a->[$j]) <= 0) {
$b->[$k] = $a->[$i];
$i++;
} else {
$b->[$k] = $a->[$j];
$j++;
}
$k++;
}
if ($i == $mid + 1) {
while ($j <= $right) {
$b->[$k] = $a->[$j];
$j++;
$k++;
}
} else {
while($i <= $mid) {
$b->[$k] = $a->[$i];
$i++;
$k++;
}
}
}
for ($i = 0; $i < $k; $i++) {
$a->[$i + $left] = $b->[$i];
}
}
private static method _sort_int_merge_sort : void($a : int[], $b : int[], $left : int, $right : int, $n : int, $comparator : Comparator::Int){
if ($left >= $right) {
return;
}
my $mid = ($left + $right) / 2;
Fn->_sort_int_merge_sort($a, $b, $left, $mid, $n, $comparator);
Fn->_sort_int_merge_sort($a, $b, $mid + 1, $right, $n, $comparator);
Fn->_sort_int_merge($a, $b, $left, $mid, $right, $n, $comparator);
}
private static method _sort_long_merge : void($a : long[], $b : long[], $left : int, $mid : int, $right : int, $n : int, $comparator : Comparator::Long) {
my $i = $left;
my $j = $mid + 1;
my $k = 0;
while ($i <= $mid && $j <= $right) {
$i = $left;
$j = $mid + 1;
$k = 0;
while ($i <= $mid && $j <= $right) {
if ($comparator->($a->[$i], $a->[$j]) <= 0) {
$b->[$k] = $a->[$i];
$i++;
} else {
$b->[$k] = $a->[$j];
$j++;
}
$k++;
}
if ($i == $mid + 1) {
while ($j <= $right) {
$b->[$k] = $a->[$j];
$j++;
$k++;
}
} else {
while($i <= $mid) {
$b->[$k] = $a->[$i];
$i++;
$k++;
}
}
}
for ($i = 0; $i < $k; $i++) {
$a->[$i + $left] = $b->[$i];
}
}
private static method _sort_long_merge_sort : void($a : long[], $b : long[], $left : int, $right : int, $n : int, $comparator : Comparator::Long){
if ($left >= $right) {
return;
}
my $mid = ($left + $right) / 2;
Fn->_sort_long_merge_sort($a, $b, $left, $mid, $n, $comparator);
Fn->_sort_long_merge_sort($a, $b, $mid + 1, $right, $n, $comparator);
Fn->_sort_long_merge($a, $b, $left, $mid, $right, $n, $comparator);
}
private static method _sort_float_merge : void($a : float[], $b : float[], $left : int, $mid : int, $right : int, $n : int, $comparator : Comparator::Float) {
my $i = $left;
my $j = $mid + 1;
my $k = 0;
while ($i <= $mid && $j <= $right) {
$i = $left;
$j = $mid + 1;
$k = 0;
while ($i <= $mid && $j <= $right) {
if ($comparator->($a->[$i], $a->[$j]) <= 0) {
$b->[$k] = $a->[$i];
$i++;
} else {
$b->[$k] = $a->[$j];
$j++;
}
$k++;
}
if ($i == $mid + 1) {
while ($j <= $right) {
$b->[$k] = $a->[$j];
$j++;
$k++;
}
} else {
while($i <= $mid) {
$b->[$k] = $a->[$i];
$i++;
$k++;
}
}
}
for ($i = 0; $i < $k; $i++) {
$a->[$i + $left] = $b->[$i];
}
}
private static method _sort_float_merge_sort : void($a : float[], $b : float[], $left : int, $right : int, $n : int, $comparator : Comparator::Float){
if ($left >= $right) {
return;
}
my $mid = ($left + $right) / 2;
Fn->_sort_float_merge_sort($a, $b, $left, $mid, $n, $comparator);
Fn->_sort_float_merge_sort($a, $b, $mid + 1, $right, $n, $comparator);
Fn->_sort_float_merge($a, $b, $left, $mid, $right, $n, $comparator);
}
private static method _sort_double_merge : void($a : double[], $b : double[], $left : int, $mid : int, $right : int, $n : int, $comparator : Comparator::Double) {
my $i = $left;
my $j = $mid + 1;
my $k = 0;
while ($i <= $mid && $j <= $right) {
$i = $left;
$j = $mid + 1;
$k = 0;
while ($i <= $mid && $j <= $right) {
if ($comparator->($a->[$i], $a->[$j]) <= 0) {
$b->[$k] = $a->[$i];
$i++;
} else {
$b->[$k] = $a->[$j];
$j++;
}
$k++;
}
if ($i == $mid + 1) {
while ($j <= $right) {
$b->[$k] = $a->[$j];
$j++;
$k++;
}
} else {
while($i <= $mid) {
$b->[$k] = $a->[$i];
$i++;
$k++;
}
}
}
for ($i = 0; $i < $k; $i++) {
$a->[$i + $left] = $b->[$i];
}
}
private static method _sort_double_merge_sort : void($a : double[], $b : double[], $left : int, $right : int, $n : int, $comparator : Comparator::Double){
if ($left >= $right) {
return;
}
my $mid = ($left + $right) / 2;
Fn->_sort_double_merge_sort($a, $b, $left, $mid, $n, $comparator);
Fn->_sort_double_merge_sort($a, $b, $mid + 1, $right, $n, $comparator);
Fn->_sort_double_merge($a, $b, $left, $mid, $right, $n, $comparator);
}
private static method _sort_string_merge : void($a : string[], $b : string[], $left : int, $mid : int, $right : int, $n : int, $comparator : Comparator::String) {
my $i = $left;
my $j = $mid + 1;
my $k = 0;
while ($i <= $mid && $j <= $right) {
$i = $left;
$j = $mid + 1;
$k = 0;
while ($i <= $mid && $j <= $right) {
if ($comparator->($a->[$i], $a->[$j]) <= 0) {
$b->[$k] = $a->[$i];
$i++;
} else {
$b->[$k] = $a->[$j];
$j++;
}
$k++;
}
if ($i == $mid + 1) {
while ($j <= $right) {
$b->[$k] = $a->[$j];
$j++;
$k++;
}
} else {
while($i <= $mid) {
$b->[$k] = $a->[$i];
$i++;
$k++;
}
}
}
for ($i = 0; $i < $k; $i++) {
$a->[$i + $left] = $b->[$i];
}
}
private static method _sort_string_merge_sort : void($a : string[], $b : string[], $left : int, $right : int, $n : int, $comparator : Comparator::String){
if ($left >= $right) {
return;
}
my $mid = ($left + $right) / 2;
Fn->_sort_string_merge_sort($a, $b, $left, $mid, $n, $comparator);
Fn->_sort_string_merge_sort($a, $b, $mid + 1, $right, $n, $comparator);
Fn->_sort_string_merge($a, $b, $left, $mid, $right, $n, $comparator);
}
private static method _sort_object_merge : void($a : object[], $b : object[], $left : int, $mid : int, $right : int, $n : int, $comparator : Comparator) {
my $i = $left;
my $j = $mid + 1;
my $k = 0;
while ($i <= $mid && $j <= $right) {
$i = $left;
$j = $mid + 1;
$k = 0;
while ($i <= $mid && $j <= $right) {
if ($comparator->($a->[$i], $a->[$j]) <= 0) {
$b->[$k] = $a->[$i];
$i++;
} else {
$b->[$k] = $a->[$j];
$j++;
}
$k++;
}
if ($i == $mid + 1) {
while ($j <= $right) {
$b->[$k] = $a->[$j];
$j++;
$k++;
}
} else {
while($i <= $mid) {
$b->[$k] = $a->[$i];
$i++;
$k++;
}
}
}
for ($i = 0; $i < $k; $i++) {
$a->[$i + $left] = $b->[$i];
}
}
private static method _sort_object_merge_sort : void($a : object[], $b : object[], $left : int, $right : int, $n : int, $comparator : Comparator){
if ($left >= $right) {
return;
}
my $mid = ($left + $right) / 2;
Fn->_sort_object_merge_sort($a, $b, $left, $mid, $n, $comparator);
Fn->_sort_object_merge_sort($a, $b, $mid + 1, $right, $n, $comparator);
Fn->_sort_object_merge($a, $b, $left, $mid, $right, $n, $comparator);
}
}