summaryrefslogtreecommitdiff
path: root/libguile/bitvectors.c
diff options
context:
space:
mode:
Diffstat (limited to 'libguile/bitvectors.c')
-rw-r--r--libguile/bitvectors.c167
1 files changed, 66 insertions, 101 deletions
diff --git a/libguile/bitvectors.c b/libguile/bitvectors.c
index 356b1c743..40da4757e 100644
--- a/libguile/bitvectors.c
+++ b/libguile/bitvectors.c
@@ -61,6 +61,9 @@
#define VALIDATE_BITVECTOR(_pos, _obj) \
SCM_ASSERT_TYPE (IS_BITVECTOR (_obj), (_obj), (_pos), FUNC_NAME, \
"bitvector")
+#define VALIDATE_MUTABLE_BITVECTOR(_pos, _obj) \
+ SCM_ASSERT_TYPE (IS_MUTABLE_BITVECTOR (_obj), (_obj), (_pos), \
+ FUNC_NAME, "mutable bitvector")
uint32_t *
scm_i_bitvector_bits (SCM vec)
@@ -575,125 +578,87 @@ SCM_DEFINE (scm_bitvector_position, "bitvector-position", 2, 1, 0,
}
#undef FUNC_NAME
-SCM_DEFINE (scm_bit_set_star_x, "bit-set*!", 3, 0, 0,
- (SCM v, SCM kv, SCM obj),
- "Set entries of bit vector @var{v} to @var{obj}, with @var{kv}\n"
- "selecting the entries to change. The return value is\n"
- "unspecified.\n"
- "\n"
- "If @var{kv} is a bit vector, then those entries where it has\n"
- "@code{#t} are the ones in @var{v} which are set to @var{obj}.\n"
- "@var{v} must be at least as long as @var{kv}. When @var{obj}\n"
- "is @code{#t} it's like @var{kv} is OR'ed into @var{v}. Or when\n"
- "@var{obj} is @code{#f} it can be seen as an ANDNOT.\n"
+SCM_DEFINE (scm_bitvector_set_bits_x, "bitvector-set-bits!", 2, 0, 0,
+ (SCM v, SCM bits),
+ "Update the bitvector @var{v} in place by performing a logical\n"
+ "OR of its bits with those of @var{bits}.\n"
+ "For example:\n"
"\n"
"@example\n"
- "(define bv #*01000010)\n"
- "(bit-set*! bv #*10010001 #t)\n"
+ "(define bv (bitvector-copy #*11000010))\n"
+ "(bitvector-set-bits! bv #*10010001)\n"
"bv\n"
"@result{} #*11010011\n"
- "@end example\n"
- "\n"
- "If @var{kv} is a u32vector, then its elements are\n"
- "indices into @var{v} which are set to @var{obj}.\n"
+ "@end example")
+#define FUNC_NAME s_scm_bitvector_set_bits_x
+{
+ VALIDATE_MUTABLE_BITVECTOR (1, v);
+ VALIDATE_BITVECTOR (2, bits);
+ size_t v_len = BITVECTOR_LENGTH (v);
+ uint32_t *v_bits = BITVECTOR_BITS (v);
+ size_t kv_len = BITVECTOR_LENGTH (bits);
+ const uint32_t *kv_bits = BITVECTOR_BITS (bits);
+
+ if (v_len < kv_len)
+ scm_misc_error (NULL,
+ "selection bitvector longer than target bitvector",
+ SCM_EOL);
+
+ if (kv_len > 0)
+ {
+ size_t word_len = (kv_len + 31) / 32;
+ uint32_t last_mask = ((uint32_t)-1) >> (32*word_len - kv_len);
+ size_t i;
+ for (i = 0; i < word_len-1; i++)
+ v_bits[i] |= kv_bits[i];
+ v_bits[i] |= kv_bits[i] & last_mask;
+ }
+
+ return SCM_UNSPECIFIED;
+}
+#undef FUNC_NAME
+
+SCM_DEFINE (scm_bitvector_clear_bits_x, "bitvector-clear-bits!", 2, 0, 0,
+ (SCM v, SCM bits),
+ "Update the bitvector @var{v} in place by performing a logical\n"
+ "AND of its bits with the complement of those of @var{bits}.\n"
+ "For example:\n"
"\n"
"@example\n"
- "(define bv #*01000010)\n"
- "(bit-set*! bv #u32(5 2 7) #t)\n"
+ "(define bv (bitvector-copy #*11000010))\n"
+ "(bitvector-clear-bits! bv #*10010001)\n"
"bv\n"
- "@result{} #*01100111\n"
+ "@result{} #*01000010\n"
"@end example")
-#define FUNC_NAME s_scm_bit_set_star_x
+#define FUNC_NAME s_scm_bitvector_clear_bits_x
{
- /* Validate that OBJ is a boolean so this is done even if we don't
- need BIT. */
- int bit = scm_to_bool (obj);
-
- if (IS_MUTABLE_BITVECTOR (v) && IS_BITVECTOR (kv))
- {
- size_t v_len = BITVECTOR_LENGTH (v);
- uint32_t *v_bits = BITVECTOR_BITS (v);
- size_t kv_len = BITVECTOR_LENGTH (kv);
- const uint32_t *kv_bits = BITVECTOR_BITS (kv);
-
- if (v_len < kv_len)
- scm_misc_error (NULL,
- "selection bitvector longer than target bitvector",
- SCM_EOL);
+ VALIDATE_MUTABLE_BITVECTOR (1, v);
+ VALIDATE_BITVECTOR (2, bits);
+ size_t v_len = BITVECTOR_LENGTH (v);
+ uint32_t *v_bits = BITVECTOR_BITS (v);
+ size_t kv_len = BITVECTOR_LENGTH (bits);
+ const uint32_t *kv_bits = BITVECTOR_BITS (bits);
+
+ if (v_len < kv_len)
+ scm_misc_error (NULL,
+ "selection bitvector longer than target bitvector",
+ SCM_EOL);
- if (kv_len > 0)
- {
- size_t word_len = (kv_len + 31) / 32;
- uint32_t last_mask = ((uint32_t)-1) >> (32*word_len - kv_len);
- size_t i;
-
- if (bit == 0)
- {
- for (i = 0; i < word_len-1; i++)
- v_bits[i] &= ~kv_bits[i];
- v_bits[i] &= ~(kv_bits[i] & last_mask);
- }
- else
- {
- for (i = 0; i < word_len-1; i++)
- v_bits[i] |= kv_bits[i];
- v_bits[i] |= kv_bits[i] & last_mask;
- }
- }
- }
- else
+ if (kv_len > 0)
{
- scm_t_array_handle v_handle;
- size_t v_off, v_len;
- ssize_t v_inc;
- scm_bitvector_writable_elements (v, &v_handle, &v_off, &v_len, &v_inc);
-
- if (!IS_MUTABLE_BITVECTOR (v))
- scm_c_issue_deprecation_warning
- ("Using bit-set*! on arrays is deprecated. "
- "Use array-set! in a loop instead.");
-
- if (IS_BITVECTOR (kv))
- {
- size_t kv_len = BITVECTOR_LENGTH (kv);
-
- if (v_len < kv_len)
- scm_misc_error (NULL,
- "selection bitvector longer than target bitvector",
- SCM_EOL);
-
- for (size_t i = 0; i < kv_len; i++)
- if (scm_is_true (scm_c_bitvector_ref (kv, i)))
- scm_array_handle_set (&v_handle, i*v_inc, obj);
- }
- else if (scm_is_true (scm_u32vector_p (kv)))
- {
- scm_c_issue_deprecation_warning
- ("Passing a u32vector to bit-set*! is deprecated. "
- "Use bitvector-set! in a loop instead.");
-
- scm_t_array_handle kv_handle;
- size_t kv_len;
- ssize_t kv_inc;
- const uint32_t *kv_elts;
-
- kv_elts = scm_u32vector_elements (kv, &kv_handle, &kv_len, &kv_inc);
- for (size_t i = 0; i < kv_len; i++, kv_elts += kv_inc)
- scm_array_handle_set (&v_handle, (*kv_elts)*v_inc, obj);
-
- scm_array_handle_release (&kv_handle);
- }
- else
- scm_wrong_type_arg_msg (NULL, 0, kv, "bitvector or u32vector");
+ size_t word_len = (kv_len + 31) / 32;
+ uint32_t last_mask = ((uint32_t)-1) >> (32*word_len - kv_len);
+ size_t i;
- scm_array_handle_release (&v_handle);
+ for (i = 0; i < word_len-1; i++)
+ v_bits[i] &= ~kv_bits[i];
+ v_bits[i] &= ~(kv_bits[i] & last_mask);
}
return SCM_UNSPECIFIED;
}
#undef FUNC_NAME
-
SCM_DEFINE (scm_bit_count_star, "bit-count*", 3, 0, 0,
(SCM v, SCM kv, SCM obj),
"Return a count of how many entries in bit vector @var{v} are\n"