Fix Dictionary and HashSet iterators to prevent unwanted data copies

#1361
This commit is contained in:
Wojtek Figat
2023-09-10 11:25:36 +02:00
parent 0c89aa1958
commit 9291295a4d
5 changed files with 57 additions and 52 deletions

View File

@@ -213,17 +213,17 @@ public:
{
friend HashSet;
private:
HashSet& _collection;
HashSet* _collection;
int32 _index;
Iterator(HashSet& collection, const int32 index)
Iterator(HashSet* collection, const int32 index)
: _collection(collection)
, _index(index)
{
}
Iterator(HashSet const& collection, const int32 index)
: _collection((HashSet&)collection)
Iterator(HashSet const* collection, const int32 index)
: _collection(const_cast<HashSet*>(collection))
, _index(index)
{
}
@@ -244,27 +244,27 @@ public:
public:
FORCE_INLINE bool IsEnd() const
{
return _index == _collection.Capacity();
return _index == _collection->_size;
}
FORCE_INLINE bool IsNotEnd() const
{
return _index != _collection.Capacity();
return _index != _collection->_size;
}
FORCE_INLINE Bucket& operator*() const
{
return _collection._allocation.Get()[_index];
return _collection->_allocation.Get()[_index];
}
FORCE_INLINE Bucket* operator->() const
{
return &_collection._allocation.Get()[_index];
return &_collection->_allocation.Get()[_index];
}
FORCE_INLINE explicit operator bool() const
{
return _index >= 0 && _index < _collection._size;
return _index >= 0 && _index < _collection->_size;
}
FORCE_INLINE bool operator !() const
@@ -274,12 +274,12 @@ public:
FORCE_INLINE bool operator==(const Iterator& v) const
{
return _index == v._index && &_collection == &v._collection;
return _index == v._index && _collection == v._collection;
}
FORCE_INLINE bool operator!=(const Iterator& v) const
{
return _index != v._index || &_collection != &v._collection;
return _index != v._index || _collection != v._collection;
}
Iterator& operator=(const Iterator& v)
@@ -291,10 +291,10 @@ public:
Iterator& operator++()
{
const int32 capacity = _collection.Capacity();
const int32 capacity = _collection->_size;
if (_index != capacity)
{
const Bucket* data = _collection._allocation.Get();
const Bucket* data = _collection->_allocation.Get();
do
{
_index++;
@@ -314,7 +314,7 @@ public:
{
if (_index > 0)
{
const Bucket* data = _collection._allocation.Get();
const Bucket* data = _collection->_allocation.Get();
do
{
_index--;
@@ -464,7 +464,7 @@ public:
/// <param name="i">Iterator with item to add</param>
void Add(const Iterator& i)
{
ASSERT(&i._collection != this && i);
ASSERT(i._collection != this && i);
const Bucket& bucket = *i;
Add(bucket.Item);
}
@@ -498,7 +498,7 @@ public:
/// <returns>True if cannot remove item from the collection because cannot find it, otherwise false.</returns>
bool Remove(const Iterator& i)
{
ASSERT(&i._collection == this);
ASSERT(i._collection == this);
if (i)
{
ASSERT(_allocation.Get()[i._index].IsOccupied());
@@ -523,7 +523,7 @@ public:
return End();
FindPositionResult pos;
FindPosition(item, pos);
return pos.ObjectIndex != -1 ? Iterator(*this, pos.ObjectIndex) : End();
return pos.ObjectIndex != -1 ? Iterator(this, pos.ObjectIndex) : End();
}
/// <summary>
@@ -559,38 +559,38 @@ public:
public:
Iterator Begin() const
{
Iterator i(*this, -1);
Iterator i(this, -1);
++i;
return i;
}
Iterator End() const
{
return Iterator(*this, _size);
return Iterator(this, _size);
}
Iterator begin()
{
Iterator i(*this, -1);
Iterator i(this, -1);
++i;
return i;
}
FORCE_INLINE Iterator end()
{
return Iterator(*this, _size);
return Iterator(this, _size);
}
const Iterator begin() const
{
Iterator i(*this, -1);
Iterator i(this, -1);
++i;
return i;
}
FORCE_INLINE const Iterator end() const
{
return Iterator(*this, _size);
return Iterator(this, _size);
}
protected: