## vector-of-chars.pkg
## Vectors of characters (also known as "strings").
# Compiled by:
#
src/lib/std/src/standard-core.sublibstipulate
package ig = int_guts; # int_guts is from
src/lib/std/src/int-guts.pkg package it = inline_t; # inline_t is from
src/lib/core/init/built-in.pkg package str = string_guts; # string_guts is from
src/lib/std/src/string-guts.pkgherein
package vector_of_chars
# ===============
#
: (weak) Typelocked_Vector # Typelocked_Vector is from
src/lib/std/src/typelocked-vector.api {
# Fast add/subtract avoiding
# the overflow test:
#
infix my --- +++ ;
#
fun x --- y = it::tu::copyt_tagged_int (it::tu::copyf_tagged_int x - it::tu::copyf_tagged_int y);
fun x +++ y = it::tu::copyt_tagged_int (it::tu::copyf_tagged_int x + it::tu::copyf_tagged_int y);
# my (op <) = it::default_int::(<)
# my (op >=) = it::default_int::(>=)
# my (op +) = it::default_int::(+)
unsafe_get = it::vector_of_chars::get_byte_as_char;
unsafe_set = it::vector_of_chars::set_char_as_byte;
Element = Char;
Vector = String;
maximum_vector_length = str::maximum_vector_length;
from_list = str::implode;
fun from_fn (0, _)
=>
"";
from_fn (n, f)
=>
{ if (it::default_int::ltu (maximum_vector_length, n))
#
raise exception exceptions_guts::SIZE;
fi;
ss = runtime::asm::make_string n;
fun fill i
=
if (i < n)
unsafe_set (ss, i, f i); fill (i +++ 1);
fi;
fill 0;
ss;
};
end;
length = it::vector_of_chars::length;
cat = str::cat;
get = it::vector_of_chars::get_byte_as_char_with_boundscheck;
fun set (v, i, x)
=
from_fn
( length v,
\\ i' = if (i == i') x;
else unsafe_get (v, i');
fi
);
(_[]) = get;
(_[]:=) = set;
fun keyed_apply f vec
=
apply 0
where
len = length vec;
fun apply i
=
if (i < len)
f (i, unsafe_get (vec, i));
apply (i +++ 1);
fi;
end;
fun apply f vec
=
apply 0
where
len = length vec;
fun apply i
=
if (i < len)
f (unsafe_get (vec, i));
apply (i +++ 1);
fi;
end;
fun keyed_map f vec
=
from_fn
( length vec,
\\ i = f (i, unsafe_get (vec, i))
);
map = str::map;
fun keyed_fold_forward f init vec
=
fold (0, init)
where
len = length vec;
fun fold (i, a)
=
if (i >= len) a;
else fold (i +++ 1, f (i, unsafe_get (vec, i), a));
fi;
end;
fun keyed_fold_backward f init vec
=
fold (length vec --- 1, init)
where
fun fold (i, a)
=
if (i < 0) a;
else fold (i --- 1, f (i, unsafe_get (vec, i), a));
fi;
end;
fun fold_forward f init vec
=
fold (0, init)
where
len = length vec;
fun fold (i, a)
=
if (i >= len) a;
else fold (i +++ 1, f (unsafe_get (vec, i), a));
fi;
end;
fun fold_backward f init vec
=
fold (length vec --- 1, init)
where
fun fold (i, a)
=
if (i < 0) a;
else fold (i --- 1, f (unsafe_get (vec, i), a));
fi;
end;
fun keyed_find p vec
=
fnd 0
where
len = length vec;
fun fnd i
=
if (i >= len)
NULL;
else
x = unsafe_get (vec, i);
if (p (i, x)) THE (i, x);
else fnd (i +++ 1);
fi;
fi;
end;
fun find p vec
=
fnd 0
where
len = length vec;
fun fnd i
=
if (i >= len)
NULL;
else
x = unsafe_get (vec, i);
#
if (p x) THE x;
else fnd (i +++ 1);
fi;
fi;
end;
fun exists p vec
=
ex 0
where
len = length vec;
fun ex i
=
i < len
and
( p (unsafe_get (vec, i))
or
ex (i +++ 1)
);
end;
fun all p vec
=
al 0
where
len = length vec;
fun al i
=
i >= len
or
( p (unsafe_get (vec, i))
and
al (i +++ 1)
);
end;
fun compare_sequences c (v1, v2)
=
col 0
where
l1 = length v1;
l2 = length v2;
l12 = it::ti::min (l1, l2);
fun col i
=
if (i >= l12)
#
ig::compare (l1, l2);
else
case (c (unsafe_get (v1, i), unsafe_get (v2, i)))
#
EQUAL => col (i +++ 1);
unequal => unequal;
esac;
fi;
end;
}; # package vector_of_chars
end;