Replace size_t size of containers by uint64

This commit is contained in:
Daniel Chappuis 2021-11-09 17:11:51 +01:00
parent a33a10440c
commit b9f123ff8a
7 changed files with 195 additions and 194 deletions

View File

@ -51,10 +51,10 @@ class Array {
T* mBuffer;
/// Number of elements in the array
size_t mSize;
uint64 mSize;
/// Number of allocated elements in the array
size_t mCapacity;
uint64 mCapacity;
/// Memory allocator
MemoryAllocator& mAllocator;
@ -69,9 +69,9 @@ class Array {
private:
size_t mCurrentIndex;
uint64 mCurrentIndex;
T* mBuffer;
size_t mSize;
uint64 mSize;
public:
@ -88,7 +88,7 @@ class Array {
Iterator() = default;
/// Constructor
Iterator(void* buffer, size_t index, size_t size)
Iterator(void* buffer, uint64 index, uint64 size)
:mCurrentIndex(index), mBuffer(static_cast<T*>(buffer)), mSize(size) {
}
@ -213,7 +213,7 @@ class Array {
// -------------------- Methods -------------------- //
/// Constructor
Array(MemoryAllocator& allocator, size_t capacity = 0)
Array(MemoryAllocator& allocator, uint64 capacity = 0)
: mBuffer(nullptr), mSize(0), mCapacity(0), mAllocator(allocator) {
if (capacity > 0) {
@ -247,7 +247,7 @@ class Array {
}
/// Allocate memory for a given number of elements
void reserve(size_t capacity) {
void reserve(uint64 capacity) {
if (capacity <= mCapacity) return;
@ -263,7 +263,7 @@ class Array {
std::uninitialized_copy(mBuffer, mBuffer + mSize, destination);
// Destruct the previous items
for (size_t i=0; i<mSize; i++) {
for (uint64 i=0; i<mSize; i++) {
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
void addWithoutInit(size_t nbElements) {
void addWithoutInit(uint64 nbElements) {
// If we need to allocate more memory
if ((mSize + nbElements) > mCapacity) {
@ -323,7 +323,7 @@ class Array {
/// this method returns the end() iterator
Iterator find(const T& element) {
for (size_t i=0; i<mSize; i++) {
for (uint64 i=0; i<mSize; i++) {
if (element == mBuffer[i]) {
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)
Iterator removeAt(size_t index) {
Iterator removeAt(uint64 index) {
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)
void removeAtAndReplaceByLast(size_t index) {
void removeAtAndReplaceByLast(uint64 index) {
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)
/// Append another array at the end of the current one
void addRange(const Array<T>& array, size_t startIndex = 0) {
void addRange(const Array<T>& array, uint64 startIndex = 0) {
assert(startIndex <= array.size());
@ -393,7 +393,7 @@ class Array {
}
// Add the elements of the array to the current one
for(size_t i=startIndex; i<array.size(); i++) {
for(uint64 i=startIndex; i<array.size(); i++) {
new (reinterpret_cast<void*>(mBuffer + mSize)) T(array[i]);
mSize++;
@ -404,7 +404,7 @@ class Array {
void clear(bool releaseMemory = false) {
// Call the destructor of each element
for (size_t i=0; i < mSize; i++) {
for (uint64 i=0; i < mSize; i++) {
mBuffer[i].~T();
}
@ -422,23 +422,23 @@ class Array {
}
/// Return the number of elements in the array
size_t size() const {
uint64 size() const {
return mSize;
}
/// Return the capacity of the array
size_t capacity() const {
uint64 capacity() const {
return mCapacity;
}
/// Overloaded index operator
T& operator[](const size_t index) {
T& operator[](const uint64 index) {
assert(index >= 0 && index < mSize);
return mBuffer[index];
}
/// Overloaded const index operator
const T& operator[](const size_t index) const {
const T& operator[](const uint64 index) const {
assert(index >= 0 && index < mSize);
return mBuffer[index];
}
@ -448,7 +448,7 @@ class Array {
if (mSize != array.mSize) return false;
for (size_t i=0; i < mSize; i++) {
for (uint64 i=0; i < mSize; i++) {
if (mBuffer[i] != array[i]) {
return false;
}

View File

@ -55,10 +55,10 @@ class Deque {
// -------------------- Constants -------------------- //
/// Number of items in a chunk
const size_t CHUNK_NB_ITEMS = 17;
const uint64 CHUNK_NB_ITEMS = 17;
/// First item index in a chunk
const size_t CHUNK_FIRST_ITEM_INDEX = CHUNK_NB_ITEMS / 2;
const uint64 CHUNK_FIRST_ITEM_INDEX = CHUNK_NB_ITEMS / 2;
// -------------------- Attributes -------------------- //
@ -66,16 +66,16 @@ class Deque {
T** mChunks;
/// Number of current elements in the deque
size_t mSize;
uint64 mSize;
/// Number of chunks
size_t mNbChunks;
uint64 mNbChunks;
/// Index of the chunk with the first element of the deque
size_t mFirstChunkIndex;
uint64 mFirstChunkIndex;
/// Index of the chunk with the last element of the deque
size_t mLastChunkIndex;
uint64 mLastChunkIndex;
/// Index of the first element in the first chunk
uint8 mFirstItemIndex;
@ -89,15 +89,15 @@ class Deque {
// -------------------- Methods -------------------- //
/// Return a reference to an item at the given virtual index in range [0; mSize-1]
T& getItem(size_t virtualIndex) const {
T& getItem(uint64 virtualIndex) const {
// If the virtual index is valid
if (virtualIndex < mSize) {
size_t chunkIndex = mFirstChunkIndex;
size_t itemIndex = mFirstItemIndex;
uint64 chunkIndex = mFirstChunkIndex;
uint64 itemIndex = mFirstItemIndex;
const size_t nbItemsFirstChunk = CHUNK_NB_ITEMS - mFirstItemIndex;
const uint64 nbItemsFirstChunk = CHUNK_NB_ITEMS - mFirstItemIndex;
if (virtualIndex < nbItemsFirstChunk) {
itemIndex += virtualIndex;
}
@ -118,18 +118,18 @@ class Deque {
}
/// Add more chunks
void expandChunks(size_t atLeastNbChunks = 0) {
void expandChunks(uint64 atLeastNbChunks = 0) {
// If it is not necessary to expand the chunks
if (atLeastNbChunks > 0 && atLeastNbChunks <= mNbChunks) {
return;
}
size_t newNbChunks = mNbChunks == 0 ? 3 : 2 * mNbChunks - 1;
uint64 newNbChunks = mNbChunks == 0 ? 3 : 2 * mNbChunks - 1;
if (atLeastNbChunks > 0 && newNbChunks < atLeastNbChunks) {
newNbChunks = size_t(atLeastNbChunks / 2) * 2 + 1;
newNbChunks = uint64(atLeastNbChunks / 2) * 2 + 1;
}
const size_t halfNbChunksToAdd = mNbChunks == 0 ? 1 : (mNbChunks - 1) / 2;
const uint64 halfNbChunksToAdd = mNbChunks == 0 ? 1 : (mNbChunks - 1) / 2;
// Allocate memory for the new array of pointers to chunk
void* newMemory = mAllocator.allocate(newNbChunks * sizeof(T*));
@ -157,7 +157,7 @@ class Deque {
mNbChunks = newNbChunks;
// Allocate memory for each new chunk
for (size_t i=0; i < halfNbChunksToAdd; i++) {
for (uint64 i=0; i < halfNbChunksToAdd; i++) {
// Allocate memory for the new chunk
mChunks[i] = static_cast<T*>(mAllocator.allocate(sizeof(T) * CHUNK_NB_ITEMS));
@ -182,7 +182,7 @@ class Deque {
private:
size_t mVirtualIndex;
uint64 mVirtualIndex;
const Deque<T>* mDeque;
public:
@ -197,7 +197,7 @@ class Deque {
using iterator_category = std::random_access_iterator_tag;
/// Constructor
Iterator(const Deque<T>* deque, size_t virtualIndex) : mVirtualIndex(virtualIndex), mDeque(deque) {
Iterator(const Deque<T>* deque, uint64 virtualIndex) : mVirtualIndex(virtualIndex), mDeque(deque) {
}
@ -337,14 +337,14 @@ class Deque {
if (deque.mSize > 0) {
const size_t dequeHalfSize1 = std::ceil(deque.mSize / 2.0f);
const size_t dequeHalfSize2 = deque.mSize - dequeHalfSize1;
const uint64 dequeHalfSize1 = std::ceil(deque.mSize / 2.0f);
const uint64 dequeHalfSize2 = deque.mSize - dequeHalfSize1;
// Add the items into the deque
for(size_t i=0; i < dequeHalfSize1; i++) {
for(uint64 i=0; i < dequeHalfSize1; i++) {
addFront(deque[dequeHalfSize1 - 1 - i]);
}
for(size_t i=0; i < dequeHalfSize2; i++) {
for(uint64 i=0; i < dequeHalfSize2; i++) {
addBack(deque[dequeHalfSize1 + i]);
}
}
@ -356,7 +356,7 @@ class Deque {
clear();
// Release each chunk
for (size_t i=0; i < mNbChunks; i++) {
for (uint64 i=0; i < mNbChunks; i++) {
mAllocator.release(mChunks[i], sizeof(T) * CHUNK_NB_ITEMS);
}
@ -511,7 +511,7 @@ class Deque {
if (mSize > 0) {
// Call the destructor of every items
for (size_t i=0; i < mSize; i++) {
for (uint64 i=0; i < mSize; i++) {
getItem(i).~T();
}
@ -525,18 +525,18 @@ class Deque {
}
/// Return the number of elements in the deque
size_t size() const {
uint64 size() const {
return mSize;
}
/// Overloaded index operator
T& operator[](const size_t index) {
T& operator[](const uint64 index) {
assert(index < mSize);
return getItem(index);
}
/// Overloaded const index operator
const T& operator[](const size_t index) const {
const T& operator[](const uint64 index) const {
assert(index < mSize);
return getItem(index);
}
@ -546,7 +546,7 @@ class Deque {
if (mSize != deque.mSize) return false;
for (size_t i=0; i < mSize; i++) {
for (uint64 i=0; i < mSize; i++) {
if (getItem(i) != deque.getItem(i)) {
return false;
}
@ -572,19 +572,19 @@ class Deque {
if (deque.mSize > 0) {
// Number of used chunks
const size_t nbUsedChunks = deque.mLastChunkIndex - deque.mFirstChunkIndex + 1;
const uint64 nbUsedChunks = deque.mLastChunkIndex - deque.mFirstChunkIndex + 1;
// Expand the chunk if necessary
expandChunks(nbUsedChunks);
const size_t dequeHalfSize1 = std::ceil(deque.mSize / 2.0f);
const size_t dequeHalfSize2 = deque.mSize - dequeHalfSize1;
const uint64 dequeHalfSize1 = std::ceil(deque.mSize / 2.0f);
const uint64 dequeHalfSize2 = deque.mSize - dequeHalfSize1;
// Add the items into the deque
for(size_t i=0; i < dequeHalfSize1; i++) {
for(uint64 i=0; i < dequeHalfSize1; i++) {
addFront(deque[dequeHalfSize1 - 1 - i]);
}
for(size_t i=0; i < dequeHalfSize2; i++) {
for(uint64 i=0; i < dequeHalfSize2; i++) {
addBack(deque[dequeHalfSize1 + i]);
}
}

View File

@ -53,47 +53,47 @@ class Map {
static constexpr float DEFAULT_LOAD_FACTOR = 0.75;
/// Invalid index in the array
static constexpr size_t INVALID_INDEX = -1;
static constexpr uint64 INVALID_INDEX = -1;
// -------------------- Attributes -------------------- //
/// Total number of allocated entries
size_t mNbAllocatedEntries;
uint64 mNbAllocatedEntries;
/// Number of items in the set
size_t mNbEntries;
uint64 mNbEntries;
/// Number of buckets and size of the hash table (nbEntries = loadFactor * mHashSize)
size_t mHashSize ;
uint64 mHashSize ;
/// Array with all the buckets
size_t* mBuckets;
uint64* mBuckets;
/// Array with all the entries
Pair<K, V>* mEntries;
/// For each entry, index of the next entry at the same bucket
size_t* mNextEntries;
uint64* mNextEntries;
/// Memory allocator
MemoryAllocator& mAllocator;
/// Index to the fist free entry
size_t mFreeIndex;
uint64 mFreeIndex;
// -------------------- Methods -------------------- //
/// Return the index of the entry with a given key or INVALID_INDEX if there is no entry with this key
size_t findEntry(const K& key) const {
uint64 findEntry(const K& key) const {
if (mHashSize > 0) {
const size_t hashCode = Hash()(key);
const size_t divider = mHashSize - 1;
const size_t bucket = hashCode & divider;
const uint64 bucket = static_cast<uint64>(hashCode & divider);
auto keyEqual = KeyEqual();
for (size_t i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
for (uint64 i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
if (Hash()(mEntries[i].first) == hashCode && keyEqual(mEntries[i].first, key)) {
return i;
}
@ -117,10 +117,10 @@ class Map {
const Map* mMap;
/// Index of the current bucket
size_t mCurrentBucketIndex;
uint64 mCurrentBucketIndex;
/// Index of the current entry
size_t mCurrentEntryIndex;
uint64 mCurrentEntryIndex;
/// Advance the iterator
void advance() {
@ -158,7 +158,7 @@ class Map {
Iterator() = default;
/// Constructor
Iterator(const Map* map, size_t bucketIndex, size_t entryIndex)
Iterator(const Map* map, uint64 bucketIndex, uint64 entryIndex)
:mMap(map), mCurrentBucketIndex(bucketIndex), mCurrentEntryIndex(entryIndex) {
}
@ -205,7 +205,7 @@ class Map {
// -------------------- Methods -------------------- //
/// Constructor
Map(MemoryAllocator& allocator, size_t capacity = 0)
Map(MemoryAllocator& allocator, uint64 capacity = 0)
: mNbAllocatedEntries(0), mNbEntries(0), mHashSize(0), mBuckets(nullptr),
mEntries(nullptr), mNextEntries(nullptr), mAllocator(allocator), mFreeIndex(INVALID_INDEX) {
@ -223,22 +223,22 @@ class Map {
if (mHashSize > 0) {
// Allocate memory for the buckets
mBuckets = static_cast<size_t*>(mAllocator.allocate(mHashSize * sizeof(size_t)));
mBuckets = static_cast<uint64*>(mAllocator.allocate(mHashSize * sizeof(uint64)));
// Allocate memory for the entries
mEntries = static_cast<Pair<K, V>*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(Pair<K, V>)));
mNextEntries = static_cast<size_t*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(size_t)));
mNextEntries = static_cast<uint64*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(uint64)));
// Copy the buckets array
std::memcpy(mBuckets, map.mBuckets, mHashSize * sizeof(size_t));
std::memcpy(mBuckets, map.mBuckets, mHashSize * sizeof(uint64));
// Copy the next entries indices
std::memcpy(mNextEntries, map.mNextEntries, mNbAllocatedEntries * sizeof(size_t));
std::memcpy(mNextEntries, map.mNextEntries, mNbAllocatedEntries * sizeof(uint64));
// Copy the entries
for (size_t i=0; i<mHashSize; i++) {
for (uint64 i=0; i<mHashSize; i++) {
size_t entryIndex = mBuckets[i];
uint64 entryIndex = mBuckets[i];
while(entryIndex != INVALID_INDEX) {
// 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
void reserve(size_t capacity) {
void reserve(uint64 capacity) {
if (capacity <= mHashSize) return;
@ -265,7 +265,7 @@ class Map {
// Make sure we have a power of two size
if (!isPowerOfTwo(capacity)) {
capacity = nextPowerOfTwo32Bits(capacity);
capacity = nextPowerOfTwo64Bits(capacity);
}
assert(capacity < INVALID_INDEX);
@ -273,19 +273,19 @@ class Map {
assert(capacity > mHashSize);
// Allocate memory for the buckets
size_t* newBuckets = static_cast<size_t*>(mAllocator.allocate(capacity * sizeof(size_t)));
uint64* newBuckets = static_cast<uint64*>(mAllocator.allocate(capacity * sizeof(uint64)));
// Allocate memory for the entries
const size_t nbAllocatedEntries = static_cast<size_t>(capacity * DEFAULT_LOAD_FACTOR);
const uint64 nbAllocatedEntries = static_cast<uint64>(capacity * DEFAULT_LOAD_FACTOR);
assert(nbAllocatedEntries > 0);
Pair<K, V>* newEntries = static_cast<Pair<K, V>*>(mAllocator.allocate(nbAllocatedEntries * sizeof(Pair<K, V>)));
size_t* newNextEntries = static_cast<size_t*>(mAllocator.allocate(nbAllocatedEntries * sizeof(size_t)));
uint64* newNextEntries = static_cast<uint64*>(mAllocator.allocate(nbAllocatedEntries * sizeof(uint64)));
assert(newEntries != nullptr);
assert(newNextEntries != nullptr);
// Initialize the new buckets
for (size_t i=0; i<capacity; i++) {
for (uint64 i=0; i<capacity; i++) {
newBuckets[i] = INVALID_INDEX;
}
@ -294,19 +294,19 @@ class Map {
assert(mNextEntries != nullptr);
// Copy the free nodes indices in the nextEntries array
std::memcpy(newNextEntries, mNextEntries, mNbAllocatedEntries * sizeof(size_t));
std::memcpy(newNextEntries, mNextEntries, mNbAllocatedEntries * sizeof(uint64));
}
// Recompute the buckets (hash) with the new hash size
for (size_t i=0; i<mHashSize; i++) {
for (uint64 i=0; i<mHashSize; i++) {
size_t entryIndex = mBuckets[i];
uint64 entryIndex = mBuckets[i];
while(entryIndex != INVALID_INDEX) {
// Get the corresponding bucket
const size_t hashCode = Hash()(mEntries[entryIndex].first);
const size_t divider = capacity - 1;
const size_t bucketIndex = hashCode & divider;
const uint64 bucketIndex = static_cast<uint64>(hashCode & divider);
newNextEntries[entryIndex] = newBuckets[bucketIndex];
newBuckets[bucketIndex] = entryIndex;
@ -322,13 +322,13 @@ class Map {
if (mNbAllocatedEntries > 0) {
// Release previously allocated memory
mAllocator.release(mBuckets, mHashSize * sizeof(size_t));
mAllocator.release(mBuckets, mHashSize * sizeof(uint64));
mAllocator.release(mEntries, mNbAllocatedEntries * sizeof(Pair<K, V>));
mAllocator.release(mNextEntries, mNbAllocatedEntries * sizeof(size_t));
mAllocator.release(mNextEntries, mNbAllocatedEntries * sizeof(uint64));
}
// Add the new entries to the free list
for (size_t i=mNbAllocatedEntries; i < nbAllocatedEntries-1; i++) {
for (uint64 i=mNbAllocatedEntries; i < nbAllocatedEntries-1; i++) {
newNextEntries[i] = i + 1;
}
newNextEntries[nbAllocatedEntries - 1] = mFreeIndex;
@ -352,7 +352,7 @@ class Map {
/// Returns true if the item has been inserted and false otherwise.
bool add(const Pair<K,V>& keyValue, bool insertIfAlreadyPresent = false) {
size_t bucket = INVALID_INDEX;
uint64 bucket = INVALID_INDEX;
// Compute the hash code of the value
const size_t hashCode = Hash()(keyValue.first);
@ -361,12 +361,12 @@ class Map {
// Compute the corresponding bucket index
const size_t divider = mHashSize - 1;
bucket = hashCode & divider;
bucket = static_cast<uint64>(hashCode & divider);
auto keyEqual = KeyEqual();
// Check if the item is already in the set
for (size_t i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
for (uint64 i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
// 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)) {
@ -389,7 +389,7 @@ class Map {
}
}
size_t entryIndex;
uint64 entryIndex;
// If there are no more free entries to use
if (mFreeIndex == INVALID_INDEX) {
@ -399,7 +399,7 @@ class Map {
// Recompute the bucket index
const size_t divider = mHashSize - 1;
bucket = hashCode & divider;
bucket = static_cast<uint64>(hashCode & divider);
}
assert(mNbEntries < mNbAllocatedEntries);
@ -438,9 +438,9 @@ class Map {
const size_t hashcode = Hash()(key);
auto keyEqual = KeyEqual();
const size_t divider = mHashSize - 1;
const size_t bucket = hashcode & divider;
size_t last = INVALID_INDEX;
for (size_t i = mBuckets[bucket]; i != INVALID_INDEX; last = i, i = mNextEntries[i]) {
const uint64 bucket = static_cast<uint64>(hashcode & divider);
uint64 last = INVALID_INDEX;
for (uint64 i = mBuckets[bucket]; i != INVALID_INDEX; last = i, i = mNextEntries[i]) {
// If we have found the item
if (Hash()(mEntries[i].first) == hashcode && keyEqual(mEntries[i].first, key)) {
@ -452,8 +452,8 @@ class Map {
mNextEntries[last] = mNextEntries[i];
}
size_t nextEntryIndex = mNextEntries[i];
size_t nextBucketIndex = bucket;
uint64 nextEntryIndex = mNextEntries[i];
uint64 nextBucketIndex = bucket;
mEntries[i].~Pair<K,V>();
mNextEntries[i] = mFreeIndex;
@ -484,15 +484,15 @@ class Map {
/// Clear the map
void clear(bool releaseMemory = false) {
for (size_t i=0; i<mHashSize; i++) {
for (uint64 i=0; i<mHashSize; i++) {
size_t entryIndex = mBuckets[i];
uint64 entryIndex = mBuckets[i];
while(entryIndex != INVALID_INDEX) {
// Destroy the entry
mEntries[entryIndex].~Pair<K,V>();
size_t nextEntryIndex = mNextEntries[entryIndex];
uint64 nextEntryIndex = mNextEntries[entryIndex];
// Add entry to the free list
mNextEntries[entryIndex] = mFreeIndex;
@ -507,9 +507,9 @@ class Map {
if (releaseMemory && mNbAllocatedEntries > 0) {
// Release previously allocated memory
mAllocator.release(mBuckets, mHashSize * sizeof(size_t));
mAllocator.release(mBuckets, mHashSize * sizeof(uint64));
mAllocator.release(mEntries, mNbAllocatedEntries * sizeof(Pair<K, V>));
mAllocator.release(mNextEntries, mNbAllocatedEntries * sizeof(size_t));
mAllocator.release(mNextEntries, mNbAllocatedEntries * sizeof(uint64));
mBuckets = nullptr;
mEntries = nullptr;
@ -523,12 +523,12 @@ class Map {
}
/// Return the number of elements in the map
size_t size() const {
uint64 size() const {
return mNbEntries;
}
/// Return the capacity of the map
size_t capacity() const {
uint64 capacity() const {
return mHashSize;
}
@ -537,17 +537,17 @@ class Map {
/// an iterator pointing to the end if not found
Iterator find(const K& key) const {
size_t bucket;
size_t entry = INVALID_INDEX;
uint64 bucket;
uint64 entry = INVALID_INDEX;
if (mHashSize > 0) {
const size_t hashCode = Hash()(key);
const size_t divider = mHashSize - 1;
bucket = hashCode & divider;
bucket = static_cast<uint64>(hashCode & divider);
auto keyEqual = KeyEqual();
for (size_t i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
for (uint64 i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
if (Hash()(mEntries[i].first) == hashCode && keyEqual(mEntries[i].first, key)) {
entry = i;
break;
@ -565,7 +565,7 @@ class Map {
/// Overloaded index operator
V& operator[](const K& key) {
const size_t entry = findEntry(key);
const uint64 entry = findEntry(key);
if (entry == INVALID_INDEX) {
assert(false);
@ -578,7 +578,7 @@ class Map {
/// Overloaded index operator
const V& operator[](const K& key) const {
const size_t entry = findEntry(key);
const uint64 entry = findEntry(key);
if (entry == INVALID_INDEX) {
assert(false);
@ -633,22 +633,22 @@ class Map {
if (mHashSize > 0) {
// Allocate memory for the buckets
mBuckets = static_cast<size_t*>(mAllocator.allocate(mHashSize * sizeof(size_t)));
mBuckets = static_cast<uint64*>(mAllocator.allocate(mHashSize * sizeof(uint64)));
// Allocate memory for the entries
mEntries = static_cast<Pair<K,V>*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(Pair<K,V>)));
mNextEntries = static_cast<size_t*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(size_t)));
mNextEntries = static_cast<uint64*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(uint64)));
// Copy the buckets array
std::memcpy(mBuckets, map.mBuckets, mHashSize * sizeof(size_t));
std::memcpy(mBuckets, map.mBuckets, mHashSize * sizeof(uint64));
// Copy the next entries indices
std::memcpy(mNextEntries, map.mNextEntries, mNbAllocatedEntries * sizeof(size_t));
std::memcpy(mNextEntries, map.mNextEntries, mNbAllocatedEntries * sizeof(uint64));
// Copy the entries
for (size_t i=0; i<mHashSize; i++) {
for (uint64 i=0; i<mHashSize; i++) {
size_t entryIndex = mBuckets[i];
uint64 entryIndex = mBuckets[i];
while(entryIndex != INVALID_INDEX) {
// Copy the entry to the new location and destroy the previous one
@ -674,7 +674,7 @@ class Map {
}
// Find the first used entry
size_t bucketIndex = 0;
uint64 bucketIndex = 0;
while (mBuckets[bucketIndex] == INVALID_INDEX) {
bucketIndex++;

View File

@ -52,47 +52,47 @@ class Set {
static constexpr float DEFAULT_LOAD_FACTOR = 0.75;
/// Invalid index in the array
static constexpr size_t INVALID_INDEX = -1;
static constexpr uint64 INVALID_INDEX = -1;
// -------------------- Attributes -------------------- //
/// Total number of allocated entries
size_t mNbAllocatedEntries;
uint64 mNbAllocatedEntries;
/// Number of items in the set
size_t mNbEntries;
uint64 mNbEntries;
/// Number of buckets and size of the hash table (nbEntries = loadFactor * mHashSize)
size_t mHashSize ;
uint64 mHashSize ;
/// Array with all the buckets
size_t* mBuckets;
uint64* mBuckets;
/// Array with all the entries (nbEntries = loadFactor * mHashSize)
V* mEntries;
/// For each entry, index of the next entry at the same bucket
size_t* mNextEntries;
uint64* mNextEntries;
/// Memory allocator
MemoryAllocator& mAllocator;
/// Index to the fist free entry
size_t mFreeIndex;
uint64 mFreeIndex;
// -------------------- Methods -------------------- //
/// Return the index of the entry with a given value or -1 if there is no entry with this value
size_t findEntry(const V& value) const {
uint64 findEntry(const V& value) const {
if (mHashSize > 0) {
const size_t hashCode = Hash()(value);
const size_t divider = mHashSize - 1;
const size_t bucket = hashCode & divider;
const uint64 bucket = static_cast<uint64>(hashCode & divider);
auto keyEqual = KeyEqual();
for (size_t i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
for (uint64 i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
if (Hash()(mEntries[i]) == hashCode && keyEqual(mEntries[i], value)) {
return i;
}
@ -116,10 +116,10 @@ class Set {
const Set* mSet;
/// Index of the current bucket
size_t mCurrentBucketIndex;
uint64 mCurrentBucketIndex;
/// Index of the current entry
size_t mCurrentEntryIndex;
uint64 mCurrentEntryIndex;
/// Advance the iterator
void advance() {
@ -157,7 +157,7 @@ class Set {
Iterator() = default;
/// Constructor
Iterator(const Set* set, size_t bucketIndex, size_t entryIndex)
Iterator(const Set* set, uint64 bucketIndex, uint64 entryIndex)
:mSet(set), mCurrentBucketIndex(bucketIndex), mCurrentEntryIndex(entryIndex) {
}
@ -204,7 +204,7 @@ class Set {
// -------------------- Methods -------------------- //
/// Constructor
Set(MemoryAllocator& allocator, size_t capacity = 0)
Set(MemoryAllocator& allocator, uint64 capacity = 0)
: mNbAllocatedEntries(0), mNbEntries(0), mHashSize(0), mBuckets(nullptr),
mEntries(nullptr), mNextEntries(nullptr), mAllocator(allocator), mFreeIndex(INVALID_INDEX) {
@ -222,22 +222,22 @@ class Set {
if (mHashSize > 0) {
// Allocate memory for the buckets
mBuckets = static_cast<size_t*>(mAllocator.allocate(mHashSize * sizeof(size_t)));
mBuckets = static_cast<uint64*>(mAllocator.allocate(mHashSize * sizeof(uint64)));
// Allocate memory for the entries
mEntries = static_cast<V*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(V)));
mNextEntries = static_cast<size_t*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(size_t)));
mNextEntries = static_cast<uint64*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(uint64)));
// Copy the buckets array
std::memcpy(mBuckets, set.mBuckets, mHashSize * sizeof(size_t));
std::memcpy(mBuckets, set.mBuckets, mHashSize * sizeof(uint64));
// Copy the next entries indices
std::memcpy(mNextEntries, set.mNextEntries, mNbAllocatedEntries * sizeof(size_t));
std::memcpy(mNextEntries, set.mNextEntries, mNbAllocatedEntries * sizeof(uint64));
// Copy the entries
for (size_t i=0; i<mHashSize; i++) {
for (uint64 i=0; i<mHashSize; i++) {
size_t entryIndex = mBuckets[i];
uint64 entryIndex = mBuckets[i];
while(entryIndex != INVALID_INDEX) {
// 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
void reserve(size_t capacity) {
void reserve(uint64 capacity) {
if (capacity <= mHashSize) return;
@ -264,7 +264,7 @@ class Set {
// Make sure we have a power of two size
if (!isPowerOfTwo(capacity)) {
capacity = nextPowerOfTwo32Bits(capacity);
capacity = nextPowerOfTwo64Bits(capacity);
}
assert(capacity < INVALID_INDEX);
@ -272,19 +272,19 @@ class Set {
assert(capacity > mHashSize);
// Allocate memory for the buckets
size_t* newBuckets = static_cast<size_t*>(mAllocator.allocate(capacity * sizeof(size_t)));
uint64* newBuckets = static_cast<uint64*>(mAllocator.allocate(capacity * sizeof(uint64)));
// Allocate memory for the entries
const size_t nbAllocatedEntries = static_cast<size_t>(capacity * DEFAULT_LOAD_FACTOR);
const uint64 nbAllocatedEntries = static_cast<uint64>(capacity * DEFAULT_LOAD_FACTOR);
assert(nbAllocatedEntries > 0);
V* newEntries = static_cast<V*>(mAllocator.allocate(nbAllocatedEntries * sizeof(V)));
size_t* newNextEntries = static_cast<size_t*>(mAllocator.allocate(nbAllocatedEntries * sizeof(size_t)));
uint64* newNextEntries = static_cast<uint64*>(mAllocator.allocate(nbAllocatedEntries * sizeof(uint64)));
assert(newEntries != nullptr);
assert(newNextEntries != nullptr);
// Initialize the new buckets
for (size_t i=0; i<capacity; i++) {
for (uint64 i=0; i<capacity; i++) {
newBuckets[i] = INVALID_INDEX;
}
@ -293,19 +293,19 @@ class Set {
assert(mNextEntries != nullptr);
// Copy the free nodes indices in the nextEntries array
std::memcpy(newNextEntries, mNextEntries, mNbAllocatedEntries * sizeof(size_t));
std::memcpy(newNextEntries, mNextEntries, mNbAllocatedEntries * sizeof(uint64));
}
// Recompute the buckets (hash) with the new hash size
for (size_t i=0; i<mHashSize; i++) {
for (uint64 i=0; i<mHashSize; i++) {
size_t entryIndex = mBuckets[i];
uint64 entryIndex = mBuckets[i];
while(entryIndex != INVALID_INDEX) {
// Get the corresponding bucket
const size_t hashCode = Hash()(mEntries[entryIndex]);
const size_t divider = capacity - 1;
const size_t bucketIndex = hashCode & divider;
const uint64 bucketIndex = static_cast<uint64>(hashCode & divider);
newNextEntries[entryIndex] = newBuckets[bucketIndex];
newBuckets[bucketIndex] = entryIndex;
@ -321,13 +321,13 @@ class Set {
if (mNbAllocatedEntries > 0) {
// Release previously allocated memory
mAllocator.release(mBuckets, mHashSize * sizeof(size_t));
mAllocator.release(mBuckets, mHashSize * sizeof(uint64));
mAllocator.release(mEntries, mNbAllocatedEntries * sizeof(V));
mAllocator.release(mNextEntries, mNbAllocatedEntries * sizeof(size_t));
mAllocator.release(mNextEntries, mNbAllocatedEntries * sizeof(uint64));
}
// Add the new entries to the free list
for (size_t i=mNbAllocatedEntries; i < nbAllocatedEntries-1; i++) {
for (uint64 i=mNbAllocatedEntries; i < nbAllocatedEntries-1; i++) {
newNextEntries[i] = i + 1;
}
newNextEntries[nbAllocatedEntries - 1] = mFreeIndex;
@ -351,7 +351,7 @@ class Set {
/// Returns true if the item has been inserted and false otherwise.
bool add(const V& value) {
size_t bucket;
uint64 bucket;
// Compute the hash code of the value
const size_t hashCode = Hash()(value);
@ -360,12 +360,12 @@ class Set {
// Compute the corresponding bucket index
const size_t divider = mHashSize - 1;
bucket = hashCode & divider;
bucket = static_cast<uint64>(hashCode & divider);
auto keyEqual = KeyEqual();
// Check if the item is already in the set
for (size_t i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
for (uint64 i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
// If there is already an item with the same value in the set
if (Hash()(mEntries[i]) == hashCode && keyEqual(mEntries[i], value)) {
@ -375,7 +375,7 @@ class Set {
}
}
size_t entryIndex;
uint64 entryIndex;
// If there are no more free entries to use
if (mFreeIndex == INVALID_INDEX) {
@ -385,7 +385,7 @@ class Set {
// Recompute the bucket index
const size_t divider = mHashSize - 1;
bucket = hashCode & divider;
bucket = static_cast<uint64>(hashCode & divider);
}
assert(mNbEntries < mNbAllocatedEntries);
@ -423,8 +423,8 @@ class Set {
auto keyEqual = KeyEqual();
const size_t divider = mHashSize - 1;
const size_t bucket = hashcode & divider;
size_t last = INVALID_INDEX;
for (size_t i = mBuckets[bucket]; i != INVALID_INDEX; last = i, i = mNextEntries[i]) {
uint64 last = INVALID_INDEX;
for (uint64 i = mBuckets[bucket]; i != INVALID_INDEX; last = i, i = mNextEntries[i]) {
// If we have found the item
if (Hash()(mEntries[i]) == hashcode && keyEqual(mEntries[i], value)) {
@ -436,8 +436,8 @@ class Set {
mNextEntries[last] = mNextEntries[i];
}
size_t nextEntryIndex = mNextEntries[i];
size_t nextBucketIndex = bucket;
uint64 nextEntryIndex = mNextEntries[i];
uint64 nextBucketIndex = bucket;
mEntries[i].~V();
mNextEntries[i] = mFreeIndex;
@ -480,15 +480,15 @@ class Set {
/// Clear the set
void clear(bool releaseMemory = false) {
for (size_t i=0; i<mHashSize; i++) {
for (uint64 i=0; i<mHashSize; i++) {
size_t entryIndex = mBuckets[i];
uint64 entryIndex = mBuckets[i];
while(entryIndex != INVALID_INDEX) {
// Destroy the entry
mEntries[entryIndex].~V();
size_t nextEntryIndex = mNextEntries[entryIndex];
uint64 nextEntryIndex = mNextEntries[entryIndex];
// Add entry to the free list
mNextEntries[entryIndex] = mFreeIndex;
@ -503,9 +503,9 @@ class Set {
if (releaseMemory && mNbAllocatedEntries > 0) {
// Release previously allocated memory
mAllocator.release(mBuckets, mHashSize * sizeof(size_t));
mAllocator.release(mBuckets, mHashSize * sizeof(uint64));
mAllocator.release(mEntries, mNbAllocatedEntries * sizeof(V));
mAllocator.release(mNextEntries, mNbAllocatedEntries * sizeof(size_t));
mAllocator.release(mNextEntries, mNbAllocatedEntries * sizeof(uint64));
mBuckets = nullptr;
mEntries = nullptr;
@ -519,12 +519,12 @@ class Set {
}
/// Return the number of elements in the set
size_t size() const {
uint64 size() const {
return mNbEntries;
}
/// Return the capacity of the set
size_t capacity() const {
uint64 capacity() const {
return mHashSize;
}
@ -533,17 +533,17 @@ class Set {
/// an iterator pointing to the end if not found
Iterator find(const V& value) const {
size_t bucket;
size_t entry = INVALID_INDEX;
uint64 bucket;
uint64 entry = INVALID_INDEX;
if (mHashSize > 0) {
const size_t hashCode = Hash()(value);
const size_t divider = mHashSize - 1;
bucket = hashCode & divider;
bucket = static_cast<uint64>(hashCode & divider);
auto keyEqual = KeyEqual();
for (size_t i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
for (uint64 i = mBuckets[bucket]; i != INVALID_INDEX; i = mNextEntries[i]) {
if (Hash()(mEntries[i]) == hashCode && keyEqual(mEntries[i], value)) {
entry = i;
break;
@ -595,22 +595,22 @@ class Set {
if (mHashSize > 0) {
// Allocate memory for the buckets
mBuckets = static_cast<size_t*>(mAllocator.allocate(mHashSize * sizeof(size_t)));
mBuckets = static_cast<uint64*>(mAllocator.allocate(mHashSize * sizeof(uint64)));
// Allocate memory for the entries
mEntries = static_cast<V*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(V)));
mNextEntries = static_cast<size_t*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(size_t)));
mNextEntries = static_cast<uint64*>(mAllocator.allocate(mNbAllocatedEntries * sizeof(uint64)));
// Copy the buckets array
std::memcpy(mBuckets, set.mBuckets, mHashSize * sizeof(size_t));
std::memcpy(mBuckets, set.mBuckets, mHashSize * sizeof(uint64));
// Copy the next entries indices
std::memcpy(mNextEntries, set.mNextEntries, mNbAllocatedEntries * sizeof(size_t));
std::memcpy(mNextEntries, set.mNextEntries, mNbAllocatedEntries * sizeof(uint64));
// Copy the entries
for (size_t i=0; i<mHashSize; i++) {
for (uint64 i=0; i<mHashSize; i++) {
size_t entryIndex = mBuckets[i];
uint64 entryIndex = mBuckets[i];
while(entryIndex != INVALID_INDEX) {
// Copy the entry to the new location and destroy the previous one
@ -636,7 +636,7 @@ class Set {
}
// Find the first used entry
size_t bucketIndex = 0;
uint64 bucketIndex = 0;
while (mBuckets[bucketIndex] == INVALID_INDEX) {
bucketIndex++;

View File

@ -51,15 +51,15 @@ class Stack {
T* mArray;
/// Number of elements in the stack
size_t mNbElements;
uint64 mNbElements;
/// Number of allocated elements in the stack
size_t mCapacity;
uint64 mCapacity;
// -------------------- Methods -------------------- //
/// Allocate more memory
void allocate(size_t capacity) {
void allocate(uint64 capacity) {
T* newArray = static_cast<T*>(mAllocator.allocate(capacity * sizeof(T)));
assert(newArray != nullptr);
@ -87,7 +87,7 @@ class Stack {
// -------------------- Methods -------------------- //
/// Constructor
Stack(MemoryAllocator& allocator, size_t capacity = 0)
Stack(MemoryAllocator& allocator, uint64 capacity = 0)
:mAllocator(allocator), mArray(nullptr), mNbElements(0), mCapacity(0) {
if (capacity > 0) {
@ -130,7 +130,7 @@ class Stack {
void clear() {
// Destruct the items
for (size_t i = 0; i < mNbElements; i++) {
for (uint64 i = 0; i < mNbElements; i++) {
mArray[i].~T();
}
@ -169,12 +169,12 @@ class Stack {
}
/// Return the number of items in the stack
size_t size() const {
uint64 size() const {
return mNbElements;
}
/// Return the capacity of the stack
size_t capacity() const {
uint64 capacity() const {
return mCapacity;
}
};

View File

@ -403,18 +403,19 @@ RP3D_FORCE_INLINE decimal computePointToPlaneDistance(const Vector3& point, cons
}
/// Return true if a number is a power of two
RP3D_FORCE_INLINE bool isPowerOfTwo(uint32 number) {
RP3D_FORCE_INLINE bool isPowerOfTwo(uint64 number) {
return number != 0 && !(number & (number -1));
}
/// Return the next power of two larger than the number in parameter
RP3D_FORCE_INLINE uint32 nextPowerOfTwo32Bits(uint32 number) {
RP3D_FORCE_INLINE uint32 nextPowerOfTwo64Bits(uint64 number) {
number--;
number |= number >> 1;
number |= number >> 2;
number |= number >> 4;
number |= number >> 8;
number |= number >> 16;
number |= number >> 32;
number++;
number += (number == 0);
return number;

View File

@ -291,16 +291,16 @@ class TestMathematicsFunctions : public Test {
rp3d_test(isPowerOfTwo(2048));
// Test nextPowerOfTwo32Bits()
rp3d_test(nextPowerOfTwo32Bits(0) == 1);
rp3d_test(nextPowerOfTwo32Bits(1) == 1);
rp3d_test(nextPowerOfTwo32Bits(2) == 2);
rp3d_test(nextPowerOfTwo32Bits(3) == 4);
rp3d_test(nextPowerOfTwo32Bits(5) == 8);
rp3d_test(nextPowerOfTwo32Bits(6) == 8);
rp3d_test(nextPowerOfTwo32Bits(7) == 8);
rp3d_test(nextPowerOfTwo32Bits(1000) == 1024);
rp3d_test(nextPowerOfTwo32Bits(129) == 256);
rp3d_test(nextPowerOfTwo32Bits(260) == 512);
rp3d_test(nextPowerOfTwo64Bits(0) == 1);
rp3d_test(nextPowerOfTwo64Bits(1) == 1);
rp3d_test(nextPowerOfTwo64Bits(2) == 2);
rp3d_test(nextPowerOfTwo64Bits(3) == 4);
rp3d_test(nextPowerOfTwo64Bits(5) == 8);
rp3d_test(nextPowerOfTwo64Bits(6) == 8);
rp3d_test(nextPowerOfTwo64Bits(7) == 8);
rp3d_test(nextPowerOfTwo64Bits(1000) == 1024);
rp3d_test(nextPowerOfTwo64Bits(129) == 256);
rp3d_test(nextPowerOfTwo64Bits(260) == 512);
}
};