UPDATE: Nowadays, alexandria has a copy-array
very similar to the implementation given below. Use that.
OBSOLETE ANSWER: I used the following, which I believed was better than the alexandria version at the time:
(defun copy-array (array &key
(element-type (array-element-type array))
(fill-pointer (and (array-has-fill-pointer-p array)
(fill-pointer array)))
(adjustable (adjustable-array-p array)))
"Returns an undisplaced copy of ARRAY, with same fill-pointer and
adjustability (if any) as the original, unless overridden by the keyword
arguments."
(let* ((dimensions (array-dimensions array))
(new-array (make-array dimensions
:element-type element-type
:adjustable adjustable
:fill-pointer fill-pointer)))
(dotimes (i (array-total-size array))
(setf (row-major-aref new-array i)
(row-major-aref array i)))
new-array))
The problem with the alexandria version was that the adjust-array
hack causes the result (at least on SBCL) to never be a
simple-array
, which some other libraries (e.g. opticl) expect. The
above version also was faster for me.
Someone else has published a very similar version in a different
library, but I forgot the names of both person and library.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…