mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 11:40:18 +02:00
bitvector-count-bits replaces bit-count*
* NEWS: Add entry. * doc/ref/api-data.texi (Bit Vectors): Update. * libguile/bitvectors.h: * libguile/bitvectors.c (scm_c_bitvector_count_bits): New function. * libguile/deprecated.h: * libguile/deprecated.c (scm_bit_count_star): Deprecate. * module/ice-9/sandbox.scm (bitvector-bindings): Replace bit-count* with bitvector-count-bits. * test-suite/tests/bitvectors.test: Update.
This commit is contained in:
parent
1fbe89f7bd
commit
bfd38b8577
8 changed files with 154 additions and 118 deletions
12
NEWS
12
NEWS
|
@ -9,10 +9,11 @@ Changes in 3.0.3 (since 3.0.2)
|
||||||
|
|
||||||
* New interfaces and functionality
|
* New interfaces and functionality
|
||||||
|
|
||||||
** New bitvector-count, bitvector-position procedures
|
** New bitvector-count, bitvector-count-bits, bitvector-position
|
||||||
|
procedures
|
||||||
|
|
||||||
These replace the wonky "bit-count" and "bit-position" procedures. See
|
These replace the wonky "bit-count", "bit-count*", and "bit-position"
|
||||||
"Bit Vectors" in the manual, for more.
|
procedures. See "Bit Vectors" in the manual, for more.
|
||||||
|
|
||||||
** New bitvector-bit-set?, bitvector-bit-clear? procedures
|
** New bitvector-bit-set?, bitvector-bit-clear? procedures
|
||||||
|
|
||||||
|
@ -66,6 +67,11 @@ Use 'bitvector-flip-all-bits! instead.
|
||||||
|
|
||||||
Use 'bitvector-set-bits!' or 'bitvector-clear-bits!' instead.
|
Use 'bitvector-set-bits!' or 'bitvector-clear-bits!' instead.
|
||||||
|
|
||||||
|
** 'bit-count*' deprecated
|
||||||
|
|
||||||
|
Use 'bitvector-count-bits' instead, subtracting from 'bitvector-count'
|
||||||
|
on the mask bitvector if you are counting unset bits.
|
||||||
|
|
||||||
** Passing a u32vector to 'bit-set*!' and 'bit-count*' deprecated
|
** Passing a u32vector to 'bit-set*!' and 'bit-count*' deprecated
|
||||||
|
|
||||||
These functions had an interface that allowed the second bit-selection
|
These functions had an interface that allowed the second bit-selection
|
||||||
|
|
|
@ -6631,6 +6631,23 @@ Return a count of how many entries in @var{bitvector} are set.
|
||||||
@end example
|
@end example
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} bitvector-count-bits bitvector bits
|
||||||
|
Return a count of how many entries in @var{bitvector} are set, with the
|
||||||
|
bitvector @var{bits} selecting the entries to consider. @var{bitvector}
|
||||||
|
must be at least as long as @var{bits}.
|
||||||
|
|
||||||
|
For example,
|
||||||
|
|
||||||
|
@example
|
||||||
|
(bitvector-count-bits #*01110111 #*11001101) @result{} 3
|
||||||
|
@end example
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deftypefn {C Function} size_t scm_c_bitvector_count_bits (SCM bitvector, SCM bits)
|
||||||
|
Same as @code{bitvector-count-bits}, but returning a @code{size_t} for
|
||||||
|
C.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} bitvector-position bitvector bool start
|
@deffn {Scheme Procedure} bitvector-position bitvector bool start
|
||||||
@deffnx {C Function} scm_bitvector_position (bitvector, bool, start)
|
@deffnx {C Function} scm_bitvector_position (bitvector, bool, start)
|
||||||
Return the index of the first occurrence of @var{bool} in
|
Return the index of the first occurrence of @var{bool} in
|
||||||
|
@ -6672,19 +6689,6 @@ bv
|
||||||
@end example
|
@end example
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} bit-count* bitvector bits bool
|
|
||||||
@deffnx {C Function} scm_bit_count_star (bitvector, bits, bool)
|
|
||||||
Return a count of how many entries in @var{bitvector} are equal to
|
|
||||||
@var{bool}, with the bitvector @var{bits} selecting the entries to
|
|
||||||
consider. @var{bitvector} must be at least as long as @var{bits}.
|
|
||||||
|
|
||||||
For example,
|
|
||||||
|
|
||||||
@example
|
|
||||||
(bit-count* #*01110111 #*11001101 #t) @result{} 3
|
|
||||||
@end example
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@deftypefn {C Function} {const scm_t_uint32 *} scm_bitvector_elements (SCM vec, scm_t_array_handle *handle, size_t *offp, size_t *lenp, ssize_t *incp)
|
@deftypefn {C Function} {const scm_t_uint32 *} scm_bitvector_elements (SCM vec, scm_t_array_handle *handle, size_t *offp, size_t *lenp, ssize_t *incp)
|
||||||
Like @code{scm_vector_elements} (@pxref{Vector Accessing from C}), but
|
Like @code{scm_vector_elements} (@pxref{Vector Accessing from C}), but
|
||||||
for bitvectors. The variable pointed to by @var{offp} is set to the
|
for bitvectors. The variable pointed to by @var{offp} is set to the
|
||||||
|
|
|
@ -663,107 +663,47 @@ SCM_DEFINE (scm_bitvector_clear_bits_x, "bitvector-clear-bits!", 2, 0, 0,
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
SCM_DEFINE (scm_bit_count_star, "bit-count*", 3, 0, 0,
|
size_t
|
||||||
(SCM v, SCM kv, SCM obj),
|
scm_c_bitvector_count_bits (SCM bv, SCM bits)
|
||||||
"Return a count of how many entries in bit vector @var{v} are\n"
|
#define FUNC_NAME "bitvector-count-bits"
|
||||||
"equal to @var{obj}, with @var{kv} selecting the entries to\n"
|
|
||||||
"consider.\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 considered.\n"
|
|
||||||
"@var{kv} and @var{v} must be the same length.\n"
|
|
||||||
"\n"
|
|
||||||
"If @var{kv} is a u32vector, then it contains\n"
|
|
||||||
"the indexes in @var{v} to consider.\n"
|
|
||||||
"\n"
|
|
||||||
"For example,\n"
|
|
||||||
"\n"
|
|
||||||
"@example\n"
|
|
||||||
"(bit-count* #*01110111 #*11001101 #t) @result{} 3\n"
|
|
||||||
"(bit-count* #*01110111 #u32(7 0 4) #f) @result{} 2\n"
|
|
||||||
"@end example")
|
|
||||||
#define FUNC_NAME s_scm_bit_count_star
|
|
||||||
{
|
{
|
||||||
size_t count = 0;
|
VALIDATE_BITVECTOR (1, bv);
|
||||||
|
VALIDATE_BITVECTOR (2, bits);
|
||||||
|
|
||||||
/* Validate that OBJ is a boolean so this is done even if we don't
|
size_t v_len = BITVECTOR_LENGTH (bv);
|
||||||
need BIT.
|
const uint32_t *v_bits = BITVECTOR_BITS (bv);
|
||||||
*/
|
size_t kv_len = BITVECTOR_LENGTH (bits);
|
||||||
int bit = scm_to_bool (obj);
|
const uint32_t *kv_bits = BITVECTOR_BITS (bits);
|
||||||
|
|
||||||
if (IS_BITVECTOR (v) && IS_BITVECTOR (kv))
|
|
||||||
{
|
|
||||||
size_t v_len = BITVECTOR_LENGTH (v);
|
|
||||||
const 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)
|
if (v_len < kv_len)
|
||||||
scm_misc_error (NULL,
|
SCM_MISC_ERROR ("selection bitvector longer than target bitvector",
|
||||||
"selection bitvector longer than target bitvector",
|
|
||||||
SCM_EOL);
|
SCM_EOL);
|
||||||
|
|
||||||
size_t i, word_len = (kv_len + 31) / 32;
|
size_t i, word_len = (kv_len + 31) / 32;
|
||||||
uint32_t last_mask = ((uint32_t)-1) >> (32*word_len - kv_len);
|
uint32_t last_mask = ((uint32_t)-1) >> (32*word_len - kv_len);
|
||||||
uint32_t xor_mask = bit? 0 : ((uint32_t)-1);
|
|
||||||
|
|
||||||
|
size_t count = 0;
|
||||||
for (i = 0; i < word_len-1; i++)
|
for (i = 0; i < word_len-1; i++)
|
||||||
count += count_ones ((v_bits[i]^xor_mask) & kv_bits[i]);
|
count += count_ones (v_bits[i] & kv_bits[i]);
|
||||||
count += count_ones ((v_bits[i]^xor_mask) & kv_bits[i] & last_mask);
|
count += count_ones (v_bits[i] & kv_bits[i] & last_mask);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
scm_t_array_handle v_handle;
|
|
||||||
size_t v_off, v_len;
|
|
||||||
ssize_t v_inc;
|
|
||||||
|
|
||||||
scm_bitvector_elements (v, &v_handle, &v_off, &v_len, &v_inc);
|
return count;
|
||||||
|
}
|
||||||
|
#undef FUNC_NAME
|
||||||
|
|
||||||
if (!IS_BITVECTOR (v))
|
SCM_DEFINE_STATIC (scm_bitvector_count_bits, "bitvector-count-bits", 2, 0, 0,
|
||||||
scm_c_issue_deprecation_warning
|
(SCM v, SCM kv),
|
||||||
("Using bit-count* on arrays is deprecated. "
|
"Return a count of how many entries in bit vector @var{v}\n"
|
||||||
"Use array-set! in a loop instead.");
|
"are set, with @var{kv} selecting the entries to consider.\n"
|
||||||
|
"\n"
|
||||||
if (IS_BITVECTOR (kv))
|
"For example,\n"
|
||||||
{
|
"\n"
|
||||||
size_t kv_len = BITVECTOR_LENGTH (kv);
|
"@example\n"
|
||||||
for (size_t i = 0; i < kv_len; i++)
|
"(bitvector-count-bits #*01110111 #*11001101) @result{} 3\n"
|
||||||
if (scm_c_bitvector_bit_is_set (kv, i))
|
"@end example")
|
||||||
{
|
#define FUNC_NAME s_scm_bitvector_count_bits
|
||||||
SCM elt = scm_array_handle_ref (&v_handle, i*v_inc);
|
{
|
||||||
if ((bit && scm_is_true (elt)) || (!bit && scm_is_false (elt)))
|
return scm_from_size_t (scm_c_bitvector_count_bits (v, kv));
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (scm_is_true (scm_u32vector_p (kv)))
|
|
||||||
{
|
|
||||||
scm_t_array_handle kv_handle;
|
|
||||||
size_t i, kv_len;
|
|
||||||
ssize_t kv_inc;
|
|
||||||
const uint32_t *kv_elts;
|
|
||||||
|
|
||||||
scm_c_issue_deprecation_warning
|
|
||||||
("Passing a u32vector to bit-count* is deprecated. "
|
|
||||||
"Use bitvector-ref in a loop instead.");
|
|
||||||
|
|
||||||
kv_elts = scm_u32vector_elements (kv, &kv_handle, &kv_len, &kv_inc);
|
|
||||||
|
|
||||||
for (i = 0; i < kv_len; i++, kv_elts += kv_inc)
|
|
||||||
{
|
|
||||||
SCM elt = scm_array_handle_ref (&v_handle, (*kv_elts)*v_inc);
|
|
||||||
if ((bit && scm_is_true (elt)) || (!bit && scm_is_false (elt)))
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
scm_array_handle_release (&kv_handle);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
scm_wrong_type_arg_msg (NULL, 0, kv, "bitvector or u32vector");
|
|
||||||
|
|
||||||
scm_array_handle_release (&v_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
return scm_from_size_t (count);
|
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,6 @@ SCM_API SCM scm_bitvector_position (SCM v, SCM item, SCM start);
|
||||||
SCM_API SCM scm_bitvector_set_bits_x (SCM v, SCM bits);
|
SCM_API SCM scm_bitvector_set_bits_x (SCM v, SCM bits);
|
||||||
SCM_API SCM scm_bitvector_clear_bits_x (SCM v, SCM bits);
|
SCM_API SCM scm_bitvector_clear_bits_x (SCM v, SCM bits);
|
||||||
|
|
||||||
SCM_API SCM scm_bit_count_star (SCM v, SCM kv, SCM obj);
|
|
||||||
|
|
||||||
SCM_API int scm_is_bitvector (SCM obj);
|
SCM_API int scm_is_bitvector (SCM obj);
|
||||||
SCM_API SCM scm_c_make_bitvector (size_t len, SCM fill);
|
SCM_API SCM scm_c_make_bitvector (size_t len, SCM fill);
|
||||||
SCM_API size_t scm_c_bitvector_length (SCM vec);
|
SCM_API size_t scm_c_bitvector_length (SCM vec);
|
||||||
|
@ -56,6 +54,7 @@ SCM_API void scm_c_bitvector_clear_bit_x (SCM vec, size_t idx);
|
||||||
SCM_API void scm_c_bitvector_set_all_bits_x (SCM vec);
|
SCM_API void scm_c_bitvector_set_all_bits_x (SCM vec);
|
||||||
SCM_API void scm_c_bitvector_clear_all_bits_x (SCM vec);
|
SCM_API void scm_c_bitvector_clear_all_bits_x (SCM vec);
|
||||||
SCM_API void scm_c_bitvector_flip_all_bits_x (SCM vec);
|
SCM_API void scm_c_bitvector_flip_all_bits_x (SCM vec);
|
||||||
|
SCM_API size_t scm_c_bitvector_count_bits (SCM v, SCM bits);
|
||||||
SCM_API const uint32_t *scm_array_handle_bit_elements (scm_t_array_handle *h);
|
SCM_API const uint32_t *scm_array_handle_bit_elements (scm_t_array_handle *h);
|
||||||
SCM_API uint32_t *scm_array_handle_bit_writable_elements (scm_t_array_handle *h);
|
SCM_API uint32_t *scm_array_handle_bit_writable_elements (scm_t_array_handle *h);
|
||||||
SCM_API size_t scm_array_handle_bit_elements_offset (scm_t_array_handle *h);
|
SCM_API size_t scm_array_handle_bit_elements_offset (scm_t_array_handle *h);
|
||||||
|
|
|
@ -272,6 +272,92 @@ SCM_DEFINE (scm_bit_count, "bit-count", 2, 0, 0,
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#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"
|
||||||
|
"equal to @var{obj}, with @var{kv} selecting the entries to\n"
|
||||||
|
"consider.\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 considered.\n"
|
||||||
|
"@var{kv} and @var{v} must be the same length.\n"
|
||||||
|
"\n"
|
||||||
|
"If @var{kv} is a u32vector, then it contains\n"
|
||||||
|
"the indexes in @var{v} to consider.\n"
|
||||||
|
"\n"
|
||||||
|
"For example,\n"
|
||||||
|
"\n"
|
||||||
|
"@example\n"
|
||||||
|
"(bit-count* #*01110111 #*11001101 #t) @result{} 3\n"
|
||||||
|
"(bit-count* #*01110111 #u32(7 0 4) #f) @result{} 2\n"
|
||||||
|
"@end example")
|
||||||
|
#define FUNC_NAME s_scm_bit_count_star
|
||||||
|
{
|
||||||
|
size_t count = 0;
|
||||||
|
|
||||||
|
scm_c_issue_deprecation_warning
|
||||||
|
("bit-count* is deprecated. Use bitvector-count-bits instead, and in the "
|
||||||
|
"case of counting false bits, subtract from a bitvector-count on the "
|
||||||
|
"selection bitvector.");
|
||||||
|
|
||||||
|
/* Validate that OBJ is a boolean so this is done even if we don't
|
||||||
|
need BIT.
|
||||||
|
*/
|
||||||
|
int bit = scm_to_bool (obj);
|
||||||
|
|
||||||
|
if (scm_is_bitvector (v) && scm_is_bitvector (kv))
|
||||||
|
{
|
||||||
|
count = scm_c_bitvector_count_bits (v, kv);
|
||||||
|
if (count == 0)
|
||||||
|
count = scm_to_size_t (scm_bitvector_count (kv)) - count;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scm_t_array_handle v_handle;
|
||||||
|
size_t v_off, v_len;
|
||||||
|
ssize_t v_inc;
|
||||||
|
|
||||||
|
scm_bitvector_elements (v, &v_handle, &v_off, &v_len, &v_inc);
|
||||||
|
|
||||||
|
if (scm_is_bitvector (kv))
|
||||||
|
{
|
||||||
|
size_t kv_len = scm_c_bitvector_length (kv);
|
||||||
|
for (size_t i = 0; i < kv_len; i++)
|
||||||
|
if (scm_c_bitvector_bit_is_set (kv, i))
|
||||||
|
{
|
||||||
|
SCM elt = scm_array_handle_ref (&v_handle, i*v_inc);
|
||||||
|
if ((bit && scm_is_true (elt)) || (!bit && scm_is_false (elt)))
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (scm_is_true (scm_u32vector_p (kv)))
|
||||||
|
{
|
||||||
|
scm_t_array_handle kv_handle;
|
||||||
|
size_t i, kv_len;
|
||||||
|
ssize_t kv_inc;
|
||||||
|
const uint32_t *kv_elts;
|
||||||
|
|
||||||
|
kv_elts = scm_u32vector_elements (kv, &kv_handle, &kv_len, &kv_inc);
|
||||||
|
|
||||||
|
for (i = 0; i < kv_len; i++, kv_elts += kv_inc)
|
||||||
|
{
|
||||||
|
SCM elt = scm_array_handle_ref (&v_handle, (*kv_elts)*v_inc);
|
||||||
|
if ((bit && scm_is_true (elt)) || (!bit && scm_is_false (elt)))
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
scm_array_handle_release (&kv_handle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
scm_wrong_type_arg_msg (NULL, 0, kv, "bitvector or u32vector");
|
||||||
|
|
||||||
|
scm_array_handle_release (&v_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return scm_from_size_t (count);
|
||||||
|
}
|
||||||
|
#undef FUNC_NAME
|
||||||
|
|
||||||
SCM_DEFINE (scm_bit_position, "bit-position", 3, 0, 0,
|
SCM_DEFINE (scm_bit_position, "bit-position", 3, 0, 0,
|
||||||
(SCM item, SCM v, SCM k),
|
(SCM item, SCM v, SCM k),
|
||||||
"Return the index of the first occurrence of @var{item} in bit\n"
|
"Return the index of the first occurrence of @var{item} in bit\n"
|
||||||
|
|
|
@ -122,6 +122,7 @@ SCM_DEPRECATED SCM scm_bitvector_set_x (SCM vec, SCM idx, SCM val);
|
||||||
SCM_DEPRECATED SCM scm_bitvector_fill_x (SCM vec, SCM val);
|
SCM_DEPRECATED SCM scm_bitvector_fill_x (SCM vec, SCM val);
|
||||||
SCM_DEPRECATED SCM scm_bit_invert_x (SCM vec);
|
SCM_DEPRECATED SCM scm_bit_invert_x (SCM vec);
|
||||||
SCM_DEPRECATED SCM scm_bit_count (SCM item, SCM seq);
|
SCM_DEPRECATED SCM scm_bit_count (SCM item, SCM seq);
|
||||||
|
SCM_DEPRECATED SCM scm_bit_count_star (SCM v, SCM kv, SCM obj);
|
||||||
SCM_DEPRECATED SCM scm_bit_position (SCM item, SCM v, SCM k);
|
SCM_DEPRECATED SCM scm_bit_position (SCM item, SCM v, SCM k);
|
||||||
SCM_DEPRECATED SCM scm_bit_set_star_x (SCM v, SCM kv, SCM obj);
|
SCM_DEPRECATED SCM scm_bit_set_star_x (SCM v, SCM kv, SCM obj);
|
||||||
SCM_DEPRECATED SCM scm_istr2bve (SCM str);
|
SCM_DEPRECATED SCM scm_istr2bve (SCM str);
|
||||||
|
|
|
@ -1077,7 +1077,7 @@ allocation limit is exceeded, an exception will be thrown to the
|
||||||
'(((guile)
|
'(((guile)
|
||||||
bitvector-count
|
bitvector-count
|
||||||
bitvector-position
|
bitvector-position
|
||||||
bit-count*
|
bitvector-count-bits
|
||||||
bit-extract
|
bit-extract
|
||||||
bitvector
|
bitvector
|
||||||
bitvector->list
|
bitvector->list
|
||||||
|
|
|
@ -101,5 +101,5 @@
|
||||||
(pass-if-equal 5 (bitvector-position #*01110111 #t 5))
|
(pass-if-equal 5 (bitvector-position #*01110111 #t 5))
|
||||||
(pass-if-equal #f (bitvector-position #*01110111 #f 5)))
|
(pass-if-equal #f (bitvector-position #*01110111 #f 5)))
|
||||||
|
|
||||||
(with-test-prefix "bit-count*"
|
(with-test-prefix "bitvector-count-bits"
|
||||||
(pass-if-equal 3 (bit-count* #*01110111 #*11001101 #t)))
|
(pass-if-equal 3 (bitvector-count-bits #*01110111 #*11001101)))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue