#pragma once #include "SparseArray.h" template class TSetElement { public: ElementType Value; mutable int32 HashNextId; mutable int32 HashIndex; TSetElement(ElementType InValue, int32 InHashNextId, int32 InHashIndex) : Value(InValue) , HashNextId(InHashNextId) , HashIndex(InHashIndex) { } FORCEINLINE TSetElement& operator=(const TSetElement& Other) { Value = Other.Value; } FORCEINLINE bool operator==(const TSetElement& Other) const { return Value == Other.Value; } FORCEINLINE bool operator!=(const TSetElement& Other) const { return Value != Other.Value; } }; template class TSet { private: friend TSparseArray; public: typedef TSetElement ElementType; typedef TSparseArrayElementOrListLink ArrayElementType; public: TSparseArray Elements; mutable TInlineAllocator<1>::ForElementType Hash; mutable int32 HashSize; public: class FBaseIterator { private: TSet& IteratedSet; TSparseArray::FBaseIterator ElementIt; public: FORCEINLINE FBaseIterator(const TSet& InSet, TSparseArray>::FBaseIterator InElementIt) : IteratedSet(const_cast&>(InSet)) , ElementIt(InElementIt) { } FORCEINLINE explicit operator bool() const { return (bool)ElementIt; } FORCEINLINE TSet::FBaseIterator& operator++() { ++ElementIt; return *this; } FORCEINLINE bool operator==(const TSet::FBaseIterator& OtherIt) const { return ElementIt == OtherIt.ElementIt; } FORCEINLINE bool operator!=(const TSet::FBaseIterator& OtherIt) const { return ElementIt != OtherIt.ElementIt; } FORCEINLINE TSet::FBaseIterator& operator=(TSet::FBaseIterator& OtherIt) { return ElementIt = OtherIt.ElementIt; } FORCEINLINE SetType& operator*() { return (*ElementIt).Value; } FORCEINLINE const SetType& operator*() const { return &((*ElementIt).Value); } FORCEINLINE SetType* operator->() { return &((*ElementIt).Value); } FORCEINLINE const SetType* operator->() const { return &(*ElementIt).Value; } FORCEINLINE const int32 GetIndex() const { return ElementIt.GetIndex(); } FORCEINLINE ElementType& GetSetElement() { return *ElementIt; } FORCEINLINE const ElementType& GetSetElement() const { return *ElementIt; } FORCEINLINE bool IsElementValid() const { return ElementIt.IsElementValid(); } }; public: FORCEINLINE TSet::FBaseIterator begin() { return TSet::FBaseIterator(*this, Elements.begin()); } FORCEINLINE const TSet::FBaseIterator begin() const { return TSet::FBaseIterator(*this, Elements.begin()); } FORCEINLINE TSet::FBaseIterator end() { return TSet::FBaseIterator(*this, Elements.end()); } FORCEINLINE const TSet::FBaseIterator end() const { return TSet::FBaseIterator(*this, Elements.end()); } FORCEINLINE SetType& operator[](int Index) { return Elements[Index].ElementData.Value; } FORCEINLINE int32 Num() const { return Elements.Num(); } FORCEINLINE bool IsValid() const { return Elements.Data.Data != nullptr && Elements.AllocationFlags.MaxBits > 0; } FORCEINLINE TSparseArray& GetElements() { return Elements; } FORCEINLINE const TSparseArray& GetElements() const { return Elements; } FORCEINLINE const TBitArray& GetAllocationFlags() const { return Elements.GetAllocationFlags(); } FORCEINLINE bool IsIndexValid(int32 IndexToCheck) const { return Elements.IsIndexValid(IndexToCheck); } FORCEINLINE const bool Contains(const SetType& ElementToLookFor) const { if (Num() <= 0) return false; for (SetType Element : *this) { if (Element == ElementToLookFor) return true; } return false; } FORCEINLINE const int32 Find(const SetType& ElementToLookFor) const { for (auto It = this->begin(); It != this->end(); ++It) { if (*It == ElementToLookFor) { return It.GetIndex(); } } return -1; } FORCEINLINE bool Remove(const SetType& ElementToRemove) { return Elements.RemoveAt(Find(ElementToRemove)); } FORCEINLINE bool Remove(int Index) { return Elements.RemoveAt(Index); } }; /* template //, typename KeyFuncs, typename Allocator> class TSet { public: typedef TSetElement ElementType; typedef TSparseArrayElementOrListLink ArrayElementType; TSparseArray Elements; mutable TInlineAllocator<1>::ForElementType Hash; mutable int32 HashSize; }; */