What is the known most concise way to copy an
arbitrary array I wonder.
For now I had only seen something
(let ((new-array (make-array (array-dimensions old-array)
:element-type (array-element-type old-array)
;; Some sort of LOOPs here to copy contents
)
I have no bright idea how to copy array's contents,
not saying about fill-pointer, displacement etc.
For now I'd satisfied with dimensions, type and contents
and leave others to some future time.
--
Vladimir Zolotykh
Vladimir Zolotykh <······@eurocom.od.ua> writes:
> ;; Some sort of LOOPs here to copy contents
If you use ROW-MAJOR-AREF and ARRAY-TOTAL-SIZE, you need only one loop.
Kalle Olavi Niemitalo <···@iki.fi> wrote in message news:<··············@Astalo.y2000.kon.iki.fi>...
> Vladimir Zolotykh <······@eurocom.od.ua> writes:
>
> > ;; Some sort of LOOPs here to copy contents
>
> If you use ROW-MAJOR-AREF and ARRAY-TOTAL-SIZE, you need only one loop.
You can get away with no loops like this:
(defun linearize-array (array)
(make-array (array-total-size array) :displaced-to array))
(defun copy-array (array)
(let ((storage (copy-seq (linearize-array array))))
(make-array (array-dimensions array) :displaced-to storage)))
^L
Very nice!
BTW the following code I have found in C.L.L archives
posted some time ago by Barry Margolin if I am not mistaken.
Could you tell me why it might not work in ACL61 ?
Should it work in compliant CL I wonder ?
It works in CMUCL18c for example.
(defun copy-array (array)
(let ((new (make-array (array-dimensions array) :displaced-to array)))
(adjust-array new (array-dimensions array) :displayced-to nil)))
Louis Theran wrote:
>
> Kalle Olavi Niemitalo <···@iki.fi> wrote in message news:<··············@Astalo.y2000.kon.iki.fi>...
> > Vladimir Zolotykh <······@eurocom.od.ua> writes:
> >
> > > ;; Some sort of LOOPs here to copy contents
> >
> > If you use ROW-MAJOR-AREF and ARRAY-TOTAL-SIZE, you need only one loop.
>
> You can get away with no loops like this:
>
> (defun linearize-array (array)
> (make-array (array-total-size array) :displaced-to array))
>
> (defun copy-array (array)
> (let ((storage (copy-seq (linearize-array array))))
> (make-array (array-dimensions array) :displaced-to storage)))
>
> ^L
--
Vladimir Zolotykh
In article <·················@eurocom.od.ua>, Vladimir Zolotykh wrote:
> What is the known most concise way to copy an
> arbitrary array I wonder.
>
> For now I had only seen something
>
> (let ((new-array (make-array (array-dimensions old-array)
> :element-type (array-element-type old-array)
> ;; Some sort of LOOPs here to copy contents
> )
>
> I have no bright idea how to copy array's contents,
> not saying about fill-pointer, displacement etc.
I just wrote this. I may have made errors. Corrections welcome.
;;; Trying to make exact copy of an array.
(defun copy-array (old-array)
"Copy array." ;<- Better docstring is left as an exercise for the reader
(check-type old-array array)
(multiple-value-bind (displaced-to displaced-index-offset)
(array-displacement old-array)
;; initial-contents must not be supplied if displaced-to is supplied.
(if displaced-to
;; displaced array
(make-array (array-dimensions old-array)
:element-type (array-element-type old-array)
:adjustable (adjustable-array-p old-array)
:fill-pointer (if (array-has-fill-pointer-p old-array)
(fill-pointer old-array)
nil)
:displaced-to displaced-to
:displaced-index-offset displaced-index-offset)
;; array with initial contents
(make-array (array-dimensions old-array)
:element-type (array-element-type old-array)
:initial-contents old-array
:adjustable (adjustable-array-p old-array)
:fill-pointer (if (array-has-fill-pointer-p old-array)
(fill-pointer old-array)
nil)))))
-- Kimmo, http://www.iki.fi/kt/
((lambda (integer)
(coerce (loop for i upfrom 0 by 8 below (integer-length integer)
collect (code-char (ldb (byte 8 i) integer))) 'string))
100291759904362517251920937783274743691485481194069255743433035)
Kimmo T Takkunen wrote:
>
> In article <·················@eurocom.od.ua>, Vladimir Zolotykh wrote:
> > What is the known most concise way to copy an
> > arbitrary array I wonder.
> >
> > For now I had only seen something
> >
> > (let ((new-array (make-array (array-dimensions old-array)
> > :element-type (array-element-type old-array)
> > ;; Some sort of LOOPs here to copy contents
> > )
> >
> > I have no bright idea how to copy array's contents,
> > not saying about fill-pointer, displacement etc.
>
> I just wrote this. I may have made errors. Corrections welcome.
>
> ;;; Trying to make exact copy of an array.
> (defun copy-array (old-array)
> "Copy array." ;<- Better docstring is left as an exercise for the reader
> (check-type old-array array)
> (multiple-value-bind (displaced-to displaced-index-offset)
> (array-displacement old-array)
> ;; initial-contents must not be supplied if displaced-to is supplied.
> (if displaced-to
> ;; displaced array
> (make-array (array-dimensions old-array)
> :element-type (array-element-type old-array)
> :adjustable (adjustable-array-p old-array)
> :fill-pointer (if (array-has-fill-pointer-p old-array)
> (fill-pointer old-array)
> nil)
> :displaced-to displaced-to
> :displaced-index-offset displaced-index-offset)
> ;; array with initial contents
> (make-array (array-dimensions old-array)
> :element-type (array-element-type old-array)
> :initial-contents old-array
Which CL implementation you are using ? Does it support array
as value for :initial-contents ?
> :adjustable (adjustable-array-p old-array)
> :fill-pointer (if (array-has-fill-pointer-p old-array)
> (fill-pointer old-array)
> nil)))))
>
> -- Kimmo, http://www.iki.fi/kt/
> ((lambda (integer)
> (coerce (loop for i upfrom 0 by 8 below (integer-length integer)
> collect (code-char (ldb (byte 8 i) integer))) 'string))
> 100291759904362517251920937783274743691485481194069255743433035)
--
Vladimir Zolotykh
In article <·················@eurocom.od.ua>, Vladimir Zolotykh wrote:
> Kimmo T Takkunen wrote:
>>
>> In article <·················@eurocom.od.ua>, Vladimir Zolotykh wrote:
>> > What is the known most concise way to copy an
>> > arbitrary array I wonder.
>> >
>> > For now I had only seen something
>> >
>> > (let ((new-array (make-array (array-dimensions old-array)
>> > :element-type (array-element-type old-array)
>> > ;; Some sort of LOOPs here to copy contents
>> > )
>> >
>> > I have no bright idea how to copy array's contents,
>> > not saying about fill-pointer, displacement etc.
>>
>> ;; array with initial contents
>> (make-array (array-dimensions old-array)
>> :element-type (array-element-type old-array)
>> :initial-contents old-array
Heh. It seems I had blind spot in my thinking.
It was so intuitively evident to me that initial-contents takes array values
that I didn't even understand your question.
> Which CL implementation you are using ? Does it support array
> as value for :initial-contents ?
No. It's a bug. Function was wrongly named. Should have been
copy-vector. When I made this function, I wanted copy-vector and it
worked. Then I just over-generalized.
;;; Sigh. Next version.
(defun copy-array-elements (from to)
(loop for i below (array-total-size from)
do (setf (row-major-aref to i) (row-major-aref from i))
finally (return to)))
(defun copy-array (old-array)
"Make exact copy of array."
(check-type old-array array)
(multiple-value-bind (displaced-to displaced-index-offset)
(array-displacement old-array)
;; initial-contents must not be supplied if displaced-to is supplied.
(if displaced-to
;; displaced array
(make-array (array-dimensions old-array)
:element-type (array-element-type old-array)
:adjustable (adjustable-array-p old-array)
:fill-pointer (if (array-has-fill-pointer-p old-array)
(fill-pointer old-array)
nil)
:displaced-to displaced-to
:displaced-index-offset displaced-index-offset)
;; array with initial contents
(copy-array-elements old-array
(make-array (array-dimensions old-array)
:element-type (array-element-type old-array)
:adjustable (adjustable-array-p old-array)
:fill-pointer (if (array-has-fill-pointer-p old-array)
(fill-pointer old-array)
nil))))))
-- Kimmo, http://www.iki.fi/kt/
((lambda (integer)
(coerce (loop for i upfrom 0 by 8 below (integer-length integer)
collect (code-char (ldb (byte 8 i) integer))) 'string))
100291759904362517251920937783274743691485481194069255743433035)
········@cc.helsinki.fi (Kimmo T Takkunen) writes:
> (make-array (array-dimensions old-array)
> :element-type (array-element-type old-array)
> :initial-contents old-array
The initial-contents must be a nested structure of sequences, so
this works only with one-dimensional arrays. That is, the
initial-contents of a 2*2 array could be ((1 2) (3 4)), #(#(1 2)
#(3 4)) or a mix like ((1 2) #(3 4)), but not #2A((1 2) (3 4)).