+struct bbitset_struct
+{
+ const struct bitset_vtable * vtable;
+ bitset_windex cindex; /* Cache word index. */
+ bitset_windex csize; /* Cache size in words. */
+ bitset_word *cdata; /* Cache data pointer. */
+ /* Perhaps we could sacrifice another word to indicate
+ that the bitset is known to be zero, that a bit has been set
+ in the cache, and that a bit has been cleared in the cache.
+ This would speed up some of the searches but slightly slow down
+ bit set/reset operations of cached bits. */
+};
+
+
+typedef struct bitset_struct *bitset;
+
+
+/* The contents of this structure should be considered private. */
+struct bitset_vtable
+{
+ void (*set) PARAMS ((struct bitset_struct *, bitset_bindex));
+ void (*reset) PARAMS ((struct bitset_struct *, bitset_bindex));
+ int (*toggle) PARAMS ((struct bitset_struct *, bitset_bindex));
+ int (*test) PARAMS ((struct bitset_struct *, bitset_bindex));
+ int (*size) PARAMS ((struct bitset_struct *));
+ int (*count) PARAMS ((struct bitset_struct *));
+
+ int (*empty_p) PARAMS ((struct bitset_struct *));
+ void (*ones) PARAMS ((struct bitset_struct *));
+ void (*zero) PARAMS ((struct bitset_struct *));
+
+ void (*copy) PARAMS ((struct bitset_struct *, struct bitset_struct *));
+ int (*disjoint_p) PARAMS ((struct bitset_struct *, struct bitset_struct *));
+ int (*equal_p) PARAMS ((struct bitset_struct *, struct bitset_struct *));
+ void (*not) PARAMS ((struct bitset_struct *, struct bitset_struct *));
+ int (*subset_p) PARAMS ((struct bitset_struct *, struct bitset_struct *));
+
+ void (*and) PARAMS ((struct bitset_struct *, struct bitset_struct *,
+ struct bitset_struct *));
+ int (*and_cmp) PARAMS ((struct bitset_struct *, struct bitset_struct *,
+ struct bitset_struct *));
+ void (*andn) PARAMS ((struct bitset_struct *, struct bitset_struct *,
+ struct bitset_struct *));
+ int (*andn_cmp) PARAMS ((struct bitset_struct *, struct bitset_struct *,
+ struct bitset_struct *));
+ void (*or) PARAMS ((struct bitset_struct *, struct bitset_struct *,
+ struct bitset_struct *));
+ int (*or_cmp) PARAMS ((struct bitset_struct *, struct bitset_struct *,
+ struct bitset_struct *));
+ void (*xor) PARAMS ((struct bitset_struct *, struct bitset_struct *,
+ struct bitset_struct *));
+ int (*xor_cmp) PARAMS ((struct bitset_struct *, struct bitset_struct *,
+ struct bitset_struct *));
+
+ void (*and_or) PARAMS ((struct bitset_struct *, struct bitset_struct *,
+ struct bitset_struct *, struct bitset_struct *));
+ int (*and_or_cmp) PARAMS ((struct bitset_struct *, struct bitset_struct *,
+ struct bitset_struct *, struct bitset_struct *));
+ void (*andn_or) PARAMS ((struct bitset_struct *, struct bitset_struct *,
+ struct bitset_struct *, struct bitset_struct *));
+ int (*andn_or_cmp) PARAMS ((struct bitset_struct *, struct bitset_struct *,
+ struct bitset_struct *, struct bitset_struct *));
+ void (*or_and) PARAMS ((struct bitset_struct *, struct bitset_struct *,
+ struct bitset_struct *, struct bitset_struct *));
+ int (*or_and_cmp) PARAMS ((struct bitset_struct *, struct bitset_struct *,
+ struct bitset_struct *, struct bitset_struct *));
+
+ int (*list) PARAMS ((struct bitset_struct *, bitset_bindex *,
+ bitset_bindex, bitset_bindex *));
+ int (*list_reverse) PARAMS ((struct bitset_struct *, bitset_bindex *,
+ bitset_bindex, bitset_bindex *));
+ void (*free) PARAMS ((struct bitset_struct *));
+ enum bitset_type type;
+};
+
+#define BITSET_COMPATIBLE_(BSET1, BSET2) ((BSET1)->b.vtable == (BSET2)->b.vtable)
+
+#define BITSET_CHECK2_(DST, SRC) \
+if (!BITSET_COMPATIBLE_ (DST, SRC)) abort ();
+
+#define BITSET_CHECK3_(DST, SRC1, SRC2) \
+if (!BITSET_COMPATIBLE_ (DST, SRC1) \
+ || !BITSET_COMPATIBLE_ (DST, SRC2)) abort ();
+
+#define BITSET_CHECK4_(DST, SRC1, SRC2, SRC3) \
+if (!BITSET_COMPATIBLE_ (DST, SRC1) || !BITSET_COMPATIBLE_ (DST, SRC2) \
+ || !BITSET_COMPATIBLE_ (DST, SRC3)) abort ();
+
+