Browse Source

Use i64 as length for containers

Kajetan Johannes Hammerle 2 months ago
parent
commit
8e99d0f6d4

+ 6 - 6
include/core/data/Array.hpp

@@ -4,10 +4,10 @@
 #include "core/utils/ArrayString.hpp"
 
 namespace Core {
-    template<typename T, int N>
+    template<typename T, i64 N>
     class Array final {
         static_assert(N > 0, "Array size must be positive");
-        T data[static_cast<unsigned int>(N)];
+        T data[static_cast<u64>(N)];
 
     public:
         constexpr Array() = default;
@@ -17,16 +17,16 @@ namespace Core {
         }
 
         constexpr void fill(const T& t) {
-            for(int i = 0; i < N; i++) {
+            for(i64 i = 0; i < N; i++) {
                 data[i] = t;
             }
         }
 
-        constexpr T& operator[](int index) {
+        constexpr T& operator[](i64 index) {
             return data[index];
         }
 
-        constexpr const T& operator[](int index) const {
+        constexpr const T& operator[](i64 index) const {
             return data[index];
         }
 
@@ -46,7 +46,7 @@ namespace Core {
             return data + N;
         }
 
-        static consteval int getLength() {
+        static consteval i64 getLength() {
             return N;
         }
 

+ 10 - 10
include/core/data/ArrayList.hpp

@@ -5,12 +5,12 @@
 #include "core/utils/ArrayString.hpp"
 
 namespace Core {
-    template<typename T, int N>
+    template<typename T, i64 N>
     class ArrayList final {
         static_assert(N > 0, "ArrayList size must be positive");
 
-        AlignedType<T> data[static_cast<unsigned int>(N)];
-        int length;
+        AlignedType<T> data[static_cast<u64>(N)];
+        i64 length;
 
     public:
         ArrayList() : length(0) {
@@ -77,26 +77,26 @@ namespace Core {
             return put(t, Core::forward<Args>(args)...);
         }
 
-        T& operator[](int index) {
+        T& operator[](i64 index) {
             return begin()[index];
         }
 
-        const T& operator[](int index) const {
+        const T& operator[](i64 index) const {
             return begin()[index];
         }
 
-        int getLength() const {
+        i64 getLength() const {
             return length;
         }
 
         void clear() {
-            for(int i = 0; i < length; i++) {
+            for(i64 i = 0; i < length; i++) {
                 begin()[i].~T();
             }
             length = 0;
         }
 
-        check_return Error removeBySwap(int index) {
+        check_return Error removeBySwap(i64 index) {
             if(index < 0 || index >= length) {
                 return Error::INVALID_INDEX;
             }
@@ -119,13 +119,13 @@ namespace Core {
 
     private:
         void copy(const ArrayList& other) {
-            for(int i = 0; i < other.length; i++) {
+            for(i64 i = 0; i < other.length; i++) {
                 (void)add(other[i]);
             }
         }
 
         void move(ArrayList&& other) {
-            for(int i = 0; i < other.length; i++) {
+            for(i64 i = 0; i < other.length; i++) {
                 (void)add(Core::move(other[i]));
             }
         }

+ 14 - 14
include/core/data/BitArray.hpp

@@ -5,9 +5,8 @@
 
 namespace Core {
     class BitArray final {
-        int length;
-        int bits;
-        int* data;
+        u64 lengthBits;
+        u64* data;
 
     public:
         BitArray();
@@ -19,29 +18,30 @@ namespace Core {
 
         check_return Error copyFrom(const BitArray& other);
 
-        BitArray& set(int index, int value);
-        int get(int index) const;
+        BitArray& set(u64 index, u64 value);
+        u64 get(u64 index) const;
 
-        int getLength() const;
-        int getBits() const;
-        int getInternalByteSize() const;
+        u64 getLength() const;
+        u64 getBits() const;
+        u64 getInternalByteSize() const;
 
-        int select(int index) const;
+        i64 select(u64 index) const;
 
-        check_return Error resize(int newLength, int newBits);
+        check_return Error resize(u64 newLength, u64 newBits);
 
-        void fill(int value);
+        void fill(u64 value);
 
         template<typename String>
         check_return Error toString(String& s) const {
             CORE_RETURN_ERROR(s.append("["));
+            u64 length = getLength();
             if(length > 0) {
-                int end = length - 1;
-                for(int i = 0; i < end; i++) {
+                length--;
+                for(u64 i = 0; i < length; i++) {
                     CORE_RETURN_ERROR(s.append(get(i)));
                     CORE_RETURN_ERROR(s.append(", "));
                 }
-                CORE_RETURN_ERROR(s.append(get(end)));
+                CORE_RETURN_ERROR(s.append(get(length)));
             }
             return s.append("]");
         }

+ 10 - 10
include/core/data/Components.hpp

@@ -8,7 +8,7 @@ namespace Core {
 
     template<typename T>
     class Components final {
-        HashMap<Entity, int> entityToIndex{};
+        HashMap<Entity, i64> entityToIndex{};
         List<Entity> indexToEntity{};
         List<T> components{};
 
@@ -22,10 +22,10 @@ namespace Core {
         template<typename C, typename R>
         class EntityIterator final {
             C& components;
-            int index;
+            i64 index;
 
         public:
-            EntityIterator(C& components_, int index_)
+            EntityIterator(C& components_, i64 index_)
                 : components(components_), index(index_) {
             }
 
@@ -60,8 +60,8 @@ namespace Core {
 
         template<typename... Args>
         check_return Error put(T*& t, Entity ent, Args&&... args) {
-            int index = components.getLength();
-            int* indexP = nullptr;
+            i64 index = components.getLength();
+            i64* indexP = nullptr;
             CORE_RETURN_ERROR(entityToIndex.tryEmplace(indexP, ent, index));
             Error e = Error::NONE;
             if(checkError(e, indexToEntity.add(ent))) {
@@ -82,12 +82,12 @@ namespace Core {
         }
 
         check_return Error remove(Entity ent) {
-            int* indexP = entityToIndex.search(ent);
+            i64* indexP = entityToIndex.search(ent);
             if(indexP == nullptr) {
                 return Error::NOT_FOUND;
             }
-            int lastIndex = components.getLength() - 1;
-            int index = *indexP;
+            i64 lastIndex = components.getLength() - 1;
+            i64 index = *indexP;
             CORE_RETURN_ERROR(entityToIndex.remove(ent));
             CORE_RETURN_ERROR(components.removeBySwap(index));
             if(index == lastIndex) {
@@ -99,7 +99,7 @@ namespace Core {
         }
 
         T* search(Entity e) {
-            int* index = entityToIndex.search(e);
+            i64* index = entityToIndex.search(e);
             if(index == nullptr) {
                 return nullptr;
             }
@@ -107,7 +107,7 @@ namespace Core {
         }
 
         const T* search(Entity e) const {
-            const int* index = entityToIndex.search(e);
+            const i64* index = entityToIndex.search(e);
             if(index == nullptr) {
                 return nullptr;
             }

+ 12 - 11
include/core/data/HashMap.hpp

@@ -127,16 +127,16 @@ namespace Core {
             return Error::NONE;
         }
 
-        check_return Error rehash(int minCapacity) {
+        check_return Error rehash(i64 minCapacity) {
             if(minCapacity <= nodePointers.getLength()) {
                 return Error::NONE;
             }
             HashMap<K, V> map;
-            int l = Core::Math::max(1 << Math::roundUpLog2(minCapacity), 8);
+            i64 l = 1l << Math::roundUpLog2(Core::Math::max(minCapacity, 8l));
             CORE_RETURN_ERROR(map.nodePointers.resize(l));
             for(NodePointerList& list : nodePointers) {
                 for(NodePointer& n : list) {
-                    int h = map.hashIndex(n->data.key);
+                    i64 h = map.hashIndex(n->data.key);
                     CORE_RETURN_ERROR(map.nodePointers[h].add(n));
                 }
             }
@@ -147,7 +147,7 @@ namespace Core {
         template<typename... Args>
         check_return Error tryEmplace(V*& v, const K& key, Args&&... args) {
             CORE_RETURN_ERROR(rehash(nodes.getLength() + 1));
-            int h = hashIndex(key);
+            i64 h = hashIndex(key);
             v = searchList(key, h);
             if(v != nullptr) {
                 return Error::EXISTING_KEY;
@@ -166,7 +166,7 @@ namespace Core {
         template<typename VA>
         check_return Error put(V*& v, const K& key, VA&& value) {
             CORE_RETURN_ERROR(rehash(nodes.getLength() + 1));
-            int h = hashIndex(key);
+            i64 h = hashIndex(key);
             v = searchList(key, h);
             if(v != nullptr) {
                 *v = Core::forward<VA>(value);
@@ -191,7 +191,7 @@ namespace Core {
 
         check_return Error remove(const K& key) {
             NodePointerList& list = nodePointers[hashIndex(key)];
-            for(int i = 0; i < list.getLength(); i++) {
+            for(i64 i = 0; i < list.getLength(); i++) {
                 if(list[i]->data.key == key) {
                     nodes.remove(list[i]);
                     return list.removeBySwap(i);
@@ -255,12 +255,13 @@ namespace Core {
 
     private:
         template<typename H>
-        int hashIndex(const H& key) const {
-            return static_cast<int>(hashCode(key)) &
-                   (nodePointers.getLength() - 1);
+        i64 hashIndex(const H& key) const {
+            return static_cast<i64>(
+                hashCode(key) &
+                (static_cast<u64>(nodePointers.getLength()) - 1));
         }
 
-        const V* searchList(const K& key, int h) const {
+        const V* searchList(const K& key, i64 h) const {
             if(nodePointers.getLength() == 0) {
                 return nullptr;
             }
@@ -272,7 +273,7 @@ namespace Core {
             return nullptr;
         }
 
-        V* searchList(const K& key, int h) {
+        V* searchList(const K& key, i64 h) {
             return const_cast<V*>(
                 static_cast<const HashMap*>(this)->searchList(key, h));
         }

+ 2 - 5
include/core/data/LinkedList.hpp

@@ -47,7 +47,7 @@ namespace Core {
     private:
         Node* first;
         Node* last;
-        int length;
+        i64 length;
 
     public:
         LinkedList() : first(nullptr), last(nullptr), length(0) {
@@ -81,9 +81,6 @@ namespace Core {
 
         template<typename... Args>
         check_return Error put(Node*& n, Args&&... args) {
-            if(length >= CORE_INT_MAX) {
-                return Error::CAPACITY_REACHED;
-            }
             n = new Node(Core::forward<Args>(args)...);
             if(n == nullptr) {
                 return Error::OUT_OF_MEMORY;
@@ -122,7 +119,7 @@ namespace Core {
             return {nullptr};
         }
 
-        int getLength() const {
+        i64 getLength() const {
             return length;
         }
 

+ 24 - 32
include/core/data/List.hpp

@@ -8,8 +8,8 @@
 namespace Core {
     template<typename T>
     class List final {
-        int length;
-        int capacity;
+        i64 length;
+        i64 capacity;
         T* data;
 
     public:
@@ -38,7 +38,7 @@ namespace Core {
             List copy;
             CORE_RETURN_ERROR(allocate(copy.data, other.capacity));
             copy.capacity = other.capacity;
-            for(int i = 0; i < other.length; i++) {
+            for(i64 i = 0; i < other.length; i++) {
                 copy.unsafeAdd(other[i]);
             }
             swap(copy);
@@ -61,7 +61,7 @@ namespace Core {
             return data + length;
         }
 
-        check_return Error reserve(int n) {
+        check_return Error reserve(i64 n) {
             if(n <= capacity) {
                 return Error::NONE;
             }
@@ -75,14 +75,14 @@ namespace Core {
             return setSize(length);
         }
 
-        check_return Error resize(int n, const T& t) {
+        check_return Error resize(i64 n, const T& t) {
             if(length < n) {
                 CORE_RETURN_ERROR(reserve(n));
-                for(int i = n - length; i != 0; i--) {
+                for(i64 i = n - length; i != 0; i--) {
                     unsafeAdd(t);
                 }
             } else if(length > n) {
-                for(int i = n; i < length; i++) {
+                for(i64 i = n; i < length; i++) {
                     data[i].~T();
                 }
                 length = n;
@@ -90,14 +90,14 @@ namespace Core {
             return Error::NONE;
         }
 
-        check_return Error resize(int n) {
+        check_return Error resize(i64 n) {
             if(length < n) {
                 CORE_RETURN_ERROR(reserve(n));
-                for(int i = n - length; i != 0; i--) {
+                for(i64 i = n - length; i != 0; i--) {
                     unsafeAdd(T());
                 }
             } else if(length > n) {
-                for(int i = n; i < length; i++) {
+                for(i64 i = n; i < length; i++) {
                     data[i].~T();
                 }
                 length = n;
@@ -118,30 +118,30 @@ namespace Core {
             return put(t, Core::forward<Args>(args)...);
         }
 
-        T& operator[](int index) {
+        T& operator[](i64 index) {
             return data[index];
         }
 
-        const T& operator[](int index) const {
+        const T& operator[](i64 index) const {
             return data[index];
         }
 
-        int getLength() const {
+        i64 getLength() const {
             return length;
         }
 
-        int getCapacity() const {
+        i64 getCapacity() const {
             return capacity;
         }
 
         void clear() {
-            for(int i = 0; i < length; i++) {
+            for(i64 i = 0; i < length; i++) {
                 data[i].~T();
             }
             length = 0;
         }
 
-        check_return Error removeBySwap(int index) {
+        check_return Error removeBySwap(i64 index) {
             if(index < 0 || index >= length) {
                 return Error::INVALID_INDEX;
             }
@@ -153,7 +153,7 @@ namespace Core {
             return Error::NONE;
         }
 
-        check_return Error remove(int index) {
+        check_return Error remove(i64 index) {
             if(index < 0 || index >= length) {
                 return Error::INVALID_INDEX;
             }
@@ -185,26 +185,18 @@ namespace Core {
         }
 
     private:
-        static Error allocate(T*& t, int n) {
+        static Error allocate(T*& t, i64 n) {
             if(n <= 0) {
                 return Error::NONE;
             }
-            t = reinterpret_cast<T*>(
-                new AlignedType<T>[static_cast<size_t>(n)]);
+            t = reinterpret_cast<T*>(new AlignedType<T>[static_cast<u64>(n)]);
             return t == nullptr ? Error::OUT_OF_MEMORY : Error::NONE;
         }
 
         check_return Error ensureCapacity() {
-            if(length == CORE_INT_MAX) {
-                return Error::CAPACITY_REACHED;
-            } else if(length < capacity) {
-                return Error::NONE;
-            }
-            int add = Core::Math::max(4, capacity / 4);
-            if(capacity > CORE_INT_MAX - add) {
-                return reserve(CORE_INT_MAX);
-            }
-            return reserve(capacity + add);
+            return length < capacity
+                       ? Error::NONE
+                       : reserve(capacity + Core::Math::max(4l, capacity / 4));
         }
 
         // does not check for capacity
@@ -213,11 +205,11 @@ namespace Core {
             return new(data + length++) T(Core::forward<Args>(args)...);
         }
 
-        check_return Error setSize(int n) {
+        check_return Error setSize(i64 n) {
             List copy;
             CORE_RETURN_ERROR(allocate(copy.data, n));
             copy.capacity = n;
-            for(int i = 0; i < length; i++) {
+            for(i64 i = 0; i < length; i++) {
                 copy.unsafeAdd(Core::move(data[i]));
             }
             swap(copy);

+ 16 - 17
include/core/data/ProbingHashMap.hpp

@@ -122,7 +122,7 @@ namespace Core {
     private:
         List<K> keys;
         V* values;
-        int entries;
+        i64 entries;
 
     public:
         ProbingHashMap() : keys(), values(nullptr), entries(0) {
@@ -135,7 +135,7 @@ namespace Core {
         }
 
         ~ProbingHashMap() {
-            for(int i = 0; i < keys.getLength(); i++) {
+            for(i64 i = 0; i < keys.getLength(); i++) {
                 if(keys[i] != emptyValue<K>()) {
                     values[i].~V();
                 }
@@ -159,19 +159,18 @@ namespace Core {
             return Error::NONE;
         }
 
-        check_return Error rehash(int minCapacity) {
+        check_return Error rehash(i64 minCapacity) {
             if(minCapacity <= keys.getLength()) {
                 return Error::NONE;
             }
             ProbingHashMap<K, V> map;
-            int l = static_cast<int>(Core::Math::max(
-                1u << static_cast<u32>(Math::roundUpLog2(minCapacity)), 8u));
+            i64 l = 1l << Math::roundUpLog2(Core::Math::max(minCapacity, 8l));
             CORE_RETURN_ERROR(map.keys.resize(l, emptyValue<K>()));
             map.values = reinterpret_cast<V*>(new AlignedType<V>[l]);
             if(map.values == nullptr) {
                 return Error::OUT_OF_MEMORY;
             }
-            for(int i = 0; i < keys.getLength(); i++) {
+            for(i64 i = 0; i < keys.getLength(); i++) {
                 if(keys[i] != emptyValue<K>()) {
                     CORE_RETURN_ERROR(map.add(keys[i], values[i]));
                 }
@@ -185,7 +184,7 @@ namespace Core {
             if(key == emptyValue<K>()) {
                 return Error::INVALID_ARGUMENT;
             }
-            int index = 0;
+            i64 index = 0;
             CORE_RETURN_ERROR(searchSlot(index, key));
             if(keys[index] == key) {
                 return Error::EXISTING_KEY;
@@ -201,7 +200,7 @@ namespace Core {
             if(key == emptyValue<K>()) {
                 return Error::INVALID_ARGUMENT;
             }
-            int index = 0;
+            i64 index = 0;
             CORE_RETURN_ERROR(searchSlot(index, key));
             if(keys[index] == key) {
                 values[index] = Core::forward<VA>(value);
@@ -278,15 +277,15 @@ namespace Core {
         }
 
     private:
-        check_return Error searchSlot(int& slot, const K& key) {
-            int rehashFactor = 2;
+        check_return Error searchSlot(i64& slot, const K& key) {
+            i64 rehashFactor = 2;
             while(true) {
                 CORE_RETURN_ERROR(rehash(entries * rehashFactor + 1));
-                u32 baseHash = hashCode(key) * 514685581u;
-                u32 end = static_cast<u32>(keys.getLength()) - 1;
+                u64 baseHash = hashCode(key) * 514685581u;
+                u64 end = static_cast<u64>(keys.getLength()) - 1;
                 // rehash on bad clustering
-                for(u32 i = 0; i <= 5; i++) {
-                    int hash = static_cast<int>((baseHash + i) & end);
+                for(u64 i = 0; i <= 5; i++) {
+                    i64 hash = static_cast<i64>((baseHash + i) & end);
                     if(keys[hash] == emptyValue<K>() || keys[hash] == key) {
                         slot = hash;
                         return Core::Error::NONE;
@@ -299,10 +298,10 @@ namespace Core {
         template<typename Value>
         Value* searchValue(const K& key) const {
             if(keys.getLength() != 0) {
-                u32 baseHash = hashCode(key) * 514685581u;
-                u32 end = static_cast<u32>(keys.getLength()) - 1;
+                u64 baseHash = hashCode(key) * 514685581u;
+                u64 end = static_cast<u64>(keys.getLength()) - 1;
                 for(u32 i = 0; i <= end; i++) [[unlikely]] {
-                    int hash = static_cast<int>((baseHash + i) & end);
+                    i64 hash = static_cast<i64>((baseHash + i) & end);
                     if(keys[hash] == key) [[likely]] {
                         return values + hash;
                     } else if(keys[hash] == emptyValue<K>()) {

+ 13 - 13
include/core/data/RingBuffer.hpp

@@ -5,14 +5,14 @@
 #include "core/utils/ArrayString.hpp"
 
 namespace Core {
-    template<typename T, int N>
+    template<typename T, i64 N>
     class RingBuffer final {
         static_assert(N > 0, "RingBuffer size must be positive");
 
-        AlignedType<T> data[static_cast<unsigned int>(N)];
-        int writeIndex;
-        int readIndex;
-        int values;
+        AlignedType<T> data[static_cast<u64>(N)];
+        i64 writeIndex;
+        i64 readIndex;
+        i64 values;
 
     public:
         RingBuffer() : writeIndex(0), readIndex(0), values(0) {
@@ -65,15 +65,15 @@ namespace Core {
             return put(t, Core::forward<Args>(args)...);
         }
 
-        T& operator[](int index) {
+        T& operator[](i64 index) {
             return reinterpret_cast<T*>(data)[(index + readIndex) % N];
         }
 
-        const T& operator[](int index) const {
+        const T& operator[](i64 index) const {
             return reinterpret_cast<const T*>(data)[(index + readIndex) % N];
         }
 
-        int getLength() const {
+        i64 getLength() const {
             return values;
         }
 
@@ -82,7 +82,7 @@ namespace Core {
         }
 
         void clear() {
-            for(int i = 0; i < getLength(); i++) {
+            for(i64 i = 0; i < getLength(); i++) {
                 (*this)[i].~T();
             }
             writeIndex = 0;
@@ -103,10 +103,10 @@ namespace Core {
         template<typename String>
         check_return Error toString(String& s) const {
             CORE_RETURN_ERROR(s.append("["));
-            int end = getLength();
+            i64 end = getLength();
             if(end > 0) {
                 end--;
-                for(int i = 0; i < end; i++) {
+                for(i64 i = 0; i < end; i++) {
                     CORE_RETURN_ERROR(s.append((*this)[i]));
                     CORE_RETURN_ERROR(s.append(", "));
                 }
@@ -117,13 +117,13 @@ namespace Core {
 
     private:
         void copy(const RingBuffer& other) {
-            for(int i = 0; i < other.getLength(); i++) {
+            for(i64 i = 0; i < other.getLength(); i++) {
                 (void)add(other[i]);
             }
         }
 
         void move(RingBuffer&& other) {
-            for(int i = 0; i < other.getLength(); i++) {
+            for(i64 i = 0; i < other.getLength(); i++) {
                 (void)add(Core::move(other[i]));
             }
         }

+ 1 - 1
include/core/data/Stack.hpp

@@ -21,7 +21,7 @@ namespace Core {
             }
 
             check_return Error pop() {
-                int index = data.getLength();
+                i64 index = data.getLength();
                 if(index <= 0) {
                     return Error::INVALID_STATE;
                 }

+ 3 - 2
include/core/math/Math.hpp

@@ -13,11 +13,12 @@ namespace Core::Math {
         return (i & (i - 1)) == 0;
     }
 
-    constexpr int roundUpLog2(int i) {
+    template<typename T>
+    constexpr T roundUpLog2(T i) {
         if(i <= 0) {
             return 0;
         }
-        int c = 1;
+        T c = 1;
         while(((i - 1) >> c) > 0) {
             c++;
         }

+ 14 - 18
include/core/utils/HashCode.hpp

@@ -7,61 +7,57 @@
 
 namespace Core {
     template<typename H>
-    inline u32 hashCode(const H& key) {
+    inline u64 hashCode(const H& key) {
         return key.hashCode();
     }
 
     template<typename T>
-    inline u32 hashNumber(T t) {
+    inline u64 hashNumber(T t) {
         static_assert(sizeof(t) <= 8);
-        if constexpr(sizeof(t) <= 4) {
-            return static_cast<u32>(t);
-        }
-        return static_cast<u32>(static_cast<u64>(t) ^
-                                (static_cast<u64>(t) >> 32));
+        return static_cast<u64>(t);
     }
 
-    inline u32 hashCode(char key) {
+    inline u64 hashCode(char key) {
         return hashNumber(key);
     }
 
-    inline u32 hashCode(signed char key) {
+    inline u64 hashCode(signed char key) {
         return hashNumber(key);
     }
 
-    inline u32 hashCode(signed short key) {
+    inline u64 hashCode(signed short key) {
         return hashNumber(key);
     }
 
-    inline u32 hashCode(signed int key) {
+    inline u64 hashCode(signed int key) {
         return hashNumber(key);
     }
 
-    inline u32 hashCode(signed long key) {
+    inline u64 hashCode(signed long key) {
         return hashNumber(key);
     }
 
-    inline u32 hashCode(signed long long key) {
+    inline u64 hashCode(signed long long key) {
         return hashNumber(key);
     }
 
-    inline u32 hashCode(unsigned char key) {
+    inline u64 hashCode(unsigned char key) {
         return hashNumber(key);
     }
 
-    inline u32 hashCode(unsigned short key) {
+    inline u64 hashCode(unsigned short key) {
         return hashNumber(key);
     }
 
-    inline u32 hashCode(unsigned int key) {
+    inline u64 hashCode(unsigned int key) {
         return hashNumber(key);
     }
 
-    inline u32 hashCode(unsigned long key) {
+    inline u64 hashCode(unsigned long key) {
         return hashNumber(key);
     }
 
-    inline u32 hashCode(unsigned long long key) {
+    inline u64 hashCode(unsigned long long key) {
         return hashNumber(key);
     }
 

+ 0 - 6
include/core/utils/Types.hpp

@@ -14,10 +14,4 @@ using u16 = uint16_t;
 using u8 = uint8_t;
 using c32 = char32_t;
 
-// user customizable max container size
-#ifndef CORE_INT_MAX
-#define CORE_INT_MAX 65535
-#endif
-static_assert(CORE_INT_MAX < INT_MAX, "custom int max too large");
-
 #endif

+ 11 - 10
include/core/utils/Utility.hpp

@@ -3,15 +3,16 @@
 
 #include "core/utils/Check.hpp"
 #include "core/utils/Error.hpp"
+#include "core/utils/Types.hpp"
 
-#define CORE_SIZE(t) static_cast<int>(sizeof(t))
+#define CORE_SIZE(t) static_cast<i64>(sizeof(t))
 
 namespace Core {
-    template<typename T>
-    int popCount(const T& t) {
-        static constexpr int map[16] = {0, 1, 1, 2, 1, 2, 2, 3,
-                                        1, 2, 2, 3, 2, 3, 3, 4};
-        int sum = 0;
+    template<typename T, typename C = int>
+    C popCount(const T& t) {
+        static constexpr C map[16] = {0, 1, 1, 2, 1, 2, 2, 3,
+                                      1, 2, 2, 3, 2, 3, 3, 4};
+        C sum = 0;
         for(int i = 0; i < CORE_SIZE(T) * 8; i += 4) {
             sum += map[(t >> i) & 0xF];
         }
@@ -38,10 +39,10 @@ namespace Core {
 
     check_return Error putChar(int c);
 
-    void memorySet(void* p, int c, int n);
-    void memoryCopy(void* dest, const void* src, int n);
-    bool memoryCompare(const void* a, const void* b, int n);
-    check_return Error reallocate(char*& p, int n);
+    void memorySet(void* p, int c, i64 n);
+    void memoryCopy(void* dest, const void* src, i64 n);
+    bool memoryCompare(const void* a, const void* b, i64 n);
+    check_return Error reallocate(char*& p, i64 n);
     void free(void* p);
 }
 

+ 63 - 60
src/BitArray.cpp

@@ -3,54 +3,58 @@
 #include "core/math/Math.hpp"
 #include "core/utils/New.hpp"
 
-static int roundUpDivide(int a, int b) {
+static u64 roundUpDivide(u64 a, u64 b) {
     if(a % b == 0) {
         return a / b;
     }
     return a / b + 1;
 }
 
-static constexpr int INT_BITS = sizeof(int) * 8;
-static constexpr int DIVIDE_BITS = Core::Math::roundUpLog2(INT_BITS);
+static constexpr u64 U64_BITS = 64;
+static constexpr u64 DIVIDE_BITS = Core::Math::roundUpLog2(U64_BITS);
+static constexpr u64 LENGTH_MASK = 0x01FF'FFFF'FFFF'FFFF;
+static constexpr u64 LENGTH_BITS = Core::Math::roundUpLog2(LENGTH_MASK);
+static_assert(LENGTH_BITS == 57, "wusi");
 
-static int readBits(const int* data, int index, int bits) {
-    int dataIndexA = (index * bits) >> DIVIDE_BITS;
-    int dataIndexB = ((index * bits) + (bits - 1)) >> DIVIDE_BITS;
-    int shifts = (index * bits) & (INT_BITS - 1);
+static u64 readBits(const u64* data, u64 index, u64 bits) {
+    u64 dataIndexA = (index * bits) >> DIVIDE_BITS;
+    u64 dataIndexB = ((index * bits) + (bits - 1lu)) >> DIVIDE_BITS;
+    u64 shifts = (index * bits) & (U64_BITS - 1lu);
     if(dataIndexA == dataIndexB) {
-        return (data[dataIndexA] >> shifts) & ((1 << bits) - 1);
+        return (data[dataIndexA] >> shifts) & ((1lu << bits) - 1lu);
     }
-    int bitsInA = INT_BITS - shifts;
-    int r = (data[dataIndexA] >> shifts) & ((1 << bitsInA) - 1);
-    r |= (data[dataIndexB] & ((1 << (bits - bitsInA)) - 1)) << bitsInA;
+    u64 bitsInA = U64_BITS - shifts;
+    u64 r = (data[dataIndexA] >> shifts) & ((1lu << bitsInA) - 1lu);
+    r |= (data[dataIndexB] & ((1lu << (bits - bitsInA)) - 1lu)) << bitsInA;
     return r;
 }
 
-static void setBits(int* data, int index, int bits, int value) {
-    int mask = (1 << bits) - 1;
+static void setBits(u64* data, u64 index, u64 bits, u64 value) {
+    u64 mask = (1lu << bits) - 1lu;
     value &= mask;
-    int dataIndexA = (index * bits) >> DIVIDE_BITS;
-    int dataIndexB = ((index * bits) + (bits - 1)) >> DIVIDE_BITS;
-    int shifts = (index * bits) & (INT_BITS - 1);
+    u64 dataIndexA = (index * bits) >> DIVIDE_BITS;
+    u64 dataIndexB = ((index * bits) + (bits - 1lu)) >> DIVIDE_BITS;
+    u64 shifts = (index * bits) & (U64_BITS - 1lu);
     data[dataIndexA] &= ~(mask << shifts);
     data[dataIndexA] |= (value << shifts);
     if(dataIndexA != dataIndexB) {
-        int leftBits = bits - (INT_BITS - shifts);
-        data[dataIndexB] &= ~((1 << leftBits) - 1);
-        data[dataIndexB] |= (value >> (INT_BITS - shifts));
+        u64 leftBits = bits - (U64_BITS - shifts);
+        data[dataIndexB] &= ~((1lu << leftBits) - 1lu);
+        data[dataIndexB] |= (value >> (U64_BITS - shifts));
     }
 }
 
-static int getArrayLength(int length, int bits) {
-    return roundUpDivide(length * bits, INT_BITS);
+static u64 getArrayLength(u64 length, u64 bits) {
+    return roundUpDivide(length * bits, U64_BITS);
 }
 
-Core::BitArray::BitArray() : length(0), bits(0), data(nullptr) {
+Core::BitArray::BitArray() : lengthBits(0), data(nullptr) {
 }
 
 check_return Core::Error Core::BitArray::copyFrom(const BitArray& other) {
-    CORE_RETURN_ERROR(resize(other.length, other.bits));
-    for(int i = 0; i < length; i++) {
+    CORE_RETURN_ERROR(resize(other.getLength(), other.getBits()));
+    u64 length = getLength();
+    for(u64 i = 0; i < length; i++) {
         set(i, other.get(i));
     }
     return Error::NONE;
@@ -69,93 +73,92 @@ Core::BitArray& Core::BitArray::operator=(BitArray&& other) {
     return *this;
 }
 
-Core::BitArray& Core::BitArray::set(int index, int value) {
-    if(data == nullptr || index < 0 || index >= length) {
+Core::BitArray& Core::BitArray::set(u64 index, u64 value) {
+    if(data == nullptr || index >= getLength()) {
         return *this;
     }
-    setBits(data, index, bits, value);
+    setBits(data, index, getBits(), value);
     return *this;
 }
 
-int Core::BitArray::get(int index) const {
-    if(data == nullptr || index < 0 || index >= length) {
+u64 Core::BitArray::get(u64 index) const {
+    if(data == nullptr || index >= getLength()) {
         return 0;
     }
-    return readBits(data, index, bits);
+    return readBits(data, index, getBits());
 }
 
-int Core::BitArray::getLength() const {
-    return length;
+u64 Core::BitArray::getLength() const {
+    return lengthBits & LENGTH_MASK;
 }
 
-int Core::BitArray::getBits() const {
-    return bits;
+u64 Core::BitArray::getBits() const {
+    return (lengthBits & ~LENGTH_MASK) >> LENGTH_BITS;
 }
 
-int Core::BitArray::getInternalByteSize() const {
-    if(bits <= 0 || length <= 0) {
+u64 Core::BitArray::getInternalByteSize() const {
+    if(getLength() <= 0 || getBits() <= 0) {
         return 0;
     }
-    return getArrayLength(length, bits) * CORE_SIZE(int);
+    return getArrayLength(getLength(), getBits()) * CORE_SIZE(u64);
 }
 
-int Core::BitArray::select(int index) const {
+i64 Core::BitArray::select(u64 index) const {
     if(index <= 0) {
         return -1;
     }
-    int found = 0;
-    int end = getArrayLength(length, bits);
-    for(int i = 0; i < end; i++) {
-        int ones = Core::popCount(data[i]);
+    u64 found = 0;
+    u64 end = getArrayLength(getLength(), getBits());
+    for(u64 i = 0; i < end; i++) {
+        u64 ones = Core::popCount<u64, u64>(data[i]);
         found += ones;
         if(found >= index) {
             found -= ones;
-            int a = i * 32 - 1;
-            int d = data[i];
+            u64 a = i * U64_BITS - 1;
+            u64 d = data[i];
             while(found < index) {
                 found += d & 1;
                 d >>= 1;
                 a++;
             }
-            return a;
+            return static_cast<i64>(a);
         }
     }
     return -1;
 }
 
-void Core::BitArray::fill(int value) {
-    for(int i = 0; i < length; i++) {
+void Core::BitArray::fill(u64 value) {
+    u64 length = getLength();
+    for(u64 i = 0; i < length; i++) {
         set(i, value);
     }
 }
 
-check_return Core::Error Core::BitArray::resize(int newLength, int newBits) {
-    if(newLength <= 0 || newBits <= 0) {
-        return Error::NEGATIVE_ARGUMENT;
+check_return Core::Error Core::BitArray::resize(u64 newLength, u64 newBits) {
+    if(newLength == 0 || newBits == 0 || newBits > 64) {
+        return Error::INVALID_ARGUMENT;
     }
-    int arrayLength = getArrayLength(newLength, newBits);
-    int* newData = new int[arrayLength];
+    u64 arrayLength = getArrayLength(newLength, newBits);
+    u64* newData = new u64[arrayLength];
     if(newData == nullptr) {
         return Error::OUT_OF_MEMORY;
     }
-    Core::memorySet(newData, 0, arrayLength * CORE_SIZE(int));
+    Core::memorySet(newData, 0, static_cast<i64>(arrayLength) * CORE_SIZE(int));
 
-    int end = Math::min(length, newLength);
-    for(int i = 0; i < end; i++) {
+    u64 end = Math::min(getLength(), newLength);
+    for(u64 i = 0; i < end; i++) {
         setBits(newData, i, newBits, get(i));
     }
-    for(int i = end; i < newLength; i++) {
+    for(u64 i = end; i < newLength; i++) {
         setBits(newData, i, newBits, 0);
     }
     delete[] data;
     data = newData;
-    bits = newBits;
-    length = newLength;
+    lengthBits = newLength | (newBits << LENGTH_BITS);
     return Error::NONE;
 }
 
 void Core::BitArray::swap(BitArray& other) {
-    Core::swap(length, other.length);
-    Core::swap(bits, other.bits);
+    Core::swap(lengthBits, other.lengthBits);
     Core::swap(data, other.data);
 }

+ 8 - 8
src/Utility.cpp

@@ -54,31 +54,31 @@ Core::Error Core::putChar(int c) {
     return putchar(c) == EOF ? Error::BLOCKED_STDOUT : Error::NONE;
 }
 
-void Core::memorySet(void* p, int c, int n) {
+void Core::memorySet(void* p, int c, i64 n) {
     if(n <= 0) {
         return;
     }
-    memset(p, c, static_cast<unsigned int>(n));
+    memset(p, c, static_cast<u64>(n));
 }
 
-void Core::memoryCopy(void* dest, const void* src, int n) {
+void Core::memoryCopy(void* dest, const void* src, i64 n) {
     if(n <= 0) {
         return;
     }
-    memcpy(dest, src, static_cast<unsigned int>(n));
+    memcpy(dest, src, static_cast<u64>(n));
 }
 
-bool Core::memoryCompare(const void* a, const void* b, int n) {
-    return n <= 0 ? true : memcmp(a, b, static_cast<unsigned int>(n)) == 0;
+bool Core::memoryCompare(const void* a, const void* b, i64 n) {
+    return n <= 0 ? true : memcmp(a, b, static_cast<u64>(n)) == 0;
 }
 
-Core::Error Core::reallocate(char*& p, int n) {
+Core::Error Core::reallocate(char*& p, i64 n) {
     if(n <= 0) {
         free(p);
         p = nullptr;
         return Error::NONE;
     }
-    char* newP = static_cast<char*>(realloc(p, static_cast<unsigned int>(n)));
+    char* newP = static_cast<char*>(realloc(p, static_cast<u64>(n)));
     if(newP == nullptr || CORE_REALLOC_FAIL(newP)) {
         return Error::OUT_OF_MEMORY;
     }

+ 27 - 19
test/modules/BitArrayTests.cpp

@@ -24,34 +24,34 @@ static void testOutOfBoundsSetRead() {
 static void testBigSetRead() {
     Core::BitArray bits;
     CORE_TEST_ERROR(bits.resize(100, 13));
-    for(int i = 0; i < bits.getLength(); i++) {
+    for(u64 i = 0; i < bits.getLength(); i++) {
         bits.set(i, i);
     }
-    for(int i = 0; i < bits.getLength(); i++) {
+    for(u64 i = 0; i < bits.getLength(); i++) {
         CORE_TEST_EQUAL(i, bits.get(i));
     }
 }
 
 static void testRandomSetReadResize() {
     const int length = 100;
-    int data[length];
+    u64 data[length];
     Core::BitArray bits;
     CORE_TEST_ERROR(bits.resize(100, 13));
-    int seed = 534;
+    u64 seed = 534;
     for(int k = 0; k < 20; k++) {
-        for(int i = 0; i < bits.getLength(); i++) {
+        for(u64 i = 0; i < bits.getLength(); i++) {
             seed = seed * 636455 + 53453;
             bits.set(i, seed & (0x1FFF));
             data[i] = seed & (0x1FFF);
         }
     }
-    for(int i = 0; i < bits.getLength(); i++) {
+    for(u64 i = 0; i < bits.getLength(); i++) {
         CORE_TEST_EQUAL(data[i], bits.get(i));
     }
     CORE_TEST_ERROR(bits.resize(bits.getLength(), bits.getBits() + 1));
     CORE_TEST_EQUAL(14, bits.getBits());
     CORE_TEST_EQUAL(100, bits.getLength());
-    for(int i = 0; i < bits.getLength(); i++) {
+    for(u64 i = 0; i < bits.getLength(); i++) {
         CORE_TEST_EQUAL(data[i], bits.get(i));
     }
 }
@@ -75,7 +75,6 @@ static void testSelect() {
     bits.fill(0);
     bits.set(0, 1).set(5, 1).set(20, 1).set(31, 1);
     bits.set(32, 1).set(33, 1).set(60, 1);
-    CORE_TEST_EQUAL(-1, bits.select(-1));
     CORE_TEST_EQUAL(-1, bits.select(0));
     CORE_TEST_EQUAL(0, bits.select(1));
     CORE_TEST_EQUAL(5, bits.select(2));
@@ -110,36 +109,38 @@ static void testResizeExact() {
     Core::BitArray bits;
     CORE_TEST_EQUAL(0, bits.getInternalByteSize());
     // the size in bytes matches the internal storage type
-    int elements = CORE_SIZE(int);
+    u64 elements = sizeof(u64);
     CORE_TEST_ERROR(bits.resize(elements, 8));
-    for(int i = 0; i < elements; i++) {
+    for(u64 i = 0; i < elements; i++) {
         bits.set(i, i);
     }
-    for(int i = 0; i < elements; i++) {
+    for(u64 i = 0; i < elements; i++) {
         CORE_TEST_EQUAL(i, bits.get(i));
     }
-    CORE_TEST_EQUAL(CORE_SIZE(int), bits.getInternalByteSize());
+    CORE_TEST_EQUAL(CORE_SIZE(u64), bits.getInternalByteSize());
 }
 
 static void testMoveAssignment() {
     Core::BitArray bits;
     CORE_TEST_ERROR(bits.resize(8, 8));
-    for(int i = 0; i < bits.getLength(); i++) {
+    for(u64 i = 0; i < bits.getLength(); i++) {
         bits.set(i, i);
     }
     Core::BitArray m;
     m = Core::move(bits);
     CORE_TEST_EQUAL(8, m.getLength());
-    for(int i = 0; i < m.getLength(); i++) {
+    for(u64 i = 0; i < m.getLength(); i++) {
         CORE_TEST_EQUAL(i, m.get(i));
     }
 }
 
-static void testNegativeArgument() {
+static void testInvalidArgument() {
     Core::BitArray bits;
-    CORE_TEST_EQUAL(Core::Error::NEGATIVE_ARGUMENT, bits.resize(-1, 5));
-    CORE_TEST_EQUAL(Core::Error::NEGATIVE_ARGUMENT, bits.resize(5, -1));
-    CORE_TEST_EQUAL(Core::Error::NEGATIVE_ARGUMENT, bits.resize(-1, -1));
+    CORE_TEST_EQUAL(Core::Error::INVALID_ARGUMENT, bits.resize(0, 5));
+    CORE_TEST_EQUAL(Core::Error::INVALID_ARGUMENT, bits.resize(5, 0));
+    CORE_TEST_EQUAL(Core::Error::INVALID_ARGUMENT, bits.resize(0, 0));
+    CORE_TEST_EQUAL(Core::Error::INVALID_ARGUMENT, bits.resize(1, 65));
+    CORE_TEST_EQUAL(Core::Error::INVALID_ARGUMENT, bits.resize(5, 68));
 }
 
 static void testOutOfMemory() {
@@ -151,6 +152,12 @@ static void testOutOfMemory() {
 #endif
 }
 
+static void testOutOfMemory2() {
+    Core::BitArray bits;
+    CORE_TEST_EQUAL(Core::Error::OUT_OF_MEMORY,
+                    bits.resize(0x01FF'FFFF'FFFF'FFFF, 64));
+}
+
 void Core::testBitArray(bool outOfMemoryTest) {
     testSetRead();
     testOutOfBoundsSetRead();
@@ -163,8 +170,9 @@ void Core::testBitArray(bool outOfMemoryTest) {
     testToString3();
     testResizeExact();
     testMoveAssignment();
-    testNegativeArgument();
+    testInvalidArgument();
     if(outOfMemoryTest) {
         testOutOfMemory();
     }
+    testOutOfMemory2();
 }

+ 0 - 9
test/modules/LinkedListTests.cpp

@@ -293,14 +293,6 @@ static void testOutOfMemory() {
 #endif
 }
 
-static void testOverflow() {
-    IntList list;
-    for(int i = 0; i < CORE_INT_MAX; i++) {
-        CORE_TEST_ERROR(list.add(i));
-    }
-    CORE_TEST_EQUAL(Core::Error::CAPACITY_REACHED, list.add(1));
-}
-
 void Core::testLinkedList(bool light, bool outOfMemoryTest) {
     testWithoutCopyOrMove();
     testAdd();
@@ -319,5 +311,4 @@ void Core::testLinkedList(bool light, bool outOfMemoryTest) {
     if(outOfMemoryTest) {
         testOutOfMemory();
     }
-    testOverflow();
 }

+ 2 - 12
test/modules/ListTests.cpp

@@ -76,8 +76,8 @@ static void testCopy() {
     IntList copy;
     CORE_TEST_ERROR(copy.copyFrom(list));
     CORE_TEST_EQUAL(list.getLength(), copy.getLength());
-    int limit = Core::Math::min(copy.getLength(), list.getLength());
-    for(int i = 0; i < limit; i++) {
+    i64 limit = Core::Math::min(copy.getLength(), list.getLength());
+    for(i64 i = 0; i < limit; i++) {
         CORE_TEST_EQUAL(list[i], copy[i]);
     }
 }
@@ -212,15 +212,6 @@ static void testCopyEmpty() {
     CORE_TEST_ERROR(copy.copyFrom(list));
 }
 
-static void testOverflow() {
-    IntList list;
-    for(int i = 0; i < CORE_INT_MAX; i++) {
-        CORE_TEST_ERROR(list.add(i));
-    }
-    CORE_TEST_EQUAL(Core::Error::CAPACITY_REACHED, list.add(1));
-    CORE_TEST_EQUAL(CORE_INT_MAX, list.getCapacity());
-}
-
 void Core::testList(bool light) {
     testAdd();
     testMultipleAdd();
@@ -242,5 +233,4 @@ void Core::testList(bool light) {
     testShrinkExact();
     testShrinkResize();
     testCopyEmpty();
-    testOverflow();
 }