1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 03:40:34 +02:00

Provide xxvector-copy and xxvector-copy! for srfi-4 vectors

These use the argument conventions of vector-copy!, string-copy!,
etc. and not that of bytevector-copy! (which is from r6rs).

* module/srfi/srfi-4/gnu.scm: As stated.
* test-suite/tests/srfi-4.test: Tests.
* doc/ref/srfi-modules.texi: Documentation.
* libguile/bytevectors.c (bytevector-copy!): Add overlap note to
  docstring.
* libguile/vectors.c (vector-copy!): Reuse text for the overlap note.
This commit is contained in:
Daniel Llorens 2021-10-21 15:05:46 +02:00
parent c85724bd0a
commit 6be51f9bbf
6 changed files with 180 additions and 28 deletions

View file

@ -6395,6 +6395,7 @@ The value returned by @code{vector-fill!} is unspecified.
@end deffn @end deffn
@rnindex vector-copy @rnindex vector-copy
@anchor{x-vector-copy}
@deffn {Scheme Procedure} vector-copy vec [start [end]] @deffn {Scheme Procedure} vector-copy vec [start [end]]
@deffnx {C Function} scm_vector_copy (vec) @deffnx {C Function} scm_vector_copy (vec)
Returns a freshly allocated vector containing the elements of @var{vec} Returns a freshly allocated vector containing the elements of @var{vec}
@ -6403,6 +6404,7 @@ in the range [@var{start} ... @var{end}). @var{start} defaults to 0 and
@end deffn @end deffn
@rnindex vector-copy! @rnindex vector-copy!
@anchor{x-vector-copy!}
@deffn {Scheme Procedure} vector-copy! dst at src [start [end]] @deffn {Scheme Procedure} vector-copy! dst at src [start [end]]
Copy the block of elements from vector @var{src} in the range Copy the block of elements from vector @var{src} in the range
[@var{start} ... @var{end}) into vector @var{dst}, starting at position [@var{start} ... @var{end}) into vector @var{dst}, starting at position

View file

@ -1806,6 +1806,53 @@ a vector, or a uniform vector. When @var{obj} is already a suitable
uniform numeric vector, it is returned unchanged. uniform numeric vector, it is returned unchanged.
@end deffn @end deffn
@deffn {Scheme Procedure} u8vector-copy! dst at src [start [end]]
@deffnx {Scheme Procedure} s8vector-copy! dst at src [start [end]]
@deffnx {Scheme Procedure} u16vector-copy! dst at src [start [end]]
@deffnx {Scheme Procedure} s16vector-copy! dst at src [start [end]]
@deffnx {Scheme Procedure} u32vector-copy! dst at src [start [end]]
@deffnx {Scheme Procedure} s32vector-copy! dst at src [start [end]]
@deffnx {Scheme Procedure} u64vector-copy! dst at src [start [end]]
@deffnx {Scheme Procedure} s64vector-copy! dst at src [start [end]]
@deffnx {Scheme Procedure} f32vector-copy! dst at src [start [end]]
@deffnx {Scheme Procedure} f64vector-copy! dst at src [start [end]]
@deffnx {Scheme Procedure} c32vector-copy! dst at src [start [end]]
@deffnx {Scheme Procedure} c64vector-copy! dst at src [start [end]]
Copy a block of elements from @var{src} to @var{dst}, both of which must
be vectors of the indicated type, starting in @var{dst} at @var{at} and
starting in @var{src} at @var{start} and ending at @var{end}. It is an
error for @var{dst} to have a length less than @var{at} + (@var{end} -
@var{start}). @var{at} and @var{start} default to 0 and @var{end}
defaults to the length of @var{src}.
If source and destination overlap, copying takes place as if the
source is first copied into a temporary vector and then into the
destination.
See also @ref{x-vector-copy!,@code{vector-copy!}}.
@end deffn
@deffn {Scheme Procedure} u8vector-copy src [start [end]]
@deffnx {Scheme Procedure} s8vector-copy src [start [end]]
@deffnx {Scheme Procedure} u16vector-copy src [start [end]]
@deffnx {Scheme Procedure} s16vector-copy src [start [end]]
@deffnx {Scheme Procedure} u32vector-copy src [start [end]]
@deffnx {Scheme Procedure} s32vector-copy src [start [end]]
@deffnx {Scheme Procedure} u64vector-copy src [start [end]]
@deffnx {Scheme Procedure} s64vector-copy src [start [end]]
@deffnx {Scheme Procedure} f32vector-copy src [start [end]]
@deffnx {Scheme Procedure} f64vector-copy src [start [end]]
@deffnx {Scheme Procedure} c32vector-copy src [start [end]]
@deffnx {Scheme Procedure} c64vector-copy src [start [end]]
Returns a freshly allocated vector of the indicated type, which must be
the same as that of @var{src}, containing the elements of @var{src}
between @var{start} and @var{end}. @var{src} must be a vector of the
indicated type. @var{start} defaults to 0 and @var{end} defaults to the
length of @var{src}.
See also @ref{x-vector-copy,@code{vector-copy}}.
@end deffn
@node SRFI-6 @node SRFI-6
@subsection SRFI-6 - Basic String Ports @subsection SRFI-6 - Basic String Ports

View file

@ -609,9 +609,13 @@ SCM_DEFINE (scm_bytevector_copy_x, "bytevector-copy!", 5, 0, 0,
(SCM source, SCM source_start, SCM target, SCM target_start, (SCM source, SCM source_start, SCM target, SCM target_start,
SCM len), SCM len),
"Copy @var{len} bytes from @var{source} into @var{target}, " "Copy @var{len} bytes from @var{source} into @var{target}, "
"starting reading from @var{source_start} (a positive index " "reading from a block starting at @var{source_start} (a positive "
"within @var{source}) and start writing at " "index within @var{source}) and writing to a block starting at "
"@var{target_start}.") "@var{target_start}.\n\n"
"It is permitted for the @var{source} and @var{target} regions to "
"overlap. In that case, copying takes place as if the source is "
"first copied into a temporary bytevector and then into the "
"destination. ")
#define FUNC_NAME s_scm_bytevector_copy_x #define FUNC_NAME s_scm_bytevector_copy_x
{ {
size_t c_len, c_source_len, c_target_len; size_t c_len, c_source_len, c_target_len;

View file

@ -331,9 +331,8 @@ SCM_DEFINE (scm_vector_copy_x, "vector-copy!", 3, 2, 0,
"It is an error for @var{dst} to have a length less than\n" "It is an error for @var{dst} to have a length less than\n"
"@var{at} + (@var{end} - @var{start}). @var{at} and @var{start} default\n" "@var{at} + (@var{end} - @var{start}). @var{at} and @var{start} default\n"
"to 0 and @var{end} defaults to the length of @var{src}.\n\n" "to 0 and @var{end} defaults to the length of @var{src}.\n\n"
"The order in which elements are copied is unspecified, except that if the\n" "If source and destination overlap, copying takes place as if the source\n"
"source and destination overlap, copying takes place as if the source is\n" "is first copied into a temporary vector and then into the destination.")
"first copied into a temporary vector and then into the destination.")
#define FUNC_NAME s_scm_vector_copy_x #define FUNC_NAME s_scm_vector_copy_x
{ {
SCM_VALIDATE_MUTABLE_VECTOR (1, dst); SCM_VALIDATE_MUTABLE_VECTOR (1, dst);

View file

@ -25,6 +25,7 @@
(define-module (srfi srfi-4 gnu) (define-module (srfi srfi-4 gnu)
#:use-module (rnrs bytevectors) #:use-module (rnrs bytevectors)
#:use-module (srfi srfi-4) #:use-module (srfi srfi-4)
#:use-module ((srfi srfi-1) #:select (append-map))
#:export (;; Complex numbers with 32- and 64-bit components. #:export (;; Complex numbers with 32- and 64-bit components.
c32vector? make-c32vector c32vector c32vector-length c32vector-ref c32vector? make-c32vector c32vector c32vector-length c32vector-ref
c32vector-set! c32vector->list list->c32vector c32vector-set! c32vector->list list->c32vector
@ -37,7 +38,17 @@
;; Somewhat polymorphic conversions. ;; Somewhat polymorphic conversions.
any->u8vector any->s8vector any->u16vector any->s16vector any->u8vector any->s8vector any->u16vector any->s16vector
any->u32vector any->s32vector any->u64vector any->s64vector any->u32vector any->s32vector any->u64vector any->s64vector
any->f32vector any->f64vector any->c32vector any->c64vector)) any->f32vector any->f64vector any->c32vector any->c64vector
;; copy range
u8vector-copy s8vector-copy u16vector-copy s16vector-copy
u32vector-copy s32vector-copy u64vector-copy s64vector-copy
f32vector-copy f64vector-copy c32vector-copy c64vector-copy
;; copy range with destination
u8vector-copy! s8vector-copy! u16vector-copy! s16vector-copy!
u32vector-copy! s32vector-copy! u64vector-copy! s64vector-copy!
f32vector-copy! f64vector-copy! c32vector-copy! c64vector-copy!))
(define make-srfi-4-vector (@@ (srfi srfi-4) make-srfi-4-vector)) (define make-srfi-4-vector (@@ (srfi srfi-4) make-srfi-4-vector))
@ -58,9 +69,34 @@
((@@ (srfi srfi-4) define-bytevector-type) c32 c32-native 8) ((@@ (srfi srfi-4) define-bytevector-type) c32 c32-native 8)
((@@ (srfi srfi-4) define-bytevector-type) c64 c64-native 16) ((@@ (srfi srfi-4) define-bytevector-type) c64 c64-native 16)
(define-macro (define-any->vector . tags) (define sizeof-u8 1)
(define sizeof-u16 2)
(define sizeof-u32 4)
(define sizeof-u64 8)
(define sizeof-s8 1)
(define sizeof-s16 2)
(define sizeof-s32 4)
(define sizeof-s64 8)
(define sizeof-f32 4)
(define sizeof-f64 8)
(define sizeof-c32 8)
(define sizeof-c64 16)
(define-macro (type-check v tag)
`(unless (,(symbol-append tag 'vector?) ,v)
(scm-error 'wrong-type-arg #f
,(format #f "expecting ~a, got ~~A" (symbol-append tag 'vector))
(list ,v) (list ,v))))
(define-macro (define-funs . tags)
`(begin `(begin
,@(map (lambda (tag) ,@(append-map
(lambda (tag)
(list
; any->xxvector
`(define (,(symbol-append 'any-> tag 'vector) obj) `(define (,(symbol-append 'any-> tag 'vector) obj)
(cond ((,(symbol-append tag 'vector?) obj) obj) (cond ((,(symbol-append tag 'vector?) obj) obj)
((pair? obj) (,(symbol-append 'list-> tag 'vector) obj)) ((pair? obj) (,(symbol-append 'list-> tag 'vector) obj))
@ -74,7 +110,47 @@
v i (array-ref obj i)) v i (array-ref obj i))
(lp (1+ i))) (lp (1+ i)))
v)))) v))))
(else (scm-error 'wrong-type-arg #f "" '() (list obj)))))) (else (scm-error 'wrong-type-arg #f "" '() (list obj)))))
; xxvector-copy!
`(define* (,(symbol-append tag 'vector '-copy!) dst at src #:optional (start 0) end)
,(format #f
"Copy a block of elements from @var{src} to @var{dst}, both of
which must be ~as, starting in @var{dst} at @var{at} and
starting in @var{src} at @var{start} and ending at @var{end}. It
is an error for @var{dst} to have a length less than @var{at} +
(@var{end} - @var{start}). @var{at} and @var{start} default to 0
and @var{end} defaults to the length of @var{src}.
If source and destination overlap, copying takes place as if the
source is first copied into a temporary vector and then into the
destination."
(symbol-append tag 'vector))
(type-check src ,tag)
(type-check dst ,tag)
(let ((sof ,(symbol-append 'sizeof- tag))
(len (- (or end (,(symbol-append tag 'vector-length) src)) start)))
(bytevector-copy! src (* start sof) dst (* at sof) (* len sof))))
; xxvector-copy
`(define* (,(symbol-append tag 'vector '-copy) src #:optional (start 0) end)
,(format #f
"Returns a freshly allocated ~a containing the elements of ~a
@var{src} between @var{start} and @var{end}. @var{start} defaults
to 0 and @var{end} defaults to the length of @var{src}."
(symbol-append tag 'vector)
(symbol-append tag 'vector))
(type-check src ,tag)
(let* ((sof ,(symbol-append 'sizeof- tag))
(len (- (or end (,(symbol-append tag 'vector-length) src)) start))
(dst (,(symbol-append 'make- tag 'vector) len)))
(bytevector-copy! src (* start sof) dst 0 (* len sof))
dst))
))
tags))) tags)))
(define-any->vector u8 s8 u16 s16 u32 s32 u64 s64 f32 f64 c32 c64) (define-funs u8 s8 u16 s16 u32 s32 u64 s64 f32 f64 c32 c64)

View file

@ -540,3 +540,27 @@
(u16vector-set! v 2 0) (u16vector-set! v 2 0)
(u16vector-set! v 3 0) (u16vector-set! v 3 0)
(equal? v #u32(#xFFFFFFFF 0))))) (equal? v #u32(#xFFFFFFFF 0)))))
(with-test-prefix "typed vector copies (srfi srfi-4 gnu)"
(pass-if "f64vector-copy"
(equal? #f64(1 2 3 4) (f64vector-copy #f64(9 7 1 2 3 4 0 8) 2 6)))
(pass-if "c64vector-copy"
(equal? #c64(1 2 3 4 0 8) (c64vector-copy #c64(9 7 1 2 3 4 0 8) 2)))
(pass-if "s32vector-copy! (both optional args)"
(let ((v (s32vector 9 7 1 2 3 4 0 8)))
(s32vector-copy! v 2 #s32(-1 -2 -3 -4 -5 -6 -7 -8) 3 7)
(equal? #s32(9 7 -4 -5 -6 -7 0 8) v)))
(pass-if "s16vector-copy! (one optional arg)"
(let ((v (s16vector 9 7 1 2 3 4 0 8)))
(s16vector-copy! v 2 #s16(-1 -2 -3 -4 -5 -6 -7 -8) 3)
(equal? #s16(9 7 -4 -5 -6 -7 -8 8) v)))
(pass-if "s8vector-copy! (no optional args)"
(let ((v (s8vector 9 7 1 2 3 4 0 8)))
(s8vector-copy! v 2 #s8(-1 -2 -3 -4 -5))
(equal? #s8(9 7 -1 -2 -3 -4 -5 8) v))))