Replace size type uint32 by size_t for the containers (Array, Map, Set, ...)
This commit is contained in:
parent
0e15fa0a01
commit
c55d9c7c61
|
@ -51,10 +51,10 @@ class Array {
|
||||||
T* mBuffer;
|
T* mBuffer;
|
||||||
|
|
||||||
/// Number of elements in the array
|
/// Number of elements in the array
|
||||||
uint32 mSize;
|
size_t mSize;
|
||||||
|
|
||||||
/// Number of allocated elements in the array
|
/// Number of allocated elements in the array
|
||||||
uint32 mCapacity;
|
size_t mCapacity;
|
||||||
|
|
||||||
/// Memory allocator
|
/// Memory allocator
|
||||||
MemoryAllocator& mAllocator;
|
MemoryAllocator& mAllocator;
|
||||||
|
@ -69,9 +69,9 @@ class Array {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uint32 mCurrentIndex;
|
size_t mCurrentIndex;
|
||||||
T* mBuffer;
|
T* mBuffer;
|
||||||
uint32 mSize;
|
size_t mSize;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ class Array {
|
||||||
Iterator() = default;
|
Iterator() = default;
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
Iterator(void* buffer, uint32 index, uint32 size)
|
Iterator(void* buffer, size_t index, size_t size)
|
||||||
:mCurrentIndex(index), mBuffer(static_cast<T*>(buffer)), mSize(size) {
|
:mCurrentIndex(index), mBuffer(static_cast<T*>(buffer)), mSize(size) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,7 @@ class Array {
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
Array(MemoryAllocator& allocator, uint32 capacity = 0)
|
Array(MemoryAllocator& allocator, size_t capacity = 0)
|
||||||
: mBuffer(nullptr), mSize(0), mCapacity(0), mAllocator(allocator) {
|
: mBuffer(nullptr), mSize(0), mCapacity(0), mAllocator(allocator) {
|
||||||
|
|
||||||
if (capacity > 0) {
|
if (capacity > 0) {
|
||||||
|
@ -247,7 +247,7 @@ class Array {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocate memory for a given number of elements
|
/// Allocate memory for a given number of elements
|
||||||
void reserve(uint32 capacity) {
|
void reserve(size_t capacity) {
|
||||||
|
|
||||||
if (capacity <= mCapacity) return;
|
if (capacity <= mCapacity) return;
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@ class Array {
|
||||||
std::uninitialized_copy(mBuffer, mBuffer + mSize, destination);
|
std::uninitialized_copy(mBuffer, mBuffer + mSize, destination);
|
||||||
|
|
||||||
// Destruct the previous items
|
// Destruct the previous items
|
||||||
for (uint32 i=0; i<mSize; i++) {
|
for (size_t i=0; i<mSize; i++) {
|
||||||
mBuffer[i].~T();
|
mBuffer[i].~T();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -308,7 +308,7 @@ class Array {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a given numbers of elements at the end of the array but do not init them
|
/// Add a given numbers of elements at the end of the array but do not init them
|
||||||
void addWithoutInit(uint32 nbElements) {
|
void addWithoutInit(size_t nbElements) {
|
||||||
|
|
||||||
// If we need to allocate more memory
|
// If we need to allocate more memory
|
||||||
if ((mSize + nbElements) > mCapacity) {
|
if ((mSize + nbElements) > mCapacity) {
|
||||||
|
@ -323,7 +323,7 @@ class Array {
|
||||||
/// this method returns the end() iterator
|
/// this method returns the end() iterator
|
||||||
Iterator find(const T& element) {
|
Iterator find(const T& element) {
|
||||||
|
|
||||||
for (uint32 i=0; i<mSize; i++) {
|
for (size_t i=0; i<mSize; i++) {
|
||||||
if (element == mBuffer[i]) {
|
if (element == mBuffer[i]) {
|
||||||
return Iterator(mBuffer, i, mSize);
|
return Iterator(mBuffer, i, mSize);
|
||||||
}
|
}
|
||||||
|
@ -345,7 +345,7 @@ class Array {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove an element from the array at a given index (all the following items will be moved)
|
/// Remove an element from the array at a given index (all the following items will be moved)
|
||||||
Iterator removeAt(uint32 index) {
|
Iterator removeAt(size_t index) {
|
||||||
|
|
||||||
assert(index < mSize);
|
assert(index < mSize);
|
||||||
|
|
||||||
|
@ -367,7 +367,7 @@ class Array {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove an element from the list at a given index and replace it by the last one of the list (if any)
|
/// Remove an element from the list at a given index and replace it by the last one of the list (if any)
|
||||||
void removeAtAndReplaceByLast(uint32 index) {
|
void removeAtAndReplaceByLast(size_t index) {
|
||||||
|
|
||||||
assert(index < mSize);
|
assert(index < mSize);
|
||||||
|
|
||||||
|
@ -381,7 +381,7 @@ class Array {
|
||||||
|
|
||||||
/// Remove an element from the array at a given index and replace it by the last one of the array (if any)
|
/// Remove an element from the array at a given index and replace it by the last one of the array (if any)
|
||||||
/// Append another array at the end of the current one
|
/// Append another array at the end of the current one
|
||||||
void addRange(const Array<T>& array, uint32 startIndex = 0) {
|
void addRange(const Array<T>& array, size_t startIndex = 0) {
|
||||||
|
|
||||||
assert(startIndex <= array.size());
|
assert(startIndex <= array.size());
|
||||||
|
|
||||||
|
@ -393,7 +393,7 @@ class Array {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the elements of the array to the current one
|
// Add the elements of the array to the current one
|
||||||
for(uint32 i=startIndex; i<array.size(); i++) {
|
for(size_t i=startIndex; i<array.size(); i++) {
|
||||||
|
|
||||||
new (reinterpret_cast<void*>(mBuffer + mSize)) T(array[i]);
|
new (reinterpret_cast<void*>(mBuffer + mSize)) T(array[i]);
|
||||||
mSize++;
|
mSize++;
|
||||||
|
@ -404,7 +404,7 @@ class Array {
|
||||||
void clear(bool releaseMemory = false) {
|
void clear(bool releaseMemory = false) {
|
||||||
|
|
||||||
// Call the destructor of each element
|
// Call the destructor of each element
|
||||||
for (uint32 i=0; i < mSize; i++) {
|
for (size_t i=0; i < mSize; i++) {
|
||||||
mBuffer[i].~T();
|
mBuffer[i].~T();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,23 +422,23 @@ class Array {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the number of elements in the array
|
/// Return the number of elements in the array
|
||||||
uint32 size() const {
|
size_t size() const {
|
||||||
return mSize;
|
return mSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the capacity of the array
|
/// Return the capacity of the array
|
||||||
uint32 capacity() const {
|
size_t capacity() const {
|
||||||
return mCapacity;
|
return mCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Overloaded index operator
|
/// Overloaded index operator
|
||||||
T& operator[](const uint32 index) {
|
T& operator[](const size_t index) {
|
||||||
assert(index >= 0 && index < mSize);
|
assert(index >= 0 && index < mSize);
|
||||||
return mBuffer[index];
|
return mBuffer[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Overloaded const index operator
|
/// Overloaded const index operator
|
||||||
const T& operator[](const uint32 index) const {
|
const T& operator[](const size_t index) const {
|
||||||
assert(index >= 0 && index < mSize);
|
assert(index >= 0 && index < mSize);
|
||||||
return mBuffer[index];
|
return mBuffer[index];
|
||||||
}
|
}
|
||||||
|
@ -448,7 +448,7 @@ class Array {
|
||||||
|
|
||||||
if (mSize != array.mSize) return false;
|
if (mSize != array.mSize) return false;
|
||||||
|
|
||||||
for (uint32 i=0; i < mSize; i++) {
|
for (size_t i=0; i < mSize; i++) {
|
||||||
if (mBuffer[i] != array[i]) {
|
if (mBuffer[i] != array[i]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,10 +55,10 @@ class Deque {
|
||||||
// -------------------- Constants -------------------- //
|
// -------------------- Constants -------------------- //
|
||||||
|
|
||||||
/// Number of items in a chunk
|
/// Number of items in a chunk
|
||||||
const uint32 CHUNK_NB_ITEMS = 17;
|
const size_t CHUNK_NB_ITEMS = 17;
|
||||||
|
|
||||||
/// First item index in a chunk
|
/// First item index in a chunk
|
||||||
const uint32 CHUNK_FIRST_ITEM_INDEX = CHUNK_NB_ITEMS / 2;
|
const size_t CHUNK_FIRST_ITEM_INDEX = CHUNK_NB_ITEMS / 2;
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
|
@ -66,16 +66,16 @@ class Deque {
|
||||||
T** mChunks;
|
T** mChunks;
|
||||||
|
|
||||||
/// Number of current elements in the deque
|
/// Number of current elements in the deque
|
||||||
uint32 mSize;
|
size_t mSize;
|
||||||
|
|
||||||
/// Number of chunks
|
/// Number of chunks
|
||||||
uint32 mNbChunks;
|
size_t mNbChunks;
|
||||||
|
|
||||||
/// Index of the chunk with the first element of the deque
|
/// Index of the chunk with the first element of the deque
|
||||||
uint32 mFirstChunkIndex;
|
size_t mFirstChunkIndex;
|
||||||
|
|
||||||
/// Index of the chunk with the last element of the deque
|
/// Index of the chunk with the last element of the deque
|
||||||
uint32 mLastChunkIndex;
|
size_t mLastChunkIndex;
|
||||||
|
|
||||||
/// Index of the first element in the first chunk
|
/// Index of the first element in the first chunk
|
||||||
uint8 mFirstItemIndex;
|
uint8 mFirstItemIndex;
|
||||||
|
@ -89,15 +89,15 @@ class Deque {
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Return a reference to an item at the given virtual index in range [0; mSize-1]
|
/// Return a reference to an item at the given virtual index in range [0; mSize-1]
|
||||||
T& getItem(uint32 virtualIndex) const {
|
T& getItem(size_t virtualIndex) const {
|
||||||
|
|
||||||
// If the virtual index is valid
|
// If the virtual index is valid
|
||||||
if (virtualIndex < mSize) {
|
if (virtualIndex < mSize) {
|
||||||
|
|
||||||
uint32 chunkIndex = mFirstChunkIndex;
|
size_t chunkIndex = mFirstChunkIndex;
|
||||||
uint32 itemIndex = mFirstItemIndex;
|
size_t itemIndex = mFirstItemIndex;
|
||||||
|
|
||||||
const uint32 nbItemsFirstChunk = CHUNK_NB_ITEMS - mFirstItemIndex;
|
const size_t nbItemsFirstChunk = CHUNK_NB_ITEMS - mFirstItemIndex;
|
||||||
if (virtualIndex < nbItemsFirstChunk) {
|
if (virtualIndex < nbItemsFirstChunk) {
|
||||||
itemIndex += virtualIndex;
|
itemIndex += virtualIndex;
|
||||||
}
|
}
|
||||||
|
@ -118,18 +118,18 @@ class Deque {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add more chunks
|
/// Add more chunks
|
||||||
void expandChunks(uint32 atLeastNbChunks = 0) {
|
void expandChunks(size_t atLeastNbChunks = 0) {
|
||||||
|
|
||||||
// If it is not necessary to expand the chunks
|
// If it is not necessary to expand the chunks
|
||||||
if (atLeastNbChunks > 0 && atLeastNbChunks <= mNbChunks) {
|
if (atLeastNbChunks > 0 && atLeastNbChunks <= mNbChunks) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 newNbChunks = mNbChunks == 0 ? 3 : 2 * mNbChunks - 1;
|
size_t newNbChunks = mNbChunks == 0 ? 3 : 2 * mNbChunks - 1;
|
||||||
if (atLeastNbChunks > 0 && newNbChunks < atLeastNbChunks) {
|
if (atLeastNbChunks > 0 && newNbChunks < atLeastNbChunks) {
|
||||||
newNbChunks = uint32(atLeastNbChunks / 2) * 2 + 1;
|
newNbChunks = size_t(atLeastNbChunks / 2) * 2 + 1;
|
||||||
}
|
}
|
||||||
const uint32 halfNbChunksToAdd = mNbChunks == 0 ? 1 : (mNbChunks - 1) / 2;
|
const size_t halfNbChunksToAdd = mNbChunks == 0 ? 1 : (mNbChunks - 1) / 2;
|
||||||
|
|
||||||
// Allocate memory for the new array of pointers to chunk
|
// Allocate memory for the new array of pointers to chunk
|
||||||
void* newMemory = mAllocator.allocate(newNbChunks * sizeof(T*));
|
void* newMemory = mAllocator.allocate(newNbChunks * sizeof(T*));
|
||||||
|
@ -157,7 +157,7 @@ class Deque {
|
||||||
mNbChunks = newNbChunks;
|
mNbChunks = newNbChunks;
|
||||||
|
|
||||||
// Allocate memory for each new chunk
|
// Allocate memory for each new chunk
|
||||||
for (uint32 i=0; i < halfNbChunksToAdd; i++) {
|
for (size_t i=0; i < halfNbChunksToAdd; i++) {
|
||||||
|
|
||||||
// Allocate memory for the new chunk
|
// Allocate memory for the new chunk
|
||||||
mChunks[i] = static_cast<T*>(mAllocator.allocate(sizeof(T) * CHUNK_NB_ITEMS));
|
mChunks[i] = static_cast<T*>(mAllocator.allocate(sizeof(T) * CHUNK_NB_ITEMS));
|
||||||
|
@ -182,7 +182,7 @@ class Deque {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uint32 mVirtualIndex;
|
size_t mVirtualIndex;
|
||||||
const Deque<T>* mDeque;
|
const Deque<T>* mDeque;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -200,7 +200,7 @@ class Deque {
|
||||||
Iterator() = default;
|
Iterator() = default;
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
Iterator(const Deque<T>* deque, uint32 virtualIndex) : mVirtualIndex(virtualIndex), mDeque(deque) {
|
Iterator(const Deque<T>* deque, size_t virtualIndex) : mVirtualIndex(virtualIndex), mDeque(deque) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,14 +345,14 @@ class Deque {
|
||||||
|
|
||||||
if (deque.mSize > 0) {
|
if (deque.mSize > 0) {
|
||||||
|
|
||||||
const uint32 dequeHalfSize1 = std::ceil(deque.mSize / 2.0f);
|
const size_t dequeHalfSize1 = std::ceil(deque.mSize / 2.0f);
|
||||||
const uint32 dequeHalfSize2 = deque.mSize - dequeHalfSize1;
|
const size_t dequeHalfSize2 = deque.mSize - dequeHalfSize1;
|
||||||
|
|
||||||
// Add the items into the deque
|
// Add the items into the deque
|
||||||
for(uint32 i=0; i < dequeHalfSize1; i++) {
|
for(size_t i=0; i < dequeHalfSize1; i++) {
|
||||||
addFront(deque[dequeHalfSize1 - 1 - i]);
|
addFront(deque[dequeHalfSize1 - 1 - i]);
|
||||||
}
|
}
|
||||||
for(uint32 i=0; i < dequeHalfSize2; i++) {
|
for(size_t i=0; i < dequeHalfSize2; i++) {
|
||||||
addBack(deque[dequeHalfSize1 + i]);
|
addBack(deque[dequeHalfSize1 + i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -364,7 +364,7 @@ class Deque {
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
// Release each chunk
|
// Release each chunk
|
||||||
for (uint32 i=0; i < mNbChunks; i++) {
|
for (size_t i=0; i < mNbChunks; i++) {
|
||||||
|
|
||||||
mAllocator.release(mChunks[i], sizeof(T) * CHUNK_NB_ITEMS);
|
mAllocator.release(mChunks[i], sizeof(T) * CHUNK_NB_ITEMS);
|
||||||
}
|
}
|
||||||
|
@ -519,7 +519,7 @@ class Deque {
|
||||||
if (mSize > 0) {
|
if (mSize > 0) {
|
||||||
|
|
||||||
// Call the destructor of every items
|
// Call the destructor of every items
|
||||||
for (uint32 i=0; i < mSize; i++) {
|
for (size_t i=0; i < mSize; i++) {
|
||||||
getItem(i).~T();
|
getItem(i).~T();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,18 +533,18 @@ class Deque {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the number of elements in the deque
|
/// Return the number of elements in the deque
|
||||||
uint32 size() const {
|
size_t size() const {
|
||||||
return mSize;
|
return mSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Overloaded index operator
|
/// Overloaded index operator
|
||||||
T& operator[](const uint32 index) {
|
T& operator[](const size_t index) {
|
||||||
assert(index < mSize);
|
assert(index < mSize);
|
||||||
return getItem(index);
|
return getItem(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Overloaded const index operator
|
/// Overloaded const index operator
|
||||||
const T& operator[](const uint32 index) const {
|
const T& operator[](const size_t index) const {
|
||||||
assert(index < mSize);
|
assert(index < mSize);
|
||||||
return getItem(index);
|
return getItem(index);
|
||||||
}
|
}
|
||||||
|
@ -554,7 +554,7 @@ class Deque {
|
||||||
|
|
||||||
if (mSize != deque.mSize) return false;
|
if (mSize != deque.mSize) return false;
|
||||||
|
|
||||||
for (uint32 i=0; i < mSize; i++) {
|
for (size_t i=0; i < mSize; i++) {
|
||||||
if (getItem(i) != deque.getItem(i)) {
|
if (getItem(i) != deque.getItem(i)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -580,19 +580,19 @@ class Deque {
|
||||||
if (deque.mSize > 0) {
|
if (deque.mSize > 0) {
|
||||||
|
|
||||||
// Number of used chunks
|
// Number of used chunks
|
||||||
const uint32 nbUsedChunks = deque.mLastChunkIndex - deque.mFirstChunkIndex + 1;
|
const size_t nbUsedChunks = deque.mLastChunkIndex - deque.mFirstChunkIndex + 1;
|
||||||
|
|
||||||
// Expand the chunk if necessary
|
// Expand the chunk if necessary
|
||||||
expandChunks(nbUsedChunks);
|
expandChunks(nbUsedChunks);
|
||||||
|
|
||||||
const uint32 dequeHalfSize1 = std::ceil(deque.mSize / 2.0f);
|
const size_t dequeHalfSize1 = std::ceil(deque.mSize / 2.0f);
|
||||||
const uint32 dequeHalfSize2 = deque.mSize - dequeHalfSize1;
|
const size_t dequeHalfSize2 = deque.mSize - dequeHalfSize1;
|
||||||
|
|
||||||
// Add the items into the deque
|
// Add the items into the deque
|
||||||
for(uint32 i=0; i < dequeHalfSize1; i++) {
|
for(size_t i=0; i < dequeHalfSize1; i++) {
|
||||||
addFront(deque[dequeHalfSize1 - 1 - i]);
|
addFront(deque[dequeHalfSize1 - 1 - i]);
|
||||||
}
|
}
|
||||||
for(uint32 i=0; i < dequeHalfSize2; i++) {
|
for(size_t i=0; i < dequeHalfSize2; i++) {
|
||||||
addBack(deque[dequeHalfSize1 + i]);
|
addBack(deque[dequeHalfSize1 + i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,47 +53,47 @@ class Map {
|
||||||
static constexpr float DEFAULT_LOAD_FACTOR = 0.75;
|
static constexpr float DEFAULT_LOAD_FACTOR = 0.75;
|
||||||
|
|
||||||
/// Invalid index in the array
|
/// Invalid index in the array
|
||||||
static constexpr uint32 INVALID_INDEX = 0xffffffff;
|
static constexpr size_t INVALID_INDEX = -1;
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
/// Total number of allocated entries
|
/// Total number of allocated entries
|
||||||
uint32 mNbAllocatedEntries;
|
size_t mNbAllocatedEntries;
|
||||||
|
|
||||||
/// Number of items in the set
|
/// Number of items in the set
|
||||||
uint32 mNbEntries;
|
size_t mNbEntries;
|
||||||
|
|
||||||
/// Number of buckets and size of the hash table (nbEntries = loadFactor * mHashSize)
|
/// Number of buckets and size of the hash table (nbEntries = loadFactor * mHashSize)
|
||||||
uint32 mHashSize ;
|
size_t mHashSize ;
|
||||||
|
|
||||||
/// Array with all the buckets
|
/// Array with all the buckets
|
||||||
uint32* mBuckets;
|
size_t* mBuckets;
|
||||||
|
|
||||||
/// Array with all the entries
|
/// Array with all the entries
|
||||||
Pair<K, V>* mEntries;
|
Pair<K, V>* mEntries;
|
||||||
|
|
||||||
/// For each entry, index of the next entry at the same bucket
|
/// For each entry, index of the next entry at the same bucket
|
||||||
uint32* mNextEntries;
|
size_t* mNextEntries;
|
||||||
|
|
||||||
/// Memory allocator
|
/// Memory allocator
|
||||||
MemoryAllocator& mAllocator;
|
MemoryAllocator& mAllocator;
|
||||||
|
|
||||||
/// Index to the fist free entry
|
/// Index to the fist free entry
|
||||||
uint32 mFreeIndex;
|
size_t mFreeIndex;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Return the index of the entry with a given key or INVALID_INDEX if there is no entry with this key
|
/// Return the index of the entry with a given key or INVALID_INDEX if there is no entry with this key
|
||||||
uint32 findEntry(const K& key) const {
|
size_t findEntry(const K& key) const {
|
||||||
|
|
||||||
if (mHashSize > 0) {
|
if (mHashSize > 0) {
|
||||||
|
|
||||||
const size_t hashCode = Hash()(key);
|
const size_t hashCode = Hash()(key);
|
||||||
const size_t divider = mHashSize - 1;
|
const size_t divider = mHashSize - 1;
|
||||||
const uint32 bucket = static_cast<uint32>(hashCode & divider);
|
const size_t bucket = hashCode & divider;
|
||||||
auto keyEqual = KeyEqual();
|
auto keyEqual = KeyEqual();
|
||||||
|
|
||||||
for (uint32 i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
|
for (size_t i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
|
||||||
if (Hash()(mEntries[i].first) == hashCode && keyEqual(mEntries[i].first, key)) {
|
if (Hash()(mEntries[i].first) == hashCode && keyEqual(mEntries[i].first, key)) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -117,10 +117,10 @@ class Map {
|
||||||
const Map* mMap;
|
const Map* mMap;
|
||||||
|
|
||||||
/// Index of the current bucket
|
/// Index of the current bucket
|
||||||
uint32 mCurrentBucketIndex;
|
size_t mCurrentBucketIndex;
|
||||||
|
|
||||||
/// Index of the current entry
|
/// Index of the current entry
|
||||||
uint32 mCurrentEntryIndex;
|
size_t mCurrentEntryIndex;
|
||||||
|
|
||||||
/// Advance the iterator
|
/// Advance the iterator
|
||||||
void advance() {
|
void advance() {
|
||||||
|
@ -158,7 +158,7 @@ class Map {
|
||||||
Iterator() = default;
|
Iterator() = default;
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
Iterator(const Map* map, uint32 bucketIndex, uint32 entryIndex)
|
Iterator(const Map* map, size_t bucketIndex, size_t entryIndex)
|
||||||
:mMap(map), mCurrentBucketIndex(bucketIndex), mCurrentEntryIndex(entryIndex) {
|
:mMap(map), mCurrentBucketIndex(bucketIndex), mCurrentEntryIndex(entryIndex) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -205,7 +205,7 @@ class Map {
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
Map(MemoryAllocator& allocator, uint32 capacity = 0)
|
Map(MemoryAllocator& allocator, size_t capacity = 0)
|
||||||
: mNbAllocatedEntries(0), mNbEntries(0), mHashSize(0), mBuckets(nullptr),
|
: mNbAllocatedEntries(0), mNbEntries(0), mHashSize(0), mBuckets(nullptr),
|
||||||
mEntries(nullptr), mNextEntries(nullptr), mAllocator(allocator), mFreeIndex(INVALID_INDEX) {
|
mEntries(nullptr), mNextEntries(nullptr), mAllocator(allocator), mFreeIndex(INVALID_INDEX) {
|
||||||
|
|
||||||
|
@ -223,22 +223,22 @@ class Map {
|
||||||
if (mHashSize > 0) {
|
if (mHashSize > 0) {
|
||||||
|
|
||||||
// Allocate memory for the buckets
|
// Allocate memory for the buckets
|
||||||
mBuckets = static_cast<uint32*>(mAllocator.allocate(mHashSize * sizeof(uint32)));
|
mBuckets = static_cast<size_t*>(mAllocator.allocate(mHashSize * sizeof(size_t)));
|
||||||
|
|
||||||
// Allocate memory for the entries
|
// Allocate memory for the entries
|
||||||
mEntries = static_cast<Pair<K, V>*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(Pair<K, V>)));
|
mEntries = static_cast<Pair<K, V>*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(Pair<K, V>)));
|
||||||
mNextEntries = static_cast<uint32*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(uint32)));
|
mNextEntries = static_cast<size_t*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(size_t)));
|
||||||
|
|
||||||
// Copy the buckets array
|
// Copy the buckets array
|
||||||
std::memcpy(mBuckets, map.mBuckets, mHashSize * sizeof(uint32));
|
std::memcpy(mBuckets, map.mBuckets, mHashSize * sizeof(size_t));
|
||||||
|
|
||||||
// Copy the next entries indices
|
// Copy the next entries indices
|
||||||
std::memcpy(mNextEntries, map.mNextEntries, mNbAllocatedEntries * sizeof(uint32));
|
std::memcpy(mNextEntries, map.mNextEntries, mNbAllocatedEntries * sizeof(size_t));
|
||||||
|
|
||||||
// Copy the entries
|
// Copy the entries
|
||||||
for (uint32 i=0; i<mHashSize; i++) {
|
for (size_t i=0; i<mHashSize; i++) {
|
||||||
|
|
||||||
uint32 entryIndex = mBuckets[i];
|
size_t entryIndex = mBuckets[i];
|
||||||
while(entryIndex != INVALID_INDEX) {
|
while(entryIndex != INVALID_INDEX) {
|
||||||
|
|
||||||
// Copy the entry to the new location and destroy the previous one
|
// Copy the entry to the new location and destroy the previous one
|
||||||
|
@ -257,7 +257,7 @@ class Map {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocate memory for a given number of elements
|
/// Allocate memory for a given number of elements
|
||||||
void reserve(uint32 capacity) {
|
void reserve(size_t capacity) {
|
||||||
|
|
||||||
if (capacity <= mHashSize) return;
|
if (capacity <= mHashSize) return;
|
||||||
|
|
||||||
|
@ -273,19 +273,19 @@ class Map {
|
||||||
assert(capacity > mHashSize);
|
assert(capacity > mHashSize);
|
||||||
|
|
||||||
// Allocate memory for the buckets
|
// Allocate memory for the buckets
|
||||||
uint32* newBuckets = static_cast<uint32*>(mAllocator.allocate(capacity * sizeof(uint32)));
|
size_t* newBuckets = static_cast<size_t*>(mAllocator.allocate(capacity * sizeof(size_t)));
|
||||||
|
|
||||||
// Allocate memory for the entries
|
// Allocate memory for the entries
|
||||||
const uint32 nbAllocatedEntries = static_cast<uint32>(capacity * DEFAULT_LOAD_FACTOR);
|
const size_t nbAllocatedEntries = static_cast<size_t>(capacity * DEFAULT_LOAD_FACTOR);
|
||||||
assert(nbAllocatedEntries > 0);
|
assert(nbAllocatedEntries > 0);
|
||||||
Pair<K, V>* newEntries = static_cast<Pair<K, V>*>(mAllocator.allocate(nbAllocatedEntries * sizeof(Pair<K, V>)));
|
Pair<K, V>* newEntries = static_cast<Pair<K, V>*>(mAllocator.allocate(nbAllocatedEntries * sizeof(Pair<K, V>)));
|
||||||
uint32* newNextEntries = static_cast<uint32*>(mAllocator.allocate(nbAllocatedEntries * sizeof(uint32)));
|
size_t* newNextEntries = static_cast<size_t*>(mAllocator.allocate(nbAllocatedEntries * sizeof(size_t)));
|
||||||
|
|
||||||
assert(newEntries != nullptr);
|
assert(newEntries != nullptr);
|
||||||
assert(newNextEntries != nullptr);
|
assert(newNextEntries != nullptr);
|
||||||
|
|
||||||
// Initialize the new buckets
|
// Initialize the new buckets
|
||||||
for (uint32 i=0; i<capacity; i++) {
|
for (size_t i=0; i<capacity; i++) {
|
||||||
newBuckets[i] = INVALID_INDEX;
|
newBuckets[i] = INVALID_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,19 +294,19 @@ class Map {
|
||||||
assert(mNextEntries != nullptr);
|
assert(mNextEntries != nullptr);
|
||||||
|
|
||||||
// Copy the free nodes indices in the nextEntries array
|
// Copy the free nodes indices in the nextEntries array
|
||||||
std::memcpy(newNextEntries, mNextEntries, mNbAllocatedEntries * sizeof(uint32));
|
std::memcpy(newNextEntries, mNextEntries, mNbAllocatedEntries * sizeof(size_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recompute the buckets (hash) with the new hash size
|
// Recompute the buckets (hash) with the new hash size
|
||||||
for (uint32 i=0; i<mHashSize; i++) {
|
for (size_t i=0; i<mHashSize; i++) {
|
||||||
|
|
||||||
uint32 entryIndex = mBuckets[i];
|
size_t entryIndex = mBuckets[i];
|
||||||
while(entryIndex != INVALID_INDEX) {
|
while(entryIndex != INVALID_INDEX) {
|
||||||
|
|
||||||
// Get the corresponding bucket
|
// Get the corresponding bucket
|
||||||
const size_t hashCode = Hash()(mEntries[entryIndex].first);
|
const size_t hashCode = Hash()(mEntries[entryIndex].first);
|
||||||
const size_t divider = capacity - 1;
|
const size_t divider = capacity - 1;
|
||||||
const uint32 bucketIndex = static_cast<uint32>(hashCode & divider);
|
const size_t bucketIndex = hashCode & divider;
|
||||||
|
|
||||||
newNextEntries[entryIndex] = newBuckets[bucketIndex];
|
newNextEntries[entryIndex] = newBuckets[bucketIndex];
|
||||||
newBuckets[bucketIndex] = entryIndex;
|
newBuckets[bucketIndex] = entryIndex;
|
||||||
|
@ -322,13 +322,13 @@ class Map {
|
||||||
if (mNbAllocatedEntries > 0) {
|
if (mNbAllocatedEntries > 0) {
|
||||||
|
|
||||||
// Release previously allocated memory
|
// Release previously allocated memory
|
||||||
mAllocator.release(mBuckets, mHashSize * sizeof(uint32));
|
mAllocator.release(mBuckets, mHashSize * sizeof(size_t));
|
||||||
mAllocator.release(mEntries, mNbAllocatedEntries * sizeof(Pair<K, V>));
|
mAllocator.release(mEntries, mNbAllocatedEntries * sizeof(Pair<K, V>));
|
||||||
mAllocator.release(mNextEntries, mNbAllocatedEntries * sizeof(uint32));
|
mAllocator.release(mNextEntries, mNbAllocatedEntries * sizeof(size_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the new entries to the free list
|
// Add the new entries to the free list
|
||||||
for (uint32 i=mNbAllocatedEntries; i < nbAllocatedEntries-1; i++) {
|
for (size_t i=mNbAllocatedEntries; i < nbAllocatedEntries-1; i++) {
|
||||||
newNextEntries[i] = i + 1;
|
newNextEntries[i] = i + 1;
|
||||||
}
|
}
|
||||||
newNextEntries[nbAllocatedEntries - 1] = mFreeIndex;
|
newNextEntries[nbAllocatedEntries - 1] = mFreeIndex;
|
||||||
|
@ -352,7 +352,7 @@ class Map {
|
||||||
/// Returns true if the item has been inserted and false otherwise.
|
/// Returns true if the item has been inserted and false otherwise.
|
||||||
bool add(const Pair<K,V>& keyValue, bool insertIfAlreadyPresent = false) {
|
bool add(const Pair<K,V>& keyValue, bool insertIfAlreadyPresent = false) {
|
||||||
|
|
||||||
uint32 bucket = INVALID_INDEX;
|
size_t bucket = INVALID_INDEX;
|
||||||
|
|
||||||
// Compute the hash code of the value
|
// Compute the hash code of the value
|
||||||
const size_t hashCode = Hash()(keyValue.first);
|
const size_t hashCode = Hash()(keyValue.first);
|
||||||
|
@ -361,12 +361,12 @@ class Map {
|
||||||
|
|
||||||
// Compute the corresponding bucket index
|
// Compute the corresponding bucket index
|
||||||
const size_t divider = mHashSize - 1;
|
const size_t divider = mHashSize - 1;
|
||||||
bucket = static_cast<uint32>(hashCode & divider);
|
bucket = hashCode & divider;
|
||||||
|
|
||||||
auto keyEqual = KeyEqual();
|
auto keyEqual = KeyEqual();
|
||||||
|
|
||||||
// Check if the item is already in the set
|
// Check if the item is already in the set
|
||||||
for (uint32 i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
|
for (size_t i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
|
||||||
|
|
||||||
// If there is already an item with the same value in the set
|
// If there is already an item with the same value in the set
|
||||||
if (Hash()(mEntries[i].first) == hashCode && keyEqual(mEntries[i].first, keyValue.first)) {
|
if (Hash()(mEntries[i].first) == hashCode && keyEqual(mEntries[i].first, keyValue.first)) {
|
||||||
|
@ -389,7 +389,7 @@ class Map {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 entryIndex;
|
size_t entryIndex;
|
||||||
|
|
||||||
// If there are no more free entries to use
|
// If there are no more free entries to use
|
||||||
if (mFreeIndex == INVALID_INDEX) {
|
if (mFreeIndex == INVALID_INDEX) {
|
||||||
|
@ -399,7 +399,7 @@ class Map {
|
||||||
|
|
||||||
// Recompute the bucket index
|
// Recompute the bucket index
|
||||||
const size_t divider = mHashSize - 1;
|
const size_t divider = mHashSize - 1;
|
||||||
bucket = static_cast<uint32>(hashCode & divider);
|
bucket = hashCode & divider;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(mNbEntries < mNbAllocatedEntries);
|
assert(mNbEntries < mNbAllocatedEntries);
|
||||||
|
@ -438,9 +438,9 @@ class Map {
|
||||||
const size_t hashcode = Hash()(key);
|
const size_t hashcode = Hash()(key);
|
||||||
auto keyEqual = KeyEqual();
|
auto keyEqual = KeyEqual();
|
||||||
const size_t divider = mHashSize - 1;
|
const size_t divider = mHashSize - 1;
|
||||||
const uint32 bucket = static_cast<uint32>(hashcode & divider);
|
const size_t bucket = hashcode & divider;
|
||||||
uint32 last = INVALID_INDEX;
|
size_t last = INVALID_INDEX;
|
||||||
for (uint32 i = mBuckets[bucket]; i != INVALID_INDEX; last = i, i = mNextEntries[i]) {
|
for (size_t i = mBuckets[bucket]; i != INVALID_INDEX; last = i, i = mNextEntries[i]) {
|
||||||
|
|
||||||
// If we have found the item
|
// If we have found the item
|
||||||
if (Hash()(mEntries[i].first) == hashcode && keyEqual(mEntries[i].first, key)) {
|
if (Hash()(mEntries[i].first) == hashcode && keyEqual(mEntries[i].first, key)) {
|
||||||
|
@ -452,8 +452,8 @@ class Map {
|
||||||
mNextEntries[last] = mNextEntries[i];
|
mNextEntries[last] = mNextEntries[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 nextEntryIndex = mNextEntries[i];
|
size_t nextEntryIndex = mNextEntries[i];
|
||||||
uint32 nextBucketIndex = bucket;
|
size_t nextBucketIndex = bucket;
|
||||||
|
|
||||||
mEntries[i].~Pair<K,V>();
|
mEntries[i].~Pair<K,V>();
|
||||||
mNextEntries[i] = mFreeIndex;
|
mNextEntries[i] = mFreeIndex;
|
||||||
|
@ -484,15 +484,15 @@ class Map {
|
||||||
/// Clear the map
|
/// Clear the map
|
||||||
void clear(bool releaseMemory = false) {
|
void clear(bool releaseMemory = false) {
|
||||||
|
|
||||||
for (uint32 i=0; i<mHashSize; i++) {
|
for (size_t i=0; i<mHashSize; i++) {
|
||||||
|
|
||||||
uint32 entryIndex = mBuckets[i];
|
size_t entryIndex = mBuckets[i];
|
||||||
while(entryIndex != INVALID_INDEX) {
|
while(entryIndex != INVALID_INDEX) {
|
||||||
|
|
||||||
// Destroy the entry
|
// Destroy the entry
|
||||||
mEntries[entryIndex].~Pair<K,V>();
|
mEntries[entryIndex].~Pair<K,V>();
|
||||||
|
|
||||||
uint32 nextEntryIndex = mNextEntries[entryIndex];
|
size_t nextEntryIndex = mNextEntries[entryIndex];
|
||||||
|
|
||||||
// Add entry to the free list
|
// Add entry to the free list
|
||||||
mNextEntries[entryIndex] = mFreeIndex;
|
mNextEntries[entryIndex] = mFreeIndex;
|
||||||
|
@ -507,9 +507,9 @@ class Map {
|
||||||
if (releaseMemory && mNbAllocatedEntries > 0) {
|
if (releaseMemory && mNbAllocatedEntries > 0) {
|
||||||
|
|
||||||
// Release previously allocated memory
|
// Release previously allocated memory
|
||||||
mAllocator.release(mBuckets, mHashSize * sizeof(uint32));
|
mAllocator.release(mBuckets, mHashSize * sizeof(size_t));
|
||||||
mAllocator.release(mEntries, mNbAllocatedEntries * sizeof(Pair<K, V>));
|
mAllocator.release(mEntries, mNbAllocatedEntries * sizeof(Pair<K, V>));
|
||||||
mAllocator.release(mNextEntries, mNbAllocatedEntries * sizeof(uint32));
|
mAllocator.release(mNextEntries, mNbAllocatedEntries * sizeof(size_t));
|
||||||
|
|
||||||
mBuckets = nullptr;
|
mBuckets = nullptr;
|
||||||
mEntries = nullptr;
|
mEntries = nullptr;
|
||||||
|
@ -523,12 +523,12 @@ class Map {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the number of elements in the map
|
/// Return the number of elements in the map
|
||||||
uint32 size() const {
|
size_t size() const {
|
||||||
return mNbEntries;
|
return mNbEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the capacity of the map
|
/// Return the capacity of the map
|
||||||
uint32 capacity() const {
|
size_t capacity() const {
|
||||||
return mHashSize;
|
return mHashSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -537,17 +537,17 @@ class Map {
|
||||||
/// an iterator pointing to the end if not found
|
/// an iterator pointing to the end if not found
|
||||||
Iterator find(const K& key) const {
|
Iterator find(const K& key) const {
|
||||||
|
|
||||||
uint32 bucket;
|
size_t bucket;
|
||||||
uint32 entry = INVALID_INDEX;
|
size_t entry = INVALID_INDEX;
|
||||||
|
|
||||||
if (mHashSize > 0) {
|
if (mHashSize > 0) {
|
||||||
|
|
||||||
const size_t hashCode = Hash()(key);
|
const size_t hashCode = Hash()(key);
|
||||||
const size_t divider = mHashSize - 1;
|
const size_t divider = mHashSize - 1;
|
||||||
bucket = static_cast<uint32>(hashCode & divider);
|
bucket = hashCode & divider;
|
||||||
auto keyEqual = KeyEqual();
|
auto keyEqual = KeyEqual();
|
||||||
|
|
||||||
for (uint32 i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
|
for (size_t i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
|
||||||
if (Hash()(mEntries[i].first) == hashCode && keyEqual(mEntries[i].first, key)) {
|
if (Hash()(mEntries[i].first) == hashCode && keyEqual(mEntries[i].first, key)) {
|
||||||
entry = i;
|
entry = i;
|
||||||
break;
|
break;
|
||||||
|
@ -565,7 +565,7 @@ class Map {
|
||||||
/// Overloaded index operator
|
/// Overloaded index operator
|
||||||
V& operator[](const K& key) {
|
V& operator[](const K& key) {
|
||||||
|
|
||||||
const uint32 entry = findEntry(key);
|
const size_t entry = findEntry(key);
|
||||||
|
|
||||||
if (entry == INVALID_INDEX) {
|
if (entry == INVALID_INDEX) {
|
||||||
assert(false);
|
assert(false);
|
||||||
|
@ -578,7 +578,7 @@ class Map {
|
||||||
/// Overloaded index operator
|
/// Overloaded index operator
|
||||||
const V& operator[](const K& key) const {
|
const V& operator[](const K& key) const {
|
||||||
|
|
||||||
const uint32 entry = findEntry(key);
|
const size_t entry = findEntry(key);
|
||||||
|
|
||||||
if (entry == INVALID_INDEX) {
|
if (entry == INVALID_INDEX) {
|
||||||
assert(false);
|
assert(false);
|
||||||
|
@ -633,22 +633,22 @@ class Map {
|
||||||
if (mHashSize > 0) {
|
if (mHashSize > 0) {
|
||||||
|
|
||||||
// Allocate memory for the buckets
|
// Allocate memory for the buckets
|
||||||
mBuckets = static_cast<uint32*>(mAllocator.allocate(mHashSize * sizeof(uint32)));
|
mBuckets = static_cast<size_t*>(mAllocator.allocate(mHashSize * sizeof(size_t)));
|
||||||
|
|
||||||
// Allocate memory for the entries
|
// Allocate memory for the entries
|
||||||
mEntries = static_cast<Pair<K,V>*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(Pair<K,V>)));
|
mEntries = static_cast<Pair<K,V>*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(Pair<K,V>)));
|
||||||
mNextEntries = static_cast<uint32*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(uint32)));
|
mNextEntries = static_cast<size_t*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(size_t)));
|
||||||
|
|
||||||
// Copy the buckets array
|
// Copy the buckets array
|
||||||
std::memcpy(mBuckets, map.mBuckets, mHashSize * sizeof(uint32));
|
std::memcpy(mBuckets, map.mBuckets, mHashSize * sizeof(size_t));
|
||||||
|
|
||||||
// Copy the next entries indices
|
// Copy the next entries indices
|
||||||
std::memcpy(mNextEntries, map.mNextEntries, mNbAllocatedEntries * sizeof(uint32));
|
std::memcpy(mNextEntries, map.mNextEntries, mNbAllocatedEntries * sizeof(size_t));
|
||||||
|
|
||||||
// Copy the entries
|
// Copy the entries
|
||||||
for (uint32 i=0; i<mHashSize; i++) {
|
for (size_t i=0; i<mHashSize; i++) {
|
||||||
|
|
||||||
uint32 entryIndex = mBuckets[i];
|
size_t entryIndex = mBuckets[i];
|
||||||
while(entryIndex != INVALID_INDEX) {
|
while(entryIndex != INVALID_INDEX) {
|
||||||
|
|
||||||
// Copy the entry to the new location and destroy the previous one
|
// Copy the entry to the new location and destroy the previous one
|
||||||
|
@ -674,7 +674,7 @@ class Map {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the first used entry
|
// Find the first used entry
|
||||||
uint32 bucketIndex = 0;
|
size_t bucketIndex = 0;
|
||||||
while (mBuckets[bucketIndex] == INVALID_INDEX) {
|
while (mBuckets[bucketIndex] == INVALID_INDEX) {
|
||||||
|
|
||||||
bucketIndex++;
|
bucketIndex++;
|
||||||
|
|
|
@ -52,47 +52,47 @@ class Set {
|
||||||
static constexpr float DEFAULT_LOAD_FACTOR = 0.75;
|
static constexpr float DEFAULT_LOAD_FACTOR = 0.75;
|
||||||
|
|
||||||
/// Invalid index in the array
|
/// Invalid index in the array
|
||||||
static constexpr uint32 INVALID_INDEX = 0xffffffff;
|
static constexpr size_t INVALID_INDEX = -1;
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
/// Total number of allocated entries
|
/// Total number of allocated entries
|
||||||
uint32 mNbAllocatedEntries;
|
size_t mNbAllocatedEntries;
|
||||||
|
|
||||||
/// Number of items in the set
|
/// Number of items in the set
|
||||||
uint32 mNbEntries;
|
size_t mNbEntries;
|
||||||
|
|
||||||
/// Number of buckets and size of the hash table (nbEntries = loadFactor * mHashSize)
|
/// Number of buckets and size of the hash table (nbEntries = loadFactor * mHashSize)
|
||||||
uint32 mHashSize ;
|
size_t mHashSize ;
|
||||||
|
|
||||||
/// Array with all the buckets
|
/// Array with all the buckets
|
||||||
uint32* mBuckets;
|
size_t* mBuckets;
|
||||||
|
|
||||||
/// Array with all the entries (nbEntries = loadFactor * mHashSize)
|
/// Array with all the entries (nbEntries = loadFactor * mHashSize)
|
||||||
V* mEntries;
|
V* mEntries;
|
||||||
|
|
||||||
/// For each entry, index of the next entry at the same bucket
|
/// For each entry, index of the next entry at the same bucket
|
||||||
uint32* mNextEntries;
|
size_t* mNextEntries;
|
||||||
|
|
||||||
/// Memory allocator
|
/// Memory allocator
|
||||||
MemoryAllocator& mAllocator;
|
MemoryAllocator& mAllocator;
|
||||||
|
|
||||||
/// Index to the fist free entry
|
/// Index to the fist free entry
|
||||||
uint32 mFreeIndex;
|
size_t mFreeIndex;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Return the index of the entry with a given value or -1 if there is no entry with this value
|
/// Return the index of the entry with a given value or -1 if there is no entry with this value
|
||||||
uint32 findEntry(const V& value) const {
|
size_t findEntry(const V& value) const {
|
||||||
|
|
||||||
if (mHashSize > 0) {
|
if (mHashSize > 0) {
|
||||||
|
|
||||||
const size_t hashCode = Hash()(value);
|
const size_t hashCode = Hash()(value);
|
||||||
const size_t divider = mHashSize - 1;
|
const size_t divider = mHashSize - 1;
|
||||||
const uint32 bucket = static_cast<uint32>(hashCode & divider);
|
const size_t bucket = hashCode & divider;
|
||||||
auto keyEqual = KeyEqual();
|
auto keyEqual = KeyEqual();
|
||||||
|
|
||||||
for (uint32 i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
|
for (size_t i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
|
||||||
if (Hash()(mEntries[i]) == hashCode && keyEqual(mEntries[i], value)) {
|
if (Hash()(mEntries[i]) == hashCode && keyEqual(mEntries[i], value)) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -116,10 +116,10 @@ class Set {
|
||||||
const Set* mSet;
|
const Set* mSet;
|
||||||
|
|
||||||
/// Index of the current bucket
|
/// Index of the current bucket
|
||||||
uint32 mCurrentBucketIndex;
|
size_t mCurrentBucketIndex;
|
||||||
|
|
||||||
/// Index of the current entry
|
/// Index of the current entry
|
||||||
uint32 mCurrentEntryIndex;
|
size_t mCurrentEntryIndex;
|
||||||
|
|
||||||
/// Advance the iterator
|
/// Advance the iterator
|
||||||
void advance() {
|
void advance() {
|
||||||
|
@ -157,7 +157,7 @@ class Set {
|
||||||
Iterator() = default;
|
Iterator() = default;
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
Iterator(const Set* set, uint32 bucketIndex, uint32 entryIndex)
|
Iterator(const Set* set, size_t bucketIndex, size_t entryIndex)
|
||||||
:mSet(set), mCurrentBucketIndex(bucketIndex), mCurrentEntryIndex(entryIndex) {
|
:mSet(set), mCurrentBucketIndex(bucketIndex), mCurrentEntryIndex(entryIndex) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -204,7 +204,7 @@ class Set {
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
Set(MemoryAllocator& allocator, uint32 capacity = 0)
|
Set(MemoryAllocator& allocator, size_t capacity = 0)
|
||||||
: mNbAllocatedEntries(0), mNbEntries(0), mHashSize(0), mBuckets(nullptr),
|
: mNbAllocatedEntries(0), mNbEntries(0), mHashSize(0), mBuckets(nullptr),
|
||||||
mEntries(nullptr), mNextEntries(nullptr), mAllocator(allocator), mFreeIndex(INVALID_INDEX) {
|
mEntries(nullptr), mNextEntries(nullptr), mAllocator(allocator), mFreeIndex(INVALID_INDEX) {
|
||||||
|
|
||||||
|
@ -222,22 +222,22 @@ class Set {
|
||||||
if (mHashSize > 0) {
|
if (mHashSize > 0) {
|
||||||
|
|
||||||
// Allocate memory for the buckets
|
// Allocate memory for the buckets
|
||||||
mBuckets = static_cast<uint32*>(mAllocator.allocate(mHashSize * sizeof(uint32)));
|
mBuckets = static_cast<size_t*>(mAllocator.allocate(mHashSize * sizeof(size_t)));
|
||||||
|
|
||||||
// Allocate memory for the entries
|
// Allocate memory for the entries
|
||||||
mEntries = static_cast<V*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(V)));
|
mEntries = static_cast<V*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(V)));
|
||||||
mNextEntries = static_cast<uint32*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(uint32)));
|
mNextEntries = static_cast<size_t*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(size_t)));
|
||||||
|
|
||||||
// Copy the buckets array
|
// Copy the buckets array
|
||||||
std::memcpy(mBuckets, set.mBuckets, mHashSize * sizeof(uint32));
|
std::memcpy(mBuckets, set.mBuckets, mHashSize * sizeof(size_t));
|
||||||
|
|
||||||
// Copy the next entries indices
|
// Copy the next entries indices
|
||||||
std::memcpy(mNextEntries, set.mNextEntries, mNbAllocatedEntries * sizeof(uint32));
|
std::memcpy(mNextEntries, set.mNextEntries, mNbAllocatedEntries * sizeof(size_t));
|
||||||
|
|
||||||
// Copy the entries
|
// Copy the entries
|
||||||
for (uint32 i=0; i<mHashSize; i++) {
|
for (size_t i=0; i<mHashSize; i++) {
|
||||||
|
|
||||||
uint32 entryIndex = mBuckets[i];
|
size_t entryIndex = mBuckets[i];
|
||||||
while(entryIndex != INVALID_INDEX) {
|
while(entryIndex != INVALID_INDEX) {
|
||||||
|
|
||||||
// Copy the entry to the new location and destroy the previous one
|
// Copy the entry to the new location and destroy the previous one
|
||||||
|
@ -256,7 +256,7 @@ class Set {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocate memory for a given number of elements
|
/// Allocate memory for a given number of elements
|
||||||
void reserve(uint32 capacity) {
|
void reserve(size_t capacity) {
|
||||||
|
|
||||||
if (capacity <= mHashSize) return;
|
if (capacity <= mHashSize) return;
|
||||||
|
|
||||||
|
@ -272,19 +272,19 @@ class Set {
|
||||||
assert(capacity > mHashSize);
|
assert(capacity > mHashSize);
|
||||||
|
|
||||||
// Allocate memory for the buckets
|
// Allocate memory for the buckets
|
||||||
uint32* newBuckets = static_cast<uint32*>(mAllocator.allocate(capacity * sizeof(uint32)));
|
size_t* newBuckets = static_cast<size_t*>(mAllocator.allocate(capacity * sizeof(size_t)));
|
||||||
|
|
||||||
// Allocate memory for the entries
|
// Allocate memory for the entries
|
||||||
const uint32 nbAllocatedEntries = static_cast<uint32>(capacity * DEFAULT_LOAD_FACTOR);
|
const size_t nbAllocatedEntries = static_cast<size_t>(capacity * DEFAULT_LOAD_FACTOR);
|
||||||
assert(nbAllocatedEntries > 0);
|
assert(nbAllocatedEntries > 0);
|
||||||
V* newEntries = static_cast<V*>(mAllocator.allocate(nbAllocatedEntries * sizeof(V)));
|
V* newEntries = static_cast<V*>(mAllocator.allocate(nbAllocatedEntries * sizeof(V)));
|
||||||
uint32* newNextEntries = static_cast<uint32*>(mAllocator.allocate(nbAllocatedEntries * sizeof(uint32)));
|
size_t* newNextEntries = static_cast<size_t*>(mAllocator.allocate(nbAllocatedEntries * sizeof(size_t)));
|
||||||
|
|
||||||
assert(newEntries != nullptr);
|
assert(newEntries != nullptr);
|
||||||
assert(newNextEntries != nullptr);
|
assert(newNextEntries != nullptr);
|
||||||
|
|
||||||
// Initialize the new buckets
|
// Initialize the new buckets
|
||||||
for (uint32 i=0; i<capacity; i++) {
|
for (size_t i=0; i<capacity; i++) {
|
||||||
newBuckets[i] = INVALID_INDEX;
|
newBuckets[i] = INVALID_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,19 +293,19 @@ class Set {
|
||||||
assert(mNextEntries != nullptr);
|
assert(mNextEntries != nullptr);
|
||||||
|
|
||||||
// Copy the free nodes indices in the nextEntries array
|
// Copy the free nodes indices in the nextEntries array
|
||||||
std::memcpy(newNextEntries, mNextEntries, mNbAllocatedEntries * sizeof(uint32));
|
std::memcpy(newNextEntries, mNextEntries, mNbAllocatedEntries * sizeof(size_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recompute the buckets (hash) with the new hash size
|
// Recompute the buckets (hash) with the new hash size
|
||||||
for (uint32 i=0; i<mHashSize; i++) {
|
for (size_t i=0; i<mHashSize; i++) {
|
||||||
|
|
||||||
uint32 entryIndex = mBuckets[i];
|
size_t entryIndex = mBuckets[i];
|
||||||
while(entryIndex != INVALID_INDEX) {
|
while(entryIndex != INVALID_INDEX) {
|
||||||
|
|
||||||
// Get the corresponding bucket
|
// Get the corresponding bucket
|
||||||
const size_t hashCode = Hash()(mEntries[entryIndex]);
|
const size_t hashCode = Hash()(mEntries[entryIndex]);
|
||||||
const size_t divider = capacity - 1;
|
const size_t divider = capacity - 1;
|
||||||
const uint32 bucketIndex = static_cast<uint32>(hashCode & divider);
|
const size_t bucketIndex = hashCode & divider;
|
||||||
|
|
||||||
newNextEntries[entryIndex] = newBuckets[bucketIndex];
|
newNextEntries[entryIndex] = newBuckets[bucketIndex];
|
||||||
newBuckets[bucketIndex] = entryIndex;
|
newBuckets[bucketIndex] = entryIndex;
|
||||||
|
@ -321,13 +321,13 @@ class Set {
|
||||||
if (mNbAllocatedEntries > 0) {
|
if (mNbAllocatedEntries > 0) {
|
||||||
|
|
||||||
// Release previously allocated memory
|
// Release previously allocated memory
|
||||||
mAllocator.release(mBuckets, mHashSize * sizeof(uint32));
|
mAllocator.release(mBuckets, mHashSize * sizeof(size_t));
|
||||||
mAllocator.release(mEntries, mNbAllocatedEntries * sizeof(V));
|
mAllocator.release(mEntries, mNbAllocatedEntries * sizeof(V));
|
||||||
mAllocator.release(mNextEntries, mNbAllocatedEntries * sizeof(uint32));
|
mAllocator.release(mNextEntries, mNbAllocatedEntries * sizeof(size_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the new entries to the free list
|
// Add the new entries to the free list
|
||||||
for (uint32 i=mNbAllocatedEntries; i < nbAllocatedEntries-1; i++) {
|
for (size_t i=mNbAllocatedEntries; i < nbAllocatedEntries-1; i++) {
|
||||||
newNextEntries[i] = i + 1;
|
newNextEntries[i] = i + 1;
|
||||||
}
|
}
|
||||||
newNextEntries[nbAllocatedEntries - 1] = mFreeIndex;
|
newNextEntries[nbAllocatedEntries - 1] = mFreeIndex;
|
||||||
|
@ -351,7 +351,7 @@ class Set {
|
||||||
/// Returns true if the item has been inserted and false otherwise.
|
/// Returns true if the item has been inserted and false otherwise.
|
||||||
bool add(const V& value) {
|
bool add(const V& value) {
|
||||||
|
|
||||||
uint32 bucket;
|
size_t bucket;
|
||||||
|
|
||||||
// Compute the hash code of the value
|
// Compute the hash code of the value
|
||||||
const size_t hashCode = Hash()(value);
|
const size_t hashCode = Hash()(value);
|
||||||
|
@ -360,12 +360,12 @@ class Set {
|
||||||
|
|
||||||
// Compute the corresponding bucket index
|
// Compute the corresponding bucket index
|
||||||
const size_t divider = mHashSize - 1;
|
const size_t divider = mHashSize - 1;
|
||||||
bucket = static_cast<uint32>(hashCode & divider);
|
bucket = hashCode & divider;
|
||||||
|
|
||||||
auto keyEqual = KeyEqual();
|
auto keyEqual = KeyEqual();
|
||||||
|
|
||||||
// Check if the item is already in the set
|
// Check if the item is already in the set
|
||||||
for (uint32 i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
|
for (size_t i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
|
||||||
|
|
||||||
// If there is already an item with the same value in the set
|
// If there is already an item with the same value in the set
|
||||||
if (Hash()(mEntries[i]) == hashCode && keyEqual(mEntries[i], value)) {
|
if (Hash()(mEntries[i]) == hashCode && keyEqual(mEntries[i], value)) {
|
||||||
|
@ -375,7 +375,7 @@ class Set {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 entryIndex;
|
size_t entryIndex;
|
||||||
|
|
||||||
// If there are no more free entries to use
|
// If there are no more free entries to use
|
||||||
if (mFreeIndex == INVALID_INDEX) {
|
if (mFreeIndex == INVALID_INDEX) {
|
||||||
|
@ -385,7 +385,7 @@ class Set {
|
||||||
|
|
||||||
// Recompute the bucket index
|
// Recompute the bucket index
|
||||||
const size_t divider = mHashSize - 1;
|
const size_t divider = mHashSize - 1;
|
||||||
bucket = static_cast<uint32>(hashCode & divider);
|
bucket = hashCode & divider;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(mNbEntries < mNbAllocatedEntries);
|
assert(mNbEntries < mNbAllocatedEntries);
|
||||||
|
@ -422,9 +422,9 @@ class Set {
|
||||||
const size_t hashcode = Hash()(value);
|
const size_t hashcode = Hash()(value);
|
||||||
auto keyEqual = KeyEqual();
|
auto keyEqual = KeyEqual();
|
||||||
const size_t divider = mHashSize - 1;
|
const size_t divider = mHashSize - 1;
|
||||||
const uint32 bucket = static_cast<uint32>(hashcode & divider);
|
const size_t bucket = hashcode & divider;
|
||||||
uint32 last = INVALID_INDEX;
|
size_t last = INVALID_INDEX;
|
||||||
for (uint32 i = mBuckets[bucket]; i != INVALID_INDEX; last = i, i = mNextEntries[i]) {
|
for (size_t i = mBuckets[bucket]; i != INVALID_INDEX; last = i, i = mNextEntries[i]) {
|
||||||
|
|
||||||
// If we have found the item
|
// If we have found the item
|
||||||
if (Hash()(mEntries[i]) == hashcode && keyEqual(mEntries[i], value)) {
|
if (Hash()(mEntries[i]) == hashcode && keyEqual(mEntries[i], value)) {
|
||||||
|
@ -436,8 +436,8 @@ class Set {
|
||||||
mNextEntries[last] = mNextEntries[i];
|
mNextEntries[last] = mNextEntries[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 nextEntryIndex = mNextEntries[i];
|
size_t nextEntryIndex = mNextEntries[i];
|
||||||
uint32 nextBucketIndex = bucket;
|
size_t nextBucketIndex = bucket;
|
||||||
|
|
||||||
mEntries[i].~V();
|
mEntries[i].~V();
|
||||||
mNextEntries[i] = mFreeIndex;
|
mNextEntries[i] = mFreeIndex;
|
||||||
|
@ -480,15 +480,15 @@ class Set {
|
||||||
/// Clear the set
|
/// Clear the set
|
||||||
void clear(bool releaseMemory = false) {
|
void clear(bool releaseMemory = false) {
|
||||||
|
|
||||||
for (uint32 i=0; i<mHashSize; i++) {
|
for (size_t i=0; i<mHashSize; i++) {
|
||||||
|
|
||||||
uint32 entryIndex = mBuckets[i];
|
size_t entryIndex = mBuckets[i];
|
||||||
while(entryIndex != INVALID_INDEX) {
|
while(entryIndex != INVALID_INDEX) {
|
||||||
|
|
||||||
// Destroy the entry
|
// Destroy the entry
|
||||||
mEntries[entryIndex].~V();
|
mEntries[entryIndex].~V();
|
||||||
|
|
||||||
uint32 nextEntryIndex = mNextEntries[entryIndex];
|
size_t nextEntryIndex = mNextEntries[entryIndex];
|
||||||
|
|
||||||
// Add entry to the free list
|
// Add entry to the free list
|
||||||
mNextEntries[entryIndex] = mFreeIndex;
|
mNextEntries[entryIndex] = mFreeIndex;
|
||||||
|
@ -503,9 +503,9 @@ class Set {
|
||||||
if (releaseMemory && mNbAllocatedEntries > 0) {
|
if (releaseMemory && mNbAllocatedEntries > 0) {
|
||||||
|
|
||||||
// Release previously allocated memory
|
// Release previously allocated memory
|
||||||
mAllocator.release(mBuckets, mHashSize * sizeof(uint32));
|
mAllocator.release(mBuckets, mHashSize * sizeof(size_t));
|
||||||
mAllocator.release(mEntries, mNbAllocatedEntries * sizeof(V));
|
mAllocator.release(mEntries, mNbAllocatedEntries * sizeof(V));
|
||||||
mAllocator.release(mNextEntries, mNbAllocatedEntries * sizeof(uint32));
|
mAllocator.release(mNextEntries, mNbAllocatedEntries * sizeof(size_t));
|
||||||
|
|
||||||
mBuckets = nullptr;
|
mBuckets = nullptr;
|
||||||
mEntries = nullptr;
|
mEntries = nullptr;
|
||||||
|
@ -519,12 +519,12 @@ class Set {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the number of elements in the set
|
/// Return the number of elements in the set
|
||||||
uint32 size() const {
|
size_t size() const {
|
||||||
return mNbEntries;
|
return mNbEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the capacity of the set
|
/// Return the capacity of the set
|
||||||
uint32 capacity() const {
|
size_t capacity() const {
|
||||||
return mHashSize;
|
return mHashSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,17 +533,17 @@ class Set {
|
||||||
/// an iterator pointing to the end if not found
|
/// an iterator pointing to the end if not found
|
||||||
Iterator find(const V& value) const {
|
Iterator find(const V& value) const {
|
||||||
|
|
||||||
uint32 bucket;
|
size_t bucket;
|
||||||
uint32 entry = INVALID_INDEX;
|
size_t entry = INVALID_INDEX;
|
||||||
|
|
||||||
if (mHashSize > 0) {
|
if (mHashSize > 0) {
|
||||||
|
|
||||||
const size_t hashCode = Hash()(value);
|
const size_t hashCode = Hash()(value);
|
||||||
const size_t divider = mHashSize - 1;
|
const size_t divider = mHashSize - 1;
|
||||||
bucket = static_cast<uint32>(hashCode & divider);
|
bucket = hashCode & divider;
|
||||||
auto keyEqual = KeyEqual();
|
auto keyEqual = KeyEqual();
|
||||||
|
|
||||||
for (uint32 i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
|
for (size_t i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
|
||||||
if (Hash()(mEntries[i]) == hashCode && keyEqual(mEntries[i], value)) {
|
if (Hash()(mEntries[i]) == hashCode && keyEqual(mEntries[i], value)) {
|
||||||
entry = i;
|
entry = i;
|
||||||
break;
|
break;
|
||||||
|
@ -595,22 +595,22 @@ class Set {
|
||||||
if (mHashSize > 0) {
|
if (mHashSize > 0) {
|
||||||
|
|
||||||
// Allocate memory for the buckets
|
// Allocate memory for the buckets
|
||||||
mBuckets = static_cast<uint32*>(mAllocator.allocate(mHashSize * sizeof(uint32)));
|
mBuckets = static_cast<size_t*>(mAllocator.allocate(mHashSize * sizeof(size_t)));
|
||||||
|
|
||||||
// Allocate memory for the entries
|
// Allocate memory for the entries
|
||||||
mEntries = static_cast<V*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(V)));
|
mEntries = static_cast<V*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(V)));
|
||||||
mNextEntries = static_cast<uint32*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(uint32)));
|
mNextEntries = static_cast<size_t*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(size_t)));
|
||||||
|
|
||||||
// Copy the buckets array
|
// Copy the buckets array
|
||||||
std::memcpy(mBuckets, set.mBuckets, mHashSize * sizeof(uint32));
|
std::memcpy(mBuckets, set.mBuckets, mHashSize * sizeof(size_t));
|
||||||
|
|
||||||
// Copy the next entries indices
|
// Copy the next entries indices
|
||||||
std::memcpy(mNextEntries, set.mNextEntries, mNbAllocatedEntries * sizeof(uint32));
|
std::memcpy(mNextEntries, set.mNextEntries, mNbAllocatedEntries * sizeof(size_t));
|
||||||
|
|
||||||
// Copy the entries
|
// Copy the entries
|
||||||
for (uint32 i=0; i<mHashSize; i++) {
|
for (size_t i=0; i<mHashSize; i++) {
|
||||||
|
|
||||||
uint32 entryIndex = mBuckets[i];
|
size_t entryIndex = mBuckets[i];
|
||||||
while(entryIndex != INVALID_INDEX) {
|
while(entryIndex != INVALID_INDEX) {
|
||||||
|
|
||||||
// Copy the entry to the new location and destroy the previous one
|
// Copy the entry to the new location and destroy the previous one
|
||||||
|
@ -636,7 +636,7 @@ class Set {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the first used entry
|
// Find the first used entry
|
||||||
uint32 bucketIndex = 0;
|
size_t bucketIndex = 0;
|
||||||
while (mBuckets[bucketIndex] == INVALID_INDEX) {
|
while (mBuckets[bucketIndex] == INVALID_INDEX) {
|
||||||
|
|
||||||
bucketIndex++;
|
bucketIndex++;
|
||||||
|
|
|
@ -51,15 +51,15 @@ class Stack {
|
||||||
T* mArray;
|
T* mArray;
|
||||||
|
|
||||||
/// Number of elements in the stack
|
/// Number of elements in the stack
|
||||||
uint32 mNbElements;
|
size_t mNbElements;
|
||||||
|
|
||||||
/// Number of allocated elements in the stack
|
/// Number of allocated elements in the stack
|
||||||
uint32 mCapacity;
|
size_t mCapacity;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Allocate more memory
|
/// Allocate more memory
|
||||||
void allocate(uint32 capacity) {
|
void allocate(size_t capacity) {
|
||||||
|
|
||||||
T* newArray = static_cast<T*>(mAllocator.allocate(capacity * sizeof(T)));
|
T* newArray = static_cast<T*>(mAllocator.allocate(capacity * sizeof(T)));
|
||||||
assert(newArray != nullptr);
|
assert(newArray != nullptr);
|
||||||
|
@ -87,7 +87,7 @@ class Stack {
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
Stack(MemoryAllocator& allocator, uint32 capacity = 0)
|
Stack(MemoryAllocator& allocator, size_t capacity = 0)
|
||||||
:mAllocator(allocator), mArray(nullptr), mNbElements(0), mCapacity(0) {
|
:mAllocator(allocator), mArray(nullptr), mNbElements(0), mCapacity(0) {
|
||||||
|
|
||||||
if (capacity > 0) {
|
if (capacity > 0) {
|
||||||
|
@ -130,7 +130,7 @@ class Stack {
|
||||||
void clear() {
|
void clear() {
|
||||||
|
|
||||||
// Destruct the items
|
// Destruct the items
|
||||||
for (uint32 i = 0; i < mNbElements; i++) {
|
for (size_t i = 0; i < mNbElements; i++) {
|
||||||
mArray[i].~T();
|
mArray[i].~T();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,12 +169,12 @@ class Stack {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the number of items in the stack
|
/// Return the number of items in the stack
|
||||||
uint32 size() const {
|
size_t size() const {
|
||||||
return mNbElements;
|
return mNbElements;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the capacity of the stack
|
/// Return the capacity of the stack
|
||||||
uint32 capacity() const {
|
size_t capacity() const {
|
||||||
return mCapacity;
|
return mCapacity;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user