package body X0seq is



    --START AT BEGINNING OF SEQUENCE

    procedure Reset (S : in out Sequence) is



    begin

        S.Before := null;

        S.After := S.Head;

    end Reset;



    --READ NEXT MEMBER INTO C

    procedure Get_Next (S : in out Sequence; C : out Element_Type) is

    begin

        --    IF

        --      S.AFTER = NULL

        --    THEN

        --      RAISE NO_ELEMENT;

        --    ELSE

        C := S.After.Sdata;

        S.Before := S.After;

        S.After := S.After.Next;

        --    END IF;

    end Get_Next;



    --TRUNCATE DATA AFTER POINTER AND WRITE NEXT MEMBER OF S FROM C

    procedure Put_Next (S : in out Sequence; C : in Element_Type) is

    begin

        if

           S.After = null

            then

            S.After := new Sdata_Type;

        end if;

        if

           S.Head = null

            then

            S.Head := S.After;

        end if;

        if

           S.Before /= null and then S.Before.Next = null

            then

            S.Before.Next := S.After;

        end if;

        S.After.Sdata := C;

        S.After.Next := null;

        S.After.Previous := S.Before;

        S.Before := S.After;

        S.Tail := S.After;

        S.After := S.After.Next;



    end Put_Next;



    --READ CURRENT MEMBER INTO C (REREAD)

    procedure Get_Current (S : in Sequence; C : out Element_Type) is

    begin

        --    IF

        --       S.BEFORE = NULL

        --    THEN

        --       RAISE NO_ELEMENT;

        --    ELSE

        C := S.Before.Sdata;

        --    END IF;

    end Get_Current;



    --WRITE CURRENT MEMBER OF S FROM C (UPDATE)

    procedure Put_Current (S : in out Sequence; C : in Element_Type) is

    begin

        --    IF

        --      S.BEFORE = NULL

        --    THEN

        --      RAISE NO_ELEMENT;

        --    ELSE

        S.Before.Sdata := C;

        --    END IF;

    end Put_Current;



    --READ CURRENT MEMBER INTO C AND DELETE CURRENT MEMBER

    procedure Get_Mid (S : in out Sequence; C : out Element_Type) is

    begin

        --    IF

        --      S.BEFORE = NULL

        --    THEN

        --      RAISE NO_ELEMENT;

        --    ELSE

        C := S.Before.Sdata;

        S.Before.Previous.Next := S.After;

        S.After.Previous := S.Before.Previous;

        S.Before := S.Before.Previous;

        --    END IF;

    end Get_Mid;



    --INSERT MEMBER FROM C BEFORE CURRENT MEMBER

    procedure Put_Mid (S : in out Sequence; C : in Element_Type) is

        Temp : Link;

    begin

        Temp := new Sdata_Type;

        Temp.Sdata := C;

        if

           S.Before = null

            then

            S.Before := Temp;

            S.Head := Temp;

            Temp.Previous := null;

            Temp.Next := S.After;

        else

            Temp.Previous := S.Before.Previous;

            Temp.Next := S.Before;

            S.Before.Previous.Next := Temp;

            S.Before.Previous := Temp;

        end if;

    end Put_Mid;



    --TRUNCATE SEQUENCE AFTER POINTER

    procedure Make_Empty_To_End (S : in out Sequence) is

    begin

        S.Tail := S.Before;

        S.After := null;

        S.Before.Next := null;

    end Make_Empty_To_End;





    --TEST FOR NO MEMBERS AFTER POINTER

    function Is_Empty_To_End (S : in Sequence) return Boolean is

    begin

        return S.After = null;

    end Is_Empty_To_End;



    --TEST FOR MEMBERS AFTER POINTER

    function Is_Not_Empty_To_End (S : in Sequence) return Boolean is

    begin

        return S.After /= null;

    end Is_Not_Empty_To_End;



    --COPY ONE SEQUENCE TO ANOTHER SEQUENCE

    procedure Assign (Sin : in Sequence; Sout : out Sequence) is

        Scan : Link := Sin.Head;

        Scan2 : Link;

        Tsout : Link;

    begin

        if

           Scan = null

            then

            Sout.Head := null;

            Sout.Tail := null;

            Sout.Before := null;

            Sout.After := null;

        else

            Tsout := new Sdata_Type;

            Tsout.Sdata := Scan.Sdata;

            Scan2 := Tsout;

            Sout.Head := Tsout;

            if

               Sin.Before = null

                then

                Sout.Before := null;

            end if;

            if

               Sin.After = null

                then

                Sout.After := null;

            end if;

            loop

                Scan := Scan.Next;

                exit when

                   Scan = null;

                Scan2.Next := new Sdata_Type;

                Scan2.Next.Sdata := Scan.Sdata;

                Scan2.Next.Previous := Scan2;

                Scan2.Next.Next := null;

                Scan2 := Scan2.Next;

                if

                   Scan = Sin.Before

                    then

                    Sout.Before := Scan2;

                end if;

                if

                   Scan = Sin.After

                    then

                    Sout.After := Scan2;

                end if;

            end loop;

            Sout.Tail := Scan2;

        end if;

    end Assign;

end X0seq;