Add more functions for bitset:

* bitset_equal_p
* bitset_out_str
* bitset_in_str
* bitset_get_str
This commit is contained in:
Patrick Pelissier committed 2017-02-18 20:31:08 +01:00
1 parent 6bbfee0618
commit 703c6c12da
2 files changed
+104 -1

No files matched your search

+71 -1
View File
@@ -32,6 +32,7 @@
#include <limits.h>
#include "m-core.h"
#include "m-string.h" // Only for bitset_get_str function
typedef struct bitset_s {
size_t size; // Size is the number of bits
@@ -316,6 +317,29 @@ bitset_pop_at(bool *dest, bitset_t set, size_t key)
BITSETI_CONTRACT (set);
}
static inline bool
bitset_equal_p (const bitset_t set1, const bitset_t set2)
{
BITSETI_CONTRACT (set1);
BITSETI_CONTRACT (set2);
if (set1->size != set2->size)
return false;
/* We won't parse each bit individualy, but instead compare
them per byte */
size_t size = (set1->size) / CHAR_BIT;
for(size_t i = 0 ; i < size;i++)
if (set1->ptr[i] != set2->ptr[i])
return false;
/* Compare last byte if needed */
size_t index = set1->size % CHAR_BIT;
if (index > 0) {
size_t mask = (1 << index) - 1;
if ((set1->ptr[size] & mask) != (set2->ptr[size] & mask))
return false;
}
return true;
}
static inline void
bitset_it(bitset_it_t it, bitset_t set)
{
@@ -375,7 +399,53 @@ bitset_ref(const bitset_it_t it)
}
#define bitset_cref bitset_ref
// TODO: stringify...
static inline void
bitset_out_str(FILE *file, const bitset_t set)
{
BITSETI_CONTRACT (set);
assert(file != NULL);
fputc ('[', file);
for(size_t i = 0; i < set->size; i++) {
const bool b = bitset_get (set, i);
const char c = b ? '1' : '0';
fputc (c, file);
}
fputc (']', file);
}
static inline bool
bitset_in_str(bitset_t set, FILE *file)
{
BITSETI_CONTRACT (set);
assert(file != NULL);
bitset_clean(set);
char c = fgetc(file);
if (c != '[') return false;
c = fgetc(file);
do {
if (c != '0' && c != '1') return false;
bool b = (c == '1');
bitset_push_back (set, b);
c = fgetc(file);
} while (c != ']' && !feof(file) && !ferror(file));
BITSETI_CONTRACT (set);
return c == ']';
}
static inline void
bitset_get_str(string_t str, const bitset_t set, bool append)
{
BITSETI_CONTRACT (set);
assert(str != NULL);
(append ? string_cat_str : string_set_str) (str, "[");
for(size_t i = 0; i < set->size; i++) {
const bool b = bitset_get (set, i);
const char c = b ? '1' : '0';
string_push_back (str, c);
}
string_push_back (str, ']');
}
// TODO: OPLIST
// TODO: set_at2, insert_v, remove_v, shrink_to_fit,
+33
View File
@@ -108,8 +108,41 @@ static void test1(void)
bitset_clear(set2);
}
static void test_str(void)
{
bitset_t set1, set2;
bitset_init(set1);
bitset_init(set2);
for(int i = 0; i < 200; i++)
bitset_push_back(set1, (i*17547854547UL >> 4)&1) ;
FILE *f = fopen ("a.dat", "wt");
if (!f) abort();
bitset_out_str(f, set1);
fclose (f);
f = fopen ("a.dat", "rt");
if (!f) abort();
bool b = bitset_in_str (set2, f);
assert (b == true);
assert (bitset_equal_p (set1, set2));
fclose(f);
string_t s;
string_init (s);
bitset_get_str(s, set1, false);
assert (string_equal_str_p (s, "[01010110101101011010100101001010010101101011010110101001010010100101011010110101101010010100101001010110101101011010100101001010010101101011010110101001010010100101011010110101101010010100101001010110]"));
string_clear(s);
bitset_clear(set1);
bitset_clear(set2);
}
int main(void)
{
test1();
test_str();
exit(0);
}