
% Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are
% met:
%
%     - Redistributions of source code must retain the above copyright
%       notice, this list of conditions and the following disclaimer.
%
%     - Redistributions in binary form must reproduce the above copyright
%       notice, this list of conditions and the following disclaimer in
%       the documentation and/or other materials provided with the
%       distribution.
%
%     - Neither the name of The Numerical ALgorithms Group Ltd. nor the
%       names of its contributors may be used to endorse or promote products
%       derived from this software without specific prior written permission.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
% IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
% TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
% PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
% OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
% EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES-- LOSS OF USE, DATA, OR
% PROFITS-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
% LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


The \spadtype{FlexibleArray} domain constructor creates
one-dimensional arrays of elements of the same type.
\index{array!flexible}
Flexible arrays are an attempt to provide a data type that has the
\index{flexible array}
best features of both one-dimensional arrays (fast, random access
to elements) and lists (flexibility).
They are implemented by a fixed block of storage.
When necessary for expansion, a new, larger block of storage is
allocated and the elements from the old storage area are copied
into the new block.

Flexible arrays have available most of the operations provided by
\spadtype{OneDimensionalArray} (see \xmpref{OneDimensionalArray}
and \xmpref{Vector}).
Since flexible arrays are also of category
\spadtype{ExtensibleLinearAggregate}, they have operations
\spadfunX{concat}, \spadfunX{delete}, \spadfunX{insert},
\spadfunX{merge}, \spadfunX{remove}, \spadfunX{removeDuplicates},
and \spadfunX{select}.
In addition, the operations \spadfun{physicalLength} and
\spadfunX{physicalLength} provide user-control over expansion and
contraction.

\xtc{
A convenient way to create a flexible array is to apply
the operation \spadfun{flexibleArray} to a list of values.
}{
\spadcommand{flexibleArray [i for i in 1..6]}
}
\xtc{
Create a flexible array of six zeroes.
}{
\spadcommand{f : FARRAY INT := new(6,0)\bound{f}}
}
\xtc{
For \texht{$i=1\ldots 6$}{i = 1..6},
set the \eth{\smath{i}} element to \smath{i}.
Display \spad{f}.
}{
\spadcommand{for i in 1..6 repeat f.i := i; f\bound{f1}\free{f}}
}
\xtc{
Initially, the physical length is the same as the number of elements.
}{
\spadcommand{physicalLength f\free{f1}}
}
\xtc{
Add an element to the end of \spad{f}.
}{
\spadcommand{concat!(f,11)\bound{f2}\free{f1}}
}
\xtc{
See that its physical length has grown.
}{
\spadcommand{physicalLength f\free{f2}}
}
\xtc{
Make \spad{f} grow to have room for \spad{15} elements.
}{
\spadcommand{physicalLength!(f,15)\bound{f3}\free{f2}}
}
\xtc{
Concatenate the elements of \spad{f} to itself.
The physical length allows room for three more values at the end.
}{
\spadcommand{concat!(f,f)\bound{f4}\free{f3}}
}
\xtc{
Use \spadfunX{insert} to add an element to the front of
a flexible array.
}{
\spadcommand{insert!(22,f,1)\bound{f5}\free{f4}}
}
\xtc{
Create a second flexible array from \spad{f} consisting of the
elements from index 10 forward.
}{
\spadcommand{g := f(10..)\bound{g}\free{f5}}
}
\xtc{
Insert this array at the front of \spad{f}.
}{
\spadcommand{insert!(g,f,1)\bound{g1}\free{g f5}}
}
\xtc{
Merge the flexible array \spad{f} into \spad{g} after sorting each in place.
}{
\spadcommand{merge!(sort! f, sort! g)\bound{f6}\free{g f5}}
}
\xtc{
Remove duplicates in place.
}{
\spadcommand{removeDuplicates! f\bound{f7}\free{f6}}
}
\xtc{
Remove all odd integers.
}{
\spadcommand{select!(i +-> even? i,f)\bound{f8}\free{f7}}
}
\xtc{
All these operations have shrunk the physical length of \spad{f}.
}{
\spadcommand{physicalLength f\free{b8}}
}
\xtc{
To force \Language{} not to shrink flexible arrays call the
\spadfun{shrinkable} operation with the argument \axiom{false}.
You must package call this operation.
The previous value is returned.
}{
\spadcommand{shrinkable(false)\$FlexibleArray(Integer)}
}

\begin{texonly}
\begin{discard}
\spadcommand{shrinkable(true)\$FlexibleArray(Integer)}
\end{discard}
\end{texonly}
