diff options
author | Daniel Llorens <lloda@sarc.name> | 2019-12-18 14:31:39 +0100 |
---|---|---|
committer | Daniel Llorens <lloda@sarc.name> | 2020-01-03 13:01:04 +0100 |
commit | ddad8ae05adfdb84ef80cb2d2730e73f4d27c74b (patch) | |
tree | a0e6b848a8aa82edcb649f5291d6008f38f5dc68 /libguile/vectors.c | |
parent | 6b0491233f6b7e3ca2743ec43340a2ed04ac845e (diff) | |
download | guile-ddad8ae05adfdb84ef80cb2d2730e73f4d27c74b.tar.gz |
Extend core vector-fill! to handle a range
With this patch, these two lines
(vector-fill! vec fill)
(vector-fill! vec fill 0 end)
run at the same speed; before, the second one was much slower.
This patch also makes it an error to call vector-fill! with a non-vector
array. The previous implementation did not work correctly in this case.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): Better error message.
(vector-fill!): Handle optional arguments start, end. Do not attempt
to handle non-vector arrays. Rename the C binding to
scm_vector_fill_partial_x.
(scm_vector_fill_x): Reuse scm_vector_fill_partial_x.
* module/srfi/srfi-43.scm (vector-fill!): Remove & re-export the core
version instead.
Diffstat (limited to 'libguile/vectors.c')
-rw-r--r-- | libguile/vectors.c | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/libguile/vectors.c b/libguile/vectors.c index 87a50a3dd..1578841c3 100644 --- a/libguile/vectors.c +++ b/libguile/vectors.c @@ -43,7 +43,8 @@ #define SCM_VALIDATE_MUTABLE_VECTOR(pos, v) \ do { \ - SCM_ASSERT (SCM_I_IS_MUTABLE_VECTOR (v), v, pos, FUNC_NAME); \ + SCM_ASSERT_TYPE (SCM_I_IS_MUTABLE_VECTOR (v), v, pos, FUNC_NAME, \ + "mutable vector"); \ } while (0) @@ -311,28 +312,48 @@ SCM_DEFINE (scm_vector_to_list, "vector->list", 1, 0, 0, } #undef FUNC_NAME +static SCM scm_vector_fill_partial_x (SCM vec, SCM fill, SCM start, SCM end); -SCM_DEFINE (scm_vector_fill_x, "vector-fill!", 2, 0, 0, - (SCM v, SCM fill), - "Store @var{fill} in every position of @var{vector}. The value\n" - "returned by @code{vector-fill!} is unspecified.") -#define FUNC_NAME s_scm_vector_fill_x +SCM_DEFINE_STATIC (scm_vector_fill_partial_x, "vector-fill!", 2, 2, 0, + (SCM vec, SCM fill, SCM start, SCM end), + "Assign the value of every location in vector @var{vec} between\n" + "@var{start} and @var{end} to @var{fill}. @var{start} defaults\n" + "to 0 and @var{end} defaults to the length of @var{vec}. The value\n" + "returned by @code{vector-fill!} is unspecified.") +#define FUNC_NAME s_scm_vector_fill_partial_x { - scm_t_array_handle handle; + SCM_VALIDATE_MUTABLE_VECTOR(1, vec); + SCM *data; - size_t i, len; - ssize_t inc; + size_t i = 0; + size_t len = SCM_I_VECTOR_LENGTH (vec); - data = scm_vector_writable_elements (v, &handle, &len, &inc); - for (i = 0; i < len; i += inc) + data = SCM_I_VECTOR_WELTS (vec); + + if (!SCM_UNBNDP (start)) + i = scm_to_unsigned_integer (start, 0, len); + + if (!SCM_UNBNDP (end)) + len = scm_to_unsigned_integer (end, i, len); + + for (; i < len; ++i) data[i] = fill; - scm_array_handle_release (&handle); + return SCM_UNSPECIFIED; } #undef FUNC_NAME SCM +scm_vector_fill_x (SCM vec, SCM fill) +#define FUNC_NAME s_scm_vector_fill_x +{ + return scm_vector_fill_partial_x (vec, fill, SCM_UNDEFINED, SCM_UNDEFINED); +} +#undef FUNC_NAME + + +SCM scm_i_vector_equal_p (SCM x, SCM y) { long i; |