#line 1166 "/home/travis/build/felix-lang/felix/src/packages/arrays.fdoc"

Bounded sparse array.
Basically a sarray with a given bound.
The bound is ignored for get and set methods.
The bound is used for membership tests and iteration.
include "std/datatype/sarray";
open class Bsarray
{
private struct bsarray_ctl[T] { a: sarray[T]; n:size; };
type bsarray[T] = new &bsarray_ctl[T];

Contruct with default value and bound.
ctor[T,I in ints] bsarray[T] (dflt:T, bound:I) =>
_make_bsarray[T]\$ new bsarray_ctl[T] (sarray[T](dflt), bound.size)
;

Contrue as array value.
instance[T] ArrayValue[bsarray[T],T] {
fun len(b:bsarray[T])=> (_repr_ b)*.n;
fun unsafe_get(b:bsarray[T], i:size)=> get ((_repr_ b)*.a, i);
}

Contrue as array object.
instance[T] ArrayObject[bsarray[T],T] {
proc unsafe_set(b:bsarray[T], i:size, v:T)=> set ((_repr_ b)*.a, i, v);
}

Contrue as set: membership test.
instance[T with Eq[T]] Set[bsarray[T],T] {
// FIX ME: inefficient!
fun $$\in$$ (x:T, a:bsarray[T]) : bool = {
if len a > 0uz
for var i in 0uz upto len a - 1uz
if a.i == x return true
;
return false;
}
}

instance[T with Show[T]] Str[Bsarray::bsarray[T]] {
Convert to string.
fun str (xs:bsarray[T]) = {
var o = 'bsarray(';

if len xs > 0uz do
o += repr xs.0;

for var i in 1uz upto len xs - 1uz do
o += ', ' + repr xs.i;
done
done

return o + ')';
}
}
}

open[T] Show[Bsarray::bsarray[T]];
open[T] Set[Bsarray::bsarray[T],T];
open[T] ArrayValue[bsarray[T], T];
open[T] ArrayObject[bsarray[T], T];
open[T] ContiguousArrayObject[bsarray[T], T];