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/vector)
(define (make-gvector* #:capacity [capacity 10])
(make-gvector (make-vector capacity #f) 0))
(define make-gvector*
(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?)
(unless (exact-nonnegative-integer? index)
@ -25,27 +36,41 @@
(define ((bad-index-error who 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)]
[v (gvector-vec gv)])
(cond [(< n (vector-length v))
(vector-set! v n item)
(set-gvector-n! gv (add1 n))]
[v (gvector-vec gv)]
[item-count (length items)])
(cond [(<= (+ n item-count) (vector-length v))
(for ([index (in-naturals n)] [item (in-list items)])
(vector-set! v index item))
(set-gvector-n! gv (+ n item-count))]
[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-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-n! gv (add1 n)))])))
(set-gvector-n! gv (+ n item-count)))])))
(define SHRINK-MIN 10)
;; SLOW!
(define (gvector-remove! gv index)
(let ([n (gvector-n gv)]
[v (gvector-vec gv)])
(check-index 'gvector-remove! index n #f)
(set-gvector-n! gv (sub1 n))
(vector-copy! v index v (add1 index) n)
(vector-set! v (sub1 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))
(vector-copy! v index v (add1 index) n)
(vector-set! v (sub1 n) #f)])))
(define (gvector-count gv)
(gvector-n gv))
@ -120,6 +145,22 @@
[(var ...) (in-vector gv-expr-c)]))]
[_ #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)
#:mutable
#:property prop:dict
@ -138,14 +179,16 @@
(provide/contract
[gvector?
(-> any/c any)]
[rename gvector* gvector
(->* () () #:rest any/c gvector?)]
[rename make-gvector* make-gvector
(->* () (#:capacity exact-positive-integer?) any)]
(->* () (#:capacity exact-positive-integer?) gvector?)]
[gvector-ref
(->* (gvector? exact-nonnegative-integer?) (any/c) any)]
[gvector-set!
(-> gvector? exact-nonnegative-integer? any/c any)]
[gvector-add!
(-> gvector? any/c any)]
(->* (gvector?) () #:rest any/c any)]
[gvector-remove!
(-> gvector? exact-nonnegative-integer? any)]
[gvector-count

View File

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