User Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

cl:functions:adjust-array [2019/06/15 02:00]
cl:functions:adjust-array [2019/06/19 03:00] (current)
Line 1: Line 1:
 +====== Function ADJUST-ARRAY ======
 +
 +====Syntax====
 +  * **adjust-array** //array new-dimensions ''&​key''​ element-type initial-element initial-contents fill-pointer displaced-to displaced-index-offset//​ → //​adjusted-array//​
 +
 +====Arguments and Values====
 +  * //array// - an //​[[CL:​Glossary:​array]]//​.
 +  * //​new-dimensions//​ - a //​[[CL:​Glossary:​valid array dimension]]//​ or a //​[[CL:​Glossary:​list]]//​ of //​[[CL:​Glossary:​valid array dimension|valid array dimensions]]//​.
 +  * //​element-type//​ - a //​[[CL:​Glossary:​type specifier]]//​.
 +  * //​initial-element//​ - an //​[[CL:​Glossary:​object]]//​. //​initial-element//​ must not be supplied if either //​initial-contents//​ or //​displaced-to//​ is supplied.
 +  * //​initial-contents//​ - an //​[[CL:​Glossary:​object]]//​. If //​[[CL:​Glossary:​array]]//​ has rank greater than zero, then //​initial-contents//​ is composed of nested //​[[CL:​Glossary:​sequence|sequences]]//,​ the depth of which must equal the rank of //array//. Otherwise, //​[[CL:​Glossary:​array]]//​is zero-dimensional and //​initial-contents//​ supplies the single element. //​initial-contents//​ must not be supplied if either //​initial-element//​ or //​displaced-to//​ is given.
 +  * //​fill-pointer//​ - a //​[[CL:​Glossary:​valid fill pointer]]// for the //​[[CL:​Glossary:​array]]//​ to be created, or **[[CL:​Constant Variables:​t]]**,​ or **[[CL:​Constant Variables:​nil]]**. The default is **[[CL:​Constant Variables:​nil]]**.
 +  * //​displaced-to//​ - an //​[[CL:​Glossary:​array]]//​ or **[[CL:​Constant Variables:​nil]]**. //​initial-elements//​ and //​initial-contents//​ must not be supplied if //​displaced-to//​ is supplied.
 +  * //​displaced-index-offset//​ - an object of type ''​(fixnum 0 n)''​ where ''​n''​ is ''​(array-total-size //​displaced-to//​)''​. //​displaced-index-offset//​ may be supplied only if //​displaced-to//​ is supplied.
 +  * //​adjusted-array//​ - an //​[[CL:​Glossary:​array]]//​.
 +
 +====Description====
 +**adjust-array** changes the dimensions or elements of //array//. The result is an //​[[CL:​Glossary:​array]]//​ of the same //​[[CL:​Glossary:​type]]//​ and rank as //array//, that is either the modified //array//, or a newly created //​[[CL:​Glossary:​array]]//​ to which //array// can be displaced, and that has the given //​new-dimensions//​.
 +
 +//​new-dimensions//​ specify the size of each //​[[CL:​Glossary:​dimension]]//​ of //array//.
 +
 +//​element-type//​ specifies the //​[[CL:​Glossary:​type]]//​ of the //​[[CL:​Glossary:​element|elements]]//​ of the resulting //​[[CL:​Glossary:​array]]//​. If //​element-type//​ is supplied, the consequences are unspecified if the //​[[CL:​Glossary:​upgraded array element type]]// of //​element-type//​ is not the same as the //​[[CL:​Glossary:​actual array element type]]// of //array//.
 +
 +If //​initial-contents//​ is supplied, it is treated as for **[[CL:​Functions:​make-array]]**. In this case none of the original contents of //array// appears in the resulting //​[[CL:​Glossary:​array]]//​.
 +
 +If //​fill-pointer//​ is an //​[[CL:​Glossary:​integer]]//,​ it becomes the //​[[CL:​Glossary:​fill pointer]]// for the resulting //​[[CL:​Glossary:​array]]//​. If //​fill-pointer//​ is the symbol **[[CL:​Constant Variables:​t]]**,​ it indicates that the size of the resulting //​[[CL:​Glossary:​array]]//​ should be used as the //​[[CL:​Glossary:​fill pointer]]//​. If //​fill-pointer//​ is **[[CL:​Constant Variables:​nil]]**,​ it indicates that the //​[[CL:​Glossary:​fill pointer]]// should be left as it is.
 +
 +If //​displaced-to//​ //​[[CL:​Glossary:​non-nil]]//,​ a //​[[CL:​Glossary:​displaced array]]// is created. The resulting //​[[CL:​Glossary:​array]]//​ shares its contents with the //​[[CL:​Glossary:​array]]//​ given by //​displaced-to//​. The resulting //​[[CL:​Glossary:​array]]//​ cannot contain more elements than the //​[[CL:​Glossary:​array]]//​ it is displaced to. If //​displaced-to//​ is not supplied or **[[CL:​Constant Variables:​nil]]**,​ the resulting //​[[CL:​Glossary:​array]]//​ is not a //​[[CL:​Glossary:​displaced array]]//. 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''​. Although //array// might be a //​[[CL:​Glossary:​displaced array]]//, the resulting //​[[CL:​Glossary:​array]]//​ is not a //​[[CL:​Glossary:​displaced array]]// unless //​displaced-to//​ is supplied and not **[[CL:​Constant Variables:​nil]]**.
 +
 +The interaction between **adjust-array** and displaced //​[[CL:​Glossary:​array|arrays]]//​ is as follows given three //​[[CL:​Glossary:​array|arrays]]//,​ ''​A'',​ ''​B'',​ and ''​C'':​
 +
 +===''​A''​ is not displaced before or after the call===
 +<​blockquote>​
 +(adjust-array A ...)
 +</​blockquote>​
 +
 +The dimensions of ''​A''​ are altered, and the contents rearranged as appropriate. Additional elements of ''​A''​ are taken from //​initial-element//​. The use of //​initial-contents//​ causes all old contents to be discarded.
 +
 +===''​A''​ is not displaced before, but is displaced to ''​C''​ after the call===
 +<​blockquote>​
 +(adjust-array A ... :​displaced-to C)
 +</​blockquote>​
 +
 +None of the original contents of ''​A''​ appears in ''​A''​ afterwards; ''​A''​ now contains the contents of ''​C'',​ without any rearrangement of ''​C''​.
 +
 +===''​A''​ is displaced to ''​B''​ before the call, and is displaced to ''​C''​ after the call===
 +<​blockquote>​
 +(adjust-array A ... :​displaced-to B)
 +(adjust-array A ... :​displaced-to C)
 +</​blockquote>​
 +
 +''​B''​ and ''​C''​ might be the same. The contents of ''​B''​ do not appear in ''​A''​ afterward unless such contents also happen to be in ''​C''​ If //​displaced-index-offset//​ is not supplied in the **adjust-array** call, it defaults to zero; the old offset into ''​B''​ is not retained.
 +
 +===''​A''​ is displaced to ''​B''​ before the call, but not displaced afterward.===
 +<​blockquote> ​
 +(adjust-array A ... :​displaced-to B) 
 +(adjust-array A ... :​displaced-to nil) 
 +</​blockquote> ​
 +
 +''​A''​ gets a new "data region,"​ and contents of ''​B''​ are copied into it as appropriate to maintain the existing old contents; additional elements of ''​A''​ are taken from //​initial-element//​ if supplied. However, the use of //​initial-contents//​ causes all old contents to be discarded.
 +
 +----
 +
 +If //​displaced-index-offset//​ is supplied, it specifies the offset of the resulting //​[[CL:​Glossary:​array]]//​ from the beginning of the //​[[CL:​Glossary:​array]]//​ that it is displaced to. If //​displaced-index-offset//​ is not supplied, the offset is~0. The size of the resulting //​[[CL:​Glossary:​array]]//​ plus the offset value cannot exceed the size of the //​[[CL:​Glossary:​array]]//​ that it is displaced to.
 +
 +If only //​new-dimensions//​ and an //​initial-element//​ argument are supplied, those elements of //array// that are still in bounds appear in the resulting //​[[CL:​Glossary:​array]]//​. The elements of the resulting //​[[CL:​Glossary:​array]]//​ that are not in the bounds of //​[[CL:​Glossary:​array]]//​are initialized to //​initial-element//;​ if //​initial-element//​ is not provided, the consequences of later reading any such new //​[[CL:​Glossary:​element]]//​ of //​new-array//​ before it has been initialized are undefined.
 +
 +If //​initial-contents//​ or //​displaced-to//​ is supplied, then none of the original contents of //array// appears in the new //​[[CL:​Glossary:​array]]//​.
 +
 +The consequences are unspecified if //array// is adjusted to a size smaller than its //​[[CL:​Glossary:​fill pointer]]// without supplying the //​fill-pointer//​ argument so that its //​[[CL:​Glossary:​fill-pointer]]//​ is properly adjusted in the process.
 +
 +If ''​A''​ is displaced to ''​B'',​ the consequences are unspecified if ''​B''​ is adjusted in such a way that it no longer has enough elements to satisfy ''​A''​.
 +
 +If **adjust-array** is applied to an //​[[CL:​Glossary:​array]]//​ that is //​[[CL:​Glossary:​actually adjustable]]//,​ the //​[[CL:​Glossary:​array]]//​ returned is //​[[CL:​Glossary:​identical]]//​ to //array//.
 +
 +If the //​[[CL:​Glossary:​array]]//​ returned by **adjust-array** is //​[[CL:​Glossary:​distinct]]//​ from //array//, then the argument //array// is unchanged.
 +
 +Note that if an //​[[CL:​Glossary:​array]]//​ ''​A''​ is displaced to another //​[[CL:​Glossary:​array]]//​ ''​B'',​ and ''​B''​ is displaced to another //​[[CL:​Glossary:​array]]//​ ''​C'',​ and ''​B''​ is altered by **adjust-array**,​ ''​A''​ must now refer to the adjust contents of ''​B''​. This means that an implementation cannot collapse the chain to make ''​A''​ refer to ''​C''​ directly and forget that the chain of reference passes through ''​B''​. However, caching techniques are permitted as long as they preserve the semantics specified here.
 +
 +====Examples====
 +<​blockquote> ​
 +([[CL:​Macros:​defparameter]] *ada* 
 +  (adjust-array (make-array '(2 3) :adjustable t 
 +                                   :​initial-contents '((a b c) 
 +                                                       (1 2 3))) 
 +                '(4 6))) <​r>​*ADA*</​r>​
 +(adjustable-array-p *ada*) <r>T </r>
 +(array-dimensions *ada*) <r>(4 6) </r>
 +(aref *ada* 1 1) <r>2 </r>
 +
 +([[CL:​Macros:​defparameter]] *beta* ​
 +  (make-array '(2 3) :adjustable t)) 
 +<​r>​*BETA*</​r>​
 +*beta*
 +<​r>#​2A((NIL NIL NIL)
 +    (NIL NIL NIL))</​r>​
 +(adjust-array *beta* '(4 6) 
 +              :​displaced-to *ada*) ​
 +<​r>#​2A((A ​  ​B ​  ​C ​  NIL NIL NIL) 
 +    (1   ​2 ​  ​3 ​  NIL NIL NIL) ;; output formatted manually
 +    (NIL NIL NIL NIL NIL NIL) 
 +    (NIL NIL NIL NIL NIL NIL))</​r>​
 +(array-dimensions *beta*) <r>(4 6) </r>
 +(aref *beta* 1 1) <​r>​2</​r>​
 +
 +(defvar *array* #2A((alpha beta gamma delta) ​
 +                    (epsilon zeta eta theta) ​
 +                    (iota kappa lambda mu) 
 +                    (nu xi omicron pi)) <​r>​*ARRAY*</​r>​
 +(adjust-array m '(3 5) :​initial-element '​baz) ​
 +<​r>#​2A((ALPHA BETA GAMMA DELTA BAZ)
 +    (EPSILON ZETA ETA THETA BAZ) 
 +    (IOTA KAPPA LAMBDA MU BAZ))</​r>​
 +</​blockquote>​
 +
 +====Affected By====
 +None.
 +
 +====Exceptional Situations====
 +An error of type **[[CL:​Types:​error]]** is signaled if //​fill-pointer//​ is supplied and //​[[CL:​Glossary:​non-nil]]//​ but //array// has no //​[[CL:​Glossary:​fill pointer]]//​.
 +
 +====See Also====
 +**[[CL:​Functions:​adjustable-array-p|Function ADJUSTABLE-ARRAY-P]]**,​ **[[CL:​Functions:​make-array|Function MAKE-ARRAY]]**,​ **[[CL:​Constant Variables:​array-dimension-limit|Constant Variable ARRAY-DIMENSION-LIMIT]]**,​ **[[CL:​Constant Variables:​array-total-size-limit|Constant Variable ARRAY-TOTAL-SIZE-LIMIT]]**,​ **[[CL:​Types:​array|Type ARRAY]]**
 +
 +====Notes====
 +None.
 +
 +\issue{ARRAY-DIMENSION-LIMIT-IMPLICATIONS:​ALL-FIXNUM} \issue{ADJUST-ARRAY-FILL-POINTER} \issue{ADJUST-ARRAY-DISPLACEMENT} \issue{UNINITIALIZED-ELEMENTS:​CONSEQUENCES-UNDEFINED} \issue{ADJUST-ARRAY-NOT-ADJUSTABLE:​IMPLICIT-COPY} \issue{ADJUST-ARRAY-NOT-ADJUSTABLE:​IMPLICIT-COPY}