-----------------------------------------------------------
--                   Eiffel/S examples                   --
-----------------------------------------------------------
--               Copyright (C) 1991 - 1993               --
--                           by                          --
--                   SiG Computer GmbH                   --
--                  All rights reserved                  --
-----------------------------------------------------------
-- Release : 1.3 - October 1993                          --
-----------------------------------------------------------
-- Authors : Lambert Strether & Michael Schweitzer       --
-----------------------------------------------------------
  
class   LINKED_LIST [G -> COMPARABLE] 

inherit
    SORTED_COLLECTION [G]
        redefine
            add, remove, search, iterator, inside, item,
            first, last, next, previous, first_after, last_before
    end

creation
    make

feature

    add (x : G) is

        local
            n, p : LINK_NODE [G]

        do
            from
                p := anchor
            until
                p = void or else x <= p.item
            loop
                p := p.next
            end

            if not is_unique or else p = void or else p.item < x then
                !!n.make (x)
                n.set_next (p)

                if p = anchor then
                    anchor := n
                elseif p /= void then
                    p.prev.set_next (n)
                    n.set_prev (p.prev)
                end

                if p /= void then
                    p.set_prev (n)
                else
                    if tail /= void then
                        tail.set_next (n)
                    end

                    n.set_prev (tail) 
                    tail := n
                end

                count := count + 1
            end 
        end
-----------------------------------------------------------

    remove (x : G) is

        local
            p : LINK_NODE [G]

        do
            from
                p := anchor
            until
                p = void or else x <= p.item
            loop
                p := p.next
            end

            if p /= void and then x >= p.item then
                if p.prev = void then
                    anchor := p.next
                else
                    p.prev.set_next (p.next)
                end

                if p.next = void then
                    tail := p.prev
                else
                    p.next.set_prev (p.prev)
                end

                count := count - 1
            end
        end
-----------------------------------------------------------

    search (x : G) is

        local
            n : LINK_NODE [G]

        do
            from
                n := anchor
            until
                n = void or else n.item >= x
            loop
                n := n.next
            end

            found := (n /= void and then n.item <= x)
        end
-----------------------------------------------------------

    iterator : LINK_ITER [G] is

        do
            !!result.make (current)
            init_first (result)
        end
-----------------------------------------------------------

    inside (it : ITERATOR) : BOOLEAN is

        local
            nit : LINK_ITER [G]

        do
            nit ?= it
            result := (nit.cursor /= void)
        end
-----------------------------------------------------------

    item (it : ITERATOR) : G is

        local
            nit : LINK_ITER [G]

        do
            nit ?= it
            result := (nit.cursor.item)
        end
-----------------------------------------------------------

feature { ITERATOR }

    first (it : ITERATOR) is

        local
            nit : LINK_ITER [G]

        do
            nit ?= it
            nit.set_cursor (anchor)
        end
-----------------------------------------------------------

    last (it : ITERATOR) is

        local
            nit : LINK_ITER [G]

        do
            nit ?= it
            nit.set_cursor (tail)
        end
-----------------------------------------------------------

    next (it : ITERATOR) is

        local
            nit : LINK_ITER [G]

        do
            nit ?= it
            nit.set_cursor (nit.cursor.next)
        end
-----------------------------------------------------------

    previous (it : ITERATOR) is

        local
            nit : LINK_ITER [G]

        do
            nit ?= it
            nit.set_cursor (nit.cursor.prev)
        end
-----------------------------------------------------------

feature { NONE }

    anchor : LINK_NODE [G]
    tail   : LINK_NODE [G]

-----------------------------------------------------------

    first_after (x : G, it : LINK_ITER [G]) is

        local
            n : LINK_NODE [G]

        do
            from
                n := anchor
            until
                n = void or else x <= n.item
            loop
                n := n.next
            end

            it.set_cursor (n)
        end
-----------------------------------------------------------

    last_before (x : G, it : LINK_ITER [G]) is

        local
            n : LINK_NODE [G]

        do
            from
                n := tail
            until
                n = void or else x >= n.item
            loop
                n := n.prev
            end

            it.set_cursor (n) 
        end

end -- class LINKED_LIST

