Daniel Cussen
Daniel Cussen

Reputation: 149

How do I make a dynamic vector a simple vector again, in Common Lisp?

I want to use vectors with :adjustable and :fill-pointer set to true in order to push things onto them, but once I'm finished pushing things on I want to be able to use svref on them for faster access. Is there a good way to turn this kind of vector into a simple vector?

Upvotes: 1

Views: 938

Answers (2)

adobriyan
adobriyan

Reputation: 2662

See COERCE.

CL-USER> (defvar *xxx*)
*XXX*                                                                                                                                                                               
CL-USER> (setf *xxx* (make-array 5 :element-type '(unsigned-byte 8) :initial-element 1 :adjustable t))
#(1 1 1 1 1)                                                                                                                                                                        
CL-USER> *xxx*
#(1 1 1 1 1)                                                                                                                                                                        
CL-USER> (type-of *xxx*)
(AND (VECTOR (UNSIGNED-BYTE 8) 5) (NOT SIMPLE-ARRAY))                                                                                                                               
CL-USER> (coerce *xxx* 'simple-vector)
#(1 1 1 1 1)                                                                                                                                                                        
CL-USER> (type-of *)
(SIMPLE-VECTOR 5)

Upvotes: 3

Gareth McCaughan
Gareth McCaughan

Reputation: 19971

You can't take away the adjustability and fill-pointer-having of a vector object, but you could copy its contents to a new vector:

(make-array (array-dimensions my-adjustable-vector)
    :element-type (array-element-type my-adjustable-vector)
    :initial-contents my-adjustable-vector)

which won't be (expressly) adjustable or have a fill-pointer. Whether this is actually a performance win -- it involves paying up-front the cost of making a new array and copying the elements, and either freeing the old one or (if there are other references to it) keeping both around -- will of course depend on your application.

Upvotes: 2

Related Questions