PreviousUpNext

15.4.1165  src/lib/std/src/rw-vector-of-one-byte-unts.pkg

## rw-vector-of-one-byte-unts.pkg

# Compiled by:
#     src/lib/std/src/standard-core.sublib

###                    "The motto stated a lie. If this nation has ever trusted in God,
###                     that time has gone by; for nearly half a century almost its
###                     entire trust has been in the Republican party and the dollar --
###                     mainly the dollar.
###
###                    "I recognize that I am only making an assertion and furnishing no proof;
###                     I am sorry, but this is a habit of mine; sorry also that I am not alone in it;
###                     everybody seems to have this disease."
###
###                                                    -- Mark Twain in Eruption



package rw_vector_of_one_byte_unts: (weak)  Typelocked_Rw_Vector                # Typelocked_Rw_Vector  is from   src/lib/std/src/typelocked-rw-vector.api
=
package {

    package a =  inline_t::rw_vector_of_one_byte_unts;  # inline_t      is from   src/lib/core/init/built-in.pkg
    package v =  inline_t::vector_of_one_byte_unts;


    # Fast add/subtract avoiding
    # the overflow test:
    #
    infix val  --- +++ ;
    #
    fun x --- y =  inline_t::tu::copyt_tagged_int (inline_t::tu::copyf_tagged_int x - inline_t::tu::copyf_tagged_int y);
    fun x +++ y =  inline_t::tu::copyt_tagged_int (inline_t::tu::copyf_tagged_int x + inline_t::tu::copyf_tagged_int y);


    # Unchecked access operations 
    #
    unsafe_set =  a::set;
    unsafe_get =  a::get;
    #
    ro_unsafe_set =  v::set;
    ro_unsafe_get =  v::get;
    ro_length     =  v::length;

    Rw_Vector =  a::Rw_Vector;
    Element   =  one_byte_unt::Unt;                     # one_byte_unt          is from   src/lib/std/types-only/basis-structs.pkg
    Vector    =  vector_of_one_byte_unts::Vector;               # vector_of_one_byte_unts       is from   src/lib/std/src/vector-of-one-byte-unts.pkg

    my empty_v:  Vector = inline_t::cast "";

    max_len = core::max_length;

    fun make_rw_vector (0, _)
            =>
            a::new_array0();

        make_rw_vector (len, v)
            =>
            if (inline_t::default_int::ltu (max_len, len))
                #
                raise exception exceptions_guts::SIZE;          # exceptions_guts       is from   src/lib/std/src/exceptions-guts.pkg
            else
                arr = runtime::asm::make_unt8_rw_vector len;

                init 0
                where
                    fun init i
                        =
                        if (i < len)
                            #
                            unsafe_set (arr, i, v);
                            init (i+1);
                        fi;
                end;

                arr;
            fi;
    end;

    fun tabulate (0, _)
            =>
            a::new_array0 ();

        tabulate (len, f)
            =>
            if (inline_t::default_int::ltu (max_len, len))
                #               
                raise exception exceptions_guts::SIZE;
            else
                arr = runtime::asm::make_unt8_rw_vector len;

                fun init i
                    =
                    if (i < len)
                        #
                        unsafe_set (arr, i, f i);
                        init (i+1);
                    fi;

                init 0;

                arr;
            fi;
    end;

    fun from_list []
            =>
            a::new_array0();

        from_list l
            =>
            {   fun length ([], n) => n;
                    length (_ ! r, n) => length (r, n+1);
                end;

                len =  length (l, 0);

                if (max_len < len)    raise exception exceptions_guts::SIZE;   fi;

                arr =  runtime::asm::make_unt8_rw_vector len;

                fun init ([], _)    =>  ();
                    init (c ! r, i) =>  {  unsafe_set (arr, i, c);   init (r, i+1);  };
                end;

                init (l, 0);

                arr;
            };
    end;

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

    length =  a::length;

    get     =  a::check_sub;
    (_[])   =  a::check_sub;

    set     =  a::check_set;
    (_[]:=) =  a::check_set;

    fun to_vector a
        =
        case (length a)
            #          
            0   => empty_v;
            #
            len =>
                {   my v:  vector_of_one_byte_unts::Vector
                        =
                        inline_t::cast  (runtime::asm::make_string  len);

                    fun fill i
                        =
                        if (i < len)
                            #
                            ro_unsafe_set (v, i, unsafe_get (a, i));
                            fill (i +++ 1);
                        fi;

                    fill 0;

                    v;
                };
        esac;

    fun copy { from, to, di }
        =
        {   sl =  length  from;
            de =  sl + di;

            fun copy_dn (s, d)
                =
                if (s >= 0)
                    #
                    unsafe_set (to, d, unsafe_get (from, s));
                    copy_dn (s --- 1, d --- 1);
                fi;

            if (di < 0   or   de > length to)
                #
                raise exception SUBSCRIPT;
            else
                copy_dn (sl --- 1, de --- 1);
            fi;
        };

    fun copy_vec { from, to, di }
        =
        {   sl =  ro_length  from;
            de =  sl + di;

            fun copy_dn (s, d)
                =
                if (s >= 0)
                    #
                    unsafe_set (to, d, ro_unsafe_get (from, s));
                    copy_dn (s --- 1, d --- 1);
                fi;

            if (di < 0  or  de > length to)
                # 
                raise exception SUBSCRIPT;
            else
                copy_dn (sl --- 1, de --- 1);
            fi;
        };

    fun keyed_apply f arr
        =
        apply 0
        where
            len =  length arr;

            fun apply i
                =
                if (i < len)
                    #
                    f (i, unsafe_get (arr, i));
                    apply (i +++ 1);
                fi;
        end;

    fun apply f arr
        =
        apply 0
        where
            len = length arr;

            fun apply i
                =
                if (i < len)
                    #
                    f (unsafe_get (arr, i));
                    apply (i +++ 1);
                fi;
        end;

    fun modifyi f arr
        =
        mdf 0
        where
            len = length arr;

            fun mdf i
                =
                if (i < len)
                    #
                    unsafe_set (arr, i, f (i, unsafe_get (arr, i)));
                    mdf (i +++ 1);
                fi;
        end;

    fun modify f arr
        =
        mdf 0
        where
            len = length arr;

            fun mdf i
                =
                if (i < len)
                    #
                    unsafe_set (arr, i, f (unsafe_get (arr, i)));
                    mdf (i +++ 1);
                fi;

        end;

    fun keyed_fold_left f init arr
        =
        fold (0, init)
        where

            len = length arr;

            fun fold (i, a)
                =
                if (i >= len)   a;
                else            fold (i +++ 1, f (i, unsafe_get (arr, i), a));
                fi;
        end;

    fun fold_left f init arr
        =
        fold (0, init)
        where
            len = length arr;

            fun fold (i, a)
                =
                if (i >= len)
                    #
                    a;
                else
                    fold (i +++ 1, f (unsafe_get (arr, i), a));
                fi;

        end;

    fun keyed_fold_right f init arr
        =
        fold (length arr --- 1, init)
        where
            fun fold (i, a)
                =
                if (i < 0)
                    #
                    a;
                else
                    fold (i --- 1, f (i, unsafe_get (arr, i), a));
                fi;
        end;

    fun fold_right f init arr
        =
        fold (length arr --- 1, init)
        where
            fun fold (i, a)
                =
                if (i < 0)
                    #
                    a;
                else
                    fold (i --- 1, f (unsafe_get (arr, i), a));
                fi;
        end;

    fun findi p arr
        =
        fnd 0
        where
            len = length arr;

            fun fnd i
                =
                if   (i >= len)
                    #
                    NULL;
                else
                    x = unsafe_get (arr, i);
                    #
                    if (p (i, x))   THE (i, x);
                    else            fnd (i +++ 1);
                    fi;
                fi;
        end;

    fun find p arr
        =
        fnd 0
        where
            len = length arr;

            fun fnd i
                =
                if (i >= len)
                    #
                    NULL;
                else
                    x = unsafe_get (arr, i);
                    #
                    if (p x)   THE x;
                    else       fnd (i +++ 1);
                    fi;
                fi;
        end;

    fun exists p arr
        =
        ex 0
        where
            len = length arr;

            fun ex i
                =
                i < len
                and
                (   p (unsafe_get (arr, i))
                    or
                    ex (i +++ 1)
                );
        end;

    fun all p arr
        =
        al 0
        where
            len =  length arr;

            fun al i
                =
                i >= len
                or
                (   p (unsafe_get (arr, i))
                    and
                    al (i +++ 1)
                );
        end;

    fun collate c (a1, a2)
        =
        coll 0
        where
            l1 = length a1;
            l2 = length a2;
            l12 = inline_t::ti::min (l1, l2);

            fun coll i
                =
                if (i >= l12)
                    #
                    int_guts::compare (l1, l2);
                else
                    case (c (unsafe_get (a1, i), unsafe_get (a2, i)))
                        #
                        EQUAL   =>  coll (i +++ 1);
                        unequal =>  unequal;
                    esac;
                fi;
        end;
};                                              #  package rw_vector_of_one_byte_unts 



Comments and suggestions to: bugs@mythryl.org

PreviousUpNext