list.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 LIST{ETP} < $LIST{ETP}

class LIST{ETP} < $LIST{ETP} is -- This is an array based implementation of lists wrapping around -- the 'fast' version FLIST{ETP} which is, of course, mutable. -- Version 1.2 Nov 98. Copyright K Hopper, U of Waikato -- Development History -- ------------------- -- Date Who By Detail -- ---- ------ ------ -- 11 Apr 94 bg Original -- 13 Jan 97 kh Modified for Sather 1.1 -- 6 Nov 98 kh Revised from 1.2 & added pre/post conds. include CONTAINER{ETP} ; private attr arr : FLIST{ETP} ; private const Min_Size : CARD := 5 ; create : SAME is -- This routine creates and returns a new list of default size. me : SAME := new ; me.arr := FLIST{ETP}::create(Min_Size) ; return me end ; create( cnt : CARD ) : SAME is -- This creation routine creates a list as an array with cnt locations. -- If the count is less than Min_Size then a list of Min_Size is created. if cnt <= Min_Size then return create else me : SAME := new ; me.arr := FLIST{ETP}::create_empty_sized(cnt) ; return me end end ; create( arr : $ELT{ETP} ) : SAME is -- This routine returns a new list with the same contents as the given -- argument. me : SAME := create ; loop me.append(arr.elt!) end ; return me end ; resize( new_size : CARD ) pre ~void(self) and (new_size > 0) post (size = new_size) is -- This routine allocates a new array of the required size and copies -- whatever will fit into the new array. This effectively changes the -- actual size of the list in situ. res : FLIST{ETP} := FLIST{ETP}::create_empty_sized(new_size) ; index : CARD := 0 ; loop until!(index = new_size) ; res[index] := elt! ; index := index + 1 end ; arr := res end ; copy : SAME pre ~void(self) post true is -- This routine returns a new array which contains a copy of itself. res : SAME := new ; res.arr := arr.copy ; return res end ; copy_from( src : $ELT{ETP} ) pre ~void(self) and ~void(src) post true is -- This routine copies as many elements from src as will fit into self, -- over-writing the original contents. loop set!(src.elt!) end end ; -- Insertion and removal of list elements remove_index( index : CARD ) pre ~void(self) and (index < arr.size) post true is -- This routine deletes the element indexed by the argument. arr.delete_ordered(index) end ; clear pre ~void(self) post (arr.is_empty) is -- This routine sets all elements of self to void and the size to zero. arr.clear end ; contains( elem : ETP ) : BOOL is -- This predicate returns true if and only if the value elem is contained -- in the list. if void(self) then return false else return arr.contains(elem) end end ; has_ind( index : CARD ) : BOOL is -- This predicate returns true if and only if the given index is valid -- for the current list contents. return ~void(self) and (index < size) end ; has_range( beg, num : CARD ) : BOOL is -- This predicate returns treu if and only if self has indices in the -- complete range from beg to beg + num, otherwise false! if ~void(self) then return (beg < size) and ((beg + num) <= size) else return false end end ; equals( other : $RO_ARR{ETP} ) : BOOL is -- This predicate returns true if and only if self and other are -- identical. if void(self) then return void(other) elsif void(other) then return false else return arr.equals(other) end end ; size : CARD pre true post (void(self) and (result = 0)) or (result = arr.size) is -- This routine returns zero if self is void, otherwise the size of -- the underlying list contents! if void(self) then return 0 else return arr.size end end ; aget( index : CARD ) : ETP pre ~void(self) and has_ind(index) post (result = arr[index]) is -- This routine returns the value of the element of the list found -- at the given index position. return arr[index] end ; aset( index : CARD, val : ETP ) pre ~void(self) and has_ind(index) post (arr[index] = val) is -- This routine sets the value of the given element to be val. Note -- that it is only valid to set an already exisitng element of the list -- or the element after the current last element in the list. arr[index] := val end ; insert_after( where : CARD, val : ETP ) pre ~void(self) and (where < arr.size) post (arr.size = (initial(arr.size) + 1)) is -- This routine inserts val as a new list element at the position given -- by where. All elements from the original contents at and after where -- are moved one index position higher. arr := arr.insert_after(where,val) end ; insert_after( where : CARD, val : ETP ) : SAME pre ~void(self) and (where < arr.size) post (result.size = (arr.size + 1)) and (result.arr[where + 1] = val) is -- This routine creates a new list which is a copy of self and then -- inserts into it the element val at the position immediately after where, -- other elements from that position to the end are moved to an index -- position one position higher. res : SAME := copy ; res.insert_after(where,val) ; return res end ; insert_before( where : CARD, val : ETP ) pre ~void(self) and (where < arr.size) post (arr.size = (initial(arr.size) + 1)) is -- This routine inserts the element val at the position immediately -- before where, other elements from that position to the end are moved to -- an index position one position higher. arr := arr.insert_before(where,val) end ; insert_before( where : CARD, val : ETP ) : SAME pre ~void(self) and (where < arr.size) post (result.size = (initial(arr.size) + 1)) and (result.arr[where] = val) is -- This routine creates a copy of self and then inserts the element val -- at the position immediately before where, other elements from that -- position to the end are moved to an index position one position higher. -- The result is returned. res : SAME := copy ; res.insert_before(where,val) ; return res end ; insert_all_after( where : CARD, entries : $CONTAINER{ETP} ) pre ~void(self) and ~void(entries) and (where < arr.size) post (arr.size = (initial(arr.size) + entries.size)) is -- This routine inserts the first element of entries at the position -- where in arr, subsequent elements of entries being inserted in sequence. -- After this the original elements of arr at and beyond where are appended -- to the resulting array. arr := arr.insert_all_after(where,entries) end ; insert_all_after( where : CARD, entries : $CONTAINER{ETP} ) : SAME pre ~void(self) and ~void(entries) and (where < arr.size) post (result.size = (arr.size + entries.size)) is -- This routine creates a copy of self into which it inserts the first -- element of entries at the position where in arr, subseuent elements of -- entries being inserted in sequence. After this the original elements of -- arr at and beyond where are appended to the resulting array and the result -- is returned. res : SAME := copy ; res.insert_all_after(where,entries) ; return res end ; insert_all_before( where : CARD, entries : $CONTAINER{ETP} ) pre ~void(self) and ~void(entries) post (arr.size = (initial(arr.size) + entries.size)) is -- This routine sets the element of self which is before the element -- where to have the value of the first element of entries. Subsequent -- elements of self are altered in sequence before appending the original -- contents of self from the position before where to the result. arr := arr.insert_all_before(where,entries) end ; insert_all_before( where : CARD, entries : $CONTAINER{ETP} ) : SAME pre ~void(self) and ~void(entries) post (result.size = (arr.size + entries.size)) is -- This routine creates a copy of self into which it inserts the element -- of the copy which is before the element where to have the alue of the -- first element of entries. Subsequent elements of self are altered in -- sequence before appending the original contents of self from the position -- before where to the result. res : SAME := copy ; res.insert_all_before(where,entries) ; return res end ; append( val : ETP ) pre true post (arr.size = initial(arr.size) + 1) -- and (arr[arr.size - 1] = val) ETP::is_eq problem?? is -- This routine appends val to the list even if it is void! arr := arr.push(val) end ; append( val : ETP ) : SAME pre true post (result.size = arr.size + 1) -- and (result.arr[result.arr.size - 1] = val) ETP::is_eq problem is -- This routine appends val to the list even if it is void! res : SAME := copy ; res.append(val) ; return res end ; append_all( entries : $CONTAINER{ETP} ) pre ~void(self) post true is -- This routine appends all of entries to self. if void(entries) then -- nothing to do! return else loop arr := arr.push(entries.elt!) end end end ; append_all( entries : $CONTAINER{ETP} ) : SAME pre true post (result.size = initial(arr.size) + entries.size) is -- This routine creates a copy of self to which it appends all of -- entries before returning the result. res : SAME := copy ; res.append_all(entries) ; return res end ; ind! : CARD pre ~void(self) post (result < size) is -- This iter yields the indices of self in sequence. Self may be void. index : CARD := 0 ; sz : CARD := size ; loop until!(index >= sz) ; yield index ; index := index + 1 end end ; elt! : ETP is -- This iter yields the elements of self in list order. Self may -- be void. if void(self) then quit else sz : CARD := size ; index : CARD := 0 ; loop until!(index = sz) ; yield arr[index] ; index := index + 1 end end end ; set!( val : ETP ) pre ~void(self) post true -- (arr[ind!] = val) is -- This iter sets the elements of the list to be successive values val. sz : CARD := size ; index : CARD := 0 ; loop until!(index = sz) ; arr[index] := val ; yield ; index := index + 1 end end ; end ; -- LIST