Common Lisp the Language, 2nd Edition


next up previous contents index
Next: Strings Up: Arrays Previous: Fill Pointers

17.6. Changing the Dimensions of an Array

This function may be used to resize or reshape an array. Its options are similar to those of make-array.


[Function]
adjust-array array new-dimensions &key :element-type :initial-element :initial-contents :fill-pointer :displaced-to :displaced-index-offset

adjust-array takes an array and a number of other arguments as for make-array. The number of dimensions specified by new-dimensions must equal the rank of array.

adjust-array returns an array of the same type and rank as array, with the specified new-dimensions. In effect, the array argument itself is modified to conform to the new specifications, but this may be achieved either by modifying the array or by creating a new array and modifying the array argument to be displaced to the new array.

In the simplest case, one specifies only the new-dimensions and possibly an :initial-element argument. Those elements of array that are still in bounds appear in the new array. The elements of the new array that are not in the bounds of array are initialized to the :initial-element; if this argument is not provided, then the initial contents of any new elements are undefined.

If :element-type is specified, then array must be such that it could have been originally created with that type; otherwise an error is signaled. Specifying :element-type to adjust-array serves only to require such an error check.

If :initial-contents or :displaced-to is specified, then it is treated as for make-array. In this case none of the original contents of array appears in the new array.

If :fill-pointer is specified, the fill pointer of the array is reset as specified. An error is signaled if array had no fill pointer already.

change_begin
X3J13 voted in June 1988 (ADJUST-ARRAY-FILL-POINTER)   to clarify the treatment of the :fill-pointer argument as follows.

If the :fill-pointer argument is not supplied, then the fill pointer of the array is left alone. It is an error to try to adjust the array to a total size that is smaller than its fill pointer.

If the :fill-pointer argument is supplied, then its value must be either an integer, t, or nil. If it is an integer, then it is the new value for the fill pointer; it must be non-negative and no greater than the new size to which the array is being adjusted. If it is t, then the fill pointer is set equal to the new size for the array. If it is nil, then the fill pointer is left alone; it is as if the argument had not been supplied. Again, it is an error to try to adjust the array to a total size that is smaller than its fill pointer.

An error is signaled if a non-nil :fill-pointer value is supplied and the array to be adjusted does not already have a fill pointer.

This extended treatment of the :fill-pointer argument to adjust-array is consistent with the previously existing treatment of the :fill-pointer argument to make-array.
change_end

adjust-array may, depending on the implementation and the arguments, simply alter the given array or create and return a new one. In the latter case the given array will be altered so as to be displaced to the new array and have the given new dimensions.

old_change_begin
It is not permitted to call adjust-array on an array that was not created with the :adjustable option. The predicate adjustable-array-p may be used to determine whether or not an array is adjustable.
old_change_end

change_begin
X3J13 voted in January 1989 (ADJUST-ARRAY-NOT-ADJUSTABLE)   to allow adjust-array to be applied to any array. If adjust-array is applied to an array that was originally created with :adjustable true, the array returned is eq to its first argument. It is not specified whether adjust-array returns an array eq to its first argument for any other arrays. If the array returned by adjust-array is not eq to its first argument, the original array is unchanged and does not share storage with the new array.

Under this new definition, it is wise to treat adjust-array in the same manner as delete and nconc: one should carefully retain the returned value, for example by writing

(setq my-array (adjust-array my-array ...))

rather than relying solely on a side effect.
change_end

If adjust-array is applied to an array that is displaced to another array x, then afterwards neither array nor the returned result is displaced to x unless such displacement is explicitly re-specified in the call to adjust-array.

For example, suppose that the 4-by-4 array m looks like this:

#2A( ( alpha     beta      gamma     delta ) 
     ( epsilon   zeta      eta       theta ) 
     ( iota      kappa     lambda    mu    ) 
     ( nu        xi        omicron   pi    ) )

Then the result of

(adjust-array m '(3 5) :initial-element 'baz)

is a 3-by-5 array with contents

#2A( ( alpha     beta      gamma     delta     baz ) 
     ( epsilon   zeta      eta       theta     baz ) 
     ( iota      kappa     lambda    mu        baz ) )

Note that if array a is created displaced to array b and subsequently array b is given to adjust-array, array a will still be displaced to array b; the effects of this displacement and the rule of row-major storage order must be taken into account.

change_begin
X3J13 voted in June 1988 (ADJUST-ARRAY-DISPLACEMENT)   to clarify the interaction of adjust-array with array displacement.

Suppose that an array A is to be adjusted. There are four cases according to whether or not A was displaced before adjustment and whether or not the result is displaced after adjustment.

If array X is displaced to array Y, and array Y is displaced to array Z, and array Y is altered by adjust-array, array X must now refer to the adjusted contents of Y. This means that an implementation may not collapse the chain to make X refer to Z directly and forget that the chain of reference passes through array Y. (Caching techniques are of course permitted, as long as they preserve the semantics specified here.)

If X is displaced to Y, it is an error to adjust Y in such a way that it no longer has enough elements to satisfy X. This error may be signaled at the time of the adjustment, but this is not required.

Note that omitting the :displaced-to argument to adjust-array is equivalent to specifying :displaced-to nil; in either case, the array is not displaced after the call regardless of whether it was displaced before the call.
change_end



next up previous contents index
Next: Strings Up: Arrays Previous: Fill Pointers


AI.Repository@cs.cmu.edu