summaryrefslogtreecommitdiffstats
path: root/source/core/int-set.h
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-06-09 11:34:21 -0700
committerTim Foley <tfoley@nvidia.com>2017-06-09 13:44:59 -0700
commitfcf83dbf9effab3bd98bad2b83b2468b7eb05cfd (patch)
tree41047c94883b86ec085a81597391ce3ef557cd43 /source/core/int-set.h
parent52e8d4b9a27ab0060f874c3a63ab531847be35c0 (diff)
Initial import of code.
Diffstat (limited to 'source/core/int-set.h')
-rw-r--r--source/core/int-set.h166
1 files changed, 166 insertions, 0 deletions
diff --git a/source/core/int-set.h b/source/core/int-set.h
new file mode 100644
index 000000000..cb8f788f2
--- /dev/null
+++ b/source/core/int-set.h
@@ -0,0 +1,166 @@
+#ifndef BIT_VECTOR_INT_SET_H
+#define BIT_VECTOR_INT_SET_H
+
+#include "list.h"
+#include "slang-math.h"
+#include "common.h"
+#include "exception.h"
+
+#include <memory.h>
+
+namespace CoreLib
+{
+ namespace Basic
+ {
+ class IntSet
+ {
+ private:
+ List<int> buffer;
+ public:
+ IntSet()
+ {}
+ IntSet(const IntSet & other)
+ {
+ buffer = other.buffer;
+ }
+ IntSet(IntSet && other)
+ {
+ *this = (_Move(other));
+ }
+ IntSet & operator = (IntSet && other)
+ {
+ buffer = _Move(other.buffer);
+ return *this;
+ }
+ IntSet & operator = (const IntSet & other)
+ {
+ buffer = other.buffer;
+ return *this;
+ }
+ int GetHashCode()
+ {
+ int rs = 0;
+ for (auto val : buffer)
+ rs ^= val;
+ return rs;
+ }
+ IntSet(int maxVal)
+ {
+ SetMax(maxVal);
+ }
+ int Size() const
+ {
+ return buffer.Count()*32;
+ }
+ void SetMax(int val)
+ {
+ Resize(val);
+ Clear();
+ }
+ void SetAll()
+ {
+ for (int i = 0; i<buffer.Count(); i++)
+ buffer[i] = 0xFFFFFFFF;
+ }
+ void Resize(int size)
+ {
+ int oldBufferSize = buffer.Count();
+ buffer.SetSize((size+31)>>5);
+ if (buffer.Count() > oldBufferSize)
+ memset(buffer.Buffer()+oldBufferSize, 0, (buffer.Count()-oldBufferSize) * sizeof(int));
+ }
+ void Clear()
+ {
+ for (int i = 0; i<buffer.Count(); i++)
+ buffer[i] = 0;
+ }
+ void Add(int val)
+ {
+ int id = val>>5;
+ if (id < buffer.Count())
+ buffer[id] |= (1<<(val&31));
+ else
+ {
+ int oldSize = buffer.Count();
+ buffer.SetSize(id+1);
+ memset(buffer.Buffer() + oldSize, 0, (buffer.Count()-oldSize)*sizeof(int));
+ buffer[id] |= (1<<(val&31));
+ }
+ }
+ void Remove(int val)
+ {
+ if ((val>>5) < buffer.Count())
+ buffer[(val>>5)] &= ~(1<<(val&31));
+ }
+ bool Contains(int val) const
+ {
+ if ((val>>5) >= buffer.Count())
+ return false;
+ return (buffer[(val>>5)] & (1<<(val&31))) != 0;
+ }
+ void UnionWith(const IntSet & set)
+ {
+ for (int i = 0; i<Math::Min(set.buffer.Count(), buffer.Count()); i++)
+ {
+ buffer[i] |= set.buffer[i];
+ }
+ if (set.buffer.Count() > buffer.Count())
+ buffer.AddRange(set.buffer.Buffer()+buffer.Count(), set.buffer.Count()-buffer.Count());
+ }
+ bool operator == (const IntSet & set)
+ {
+ if (buffer.Count() != set.buffer.Count())
+ return false;
+ for (int i = 0; i<buffer.Count(); i++)
+ if (buffer[i] != set.buffer[i])
+ return false;
+ return true;
+ }
+ bool operator != (const IntSet & set)
+ {
+ return !(*this == set);
+ }
+ void IntersectWith(const IntSet & set)
+ {
+ if (set.buffer.Count() < buffer.Count())
+ memset(buffer.Buffer() + set.buffer.Count(), 0, (buffer.Count()-set.buffer.Count())*sizeof(int));
+ for (int i = 0; i<Math::Min(set.buffer.Count(), buffer.Count()); i++)
+ {
+ buffer[i] &= set.buffer[i];
+ }
+ }
+ static void Union(IntSet & rs, const IntSet & set1, const IntSet & set2)
+ {
+ rs.buffer.SetSize(Math::Max(set1.buffer.Count(), set2.buffer.Count()));
+ rs.Clear();
+ for (int i = 0; i<set1.buffer.Count(); i++)
+ rs.buffer[i] |= set1.buffer[i];
+ for (int i = 0; i<set2.buffer.Count(); i++)
+ rs.buffer[i] |= set2.buffer[i];
+ }
+ static void Intersect(IntSet & rs, const IntSet & set1, const IntSet & set2)
+ {
+ rs.buffer.SetSize(Math::Min(set1.buffer.Count(), set2.buffer.Count()));
+ for (int i = 0; i<rs.buffer.Count(); i++)
+ rs.buffer[i] = set1.buffer[i] & set2.buffer[i];
+ }
+ static void Subtract(IntSet & rs, const IntSet & set1, const IntSet & set2)
+ {
+ rs.buffer.SetSize(set1.buffer.Count());
+ for (int i = 0; i<Math::Min(set1.buffer.Count(), set2.buffer.Count()); i++)
+ rs.buffer[i] = set1.buffer[i] & (~set2.buffer[i]);
+ }
+ static bool HasIntersection(const IntSet & set1, const IntSet & set2)
+ {
+ for (int i = 0; i<Math::Min(set1.buffer.Count(), set2.buffer.Count()); i++)
+ {
+ if (set1.buffer[i] & set2.buffer[i])
+ return true;
+ }
+ return false;
+ }
+ };
+ }
+}
+
+#endif \ No newline at end of file