summaryrefslogtreecommitdiff
path: root/libguile/bitvectors.c
diff options
context:
space:
mode:
authorDaniel Llorens <lloda@sarc.name>2022-01-04 12:15:45 +0100
committerDaniel Llorens <lloda@sarc.name>2022-01-04 12:28:41 +0100
commitd70c1dbebf9ac0fd45af4578c23983ec4a7da535 (patch)
treed4ba4c2d409ff5ca75e4d20c64d4df979138b3eb /libguile/bitvectors.c
parentdc7f1b403b536a0ddd5acdef468b7cf0331ac531 (diff)
downloadguile-d70c1dbebf9ac0fd45af4578c23983ec4a7da535.tar.gz
New function bitvector-copy (scm_bitvector_copy)
* libguile/bitvectors.h: * libguile/bitvectors.c: As stated. * test-suite/tests/bitvectors.test: Tests. * doc/ref/api-data.texi: Update "Bit vectors" section. * NEWS: Update.
Diffstat (limited to 'libguile/bitvectors.c')
-rw-r--r--libguile/bitvectors.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/libguile/bitvectors.c b/libguile/bitvectors.c
index 3a279e401..41b91a51b 100644
--- a/libguile/bitvectors.c
+++ b/libguile/bitvectors.c
@@ -685,6 +685,53 @@ SCM_DEFINE_STATIC (scm_bitvector_clear_bits_x, "bitvector-clear-bits!", 2, 0, 0,
}
#undef FUNC_NAME
+SCM_DEFINE (scm_bitvector_copy, "bitvector-copy", 1, 2, 0,
+ (SCM bv, SCM start, SCM end),
+ "Returns a freshly allocated bitvector containing the elements\n"
+ "of bitvector @var{bv} between @var{start} and @var{end}.\n\n"
+ "@var{start} defaults to 0 and @var{end} defaults to the\n"
+ "length of @var{bv}.")
+#define FUNC_NAME s_scm_bitvector_copy
+{
+ VALIDATE_BITVECTOR (1, bv);
+
+ /* cf scm_vector_copy */
+
+ size_t cstart = 0, cend = BITVECTOR_LENGTH (bv);
+ if (!SCM_UNBNDP (start))
+ {
+ cstart = scm_to_size_t (start);
+ SCM_ASSERT_RANGE (SCM_ARG2, start, cstart<=cend);
+
+ if (!SCM_UNBNDP (end))
+ {
+ size_t e = scm_to_size_t (end);
+ SCM_ASSERT_RANGE (SCM_ARG3, end, e>=cstart && e<=cend);
+ cend = e;
+ }
+ }
+
+ size_t len = cend-cstart;
+ SCM result = scm_c_make_bitvector (len, SCM_BOOL_F);
+ const uint32_t *kv_bits = BITVECTOR_BITS (bv);
+ uint32_t *v_bits = BITVECTOR_BITS (result);
+
+ if (len > 0)
+ {
+ size_t wlen = (len + 31u) / 32u;
+ size_t wshift = cstart / 32u;
+ size_t bshift = cstart % 32u;
+ if (0 == bshift)
+ memcpy (v_bits, kv_bits + wshift, wlen*sizeof(uint32_t));
+ else
+ for (size_t i = 0; i < wlen; ++i)
+ v_bits[i] = (kv_bits[i + wshift] >> bshift) | (kv_bits[i + wshift + 1] << (32-bshift));
+ }
+
+ return result;
+}
+#undef FUNC_NAME
+
size_t
scm_c_bitvector_count_bits (SCM bv, SCM bits)
#define FUNC_NAME "bitvector-count-bits"