From 30eee05f3f809e3950c8d8463ecdd9807c943692 Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Thu, 9 May 2019 14:08:30 -0400 Subject: IntSet -> UIntSet (#961) * * Fix warning in vk-swap-chain around use of Index. Rename _indexOf to _indexOfFormat. * Rename IntSet to UIntSet and put in own files slang-uint-set.h.cpp. Use UInt as the held type. * On UintSet setMax -> resizeAndClear. Doing so revealed bug in add. * Closer following of conventions - use kPrefix for constants (even though held in 'enum') * Small fixes/improvements * * Add some documentation to UIntSet methods * Use memset to set/reset bits * Fix some tabbing. Rename oldBufferSize -> oldCount * Fix tabs. --- source/core/slang-uint-set.h | 118 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 source/core/slang-uint-set.h (limited to 'source/core/slang-uint-set.h') diff --git a/source/core/slang-uint-set.h b/source/core/slang-uint-set.h new file mode 100644 index 000000000..25f0c9269 --- /dev/null +++ b/source/core/slang-uint-set.h @@ -0,0 +1,118 @@ +#ifndef SLANG_UINT_SET_H +#define SLANG_UINT_SET_H + +#include "list.h" +#include "slang-math.h" +#include "common.h" + +#include + +namespace Slang +{ + +/* Hold a set of UInt values. Implementation works by storing as a bit per value */ +class UIntSet +{ +public: + typedef uint32_t Element; ///< Type that holds the bits to say if value is present + + UIntSet() {} + UIntSet(const UIntSet& other) { m_buffer = other.m_buffer; } + UIntSet(UIntSet && other) { *this = (_Move(other)); } + UIntSet(UInt maxVal) { resizeAndClear(maxVal); } + + UIntSet& operator=(UIntSet&& other); + UIntSet& operator=(const UIntSet& other); + + int GetHashCode(); + + /// Return the count of all bits directly represented + Int getCount() const { return Int(m_buffer.getCount()) * kElementSize; } + + /// Resize such that val can be stored and clear contents + void resizeAndClear(UInt val); + /// Set all of the values up to count, as set + void setAll(); + /// Resize (but maintain contents) up to bit size. + /// NOTE! That since storage is in Element blocks, it may mean some values after size are set (up to the Element boundary) + void resize(UInt size); + + /// Clear all of the contents (by clearing the bits) + void clear(); + + /// Clear all the contents and free memory + void clearAndDeallocate(); + + /// Add a value + inline void add(UInt val); + /// Remove a value + inline void remove(UInt val); + /// Returns true if the value is present + inline bool contains(UInt val) const; + + /// == + bool operator==(const UIntSet& set) const; + /// != + bool operator!=(const UIntSet& set) const { return !(*this == set); } + + /// Store the union between this and set in this + void unionWith(const UIntSet& set); + /// Store the intersection between this and set in this + void intersectWith(const UIntSet& set); + + /// Store the union of set1 and set2 in outRs + static void calcUnion(UIntSet& outRs, const UIntSet& set1, const UIntSet& set2); + /// Store the intersection of set1 and set2 in outRs + static void calcIntersection(UIntSet& outRs, const UIntSet& set1, const UIntSet& set2); + /// Store the subtraction of set2 from set1 in outRs + static void calcSubtract(UIntSet& outRs, const UIntSet& set1, const UIntSet& set2); + + /// Returns true if set1 and set2 have a same value set (ie there is an intersection) + static bool hasIntersection(const UIntSet& set1, const UIntSet& set2); + +private: + enum + { + kElementShift = 5, ///< How many bits to shift to get Element index from an index + kElementSize = sizeof(Element) * 8, ///< The number of bits in an element + kElementMask = kElementSize - 1, ///< Mask to get shift from an index + }; + + // Make sure they are correct for the Element type + SLANG_COMPILE_TIME_ASSERT((1 << kElementShift) == kElementSize); + + List m_buffer; +}; + +// -------------------------------------------------------------------------- +inline void UIntSet::remove(UInt val) +{ + const Index idx = Index(val >> kElementShift); + if (idx < m_buffer.getCount()) + { + m_buffer[idx] &= ~(Element(1) << (val & kElementMask)); + } +} + +// -------------------------------------------------------------------------- +inline bool UIntSet::contains(UInt val) const +{ + const Index idx = Index(val >> kElementShift); + return idx <= m_buffer.getCount() && + ((m_buffer[idx] & (Element(1) << (val & kElementMask))) != 0); +} + +// -------------------------------------------------------------------------- +inline void UIntSet::add(UInt val) +{ + const Index idx = Index(val >> kElementShift); + if (idx >= m_buffer.getCount()) + { + resize(val); + } + m_buffer[idx] |= Element(1) << (val & kElementMask); +} + +} + +#endif -- cgit v1.2.3