cs: faster string-copy!

Similar to e087059f21.
This commit is contained in:
Matthew Flatt 2020-01-01 15:00:23 -07:00
parent e88c2b18e6
commit e97639e525

View File

@ -17,17 +17,30 @@
[(dest d-start src s-start)
(string-copy! dest d-start src s-start (and (string? src) (string-length src)))]
[(dest d-start src s-start s-end)
(check who mutable-string? :contract "(and/c string? (not/c immutable?))" dest)
(check who exact-nonnegative-integer? d-start)
(check who string? src)
(check who exact-nonnegative-integer? s-start)
(check who exact-nonnegative-integer? s-end)
(let ([d-len (string-length dest)])
(check-range who "string" dest d-start #f d-len)
(check-range who "string" src s-start s-end (string-length src))
(let ([s-len (fx- s-end s-start)])
(check-space who "string" d-start d-len s-len)
(#%string-copy! src s-start dest d-start s-len)))]))
;; start with fast, inlined checks for valid calls, then use
;; slower tests with consistent reporting if fast tests fail
(cond
[(and (mutable-string? dest)
(string? src)
(fixnum? d-start)
(fixnum? s-start)
(fixnum? s-end)
(fx- s-end s-start)
(fx<= 0 d-start (fx+ d-start (fx- s-end s-start)) (string-length dest))
(fx<= 0 s-start s-end (string-length src)))
(#%string-copy! src s-start dest d-start (fx- s-end s-start))]
[else
(check who mutable-string? :contract "(and/c string? (not/c immutable?))" dest)
(check who exact-nonnegative-integer? d-start)
(check who string? src)
(check who exact-nonnegative-integer? s-start)
(check who exact-nonnegative-integer? s-end)
(let ([d-len (string-length dest)])
(check-range who "string" dest d-start #f d-len)
(check-range who "string" src s-start s-end (string-length src))
(let ([s-len (fx- s-end s-start)])
(check-space who "string" d-start d-len s-len)
(#%string-copy! src s-start dest d-start s-len)))])]))
(define/who substring
(case-lambda