PreviousUpNext

15.4.1194  src/lib/std/src/rw-vector-of-eight-byte-floats.pkg

## rw-vector-of-eight-byte-floats.pkg

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

###                      "It has been said that man is a rational animal.
###
###                       All my life I have been searching for evidence
###                       which could support this."
###
###                                              -- Bertrand Russell



stipulate
    package ig  =  int_guts;                                                    # int_guts              is from   src/lib/std/src/int-guts.pkg
    package inl =  inline_t;                                                    # inline_t              is from   src/lib/core/init/built-in.pkg
    package rt  =  runtime;                                                     # runtime               is from   src/lib/core/init/built-in.pkg.
    package g2d =  exceptions_guts;                                             # exceptions_guts       is from   src/lib/std/src/exceptions-guts.pkg
herein

    package  rw_vector_of_eight_byte_floats
    #        ==============================
    #
    : (weak)  Typelocked_Rw_Vector                                              # Typelocked_Rw_Vector  is from   src/lib/std/src/typelocked-rw-vector.api
    {
        # Fast add/subtract avoiding
        # the overflow test:
        #
        infix my --- +++;
        #
        fun x --- y
            =
            inl::tu::copyt_tagged_int (inl::tu::copyf_tagged_int x -
                                                 inl::tu::copyf_tagged_int y);

        fun x +++ y
            =
            inl::tu::copyt_tagged_int (inl::tu::copyf_tagged_int x +
                                                 inl::tu::copyf_tagged_int y);


        # Unchecked access operations 

        unsafe_set =  inl::rw_vector_of_eight_byte_floats::set;
        unsafe_get =  inl::rw_vector_of_eight_byte_floats::get;

    #   ro_unsafe_set =  inl::vector_of_eight_byte_floats::update     # not yet *

        ro_unsafe_get =  inl::vector_of_eight_byte_floats::get;
        ro_length =  inl::vector_of_eight_byte_floats::length;

        Rw_Vector =  rt::asm::Float64_Rw_Vector;
        Element   =  float64::Float;
        Vector    =  vector_of_eight_byte_floats::Vector;

        maximum_vector_length =  core::maximum_vector_length;


        fun make_rw_vector (0, _)
                =>
                inl::rw_vector_of_eight_byte_floats::make_zero_length_vector();

            make_rw_vector (len, v)
                =>
                vec
                where
                    if (inl::default_int::ltu (maximum_vector_length, len))    raise exception g2d::SIZE;               fi;
                    #
                    vec =  rt::asm::make_float64_rw_vector  len;

                    for (i = 0;  i < len;  ++i) {
                        #
                        unsafe_set (vec, i, v);
                    };  
                end;
            end;


        fun from_fn (0, _) =>   inl::rw_vector_of_eight_byte_floats::make_zero_length_vector();
            #
            from_fn (len, f)
                =>
                vec
                where
                    if (inl::default_int::ltu (maximum_vector_length, len))   raise exception g2d::SIZE;        fi;                             # exceptions_guts       is from   src/lib/std/src/exceptions-guts.pkg
                    #
                    vec =  rt::asm::make_float64_rw_vector len;

                    init 0
                    where
                        fun init i =    if (i < len)    unsafe_set (vec,  i,  f i);
                                                        init (i+1);
                                        fi;
                    end;
                end;
        end;


        fun from_list [] =>   inl::rw_vector_of_eight_byte_floats::make_zero_length_vector();
            #
            from_list l
                =>
                v
                where
                    fun length ([],     n) =>  n;
                        length (_ ! r,  n) =>  length (r, n+1);
                    end;

                    len = length (l, 0);

                    if (len > maximum_vector_length)   raise exception  g2d::SIZE;   fi;

                    v =  rt::asm::make_float64_rw_vector len;

                    init (l, 0)
                    where
                        fun init ([],        _) =>   ();
                            init (c ! rest,  i)
                                =>
                                {   unsafe_set (v, i, c);
                                    #
                                    init (rest, i+1);
                                };
                        end;
                    end;
                end;
        end;

        length  = inl::rw_vector_of_eight_byte_floats::length;

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

        get     = inl::rw_vector_of_eight_byte_floats::get_with_boundscheck;
        (_[])   = inl::rw_vector_of_eight_byte_floats::get_with_boundscheck;

        set     = inl::rw_vector_of_eight_byte_floats::set_with_boundscheck;
        (_[]:=) = inl::rw_vector_of_eight_byte_floats::set_with_boundscheck;

        fun to_vector a
            =
            vector_of_eight_byte_floats::from_fn
                ( length a,
                   \\ i = unsafe_get (a, i)
                );


        fun copy { from, into, at }
            =
            {   if (at < 0   or   de > length into)       raise exception INDEX_OUT_OF_BOUNDS;   fi;
                #
                copy_dn (sl --- 1, de --- 1);
            }
            where 
                sl = length from;
                de = at + sl;

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


        fun copy_vector { from, into, at }
            =
            {   sl = ro_length from;
                de = at + sl;

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

                if (at < 0  or  de > length into)   raise exception  INDEX_OUT_OF_BOUNDS;   fi;

                copy_dn (sl --- 1, de --- 1);
            };

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

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

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

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

        fun keyed_map_in_place f v
            =
            mdf 0
            where
                len = length v;

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

        fun map_in_place f v
            =
            mdf 0
            where
                len = length v;

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

        fun keyed_fold_forward f init v
            =
            fold (0, init)
            where
                len = length v;

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

        fun fold_forward f init v
            =
            fold (0, init)
            where
                len = length v;

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

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

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

        fun keyed_find p v
            =
            fnd 0
            where
                len = length v;

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

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

                fun fnd i
                    =
                    if (i >= len)
                        #
                        NULL;
                    else
                        x = unsafe_get (v, i);

                        if (p x)  THE x;
                        else      fnd (i +++ 1);
                        fi;
                    fi;
            end;

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

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

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

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

        fun compare_sequences c (a1, a2)
            =
            col 0
            where
                l1  = length a1;
                l2  = length a2;
                l12 = inl::ti::min (l1, l2);

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



Comments and suggestions to: bugs@mythryl.org

PreviousUpNext