data/gvector vararg constructor, add!
This commit is contained in:
parent
5a8d2f010e
commit
c8292be1d1
|
@ -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
|
||||||
|
|
|
@ -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?]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user