| # Examples 7.3.1: AREF |

The features of the pervasive class AREF are used in individual examples. None of the examples given is a complete class nor necessarily a complete method.

In all of the examples it will be assumed that the code shown is in a class called, say, EXAMPLE which has included AREF as

include AREF{CARD}
create -> private aref_create ;
private attr list : AREF{CARD} ;

Note that the create routine has been renamed privately in order to permit the EXAMPLE class creation routine to take additional actions for creating other components. This is private so that users of the class EXAMPLE have no access through it to the included creation routine.

#### create

This feature would typically be used in a creation routine for the EXAMPLE class as follows -

create : SAME is
me : SAME := new ;
-- other actions
me.list := aref_create(42) ;
return me
end ;

#### asize

This feature which returns the size of an AREF array as a count of the number of elements could be used in some simple expression such as -

if list.asize /= 42 then -- ...

aset This assignment routine is one of those for which 'infix' array indexing syntax is provided. The statement -

list[4] := 27

which gives the value 27 to the fifth (indexing begins at zero!) element of the list array is an alternative syntactic form of

list.aset(4,27)

which has the identical meaning. Thus the loop

loop
list[0.upto!(41)] := 99
end

and

loop
list.aset(0.upto!(41),99)
end

both set all elements of the list array to 99.

#### aget

This routine may be thought of as the reader routine corresponding to aset above. After the assignment loop above, therefore, it would be possible to check that each element did have the value 99 by either

loop
if list[0.upto!(41)] /= 99 then
...
end
end

or

loop
if list.aget(0.upto!(41)) /= 99 then
...
end
end

#### aind!

This iter, which yields every index value for the array in turn could therefore substitute for the expression "0.upto!(41)" in the above loop, giving

loop
if list.aget(aind!) /= 99 then
...
end
end

This has the advantage that it is independent of the actual size of the array and, should that change, no corresponding editing of the loop source text is needed. As a matter of programming style, the expression "0.upto!(41)" should have been written as "0.upto!(list.asize - 1)". The use of numeric values in program code - except, possibly, for 'zero' and 'one' - should be avoided and declared constants used instead. Amendments, where needed, may then be carried out in one place only!

#### aclear

This feature is useful where it is necessary to re-initialize all of the array elements - which is generally faster than allocating a new array and then setting all its elements to the initial value! The routine call

list.aclear

is provided for just this purpose.

#### array_ptr

Consider the need to pass the contents of the list array via the operating system interface to some external file or channel. In order to do this, it will in general be necessary to pass an operating system reference to the export routine. This could be written something like

list_ref : REFERENCE := list.array_ptr ;
channel.export(list_ref)

or, in abbreviated form -

channel.export(list.array_ptr)

where 'channel' is some communications channel set up by the program.

#### acopy

The ability to copy all or part of one array into another is of considerable importance and, in general, only a compiler can produce the most efficient code for doing this - hence the inclusion of four versions of 'acopy' in the AREF class.

The simplest version copies as much of some source array as will fit into self - or until all of source has been copied. Thus

dest.acopy(source)

copies from source to dest the lesser number of elements in source or dest. If dest can contain 10 elements and source has 100 then after the acopy dest will contain the first ten elements of source. If dest can contain fifty elements and source only has twenty then only the first twenty elements of dest will have been altered.

#### acopy

The requirement to append two array contents can be done by using the second variant of acopy. Consider a destination array of 50 elements with src1 having 20 and src2 30 elements, the two to be concatenated in the destination. The following two copy actions will achieve the desired effect.

dest.acopy(src1) ;
dest.acopy(20,src2)

The second statement starts copying into dest in the element next following the last element copied by the first statement.

#### acopy

Replacement of a short sequence of elements by another is achievable using the third acopy variant, thus

dest.acopy(src1) ;
dest.acopy(7,5,src2)

which replaces elements indexed 7 up to and including 11 by the first five elements of src2. This kind of replacement is, however, only possible with this version of the third acopy variant if the section to be replaced and the section replacing it are of the same size.

#### acopy

The final variant has three numeric arguments - the index of the first element in dest which is to be copied to, the count of elements to copy and, finally, the index in the source array from which copying is to begin.

Consider the case where the five elements in the example above are to be replaced by six elements from src2. The calls needed to do this are -

dest.acopy(0,7,src1) ;
dest.acopy(7,6,src2) ;
dest.acopy(13,(src1.asize - 7),12,src1)

in which the third call starts copying into dest location 13 upwards for as many elements of src1 as remain after the five uncopied elements, starting at location 12 (after the uncopied elements) in src1.

#### aelt!

The first version of the iter named 'aelt! yields in turn all of the elements of an array. This may be illustrated by a simple routine to sum all of the elements of list in the class EXAMPLE -

sum : CARD is
res : CARD := 0 ;
loop
res := res + list.aelt!
end ;
return res
end

#### aelt!

The routine could be re-written to sum the last cnt elements, say, as -

sum_tail(
| cnt : CARD
| ) : CARD is

res : CARD := 0 ;
loop
res := res + list.aelt!(list.asize - cnt)
end ;
return res
end

in which the argument to aelt! is the element at which the iter is to start.

#### aelt!

The routine could be re-written to sum the first cnt elements, say, as -

sum_head(
| cnt : CARD
| ) : CARD is

res : CARD := 0 ;
loop
res := res + list.aelt!(0,cnt)
end ;
return res
end

in which the first argument to aelt! is the element at which the iter is to start, the second is the number of values to yield.

#### aelt!

The summation routine could be re-written to sum cnt elements indexed by an odd number, say, as -

sum_odd(
| cnt : CARD
| ) : CARD is

res : CARD := 0 ;
loop
res := res + list.aelt!(0,cnt,2.int)
end ;
return res
end

in which the last argument is the stepping interval for the iteration. Note that this argument is an INT type, not a CARD.

#### aset!

Corresponding to the above four variants of aelt! there are four variants of the aset! iter. In conjunction with the first variant of aelt! the simplest form could provide an alternative (though almost inevitably less efficient) version of copying - say

loop
self.aset!(src.aelt!)
end

in which every element of the src array is copied sequentially into successive elements of self.

#### aset!

The next variant begins setting at the value given by the first argument, thus a loop copying from srcfrom the tenth element, starting to set dest at the 10th element, could readily be written as

loop
dest.aset!(9,src.aelt!(9))
end

Note that the tenth element has index 9!

#### aset!

Just as the third variant of aelt! used a count for its second argument, so does this variant of aset!. Setting the last ten elements of dest to the first ten elements of src could be done by writing

loop
dest.aset!((dest.asize - 10,10,src.aelt!(0,10))
end

#### aset!

This final feature of the class has its first three arguments the same as the final version of aelt!. A loop to reverse the contents of src into dest (assuming they are of the same size) could be written as -

loop
dest.aset!((dest.asize - 1),asize,-1,src.aelt!)
end

| Specification Index |  | Language Index |  | Section 7 Index

Comments or enquiries should be made to Keith Hopper. Page last modified: Sunday, 21 May 2000. |