array3.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 ARRAY3{T} < $ELT{T}
class ARRAY3{T} < $ELT{T} is
-- This class implements three-dimensional arrays of elements of type T.
-- Version 1.2 Nov 98. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 2 Aug 96 bg Original
-- 14 Jan 97 hk Modified for CARD
-- 4 Nov 98 kh Refined as 1.2 dist, added pre/post conds
private include AREF{T}
aclear -> aclear,
array_ptr -> array_ptr ;
readonly attr size1 : CARD ; -- of slowest changing dim.
readonly attr size2 : CARD ; -- of 2nd fastest changing dim.
readonly attr size3 : CARD ; -- of fastest changing dim.
private attr size23 : CARD ; -- size2*size3, pre-multiplied to
-- save multiplication when
-- accessing the array.
create(
dim1,
dim2,
dim3 : CARD
) : SAME
pre (dim1 > 0)
and (dim2 > 0)
and (dim3 > 0)
post ~void(result)
and (result.size23 = (dim2 * dim3))
and (result.size1 = dim1)
is
-- This routine creates a new three-dimensional array with a size
-- formed by the product of the three dimesnions. All elements are set to
-- void.
me : SAME := new(dim1 * dim2 * dim3) ;
me.size1 := dim1 ;
me.size2 := dim2 ;
me.size3 := dim3 ;
me.size23 := dim2 * dim3 ;
return me
end ;
create(
arr : ARRAY{ARRAY{ARRAY{T}}}
) : SAME
pre (arr.size > 0)
and (arr[0].size > 0)
and (arr[0][0].size > 0)
post (result.size = arr.size * arr[0].size * arr[0][0].size)
is
-- This routine creates a new three-dimensional array with the same
-- dimensions as arr, copying into it the values of arr.
--
-- NOTE It is ASSUMED that all of the rows and middle arrays have the same
-- number of elements.
sz1 : CARD := arr.size ;
sz2 : CARD := arr[0].size ;
sz3 : CARD := arr[0][0].size ;
me : SAME := create(sz1,sz2,sz3) ;
loop
out_index : CARD :=sz1.times! ;
loop
middle_index : CARD := sz2.times! ;
loop
in_index : CARD :=sz3.times! ;
me[out_index,middle_index,in_index] :=
arr[out_index][middle_index][in_index]
end
end
end ;
return me
end ;
copy : SAME
pre ~void(self)
and (size1 > 0)
and (size2 > 0)
and (size3 > 0)
post true -- (result = self)
is
-- This routine returns a new three-dimesnional array identical to self.
res : SAME := create(size1,size2,size3) ;
res.acopy(self) ;
return res
end ;
size : CARD is
-- This routine returns the total element size of this three-dimensional
-- array as the product of row, column and depth.
if void(self) then
return 0
else
return size1 * size2 * size3
end
end ;
aget(
out_index,
middle_index,
in_index : CARD
) : T
pre ~void(self)
and (out_index < size1)
and (middle_index < size2)
and (in_index < size3)
post (result = [out_index * (size23) + middle_index * size3 + in_index])
is
-- This routine returns the value of the element of self indicated by
-- the given indices.
return [out_index * (size23) + middle_index * size3 + in_index]
end ;
aset(
out_index,
middle_index,
in_index : CARD,
val : T
)
pre ~void(self)
and (out_index < size1)
and (middle_index < size2)
and (in_index < size3)
post ([out_index * (size23) + middle_index * size3 + in_index] = val)
is
-- This routine sets the value of the element of self indicated by
-- the given indices to val.
[out_index * (size23) + middle_index * size3 + in_index] := val
end ;
private to_transpose_of(
arr : SAME
)
pre ~void(arr)
and (arr.size3 = size1)
and (arr.size2 = size2)
and (arr.size1 = size3)
post true
is
-- This routine sets self to have the transposed contents of arr,
-- arranged so that the element positions are the index transposition of
-- the indices of arr.
loop
indices : TUP{CARD,CARD,CARD} := inds! ;
[indices.t1,indices.t2,indices.t3] :=
arr[indices.t3,indices.t2,indices.t1]
end
end ;
transpose : SAME
pre ~void(self)
post (result.asize = asize)
is
-- This routine returns a new three-dimensional array whose contents
-- are arranged so that the element positions are the index transposition of
-- the indices of self.
res : SAME := create(size3,size2,size1) ;
res.to_transpose_of(self) ;
return res
end ;
-- The remaining definitions are the iters for this class.
ind1! : CARD
pre ~void(self)
post (result < size1)
is
-- This iter yields successive values of the outer index in order.
loop
yield(size1.times!)
end
end ;
ind2! : CARD
pre ~void(self)
post (result < size2)
is
-- This iter yields successive values of the middle index in order.
loop
yield(size2.times!)
end
end ;
ind3! : CARD
pre ~void(self)
post (result < size3)
is
-- This iter yields successive values of the inner index in order.
loop
yield(size3.times!)
end
end ;
-- NOTE The three dimensions of this array class are called
-- respectively --
--
-- outer -- row
-- middle -- column
-- inner -- elements
--
-- in the following iters.
row_ind! : CARD
pre ~void(self)
post (result < size1)
is
-- This iter yields successive values of the outer index in order.
loop
yield(size1.times!)
end
end ;
col_ind! : CARD
pre ~void(self)
post (result < size2)
is
-- This iter yields successive values of the middle index in order.
loop
yield(size2.times!)
end
end ;
elem_ind! : CARD
pre ~void(self)
post (result < size3)
is
-- This iter yields successive values of the inner index in order.
loop
yield(size3.times!)
end
end ;
diag_elt! : T
pre ~void(self)
post true
is
-- This iter yields successive values along the diagonal of the 'cube'
-- in the smallest dimension.
loop
index : CARD := (size1.min(size2).min(size3)).times! ;
yield([index,index,index])
end
end ;
set_diag_elt!(
val : T
)
pre ~void(self)
post true
is
-- This iter sets successive values along the diagonal of the 'cube'
-- in the smallest dimension.
loop
index : CARD := (size1.min(size2).min(size3)).times! ;
[index,index,index] := val ;
yield
end
end ;
inds! : TUP{CARD,CARD,CARD}
pre ~void(self)
post (result.t1 < size1)
and (result.t2 < size2)
and (result.t3 < size3)
is
-- This iter yields tuples of the indices of self in the order row,
-- by column within row, by element within column.
loop
row : CARD := size1.times! ;
loop
column : CARD := size2.times! ;
loop
yield(TUP{CARD,CARD,CARD}::create(row,column,size3.times!))
end
end
end
end ;
elt! : T
pre ~void(self)
post true
is
-- This iter yields the sequence of all elements of self in the order
-- row, column within row, element within column.
loop
yield(aelt!)
end
end ;
set!(
val : T
)
pre ~void(self)
post true
is
-- This iter sets the elements of self in the sequence row, column
-- within roew, element within column.
loop
aset!(val) ;
yield
end
end ;
row_elt!(
once row,
once elem : CARD
) : T
pre ~void(self)
and (row < size1)
and (elem < size3)
post true
is
-- This iter yields all elements of the indicated row and element of
-- self, changing the column index.
loop
yield([row,col_ind!,elem])
end
end ;
col_elt!(
once col,
once elem : CARD
) : T
pre ~void(self)
and (col < size2)
and (elem < size3)
post true
is
-- This iter yields all elements of the indicated column and element of
-- self, changing the row index.
loop
yield([row_ind!,col,elem])
end
end ;
elem_elt!(
once row,
once col : CARD
) : T
pre ~void(self)
and (row < size1)
and (col < size2)
post true
is
-- This iter yields all elements of the indicated row and column of
-- self, changing the element index.
loop
yield([row,col,elem_ind!])
end
end ;
set_row!(
once row,
once elem : CARD,
val : T
)
pre ~void(self)
and (row < size1)
and (elem < size3)
post true
is
-- This iter sets all elements of the indicated row and element of
-- self to the values val, changing the column index.
loop
[row,col_ind!,elem] := val ;
yield
end
end ;
set_col!(
once col,
once elem : CARD,
val : T
)
pre ~void(self)
and (col < size2)
and (elem < size3)
post true
is
-- This iter sets all elements of the indicated column and element of
-- self to the values val, changing the row index.
loop
[row_ind!,col,elem] := val ;
yield
end
end ;
set_elem!(
once row,
once col : CARD,
val : T
)
pre ~void(self)
and (row < size1)
and (col < size2)
post true
is
-- This iter sets all elements of the indicated row and column of
-- self to the values val, changing the element index.
loop
[row,col,elem_ind!] := val ;
yield
end
end ;
elt1!(
once col,
once elem : CARD
) : T
pre ~void(self)
and (col < size2)
and (elem < size3)
post true
is
-- This iter yields successive elements of self from the given column
-- and element, varying the row index.
loop
yield([ind1!,col,elem])
end
end ;
elt2!(
once row,
once elem : CARD
) : T
pre ~void(self)
and (row < size1)
and (elem < size3)
post true
is
-- This iter yields successive elements of self from the given row
-- and element, varying the column index.
loop
yield([row,ind2!,elem])
end
end ;
elt3!(
once row,
once col : CARD
) : T
pre ~void(self)
and (row < size1)
and (col < size2)
post true
is
-- This iter yields successive elements of self from the given row
-- and column, varying the element index.
loop
yield([row,col,ind3!])
end
end ;
set1!(
once col,
once elem : CARD,
val : T
)
pre ~void(self)
and (col < size2)
and (elem < size3)
post true
is
-- This iter sets successive elements of self from the given row
-- and column, varying the element index to the values val.
loop
[ind1!,col,elem] := val ;
yield
end
end ;
set2!(
once row,
once elem : CARD,
val : T
)
pre ~void(self)
and (row < size1)
and (elem < size3)
post true
is
-- This iter sets successive elements of self from the given row
-- and element, varying the column index to the values val.
loop
[row,ind2!,elem] := val ;
yield
end
end ;
set3!(
once row,
once col : CARD,
val : T
)
pre ~void(self)
and (row < size1)
and (col < size2)
post true
is
-- This iter sets successive elements of self from the given row
-- and column, varying the element index to the values val.
loop
[row,col,ind3!] := val ;
yield
end
end ;
end ; -- ARRAY3{T}