llist.sa


Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
 
------------------------->  GNU Sather - sourcefile  <-------------------------
-- Copyright (C) 2000 by K Hopper, University of Waikato, New Zealand        --
-- This file is part of the GNU Sather library. It is free software; you may --
-- redistribute  and/or modify it under the terms of the GNU Library General --
-- Public  License (LGPL)  as published  by the  Free  Software  Foundation; --
-- either version 2 of the license, or (at your option) any later version.   --
-- This  library  is distributed  in the  hope that it will  be  useful, but --
-- WITHOUT ANY WARRANTY without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See Doc/LGPL for more details.       --
-- The license text is also available from:  Free Software Foundation, Inc., --
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                     --
-------------->  Please email comments to <bug-sather@gnu.org>  <--------------


class LL_NODE{T}

class LL_NODE{T} is -- This class is for the private use of the class LLIST (linked list). -- This implementation has a node which is the data value and another which -- is the next item in the list. This is very close to an explicit pointer -- in non-object oriented languages! -- Version 1.1 Apr 97. Copyright K Hopper, U of Waikato -- Development History -- ------------------- -- Date Who By Detail -- ---- ------ ------ -- 18 Jul 96 ds Original -- 4 Apr 97 kh Changed for CARD instead of INT attr data : T ; attr next : SAME ; create( val : T, next : SAME ) : SAME is -- This simple creation routine merely sets the values in a new node -- which it returns. me : SAME := new ; me.data := val ; me.next := next ; return me end ; is_eq( other : SAME ) : BOOL is -- This predicate returns true if and only if self and other are 'object -- equal. return SYS::ob_eq(self,other) end ; end ; -- LL_NODE{T}

class LLIST{T}

class LLIST{T} is -- This class is a linked list implementation of a list. It contains -- the notion of current position which can be advanced and also 'rewound'. -- Elements can be inserted either before or after a particular position as -- well as deletion of the 'current' object. -- -- The list has a header which prevents confusion with an empty list. -- Data are stored in linked nodes which are 'private' to this class. -- Version 1.2 Nov 98. Copyright K Hopper, U of Waikato -- Development History -- ------------------- -- Date Who By Detail -- ---- ------ ------ -- 5 Sep 96 bv Original -- 3 Apr 97 kh Changed for CARD instead of INT -- 6 Nov 98 kh Refinded from 1.2, added pre/post conditions. -- 16 Dec 99 kh included CONTAINER partial class. include CONTAINER{T} ; readonly attr size : CARD ; -- This returns the number of elements stored in the list. private attr first, prev, curr, last : LL_NODE{T} ; create : SAME is -- This routine returns a new empty linked list. Its successful -- operation relies on the fact that all 'new' objects in Sather have -- a zero/null value! return new end ; is_empty : BOOL pre ~void(self) post (result = (size = 0)) is -- This predicate returns true if and only if the list is empty. return size = 0 end ; at_last : BOOL pre ~void(self) and ~is_empty post (result = (last = curr)) is -- This predicate returns true if and only if the current element is -- the last element. return last = curr end ; at_end : BOOL pre ~void(self) post result = void(curr) is -- This predicate returns true if and only if the list is empty or -- the current node is void (which signifies 'beyond' the last node'. return void(curr) end ; rewind pre ~void(self) post (curr = first) and void(prev) is -- This routine sets the current position to be the first element in -- the list. curr := first ; prev := void end ; current : T pre ~void(self) and ~is_empty and ~at_end post (result = curr.data) is -- This routine returns the value of the current list element. return curr.data end ; advance pre ~void(self) and ~is_empty and ~at_end post (prev = initial(curr)) and (curr = prev.next) is -- This routine advances the current position in the list by one. prev := curr ; curr := curr.next end ; insert_after( val : T ) pre ~void(self) and ~is_empty and ~at_end post (size = (initial(size) + 1)) and (curr.next.data = val) is -- This routine inserts the given item after the current element. It -- does not change current. if void(curr.next) then assert curr = last ; last := LL_NODE{T}::create(val,void) ; curr.next := last else curr.next := LL_NODE{T}::create(val,curr.next) end ; size := size + 1 end ; insert_before( val : T ) pre ~void(self) post (size = (initial(size) + 1)) and (prev.data = val) is -- This routine inserts the new element before the current position. -- This does not change the value of current. if is_empty then first := LL_NODE{T}::create(val,void) ; last := first ; prev := first ; elsif void(prev) then assert first = curr ; first := LL_NODE{T}::create(val,curr) ; prev := first else prev.next := LL_NODE{T}::create(val,curr) ; prev := prev.next end ; if void(curr) then last := prev end ; size := size + 1 end ; insert_front( val : T ) pre ~void(self) post (size = (initial(size) + 1)) and (first.data = val) is -- This routine inserts an element at the front of the list. if void(first) then assert void(last) and void(curr) ; first := LL_NODE{T}::create(val,void) ; last := first ; curr := first else first := LL_NODE{T}::create(val,first) ; if void(prev) then assert curr = first ; prev := first end end ; size := size + 1 end ; insert_back( val : T ) pre ~void(self) post (size = (initial(size) + 1)) and (last.data = val) is -- This routine inserts the new element val at the end of the list. if void(last) then assert void(first) ; last := LL_NODE{T}::create(val,void) ; first := last ; curr := last else last.next := LL_NODE{T}::create(val,void) ; last := last.next end ; size := size + 1 end ; delete pre ~void(self) and ~is_empty and ~at_end post (void(prev) and (curr = first)) or (prev.next = curr) is -- This routine deletes the current object and advvances to the next -- item in the list. at_last : BOOL := curr = last ; if void(prev) then assert first = curr ; first := curr.next ; curr := first else curr := curr.next ; prev.next := curr end ; if at_last then last := prev end ; size := size - 1 end ; delete_all pre ~void(self) post is_empty and at_end is -- This routine deletes all elements from the list. first := void ; curr := void ; last := void ; prev := void ; size := 0 end ; elt! : T pre ~void(self) post true is -- This iter yields all elements in the list in order. It is -- re-entrant. loc : LL_NODE{T} := first ; loop until!(void(loc)) ; yield loc.data ; loc := loc.next end end ; end ; -- LLIST{T}