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}