summaryrefslogtreecommitdiffstats
path: root/generic/tkIntSet.h
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkIntSet.h')
-rw-r--r--generic/tkIntSet.h176
1 files changed, 176 insertions, 0 deletions
diff --git a/generic/tkIntSet.h b/generic/tkIntSet.h
new file mode 100644
index 0000000..b858d8d
--- /dev/null
+++ b/generic/tkIntSet.h
@@ -0,0 +1,176 @@
+/*
+ * tkSet.h --
+ *
+ * This module implements an integer set.
+ *
+ * Copyright (c) 2015-2017 Gregor Cramer
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef _TKINTSET
+#define _TKINTSET
+
+#ifndef _TK
+#include "tk.h"
+#endif
+
+#include "tkInt.h" /* required for inline support */
+#include "tkBool.h"
+
+#if defined(__GNUC__) || defined(__clang__)
+# define __warn_unused__ __attribute__((warn_unused_result))
+#else
+# define __warn_unused__
+#endif
+
+struct TkBitField;
+
+
+typedef uint32_t TkIntSetType;
+
+/*
+ * The struct below will be shared with the struct TkBitField, so the first two
+ * members must exactly match the first two members in struct TkBitField. In this
+ * way we have a struct inheritance, based on the first two members. This
+ * is portable due to C99 section 6.7.2.1 bullet point 13:
+ *
+ * Within a structure object, the non-bit-field members and the units
+ * in which bit-fields reside have addresses that increase in the order
+ * in which they are declared. A pointer to a structure object, suitably
+ * converted, points to its initial member (or if that member is a
+ * bit-field, then to the unit in which it resides), and vice versa.
+ * There may be unnamed padding within a structure object, but not at
+ * beginning.
+ *
+ * This inheritance concept is also used in the portable GTK library.
+ */
+
+typedef struct TkIntSet {
+ uint32_t refCount:31;
+ uint32_t isSetFlag:1;
+ TkIntSetType *end;
+ TkIntSetType *curr; /* mutable */
+ TkIntSetType buf[1];
+} TkIntSet;
+
+
+#define TK_SET_NPOS ((unsigned) -1)
+
+
+TkIntSet *TkIntSetNew();
+TkIntSet *TkIntSetFromBits(const struct TkBitField *bf);
+void TkIntSetDestroy(TkIntSet **setPtr);
+
+inline unsigned TkIntSetByteSize(const TkIntSet *set);
+inline const unsigned char *TkIntSetData(const TkIntSet *set);
+
+TkIntSet *TkIntSetCopy(const TkIntSet *set) __warn_unused__;
+
+TkIntSet *TkIntSetJoin(TkIntSet *dst, const TkIntSet *src) __warn_unused__;
+TkIntSet *TkIntSetIntersect(TkIntSet *dst, const TkIntSet *src) __warn_unused__;
+TkIntSet *TkIntSetRemove(TkIntSet *dst, const TkIntSet *src) __warn_unused__;
+
+TkIntSet *TkIntSetJoinBits(TkIntSet *dst, const struct TkBitField *src) __warn_unused__;
+TkIntSet *TkIntSetIntersectBits(TkIntSet *dst, const struct TkBitField *src) __warn_unused__;
+TkIntSet *TkIntSetRemoveBits(TkIntSet *dst, const struct TkBitField *src) __warn_unused__;
+/* dst := src - dst */
+TkIntSet *TkIntSetComplementToBits(TkIntSet *dst, const struct TkBitField *src) __warn_unused__;
+
+/* dst := dst + set1 + set2 */
+TkIntSet *TkIntSetJoin2(TkIntSet *dst, const TkIntSet *set1, const TkIntSet *set2) __warn_unused__;
+/* dst := src - dst */
+TkIntSet *TkIntSetComplementTo(TkIntSet *dst, const TkIntSet *src) __warn_unused__;
+/* dst := dst + (set2 - set1) */
+TkIntSet *TkIntSetJoinComplementTo(TkIntSet *dst, const TkIntSet *set1, const TkIntSet *set2)
+ __warn_unused__;
+/* dst := dst + (set1 - set2) + (set2 - set1) */
+TkIntSet *TkIntSetJoinNonIntersection(TkIntSet *dst, const TkIntSet *set1, const TkIntSet *set2)
+ __warn_unused__;
+/* dst := dst + add + ((set1 + set2) - (set1 & set2)) */
+TkIntSet *TkIntSetJoin2ComplementToIntersection(TkIntSet *dst,
+ const TkIntSet *add, const TkIntSet *set1, const TkIntSet *set2) __warn_unused__;
+/* dst := (dst - set1) + (set1 - set2) */
+TkIntSet *TkIntSetJoinOfDifferences(TkIntSet *dst, const TkIntSet *set1, const TkIntSet *set2)
+ __warn_unused__;
+
+inline bool TkIntSetIsEmpty(const TkIntSet *set);
+inline unsigned TkIntSetSize(const TkIntSet *set);
+inline unsigned TkIntSetMax(const TkIntSet *set);
+
+inline unsigned TkIntSetRefCount(const TkIntSet *set);
+inline void TkIntSetIncrRefCount(TkIntSet *set);
+inline unsigned TkIntSetDecrRefCount(TkIntSet *set);
+
+inline TkIntSetType TkIntSetAccess(const TkIntSet *set, unsigned index);
+
+inline bool TkIntSetTest(const TkIntSet *set, unsigned n);
+inline bool TkIntSetNone(const TkIntSet *set);
+inline bool TkIntSetAny(const TkIntSet *set);
+
+inline bool TkIntSetIsEqual(const TkIntSet *set1, const TkIntSet *set2);
+inline bool TkIntSetContains(const TkIntSet *set1, const TkIntSet *set2);
+inline bool TkIntSetDisjunctive(const TkIntSet *set1, const TkIntSet *set2);
+inline bool TkIntSetIntersects(const TkIntSet *set1, const TkIntSet *set2);
+
+bool TkIntSetIntersectionIsEqual(const TkIntSet *set1, const TkIntSet *set2,
+ const struct TkBitField *del);
+bool TkIntSetIsEqualBits(const TkIntSet *set, const struct TkBitField *bf);
+bool TkIntSetContainsBits(const TkIntSet *set, const struct TkBitField *bf);
+bool TkIntSetDisjunctiveBits(const TkIntSet *set, const struct TkBitField *bf);
+bool TkIntSetIntersectionIsEqualBits(const TkIntSet *set, const struct TkBitField *bf,
+ const struct TkBitField *del);
+bool TkIntSetIsContainedBits(const TkIntSet *set, const struct TkBitField *bf);
+
+inline unsigned TkIntSetFindFirst(const TkIntSet *set);
+inline unsigned TkIntSetFindNext(const TkIntSet *set);
+
+unsigned TkIntSetFindFirstInIntersection(const TkIntSet *set, const struct TkBitField *bf);
+
+TkIntSet *TkIntSetAdd(TkIntSet *set, unsigned n) __warn_unused__;
+TkIntSet *TkIntSetErase(TkIntSet *set, unsigned n) __warn_unused__;
+TkIntSet *TkIntSetTestAndSet(TkIntSet *set, unsigned n) __warn_unused__;
+TkIntSet *TkIntSetTestAndUnset(TkIntSet *set, unsigned n) __warn_unused__;
+inline TkIntSet *TkIntSetAddOrErase(TkIntSet *set, unsigned n, bool add) __warn_unused__;
+TkIntSet *TkIntSetClear(TkIntSet *set) __warn_unused__;
+
+#ifndef NDEBUG
+void TkIntSetPrint(const TkIntSet *set);
+#endif
+
+
+#if TK_UNUSED_INTSET_FUNCTIONS
+
+/*
+ * These functions are not needed anymore, but shouldn't be removed, because sometimes
+ * any of these functions might be useful.
+ */
+
+/* dst := (dst + (set - sub)) & set */
+TkIntSet *TkIntSetInnerJoinDifference(TkIntSet *dst, const TkIntSet *set, const TkIntSet *sub)
+ __warn_unused__;
+/* ((set + (add - sub)) & add) == nil */
+bool TkIntSetInnerJoinDifferenceIsEmpty(const TkIntSet *set, const TkIntSet *add, const TkIntSet *sub);
+/* set1 == set2 - sub2 */
+bool TkIntSetIsEqualToDifference(const TkIntSet *set1, const TkIntSet *set2, const TkIntSet *sub2);
+/* set1 == set2 + (add2 & set2) */
+bool TkIntSetIsEqualToInnerJoin(const TkIntSet *set1, const TkIntSet *set2, const TkIntSet *add2);
+/* set1 == ((set2 + (add2 - sub2)) & add2) */
+bool TkIntSetIsEqualToInnerJoinDifference(const TkIntSet *set1, const TkIntSet *set2,
+ const TkIntSet *add2, const TkIntSet *sub2);
+/* ((set1 + (add - sub)) & add) == ((set2 + (add - sub)) & add) */
+bool TkIntSetInnerJoinDifferenceIsEqual(const TkIntSet *set1, const TkIntSet *set2,
+ const TkIntSet *add, const TkIntSet *sub);
+
+#endif /* TK_UNUSED_INTSET_FUNCTIONS */
+
+
+#undef __warn_unused__
+
+#ifdef TK_C99_INLINE_SUPPORT
+# define _TK_NEED_IMPLEMENTATION
+# include "tkIntSetPriv.h"
+#endif
+#endif /* _TKINTSET */
+/* vi:set ts=8 sw=4: */