diff options
author | Daniel Llorens <lloda@sarc.name> | 2021-08-06 16:51:40 +0200 |
---|---|---|
committer | Daniel Llorens <lloda@sarc.name> | 2021-08-06 17:13:21 +0200 |
commit | 5df5555d12f1408a66a5368a918abb981edf5445 (patch) | |
tree | c6ffa77362fac657c6f77276fadef7efff323611 /libguile/vectors.c | |
parent | 091f5062cb2f9f5701b999c3b7ee88a480eeecf7 (diff) | |
download | guile-5df5555d12f1408a66a5368a918abb981edf5445.tar.gz |
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!.
Diffstat (limited to 'libguile/vectors.c')
-rw-r--r-- | libguile/vectors.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/libguile/vectors.c b/libguile/vectors.c index 3a2ff7ab5..40e80ddd2 100644 --- a/libguile/vectors.c +++ b/libguile/vectors.c @@ -329,6 +329,48 @@ scm_vector_copy (SCM vec) 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 vec), |