Rewrite set_first() and add set_next().

set_first() now returns a pointer to a setstate_t struct that holds the
state necessary for scanning a set. set_next() will automatically delete
the state block when the end of the set is reached. set_delstate() is also
provided to allow early termination of the scan.
This commit is contained in:
Bill Currie 2012-11-01 15:00:26 +09:00
parent 2da038ce0f
commit 8567508963
3 changed files with 66 additions and 7 deletions

View file

@ -42,6 +42,16 @@ typedef struct set_s {
unsigned defmap[8];
} set_t;
typedef struct setstate_s {
struct setstate_s *next; //< private. for ALLOC
const set_t *set;
/** The result of set_first() or set_next(). set_next() will start at the
following member.
*/
unsigned member;
} setstate_t;
void set_delstate (setstate_t *setstate);
set_t *set_new (void);
void set_delete (set_t *set);
void set_add (set_t *set, unsigned x);
@ -59,7 +69,8 @@ int set_is_intersecting (const set_t *s1, const set_t *s2);
int set_is_equivalent (const set_t *s1, const set_t *s2);
int set_is_subset (const set_t *set, const set_t *sub);
int set_is_member (const set_t *set, unsigned x);
unsigned set_first (const set_t *set);
setstate_t *set_first (const set_t *set);
setstate_t *set_next (setstate_t *setstate);
const char *set_as_string (const set_t *set);
//@}

View file

@ -314,13 +314,16 @@ make_loop (flownode_t **node_list, unsigned num_nodes, unsigned n, unsigned d)
set_add (loop->nodes, d);
insert_loop_node (loop, n, stack);
while (!set_is_empty (stack)) {
unsigned m = set_first (stack);
setstate_t *ss = set_first (stack);
unsigned m = ss->member;
set_delstate (ss);
set_remove (stack, m);
node = node_list[m];
for (pred = node->predecessors;
pred - node->predecessors < node->num_pred; pred++)
insert_loop_node (loop, *pred, stack);
}
set_delete (stack);
return loop;
}

View file

@ -43,10 +43,34 @@
#include "QF/dstring.h"
#include "QF/mathlib.h"
#include "qfcc.h"
#include "set.h"
#define BITS (sizeof (unsigned) * 8)
setstate_t *free_setstates;
static setstate_t *
new_setstate (void)
{
setstate_t *setstate;
ALLOC (16, setstate_t, setstates, setstate);
return setstate;
}
static void
delete_setstate (setstate_t *setstate)
{
setstate->next = free_setstates;
free_setstates = setstate;
}
void
set_delstate (setstate_t *setstate)
{
delete_setstate (setstate);
}
set_t *
set_new (void)
{
@ -245,15 +269,36 @@ set_is_member (const set_t *set, unsigned x)
return (set->map[x / BITS] & (1 << (x % BITS))) != 0;
}
unsigned
setstate_t *
set_first (const set_t *set)
{
unsigned x;
setstate_t *setstate;
for (x = 0; x < set->size; x++)
if (set_is_member (set, x))
return x;
return -1; // FIXME error?
for (x = 0; x < set->size; x++) {
if (set_is_member (set, x)) {
setstate = new_setstate ();
setstate->set = set;
setstate->member = x;
return setstate;
}
}
return 0;
}
setstate_t *
set_next (setstate_t *setstate)
{
unsigned x;
for (x = setstate->member + 1; x < setstate->set->size; x++) {
if (set_is_member (setstate->set, x)) {
setstate->member = x;
return setstate;
}
}
delete_setstate (setstate);
return 0;
}
const char *