Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
74b0582b
Commit
74b0582b
authored
Jan 22, 2014
by
Andreas Seltenreich
Browse files
rbitset: Add a backward iterator rbitset_prev.
Also adds accompanying bitset_t functions and unittests.
parent
f78cd2c2
Changes
3
Hide whitespace changes
Inline
Side-by-side
ir/adt/bitset.h
View file @
74b0582b
...
...
@@ -198,6 +198,38 @@ static inline size_t bitset_next_set(const bitset_t *bs, size_t pos)
#define bitset_foreach_clear(bitset, elm) \
for (size_t elm = 0; (elm = bitset_next_clear((bitset), elm)) != (size_t)-1; ++elm)
/**
* Find the previous unset bit from a given bit.
* @param bs The bitset.
* @param pos The bit from which to search for the previous unset bit.
* @return The previous unset bit from pos on, or (size_t)-1, if no unset bit was
* found before pos.
*/
static
inline
size_t
bitset_prev_clear
(
const
bitset_t
*
bs
,
size_t
pos
)
{
return
rbitset_prev
(
bs
->
data
,
pos
,
false
);
}
/**
* Find the previous set bit from a given bit.
* @param bs The bitset.
* @param pos The bit from which to search for the next set bit.
* @return The previous set bit from pos on, or (size_t)-1, if no set bit was
* found before pos.
*/
static
inline
size_t
bitset_prev_set
(
const
bitset_t
*
bs
,
size_t
pos
)
{
return
rbitset_prev
(
bs
->
data
,
pos
,
true
);
}
#define bitset_foreach_rev(bitset, elm) \
for (size_t elm = bitset->size; (elm = rbitset_prev(bitset->data, elm, true)) != (size_t)-1;)
#define bitset_foreach_clear_rev(bitset, elm) \
for (size_t elm = bitset->size; (elm = rbitset_prev(bitset->data, elm, false)) != (size_t)-1;)
/**
* Count the bits set.
* This can also be seen as the cardinality of the set.
...
...
ir/adt/raw_bitset.h
View file @
74b0582b
...
...
@@ -321,6 +321,55 @@ static inline size_t rbitset_next_max(const unsigned *bitset, size_t pos,
return
res
;
}
/**
* Returns the position of the previous bit starting from (but not including)
* a given position.
*
* @param bitset a bitset
* @param pos the position after the first bit to check
* @param set if 0 search for unset bit, else for set bit
*
* @return The first position where a matched bit was found or -1 if
* none found.
*
*/
static
inline
size_t
rbitset_prev
(
const
unsigned
*
bitset
,
size_t
pos
,
bool
set
)
{
size_t
elem_pos
=
pos
/
BITS_PER_ELEM
;
size_t
bit_pos
=
pos
%
BITS_PER_ELEM
;
unsigned
elem
=
bitset
[
elem_pos
];
unsigned
mask
=
set
?
0
:
~
0u
;
/*
* Mask out the bits larger than pos in the current unit.
* We are only interested in bits set lower than pos.
*/
unsigned
in_elem_mask
=
~
((
1u
<<
bit_pos
)
-
1u
);
elem
^=
mask
;
unsigned
p
=
nlz
(
elem
&
~
in_elem_mask
);
/* If there is a bit set in the current elem, exit. */
if
(
p
<
BITS_PER_ELEM
)
{
return
(
1
+
elem_pos
)
*
BITS_PER_ELEM
-
p
-
1
;
}
/* Else search for set bits in the previous units. */
while
(
elem_pos
>
0
)
{
elem_pos
--
;
elem
=
bitset
[
elem_pos
]
^
mask
;
p
=
nlz
(
elem
);
if
(
p
<
BITS_PER_ELEM
)
{
return
(
1
+
elem_pos
)
*
BITS_PER_ELEM
-
p
-
1
;
}
}
return
-
1
;
}
/**
* Inplace Intersection of two sets.
*
...
...
unittests/rbitset.c
View file @
74b0582b
...
...
@@ -44,6 +44,15 @@ int main(void)
assert
(
rbitset_next_max
(
field1
,
3
,
66
,
false
)
==
4
);
assert
(
rbitset_next_max
(
field1
,
60
,
66
,
true
)
==
(
size_t
)
-
1
);
assert
(
rbitset_next_max
(
field1
,
3
,
4
,
false
)
==
(
size_t
)
-
1
);
assert
(
rbitset_prev
(
field1
,
0
,
true
)
==
(
size_t
)
-
1
);
assert
(
rbitset_prev
(
field1
,
3
,
true
)
==
(
size_t
)
-
1
);
assert
(
rbitset_prev
(
field1
,
4
,
true
)
==
3
);
assert
(
rbitset_prev
(
field1
,
59
,
true
)
==
3
);
assert
(
rbitset_prev
(
field1
,
60
,
true
)
==
59
);
assert
(
rbitset_prev
(
field1
,
34
,
true
)
==
3
);
assert
(
rbitset_prev
(
field1
,
0
,
false
)
==
(
size_t
)
-
1
);
assert
(
rbitset_prev
(
field1
,
3
,
false
)
==
2
);
assert
(
rbitset_prev
(
field1
,
1
,
false
)
==
0
);
unsigned
*
null
=
(
unsigned
*
)
0
;
rbitset_flip_all
(
null
,
0
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment