PreviousUpNext

15.4.1232  src/lib/std/src/vector-of-chars.pkg

## vector-of-chars.pkg
## Vectors of characters (also known as "strings").

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

stipulate
    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.pkg
herein

    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;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext