data/gvector vararg constructor, add!

This commit is contained in:
Ryan Culpepper 2010-09-03 17:11:02 -06:00
parent 5a8d2f010e
commit c8292be1d1
2 changed files with 69 additions and 21 deletions

View File

@ -6,8 +6,19 @@
racket/dict racket/dict
racket/vector) racket/vector)
(define (make-gvector* #:capacity [capacity 10]) (define make-gvector*
(make-gvector (make-vector capacity #f) 0)) (let ([make-gvector
(lambda (#:capacity [capacity 10])
(make-gvector (make-vector capacity #f) 0))])
make-gvector))
(define gvector*
(let ([gvector
(lambda init-elements
(let ([gv (make-gvector*)])
(apply gvector-add! gv init-elements)
gv))])
gvector))
(define (check-index who index n set-to-add?) (define (check-index who index n set-to-add?)
(unless (exact-nonnegative-integer? index) (unless (exact-nonnegative-integer? index)
@ -25,27 +36,41 @@
(define ((bad-index-error who index)) (define ((bad-index-error who index))
(raise-mismatch-error who "index out of range" index)) (raise-mismatch-error who "index out of range" index))
(define (gvector-add! gv item) (define (gvector-add! gv . items)
(let ([n (gvector-n gv)] (let ([n (gvector-n gv)]
[v (gvector-vec gv)]) [v (gvector-vec gv)]
(cond [(< n (vector-length v)) [item-count (length items)])
(vector-set! v n item) (cond [(<= (+ n item-count) (vector-length v))
(set-gvector-n! gv (add1 n))] (for ([index (in-naturals n)] [item (in-list items)])
(vector-set! v index item))
(set-gvector-n! gv (+ n item-count))]
[else [else
(let ([nv (make-vector (* 2 n) #f)]) (let* ([nn (let loop ([nn n])
(if (<= (+ n item-count) nn) nn (loop (* 2 nn))))]
[nv (make-vector nn #f)])
(vector-copy! nv 0 v) (vector-copy! nv 0 v)
(vector-set! nv n item) (for ([index (in-naturals n)] [item (in-list items)])
(vector-set! nv index item))
(set-gvector-vec! gv nv) (set-gvector-vec! gv nv)
(set-gvector-n! gv (add1 n)))]))) (set-gvector-n! gv (+ n item-count)))])))
(define SHRINK-MIN 10)
;; SLOW! ;; SLOW!
(define (gvector-remove! gv index) (define (gvector-remove! gv index)
(let ([n (gvector-n gv)] (let ([n (gvector-n gv)]
[v (gvector-vec gv)]) [v (gvector-vec gv)])
(check-index 'gvector-remove! index n #f) (check-index 'gvector-remove! index n #f)
(cond [(<= SHRINK-MIN (* 3 n) (vector-length v))
(let ([nv (make-vector (floor (/ (vector-length v) 2)) #f)])
(vector-copy! nv 0 v 0 index)
(vector-copy! nv index v (add1 index) n)
(set-gvector-n! gv (sub1 n))
(set-gvector-vec! gv nv))]
[else
(set-gvector-n! gv (sub1 n)) (set-gvector-n! gv (sub1 n))
(vector-copy! v index v (add1 index) n) (vector-copy! v index v (add1 index) n)
(vector-set! v (sub1 n) #f))) (vector-set! v (sub1 n) #f)])))
(define (gvector-count gv) (define (gvector-count gv)
(gvector-n gv)) (gvector-n gv))
@ -120,6 +145,22 @@
[(var ...) (in-vector gv-expr-c)]))] [(var ...) (in-vector gv-expr-c)]))]
[_ #f]))) [_ #f])))
(define-syntax (for/gvector stx)
(syntax-case stx ()
[(_ (clause ...) . body)
(quasisyntax/loc stx
(let ([gv (make-gvector)])
(for/fold/derived #,stx () (clause ...) . body)
gv))]))
(define-syntax (for*/gvector stx)
(syntax-case stx ()
[(_ (clause ...) . body)
(quasisyntax/loc stx
(let ([gv (make-gvector)])
(for*/fold/derived #,stx () (clause ...) . body)
gv))]))
(define-struct gvector (vec n) (define-struct gvector (vec n)
#:mutable #:mutable
#:property prop:dict #:property prop:dict
@ -138,14 +179,16 @@
(provide/contract (provide/contract
[gvector? [gvector?
(-> any/c any)] (-> any/c any)]
[rename gvector* gvector
(->* () () #:rest any/c gvector?)]
[rename make-gvector* make-gvector [rename make-gvector* make-gvector
(->* () (#:capacity exact-positive-integer?) any)] (->* () (#:capacity exact-positive-integer?) gvector?)]
[gvector-ref [gvector-ref
(->* (gvector? exact-nonnegative-integer?) (any/c) any)] (->* (gvector? exact-nonnegative-integer?) (any/c) any)]
[gvector-set! [gvector-set!
(-> gvector? exact-nonnegative-integer? any/c any)] (-> gvector? exact-nonnegative-integer? any/c any)]
[gvector-add! [gvector-add!
(-> gvector? any/c any)] (->* (gvector?) () #:rest any/c any)]
[gvector-remove! [gvector-remove!
(-> gvector? exact-nonnegative-integer? any)] (-> gvector? exact-nonnegative-integer? any)]
[gvector-count [gvector-count

View File

@ -26,14 +26,19 @@ number of elements in the gvector.
@defproc[(make-gvector [#:capacity capacity exact-positive-integer? 10]) @defproc[(make-gvector [#:capacity capacity exact-positive-integer? 10])
gvector?]{ gvector?]{
Creates a new empty growable vector (gvector) with an initial capacity Creates a new empty gvector with an initial capacity of
of @racket[capacity]. @racket[capacity].
}
@defproc[(gvector [elem any/c] ...)
gvector?]{
Creates a new gvector containing each @racket[elem] in order.
} }
@defproc[(gvector? [x any/c]) boolean?]{ @defproc[(gvector? [x any/c]) boolean?]{
Returns @racket[#t] if @racket[x] was created by Returns @racket[#t] if @racket[x] is a gvector, @racket[#f] otherwise.
@racket[make-gvector], @racket[#f] otherwise.
} }
@defproc[(gvector-ref [gv gvector?] @defproc[(gvector-ref [gv gvector?]
@ -47,10 +52,10 @@ invoked if it is a procedure, returned otherwise.
} }
@defproc[(gvector-add! [gv gvector?] @defproc[(gvector-add! [gv gvector?]
[value any/c]) [value any/c] ...)
void?]{ void?]{
Adds @racket[value] to the end of the gvector @racket[gv]. Adds each @racket[value] to the end of the gvector @racket[gv].
} }
@defproc[(gvector-set! [gv gvector?] @defproc[(gvector-set! [gv gvector?]