bitvect: add a foreach_set_index(callback) function
Related to #476, where that is needed. * spot/misc/bitvect.hh: Here. * tests/core/bitvect.cc, tests/core/bitvect.test: Add some tests.
This commit is contained in:
parent
850608a5fd
commit
b6df1f8f92
3 changed files with 68 additions and 5 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2013-2020 Laboratoire de Recherche et Développement
|
// Copyright (C) 2013-2021 Laboratoire de Recherche et Développement
|
||||||
// de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -364,6 +364,45 @@ namespace spot
|
||||||
return !(other < *this);
|
return !(other < *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
void foreach_set_index(F callback) const
|
||||||
|
{
|
||||||
|
const size_t bpb = 8 * sizeof(bitvect::block_t);
|
||||||
|
size_t rest = size() % bpb;
|
||||||
|
for (size_t i = 0; i <= block_count_ - 1; ++i)
|
||||||
|
{
|
||||||
|
block_t b = storage_[i];
|
||||||
|
if ((i == block_count_ - 1) && rest)
|
||||||
|
// The last block might not be fully used, scan only the
|
||||||
|
// relevant portion.
|
||||||
|
b &= (1UL << rest) - 1;
|
||||||
|
if (b != 0)
|
||||||
|
{
|
||||||
|
unsigned base = i * bpb;
|
||||||
|
#if __GNUC__
|
||||||
|
// This version is probably faster on sparse bitsets.
|
||||||
|
do
|
||||||
|
{
|
||||||
|
unsigned bit = __builtin_ctzl(b);
|
||||||
|
b ^= 1UL << bit;
|
||||||
|
callback(base + bit);
|
||||||
|
}
|
||||||
|
while (b);
|
||||||
|
#else
|
||||||
|
unsigned bit = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (b & 1)
|
||||||
|
callback(base + bit);
|
||||||
|
++bit;
|
||||||
|
b >>= 1;
|
||||||
|
}
|
||||||
|
while (b);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
friend SPOT_API bitvect* make_bitvect(size_t bitcount);
|
friend SPOT_API bitvect* make_bitvect(size_t bitcount);
|
||||||
|
|
||||||
/// Print a bitvect.
|
/// Print a bitvect.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2013-2016, 2018 Laboratoire de Recherche et
|
// Copyright (C) 2013-2016, 2018, 2021 Laboratoire de Recherche et
|
||||||
// Développement de l'Epita (LRDE).
|
// Développement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -35,6 +35,11 @@ static void ruler()
|
||||||
std::cout << "\n\n";
|
std::cout << "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print_callback(unsigned t)
|
||||||
|
{
|
||||||
|
std::cout << t << ',';
|
||||||
|
}
|
||||||
|
|
||||||
#define ECHO(name) std::cout << #name": " << *name << '\n'
|
#define ECHO(name) std::cout << #name": " << *name << '\n'
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
|
|
@ -65,9 +70,24 @@ int main()
|
||||||
*x |= *w;
|
*x |= *w;
|
||||||
ECHO(x);
|
ECHO(x);
|
||||||
|
|
||||||
|
std::cout << "foreach in v: ";
|
||||||
|
v->foreach_set_index(print_callback);
|
||||||
|
std::cout << '\n';
|
||||||
|
std::cout << "foreach in w: ";
|
||||||
|
w->foreach_set_index(print_callback);
|
||||||
|
std::cout << '\n';
|
||||||
|
std::cout << "foreach in x: ";
|
||||||
|
x->foreach_set_index(print_callback);
|
||||||
|
std::cout << '\n';
|
||||||
|
|
||||||
std::cout << "subset? " << w->is_subset_of(*x)
|
std::cout << "subset? " << w->is_subset_of(*x)
|
||||||
<< ' ' << v->is_subset_of(*w) << '\n';
|
<< ' ' << v->is_subset_of(*w) << '\n';
|
||||||
|
|
||||||
|
*x -= *x;
|
||||||
|
std::cout << "foreach in x-x: ";
|
||||||
|
x->foreach_set_index(print_callback);
|
||||||
|
std::cout << '\n';
|
||||||
|
|
||||||
delete v;
|
delete v;
|
||||||
delete w;
|
delete w;
|
||||||
delete x;
|
delete x;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright (C) 2013, 2015, 2016 Laboratoire de Recherche et Développement
|
# Copyright (C) 2013, 2015, 2016, 2021 Laboratoire de Recherche et
|
||||||
# de l'Epita (LRDE).
|
# Développement de l'Epita (LRDE).
|
||||||
#
|
#
|
||||||
# This file is part of Spot, a model checking library.
|
# This file is part of Spot, a model checking library.
|
||||||
#
|
#
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
run 0 ../bitvect | tee stderr
|
run 0 ../bitvect | sed 's/ $//' | tee stderr
|
||||||
cat >expected <<EOF
|
cat >expected <<EOF
|
||||||
|
|
||||||
0_________1_________2_________3_________4_________5_________6_________7_____
|
0_________1_________2_________3_________4_________5_________6_________7_____
|
||||||
|
|
@ -43,7 +43,11 @@ w: 000000000010110000000000000000100000000001
|
||||||
|
|
||||||
x: 000000000000000000000000000000000000000000000000000000000000100000000010000
|
x: 000000000000000000000000000000000000000000000000000000000000100000000010000
|
||||||
x: 000000000010110000000000000000100000000001000000000000000000100000000010000
|
x: 000000000010110000000000000000100000000001000000000000000000100000000010000
|
||||||
|
foreach in v: 7,10,12,
|
||||||
|
foreach in w: 10,12,13,30,41,
|
||||||
|
foreach in x: 10,12,13,30,41,60,70,
|
||||||
subset? 1 0
|
subset? 1 0
|
||||||
|
foreach in x-x:
|
||||||
|
|
||||||
0_________1_________2_________3_________4_________5_________6_________7_____
|
0_________1_________2_________3_________4_________5_________6_________7_____
|
||||||
0123456789012345678901234567890123456789012345678901234567890123456789012345
|
0123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue