mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 12:52:46 +00:00
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:
parent
2da038ce0f
commit
8567508963
3 changed files with 66 additions and 7 deletions
|
@ -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);
|
||||
|
||||
//@}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 *
|
||||
|
|
Loading…
Reference in a new issue