mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 11:40:18 +02:00
Add function vector-copy! to core
This is up to 20%-30% faster than the previous versions in (scheme base) or (srfi srfi-43) that used vector-move-left!/vector-move-right!. * libguile/vectors.h: * libguile/vectors.c: As stated. * doc/ref/api-data.texi (vector-copy!): Document the new function. (vector-fill!): Document optional arguments. (vector-copy): Document optional arguments. * module/scheme/base.scm: Reuse core vector-copy!. * module/srfi/srfi-43.scm: Reuse core vector-copy!.
This commit is contained in:
parent
091f5062cb
commit
5df5555d12
5 changed files with 80 additions and 38 deletions
|
@ -6381,16 +6381,38 @@ Store @var{obj} in position @var{k} (a @code{size_t}) of @var{vec}.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@rnindex vector-fill!
|
@rnindex vector-fill!
|
||||||
@deffn {Scheme Procedure} vector-fill! vec fill
|
@deffn {Scheme Procedure} vector-fill! vec fill [start [end]]
|
||||||
@deffnx {C Function} scm_vector_fill_x (vec, fill)
|
@deffnx {C Function} scm_vector_fill_x (vec, fill)
|
||||||
Store @var{fill} in every position of @var{vec}. The value
|
Store @var{fill} in every position of @var{vec} in the range
|
||||||
returned by @code{vector-fill!} is unspecified.
|
[@var{start} ... @var{end}). @var{start} defaults to 0 and @var{end}
|
||||||
|
defaults to the length of @var{vec}.
|
||||||
|
|
||||||
|
The value returned by @code{vector-fill!} is unspecified.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@rnindex vector-copy
|
@rnindex vector-copy
|
||||||
@deffn {Scheme Procedure} vector-copy vec
|
@deffn {Scheme Procedure} vector-copy vec [start [end]]
|
||||||
@deffnx {C Function} scm_vector_copy (vec)
|
@deffnx {C Function} scm_vector_copy (vec)
|
||||||
Return a copy of @var{vec}.
|
Returns a freshly allocated vector containing the elements of @var{vec}
|
||||||
|
in the range [@var{start} ... @var{end}). @var{start} defaults to 0 and
|
||||||
|
@var{end} defaults to the length of @var{vec}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@rnindex vector-copy!
|
||||||
|
@deffn {Scheme Procedure} vector-copy! dst at src [start [end]]
|
||||||
|
Copy the block of elements from vector @var{src} in the range
|
||||||
|
[@var{start} ... @var{end}) into vector @var{dst}, starting at position
|
||||||
|
@var{at}. @var{at} and @var{start} default to 0 and @var{end} defaults
|
||||||
|
to the length of @var{src}.
|
||||||
|
|
||||||
|
It is an error for @var{dst} to have a length less than @var{at} +
|
||||||
|
(@var{end} - @var{start}).
|
||||||
|
|
||||||
|
The order in which elements are copied is unspecified, except that if the
|
||||||
|
source and destination overlap, copying takes place as if the source is
|
||||||
|
first copied into a temporary vector and then into the destination.
|
||||||
|
|
||||||
|
The value returned by @code{vector-copy!} is unspecified.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} vector-move-left! vec1 start1 end1 vec2 start2
|
@deffn {Scheme Procedure} vector-move-left! vec1 start1 end1 vec2 start2
|
||||||
|
@ -6403,6 +6425,8 @@ to @var{vec2} starting at position @var{start2}. @var{start1} and
|
||||||
Therefore, in the case where @var{vec1} and @var{vec2} refer to the
|
Therefore, in the case where @var{vec1} and @var{vec2} refer to the
|
||||||
same vector, @code{vector-move-left!} is usually appropriate when
|
same vector, @code{vector-move-left!} is usually appropriate when
|
||||||
@var{start1} is greater than @var{start2}.
|
@var{start1} is greater than @var{start2}.
|
||||||
|
|
||||||
|
The value returned by @code{vector-move-left!} is unspecified.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} vector-move-right! vec1 start1 end1 vec2 start2
|
@deffn {Scheme Procedure} vector-move-right! vec1 start1 end1 vec2 start2
|
||||||
|
@ -6415,6 +6439,8 @@ to @var{vec2} starting at position @var{start2}. @var{start1} and
|
||||||
Therefore, in the case where @var{vec1} and @var{vec2} refer to the
|
Therefore, in the case where @var{vec1} and @var{vec2} refer to the
|
||||||
same vector, @code{vector-move-right!} is usually appropriate when
|
same vector, @code{vector-move-right!} is usually appropriate when
|
||||||
@var{start1} is less than @var{start2}.
|
@var{start1} is less than @var{start2}.
|
||||||
|
|
||||||
|
The value returned by @code{vector-move-right!} is unspecified.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@node Vector Accessing from C
|
@node Vector Accessing from C
|
||||||
|
|
|
@ -329,6 +329,48 @@ scm_vector_copy (SCM vec)
|
||||||
return scm_vector_copy_partial (vec, SCM_UNDEFINED, SCM_UNDEFINED);
|
return scm_vector_copy_partial (vec, SCM_UNDEFINED, SCM_UNDEFINED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SCM_DEFINE (scm_vector_copy_x, "vector-copy!", 3, 2, 0,
|
||||||
|
(SCM dst, SCM at, SCM src, SCM start, SCM end),
|
||||||
|
"Copy a block of elements from @var{src} to @var{dst}, both of which must be\n"
|
||||||
|
"vectors, starting in @var{dst} at @var{at} and starting in @var{src} at\n"
|
||||||
|
"@var{start} and ending at @var{end}.\n\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"
|
||||||
|
"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"
|
||||||
|
"source and destination overlap, copying takes place as if the source is\n"
|
||||||
|
"first copied into a temporary vector and then into the destination.")
|
||||||
|
#define FUNC_NAME s_scm_vector_copy_x
|
||||||
|
{
|
||||||
|
SCM_VALIDATE_MUTABLE_VECTOR (1, dst);
|
||||||
|
SCM_VALIDATE_VECTOR (3, src);
|
||||||
|
size_t src_org = 0;
|
||||||
|
size_t dst_org = scm_to_size_t (at);
|
||||||
|
size_t src_end = SCM_I_VECTOR_LENGTH (src);
|
||||||
|
size_t dst_end = SCM_I_VECTOR_LENGTH (dst);
|
||||||
|
|
||||||
|
if (!SCM_UNBNDP (start))
|
||||||
|
{
|
||||||
|
src_org = scm_to_size_t (start);
|
||||||
|
SCM_ASSERT_RANGE (SCM_ARG4, start, src_org<=src_end);
|
||||||
|
|
||||||
|
if (!SCM_UNBNDP (end))
|
||||||
|
{
|
||||||
|
size_t e = scm_to_size_t (end);
|
||||||
|
SCM_ASSERT_RANGE (SCM_ARG5, end, e>=src_org && e<=src_end);
|
||||||
|
src_end = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t len = src_end-src_org;
|
||||||
|
SCM_ASSERT_RANGE (SCM_ARG2, at, dst_org<=dst_end && len<=dst_end-dst_org);
|
||||||
|
|
||||||
|
memmove (SCM_I_VECTOR_WELTS (dst) + dst_org, SCM_I_VECTOR_ELTS (src) + src_org,
|
||||||
|
len * sizeof(SCM));
|
||||||
|
|
||||||
|
return SCM_UNSPECIFIED;
|
||||||
|
}
|
||||||
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
|
||||||
SCM_DEFINE (scm_vector_to_list, "vector->list", 1, 0, 0,
|
SCM_DEFINE (scm_vector_to_list, "vector->list", 1, 0, 0,
|
||||||
(SCM vec),
|
(SCM vec),
|
||||||
|
|
|
@ -41,6 +41,8 @@ SCM_API SCM scm_vector_move_left_x (SCM vec1, SCM start1, SCM end1,
|
||||||
SCM_API SCM scm_vector_move_right_x (SCM vec1, SCM start1, SCM end1,
|
SCM_API SCM scm_vector_move_right_x (SCM vec1, SCM start1, SCM end1,
|
||||||
SCM vec2, SCM start2);
|
SCM vec2, SCM start2);
|
||||||
SCM_API SCM scm_vector_copy (SCM vec);
|
SCM_API SCM scm_vector_copy (SCM vec);
|
||||||
|
SCM_API SCM scm_vector_copy_partial (SCM vec, SCM start, SCM end);
|
||||||
|
SCM_API SCM scm_vector_copy_x (SCM dst, SCM at, SCM src, SCM start, SCM end);
|
||||||
|
|
||||||
SCM_API int scm_is_vector (SCM obj);
|
SCM_API int scm_is_vector (SCM obj);
|
||||||
SCM_API int scm_is_simple_vector (SCM obj);
|
SCM_API int scm_is_simple_vector (SCM obj);
|
||||||
|
@ -87,9 +89,7 @@ SCM_API SCM *scm_vector_writable_elements (SCM vec,
|
||||||
#define SCM_I_VECTOR_WELTS(x) (SCM_CELL_OBJECT_LOC (x, 1))
|
#define SCM_I_VECTOR_WELTS(x) (SCM_CELL_OBJECT_LOC (x, 1))
|
||||||
#define SCM_I_VECTOR_LENGTH(x) (((size_t) SCM_CELL_WORD_0 (x)) >> 8)
|
#define SCM_I_VECTOR_LENGTH(x) (((size_t) SCM_CELL_WORD_0 (x)) >> 8)
|
||||||
|
|
||||||
SCM_INTERNAL SCM scm_i_vector_equal_p (SCM x, SCM y);
|
SCM_INTERNAL SCM scm_i_vector_equal_p (SCM x, SCM y);
|
||||||
SCM_INTERNAL SCM scm_vector_copy_partial (SCM vec, SCM start, SCM end);
|
|
||||||
|
|
||||||
SCM_INTERNAL void scm_init_vectors (void);
|
SCM_INTERNAL void scm_init_vectors (void);
|
||||||
|
|
||||||
#endif /* SCM_VECTORS_H */
|
#endif /* SCM_VECTORS_H */
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
string->vector vector->string
|
string->vector vector->string
|
||||||
(r7:string->utf8 . string->utf8)
|
(r7:string->utf8 . string->utf8)
|
||||||
(r7:vector->list . vector->list)
|
(r7:vector->list . vector->list)
|
||||||
vector-copy! vector-append vector-for-each vector-map
|
vector-append vector-for-each vector-map
|
||||||
(r7:bytevector-copy . bytevector-copy)
|
(r7:bytevector-copy . bytevector-copy)
|
||||||
(r7:bytevector-copy! . bytevector-copy!)
|
(r7:bytevector-copy! . bytevector-copy!)
|
||||||
(r7:utf8->string . utf8->string)
|
(r7:utf8->string . utf8->string)
|
||||||
|
@ -114,7 +114,7 @@
|
||||||
(char-ready? . u8-ready?)
|
(char-ready? . u8-ready?)
|
||||||
unless
|
unless
|
||||||
unquote unquote-splicing values
|
unquote unquote-splicing values
|
||||||
vector vector-copy vector-fill!
|
vector vector-copy vector-copy! vector-fill!
|
||||||
vector-length vector-ref vector-set! vector?
|
vector-length vector-ref vector-set! vector?
|
||||||
when with-exception-handler write-char
|
when with-exception-handler write-char
|
||||||
zero?))
|
zero?))
|
||||||
|
@ -431,19 +431,6 @@
|
||||||
|
|
||||||
;;; vector
|
;;; vector
|
||||||
|
|
||||||
(define* (vector-copy! target tstart source
|
|
||||||
#:optional (sstart 0) (send (vector-length source)))
|
|
||||||
"Copy a block of elements from SOURCE to TARGET, both of which must be
|
|
||||||
vectors, starting in TARGET at TSTART and starting in SOURCE at SSTART,
|
|
||||||
ending when SEND - SSTART elements have been copied. It is an error for
|
|
||||||
TARGET to have a length less than TSTART + (SEND - SSTART). SSTART
|
|
||||||
defaults to 0 and SEND defaults to the length of SOURCE."
|
|
||||||
(let ((tlen (vector-length target))
|
|
||||||
(slen (vector-length source)))
|
|
||||||
(if (< tstart sstart)
|
|
||||||
(vector-move-left! source sstart send target tstart)
|
|
||||||
(vector-move-right! source sstart send target tstart))))
|
|
||||||
|
|
||||||
(define r7:vector->list
|
(define r7:vector->list
|
||||||
(case-lambda*
|
(case-lambda*
|
||||||
((v) (vector->list v))
|
((v) (vector->list v))
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
#:use-module (srfi srfi-8)
|
#:use-module (srfi srfi-8)
|
||||||
#:re-export (make-vector vector vector? vector-ref vector-set!
|
#:re-export (make-vector vector vector? vector-ref vector-set!
|
||||||
vector-length vector-fill!)
|
vector-length vector-fill! vector-copy!)
|
||||||
#:replace (vector-copy list->vector vector->list)
|
#:replace (vector-copy list->vector vector->list)
|
||||||
#:export (vector-empty? vector= vector-unfold vector-unfold-right
|
#:export (vector-empty? vector= vector-unfold vector-unfold-right
|
||||||
vector-reverse-copy
|
vector-reverse-copy
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
vector-binary-search
|
vector-binary-search
|
||||||
vector-any vector-every
|
vector-any vector-every
|
||||||
vector-swap! vector-reverse!
|
vector-swap! vector-reverse!
|
||||||
vector-copy! vector-reverse-copy!
|
vector-reverse-copy!
|
||||||
reverse-vector->list
|
reverse-vector->list
|
||||||
reverse-list->vector))
|
reverse-list->vector))
|
||||||
|
|
||||||
|
@ -933,19 +933,6 @@ START defaults to 0 and END defaults to the length of VEC."
|
||||||
(error-from 'copy! "would write past end of target"))
|
(error-from 'copy! "would write past end of target"))
|
||||||
(%copy! target tstart source sstart send)))))))
|
(%copy! target tstart source sstart send)))))))
|
||||||
|
|
||||||
(define-vector-copier! vector-copy!
|
|
||||||
"(vector-copy! target tstart source [sstart [send]]) -> unspecified
|
|
||||||
|
|
||||||
Copy a block of elements from SOURCE to TARGET, both of which must be
|
|
||||||
vectors, starting in TARGET at TSTART and starting in SOURCE at
|
|
||||||
SSTART, ending when SEND - SSTART elements have been copied. It is an
|
|
||||||
error for TARGET to have a length less than TSTART + (SEND - SSTART).
|
|
||||||
SSTART defaults to 0 and SEND defaults to the length of SOURCE."
|
|
||||||
(lambda (target tstart source sstart send)
|
|
||||||
(if (< tstart sstart)
|
|
||||||
(vector-move-left! source sstart send target tstart)
|
|
||||||
(vector-move-right! source sstart send target tstart))))
|
|
||||||
|
|
||||||
(define-vector-copier! vector-reverse-copy!
|
(define-vector-copier! vector-reverse-copy!
|
||||||
"(vector-reverse-copy! target tstart source [sstart [send]]) -> unspecified
|
"(vector-reverse-copy! target tstart source [sstart [send]]) -> unspecified
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue