1(define-record-type Flexvector2 (%make-flexvector fv-vector fv-length)3 flexvector?4 (fv-vector vec set-vec!)5 (fv-length flexvector-length set-flexvector-length!))67(define (cap fv)8 (vector-length (vec fv)))910(define (grow! fv)11 (define old-vec (vec fv))12 (define new-vec (make-vector (quotient (* (vector-length old-vec) 3) 2)))13 (vector-copy! new-vec 0 old-vec)14 (set-vec! fv new-vec)15 new-vec)1617(define make-flexvector18 (case-lambda19 ((size)20 (assume (>= size 0))21 (%make-flexvector (make-vector (max size 4)) size))22 ((size fill)23 (assume (>= size 0))24 (%make-flexvector (make-vector (max size 4) fill) size))))2526(define (flexvector . xs)27 (if (null? xs)28 (%make-flexvector (make-vector 4) 0)29 (list->flexvector xs)))3031(define (flexvector-ref fv index)32 (assume (flexvector? fv))33 (assume (integer? index))34 (assume (< -1 index (flexvector-length fv)))35 (vector-ref (vec fv) index))3637(define (flexvector-set! fv index x)38 (assume (flexvector? fv))39 (assume (integer? index))40 (assume (< -1 index (flexvector-length fv)))41 (let ((last-value (vector-ref (vec fv) index)))42 (vector-set! (vec fv) index x)43 last-value))4445(define flexvector-add!46 (case-lambda47 ((fv i x)48 (assume (flexvector? fv))49 (assume (integer? i))50 (let* ((len (flexvector-length fv))51 (v (if (< len (cap fv)) (vec fv) (grow! fv))))52 (assume (<= 0 i len))53 (vector-copy! v (+ i 1) v i len)54 (vector-set! v i x)55 (set-flexvector-length! fv (+ len 1))56 fv))57 ((fv i . xs)58 (flexvector-add-all! fv i xs))))5960(define flexvector-add-back!61 (case-lambda62 ((fv x)63 (assume (flexvector? fv))64 (let* ((len (flexvector-length fv))65 (v (if (< len (cap fv)) (vec fv) (grow! fv))))66 (vector-set! v len x)67 (set-flexvector-length! fv (+ len 1))68 fv))69 ((fv x . xs)70 (flexvector-add-back! fv x)71 (apply flexvector-add-back! fv xs))))7273(define (flexvector-add-all! fv i xs)74 (assume (flexvector? fv))75 (assume (integer? i))76 (assume (list? xs))77 (let* ((len (flexvector-length fv))78 (xv (list->vector xs))79 (xvlen (vector-length xv))80 (v (let lp ((v (vec fv)))81 (if (< (+ len xvlen) (vector-length v)) v (lp (grow! fv))))))82 (assume (<= 0 i len))83 (vector-copy! v (+ i xvlen) v i len)84 (vector-copy! v i xv 0 xvlen)85 (set-flexvector-length! fv (+ len xvlen))86 fv))8788(define (flexvector-remove! fv i)89 (assume (flexvector? fv))90 (assume (integer? i))91 (assume (<= 0 i (- (flexvector-length fv) 1)))92 (let ((removed (flexvector-ref fv i)))93 (flexvector-remove-range! fv i (+ i 1))94 removed))9596(define (flexvector-remove-range! fv start end)97 (assume (flexvector? fv))98 (let ((len (flexvector-length fv)))99 (when (< start 0) (set! start 0))100 (when (>= end len) (set! end len))101 (assume (<= start end))102 (vector-copy! (vec fv) start (vec fv) end)103 (let ((new-len (- len (- end start))))104 ;; Workaround a discrepancy in the implementation of vector-fill!105 ;; between R7RS and SRFI-133: R7RS doesn't error out on an empty106 ;; fill for the last vector element while SRFI-133 emits an error.107 ;;108 ;; See: http://paste.call-cc.org/paste?id=17238d2150d633b4053fc9dd0ce52ecd7c3b4f85109 (unless (eqv? start end)110 (vector-fill! (vec fv) #f new-len len))111 (set-flexvector-length! fv new-len)))112 fv)113114(define (flexvector-clear! fv)115 (assume (flexvector? fv))116 (set-vec! fv (make-vector 4))117 (set-flexvector-length! fv 0)118 fv)119120(define vector->flexvector121 (case-lambda122 ((vec)123 (assume (vector? vec))124 (vector->flexvector vec 0 (vector-length vec)))125 ((vec start)126 (assume (vector? vec))127 (vector->flexvector vec start (vector-length vec)))128 ((vec start end)129 (assume (vector? vec))130 (assume (<= 0 start end (vector-length vec)))131 (let ((len (- end start)))132 (cond133 ((< len 4)134 (let ((new-vec (make-vector 4)))135 (vector-copy! new-vec 0 vec start end)136 (%make-flexvector new-vec len)))137 (else138 (%make-flexvector (vector-copy vec start end) len)))))))139140(define flexvector->vector141 (case-lambda142 ((fv)143 (assume (flexvector? fv))144 (flexvector->vector fv 0 (flexvector-length fv)))145 ((fv start)146 (assume (flexvector? fv))147 (flexvector->vector fv start (flexvector-length fv)))148 ((fv start end)149 (assume (flexvector? fv))150 (assume (<= 0 start end (flexvector-length fv)))151 (vector-copy (vec fv) start end))))152153(define (list->flexvector xs)154 (let* ((vec (list->vector xs))155 (len (vector-length vec)))156 (cond157 ((< len 4)158 (let ((new-vec (make-vector 4)))159 (vector-copy! new-vec 0 vec)160 (%make-flexvector new-vec len)))161 (else162 (%make-flexvector vec len)))))163164(define flexvector-filter/index!165 (case-lambda166 ((pred? fv)167 (assume (flexvector? fv))168 (let ((v (vec fv)) (len (flexvector-length fv)))169 (let lp ((i 0) (j 0))170 (cond171 ((>= i len)172 (set-flexvector-length! fv j)173 fv)174 ((pred? i (vector-ref v i))175 (unless (= i j) (vector-set! v j (vector-ref v i)))176 (lp (+ i 1) (+ j 1)))177 (else178 (lp (+ i 1) j))))))179 ((pred? fv . fvs)180 (assume (flexvector? fv))181 (let ((v (vec fv)) (len (flexvector-length fv)))182 (let lp ((i 0) (j 0))183 (cond184 ((>= i len)185 (set-flexvector-length! fv j)186 fv)187 ((apply pred?188 i189 (vector-ref v i)190 (map (lambda (fv) (flexvector-ref fv i)) fvs))191 (unless (= i j) (vector-set! v j (vector-ref v i)))192 (lp (+ i 1) (+ j 1)))193 (else194 (lp (+ i 1) j))))))))195196(define flexvector-copy197 (case-lambda198 ((fv)199 (assume (flexvector? fv))200 (%make-flexvector (vector-copy (vec fv))201 (flexvector-length fv)))202 ((fv start)203 (assume (flexvector? fv))204 (flexvector-copy fv start (flexvector-length fv)))205 ((fv start end)206 (assume (flexvector? fv))207 (assume (<= 0 start end (flexvector-length fv)))208 (vector->flexvector (vector-copy (vec fv) start end)))))209210(define flexvector-copy!211 (case-lambda212 ((to at from)213 (assume (flexvector? from))214 (flexvector-copy! to at from 0 (flexvector-length from)))215 ((to at from start)216 (assume (flexvector? from))217 (flexvector-copy! to at from start (flexvector-length from)))218 ((to at from start end)219 (assume (flexvector? to))220 (assume (<= 0 at (flexvector-length to)))221 (assume (<= 0 start end (flexvector-length from)))222 (let* ((vf (vec from))223 (lt (+ (flexvector-length to) (- end start)))224 (vt (let lp ((v (vec to)))225 (if (< lt (vector-length v)) v (lp (grow! to))))))226 (vector-copy! vt at vf start end)227 (set-flexvector-length! to228 (max (flexvector-length to) (+ at (- end start))))))))