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