/* Copyright 1989, 1990 by James Aspnes, David Applegate, and Bennet Yee */
/* See the file COPYING for distribution information */
#ifndef _SET_H
#define _SET_H

#include "alist.h"

typedef struct _set {
  alist list;                   /* list of elements */
  alist names;                  /* list of elements by names */
} *set;

#define empty_set() ((set) 0)
#define set_count(s) (alist_count((s)->list))
#define set_empty(s) ((s) == 0)

extern int member (set, datum);
extern set add_member (set, datum);
extern set del_member (set, datum);
extern set copy_set (set);
extern void free_set (set);

/* mass set operations */
extern set add_members (set, set);
extern set del_members (set, set);

/* don't use this yourself */
extern void set_clear_name_list (set);
extern void set_build_name_list (set);

/* always call this before using an object's name list (i.e. never) */
extern void object_build_name_list (datum);

#define SET_FOREACH(set, var) \
{ \
    if(set) { \
	datum _SET_FOREACH_dummy; \
	FOREACH((set)->list, var, _SET_FOREACH_dummy)

#define SET_FOREACH_MATCH(set, key, var) \
{ \
    if(set) { \
	if(isempty((set)->names)) set_build_name_list(set); \
	FOREACH_MATCH((set)->names, key, var) \

#define END_SET_FOREACH END_FOREACH }}

typedef alist_iterator set_iterator;

extern datum set_first (set, set_iterator *);
extern datum set_next (set, set_iterator *);

extern datum set_first_match (set, set_iterator *, datum key);
extern datum set_next_match (set, set_iterator *);

#endif  /* _SET_H */