PreviousUpNext

15.4.885  src/lib/src/dynamic-rw-vector.pkg

## dynamic-rw-vector.pkg
#
# Dynamic (dense) rw_vector.
#
# -- Allen Leung

# Compiled by:
#     src/lib/std/standard.lib


# See also:
#     src/lib/src/expanding-rw-vector.pkg
#     src/lib/src/typelocked-expanding-rw-vector.api
#     ...
# Can we combine some of these, or do we really
# need all of them?  XXX BUGGO FIXME

# This package is (especially) used in:
#
#     src/lib/graph/digraph-by-adjacency-list.pkg
#

stipulate
    package rs  =  rw_vector_slice;                                                     # rw_vector_slice       is from   src/lib/std/src/rw-vector-slice.pkg
    package rwv =  rw_vector;                                                           # rw_vector             is from   src/lib/std/src/rw-vector.pkg
    package xns =  exceptions;                                                          # exceptions            is from   src/lib/std/exceptions.pkg
herein

    package dynamic_rw_vector
    : (weak)  
    api {
        include api Rw_Vector;                                                          # Rw_Vector             is from   src/lib/std/src/rw-vector.api
        from_array:  (rwv::Rw_Vector(X), X, Int) -> Rw_Vector(X);
        base_array:   Rw_Vector(X) -> rwv::Rw_Vector(X);
        check_array: (Rw_Vector(X), rwv::Rw_Vector(X)) -> Void;
        clear:       (Rw_Vector(X), Int) -> Void;
        expand_to:   (Rw_Vector(X), Int) -> Void;
    }
    {

        Vector(X) = rwv::Vector(X);

        Rw_Vector(X)
            =
            RW_VECTOR    (Ref( rwv::Rw_Vector(X) ), X, Ref( Int ));

        exception INDEX_OUT_OF_BOUNDS = xns::INDEX_OUT_OF_BOUNDS;
        exception SIZE                = xns::SIZE;
        exception UNIMPLEMENTED;

        infix my 9   get ;

        maximum_vector_length =  rwv::maximum_vector_length;

        fun make_rw_vector (n, d)            =  RW_VECTOR (REF (rwv::make_rw_vector (n, d)), d, REF 0); 
        fun clear (RW_VECTOR (a, def, count), n) =  { a := rwv::make_rw_vector (n, def); count := n;};
        fun from_array (a, d, n)             =  RW_VECTOR (REF a, d, REF n);

        fun base_array (RW_VECTOR (REF a, _, _)) = a;

        fun check_array (RW_VECTOR (REF a, _, _), a')
            =
            if   (a != a' )   raise exception MATCH;   fi;

        fun length (RW_VECTOR (REF a, _, REF n))
            =
            n;

        fun (RW_VECTOR (REF a, d, _)) get i
            =
            rwv::get (a, i)
            except
                _ = d;

        # Note:  The (_[])   enables   'vec[index]'           notation;
        #        The (_[]:=) enables   'vec[index] := value'  notation;

        (_[]) = (get);

        fun set (RW_VECTOR (r as REF a, d, n), i, e)
            =
            {   rwv::set (a, i, e);
                #
                n := int::max (*n, i+1);
            }
            except
                _ =
                {   new_size  = int::max (i+1,*n*2);
                    new_size  = if (new_size < 10 ) 10; else new_size;fi;
                    new_array = rwv::make_rw_vector (new_size, d);
                    rwv::copy { from => a, into => new_array, at => 0 };
                    r := new_array;
                    n := i+1;
                    rwv::set (new_array, i, e);
                };


        (_[]:=) = set;

        fun expand_to (v as RW_VECTOR(_, d, _), n)
            =
            set (v, n - 1, d);


        fun from_fn (n, f)
            = 
            {   rw_vector =  rwv::from_fn (n, f);
                default   =  rwv::get (rw_vector, 0);
                #
                RW_VECTOR (REF rw_vector, default, REF n);
            }
            except
                _ =  raise exception SIZE;


        fun from_list l
            =
            {   rw_vector = rwv::from_list l;
                default   = rwv::get (rw_vector, 0);
                #
                RW_VECTOR (REF rw_vector, default, REF (list::length l));
            }
            except
                _ =  raise exception SIZE;


        fun make_slice (RW_VECTOR (REF a, _, REF n))
            =
            rs::make_slice (a, 0, THE n);


        fun keyed_apply f v
            =
            rs::keyed_apply f (make_slice v);


        fun apply f v
            =
            rs::apply f (make_slice v);


        fun copy { from, into, at }
            =
            keyed_apply   (\\ (i, x) =  set (into, i + at, x))   from;


        fun copy_vector { from, into, at }
            =
            vector::keyed_apply   (\\ (i, x) =  set (into, i + at, x))   from;

        fun keyed_fold_forward  f init v =  rs::keyed_fold_forward  f init (make_slice v);
        fun keyed_fold_backward f init v =  rs::keyed_fold_backward f init (make_slice v);

        fun fold_forward  f init v =  rs::fold_forward  f init (make_slice v);
        fun fold_backward f init v =  rs::fold_backward f init (make_slice v);

        fun keyed_map_in_place f v =  rs::keyed_map_in_place f (make_slice v);
        fun map_in_place   f v =  rs::map_in_place   f (make_slice v);

        fun keyed_find p v =  rs::keyed_find p (make_slice v);
        fun find  p v =  rs::find  p (make_slice v);

        fun exists p v = rs::exists p (make_slice v);
        fun all p v    = rs::all    p (make_slice v);

        fun compare_sequences c (a1, a2) =  rs::compare_sequences c (make_slice a1, make_slice a2);
        fun to_vector v        =  rs::to_vector (make_slice v);
    };
end;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext