Переглянути джерело

Use return values instead of the error callback

Kajetan Johannes Hammerle 1 рік тому
батько
коміт
493b3be1e7

+ 6 - 10
data/Array.h

@@ -50,19 +50,15 @@ namespace Core {
             return N;
         }
 
-        // returns true on error and calls the error callback
         template<int L>
-        check_return bool toString(ArrayString<L>& s) const {
-            if(s.append("[")) {
-                return true;
-            }
+        check_return Error toString(ArrayString<L>& s) const {
+            CORE_RETURN_ERROR(s.append("["));
             for(int i = 0; i < N - 1; i++) {
-                if(s.append(data[i]) || s.append(", ")) {
-                    return true;
-                }
+                CORE_RETURN_ERROR(s.append(data[i]));
+                CORE_RETURN_ERROR(s.append(", "));
             }
-            if(N > 0 && s.append(data[N - 1])) {
-                return true;
+            if(N > 0) {
+                CORE_RETURN_ERROR(s.append(data[N - 1]));
             }
             return s.append("]");
         }

+ 20 - 21
data/ArrayList.h

@@ -65,14 +65,19 @@ namespace Core {
             return begin() + length;
         }
 
-        // returns a nullptr on error and calls the error callback
         template<typename... Args>
-        check_return T* add(Args&&... args) {
+        check_return Error put(T*& t, Args&&... args) {
             if(length >= N) {
-                CORE_ERROR(Error::CAPACITY_REACHED);
-                return nullptr;
+                return Error::CAPACITY_REACHED;
             }
-            return new(begin() + length++) T(Core::forward<Args>(args)...);
+            t = new(begin() + length++) T(Core::forward<Args>(args)...);
+            return Error::NONE;
+        }
+
+        template<typename... Args>
+        check_return Error add(Args&&... args) {
+            T* t = nullptr;
+            return put(t, Core::forward<Args>(args)...);
         }
 
         T& operator[](int index) {
@@ -94,37 +99,31 @@ namespace Core {
             length = 0;
         }
 
-        // returns true on error and calls the error callback
-        check_return bool removeBySwap(int index) {
+        check_return Error removeBySwap(int index) {
             if(index < 0 || index >= length) {
-                return CORE_ERROR(Error::INVALID_REMOVE_INDEX);
+                return Error::INVALID_INDEX;
             }
             length--;
             if(index != length) {
                 begin()[index] = Core::move(begin()[length]);
             }
             begin()[length].~T();
-            return false;
+            return Error::NONE;
         }
 
-        // returns true on error and calls the error callback
-        check_return bool removeLast() {
+        check_return Error removeLast() {
             return removeBySwap(length - 1);
         }
 
-        // returns true on error and calls the error callback
         template<int L>
-        check_return bool toString(ArrayString<L>& s) const {
-            if(s.append("[")) {
-                return true;
-            }
+        check_return Error toString(ArrayString<L>& s) const {
+            CORE_RETURN_ERROR(s.append("["));
             for(int i = 0; i < length - 1; i++) {
-                if(s.append(begin()[i]) || s.append(", ")) {
-                    return true;
-                }
+                CORE_RETURN_ERROR(s.append(begin()[i]));
+                CORE_RETURN_ERROR(s.append(", "));
             }
-            if(length > 0 && s.append(begin()[length - 1])) {
-                return true;
+            if(length > 0) {
+                CORE_RETURN_ERROR(s.append(begin()[length - 1]));
             }
             return s.append("]");
         }

+ 7 - 9
data/BitArray.cpp

@@ -48,14 +48,12 @@ static int getArrayLength(int length, int bits) {
 Core::BitArray::BitArray() : length(0), bits(0), data(nullptr) {
 }
 
-check_return bool Core::BitArray::copyFrom(const BitArray& other) {
-    if(resize(other.length, other.bits)) {
-        return true;
-    }
+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++) {
         set(i, other.get(i));
     }
-    return false;
+    return Error::NONE;
 }
 
 Core::BitArray::BitArray(BitArray&& other) : BitArray() {
@@ -131,14 +129,14 @@ void Core::BitArray::fill(int value) {
     }
 }
 
-check_return bool Core::BitArray::resize(int newLength, int newBits) {
+check_return Core::Error Core::BitArray::resize(int newLength, int newBits) {
     if(newLength <= 0 || newBits <= 0) {
-        return CORE_ERROR(Error::NEGATIVE_ARGUMENT);
+        return Error::NEGATIVE_ARGUMENT;
     }
     int arrayLength = getArrayLength(newLength, newBits);
     int* newData = new int[arrayLength];
     if(newData == nullptr) {
-        return CORE_ERROR(Error::OUT_OF_MEMORY);
+        return Error::OUT_OF_MEMORY;
     }
     Core::memorySet(newData, 0, arrayLength * CORE_SIZE(int));
 
@@ -153,7 +151,7 @@ check_return bool Core::BitArray::resize(int newLength, int newBits) {
     data = newData;
     bits = newBits;
     length = newLength;
-    return false;
+    return Error::NONE;
 }
 
 void Core::BitArray::swap(BitArray& other) {

+ 8 - 14
data/BitArray.h

@@ -17,8 +17,7 @@ namespace Core {
         BitArray& operator=(const BitArray& other) = delete;
         BitArray& operator=(BitArray&& other);
 
-        // returns true on error and calls the error callback
-        check_return bool copyFrom(const BitArray& other);
+        check_return Error copyFrom(const BitArray& other);
 
         BitArray& set(int index, int value);
         int get(int index) const;
@@ -29,24 +28,19 @@ namespace Core {
 
         int select(int index) const;
 
-        // returns true on error and calls the error callback
-        check_return bool resize(int newLength, int newBits);
+        check_return Error resize(int newLength, int newBits);
 
         void fill(int value);
 
-        // returns true on error and calls the error callback
         template<int L>
-        check_return bool toString(ArrayString<L>& s) const {
-            if(s.append("[")) {
-                return true;
-            }
+        check_return Error toString(ArrayString<L>& s) const {
+            CORE_RETURN_ERROR(s.append("["));
             for(int i = 0; i < length - 1; i++) {
-                if(s.append(get(i)) || s.append(", ")) {
-                    return true;
-                }
+                CORE_RETURN_ERROR(s.append(get(i)));
+                CORE_RETURN_ERROR(s.append(", "));
             }
-            if(length > 0 && s.append(get(length - 1))) {
-                return true;
+            if(length > 0) {
+                CORE_RETURN_ERROR(s.append(get(length - 1)));
             }
             return s.append("]");
         }

+ 24 - 20
data/Components.h

@@ -58,40 +58,44 @@ namespace Core {
             }
         };
 
-        // returns a nullptr on error and calls the error callback
         template<typename... Args>
-        check_return T* add(Entity e, Args&&... args) {
+        check_return Error put(T*& t, Entity ent, Args&&... args) {
             int index = components.getLength();
-            if(entityToIndex.tryEmplace(e, index) == nullptr) {
-                return nullptr;
-            } else if(indexToEntity.add(e) == nullptr) {
-                (void)entityToIndex.remove(e);
-                return nullptr;
+            int* indexP = nullptr;
+            CORE_RETURN_ERROR(entityToIndex.tryEmplace(indexP, ent, index));
+            Error e = Error::NONE;
+            if(checkError(e, indexToEntity.add(ent))) {
+                (void)entityToIndex.remove(ent);
+                return e;
             }
-            T* c = components.add(Core::forward<Args>(args)...);
-            if(c == nullptr) {
-                (void)entityToIndex.remove(e);
+            if(checkError(e, components.put(t, Core::forward<Args>(args)...))) {
+                (void)entityToIndex.remove(ent);
                 (void)indexToEntity.removeLast();
             }
-            return c;
+            return e;
+        }
+
+        template<typename... Args>
+        check_return Error add(Entity e, Args&&... args) {
+            T* t = nullptr;
+            return put(t, e, Core::forward<Args>(args)...);
         }
 
-        // returns true on error and calls the error callback
-        check_return bool remove(Entity e) {
-            int* indexP = entityToIndex.search(e);
+        check_return Error remove(Entity ent) {
+            int* indexP = entityToIndex.search(ent);
             if(indexP == nullptr) {
-                return true;
+                return Error::NOT_FOUND;
             }
             int lastIndex = components.getLength() - 1;
             int index = *indexP;
-            bool r = entityToIndex.remove(e);
-            r |= components.removeBySwap(index);
+            CORE_RETURN_ERROR(entityToIndex.remove(ent));
+            CORE_RETURN_ERROR(components.removeBySwap(index));
             if(index == lastIndex) {
-                return r | indexToEntity.removeBySwap(index);
+                return indexToEntity.removeBySwap(index);
             }
             Entity other = indexToEntity[lastIndex];
-            r |= indexToEntity.removeBySwap(index);
-            return r | (entityToIndex.add(other, index) == nullptr);
+            CORE_RETURN_ERROR(indexToEntity.removeBySwap(index));
+            return entityToIndex.add(other, index);
         }
 
         T* search(Entity e) {

+ 48 - 60
data/HashMap.h

@@ -115,96 +115,87 @@ namespace Core {
         List<NodePointerList> nodePointers;
 
     public:
-        // returns true on error and calls the error callback
-        check_return bool copyFrom(const HashMap& other) {
+        check_return Error copyFrom(const HashMap& other) {
             HashMap copy;
-            for(const auto& e : other) {
-                if(copy.add(e.getKey(), e.value) == nullptr) {
-                    return true;
-                }
+            for(const auto& en : other) {
+                CORE_RETURN_ERROR(copy.add(en.getKey(), en.value));
             }
             swap(copy.nodes, nodes);
             swap(copy.nodePointers, nodePointers);
-            return false;
+            return Error::NONE;
         }
 
-        // returns true on error and calls the error callback
-        check_return bool rehash(int minCapacity) {
+        check_return Error rehash(int minCapacity) {
             if(minCapacity <= nodePointers.getLength()) {
-                return false;
+                return Error::NONE;
             }
             HashMap<K, V> map;
             int l = 1 << Math::roundUpLog2(Core::Math::max(minCapacity, 8));
-            if(map.nodePointers.resize(l)) {
-                return true;
-            }
+            CORE_RETURN_ERROR(map.nodePointers.resize(l));
             for(NodePointerList& list : nodePointers) {
                 for(NodePointer& n : list) {
                     int h = map.hashIndex(n->data.key);
-                    if(map.nodePointers[h].add(n) == nullptr) {
-                        return true;
-                    }
+                    CORE_RETURN_ERROR(map.nodePointers[h].add(n));
                 }
             }
             Core::swap(map.nodePointers, nodePointers);
-            return false;
+            return Error::NONE;
         }
 
-        // returns a nullptr on error and calls the error callback
         template<typename... Args>
-        check_return V* tryEmplace(const K& key, Args&&... args) {
-            if(rehash(nodes.getLength() + 1)) {
-                return nullptr;
-            }
+        check_return Error tryEmplace(V*& v, const K& key, Args&&... args) {
+            CORE_RETURN_ERROR(rehash(nodes.getLength() + 1));
             int h = hashIndex(key);
-            V* v = searchList(key, h);
+            v = searchList(key, h);
             if(v != nullptr) {
-                return nullptr;
+                return Error::EXISTING_KEY;
             }
-            NodePointer np = nodes.add(key, Core::forward<Args>(args)...);
-            if(np == nullptr) {
-                return nullptr;
-            } else if(nodePointers[h].add(np) == nullptr) {
+            NodePointer np = nullptr;
+            CORE_RETURN_ERROR(nodes.put(np, key, Core::forward<Args>(args)...));
+            Error e = Error::NONE;
+            if(checkError(e, nodePointers[h].add(np))) {
                 nodes.remove(np);
-                return nullptr;
+                return e;
             }
-            return &(np->data.value);
+            v = &(np->data.value);
+            return Error::NONE;
         }
 
-        // returns a nullptr on error and calls the error callback
         template<typename VA>
-        check_return V* add(const K& key, VA&& value) {
-            if(rehash(nodes.getLength() + 1)) {
-                return nullptr;
-            }
+        check_return Error put(V*& v, const K& key, VA&& value) {
+            CORE_RETURN_ERROR(rehash(nodes.getLength() + 1));
             int h = hashIndex(key);
-            V* v = searchList(key, h);
+            v = searchList(key, h);
             if(v != nullptr) {
                 *v = Core::forward<VA>(value);
-                return v;
+                return Error::NONE;
             }
-            NodePointer np = nodes.add(key, Core::forward<VA>(value));
-            if(np == nullptr) {
-                return nullptr;
-            } else if(nodePointers[h].add(np) == nullptr) {
+            NodePointer np = nullptr;
+            CORE_RETURN_ERROR(nodes.put(np, key, Core::forward<VA>(value)));
+            Error e = Error::NONE;
+            if(checkError(e, nodePointers[h].add(np))) {
                 nodes.remove(np);
-                return nullptr;
+                return e;
             }
-            return &(np->data.value);
+            v = &(np->data.value);
+            return Error::NONE;
         }
 
-        // returns true on error and calls the error callback
-        check_return bool remove(const K& key) {
+        template<typename VA>
+        check_return Error add(const K& key, VA&& value) {
+            V* v = nullptr;
+            return put(v, key, Core::forward<VA>(value));
+        }
+
+        check_return Error remove(const K& key) {
             NodePointerList& list = nodePointers[hashIndex(key)];
             for(int i = 0; i < list.getLength(); i++) {
                 if(list[i]->data.key == key) {
-                    NodePointer np = list[i];
-                    bool r = list.removeBySwap(i);
-                    nodes.remove(np);
-                    return r;
+                    nodes.remove(list[i]);
+                    return list.removeBySwap(i);
                 }
             }
-            return true;
+            return Error::NOT_FOUND;
         }
 
         const V* search(const K& key) const {
@@ -263,21 +254,18 @@ namespace Core {
             return ConstEntryIterator(nodes.end());
         }
 
-        // returns true on error and calls the error callback
         template<int L>
-        check_return bool toString(ArrayString<L>& s) const {
-            if(s.append("[")) {
-                return true;
-            }
+        check_return Error toString(ArrayString<L>& s) const {
+            CORE_RETURN_ERROR(s.append("["))
             bool c = false;
             for(const NodePointerList& list : nodePointers) {
                 for(const NodePointer& n : list) {
-                    if(c && s.append(", ")) {
-                        return true;
-                    } else if(s.append(n->data.key) || s.append(" = ") ||
-                              s.append(n->data.value)) {
-                        return true;
+                    if(c) {
+                        CORE_RETURN_ERROR(s.append(", "))
                     }
+                    CORE_RETURN_ERROR(s.append(n->data.key))
+                    CORE_RETURN_ERROR(s.append(" = "))
+                    CORE_RETURN_ERROR(s.append(n->data.value))
                     c = true;
                 }
             }

+ 20 - 23
data/LinkedList.h

@@ -70,36 +70,37 @@ namespace Core {
             return *this;
         }
 
-        // returns true on error and calls the error callback
-        check_return bool copyFrom(const LinkedList& other) {
+        check_return Error copyFrom(const LinkedList& other) {
             LinkedList copy;
             for(const T& t : other) {
-                if(copy.add(t) == nullptr) {
-                    return true;
-                }
+                CORE_RETURN_ERROR(copy.add(t));
             }
             swap(copy);
-            return false;
+            return Error::NONE;
         }
 
-        // returns a nullptr on error and calls the error callback
         template<typename... Args>
-        check_return Node* add(Args&&... args) {
-            Node* n = new Node(Core::forward<Args>(args)...);
+        check_return Error put(Node*& n, Args&&... args) {
+            n = new Node(Core::forward<Args>(args)...);
             if(n == nullptr) {
-                CORE_ERROR(Error::OUT_OF_MEMORY);
-                return nullptr;
+                return Error::OUT_OF_MEMORY;
             }
             length++;
             if(first == nullptr) {
                 first = n;
                 last = n;
-                return n;
+                return Error::NONE;
             }
             last->next = n;
             n->previous = last;
             last = n;
-            return n;
+            return Error::NONE;
+        }
+
+        template<typename... Args>
+        check_return Error add(Args&&... args) {
+            Node* n = nullptr;
+            return put(n, Core::forward<Args>(args)...);
         }
 
         Iterator begin() {
@@ -134,21 +135,17 @@ namespace Core {
             last = nullptr;
         }
 
-        // returns true on error and calls the error callback
         template<int L>
-        check_return bool toString(ArrayString<L>& s) const {
-            if(s.append("[")) {
-                return true;
-            }
+        check_return Error toString(ArrayString<L>& s) const {
+            CORE_RETURN_ERROR(s.append("["));
             auto iter = begin();
             for(int i = 0; i < length - 1; i++) {
-                if(s.append(*iter) || s.append(", ")) {
-                    return true;
-                }
+                CORE_RETURN_ERROR(s.append(*iter));
+                CORE_RETURN_ERROR(s.append(", "));
                 ++iter;
             }
-            if(length > 0 && s.append(*iter)) {
-                return true;
+            if(length > 0) {
+                CORE_RETURN_ERROR(s.append(*iter));
             }
             return s.append("]");
         }

+ 48 - 73
data/List.h

@@ -32,19 +32,15 @@ namespace Core {
             return *this;
         }
 
-        // returns true on error and calls the error callback
-        check_return bool copyFrom(const List& other) {
+        check_return Error copyFrom(const List& other) {
             List copy;
-            copy.data = allocate(other.capacity);
-            if(copy.data == nullptr) {
-                return true;
-            }
+            CORE_RETURN_ERROR(allocate(copy.data, other.capacity));
             copy.capacity = other.capacity;
             for(int i = 0; i < other.length; i++) {
                 copy.unsafeAdd(other[i]);
             }
             swap(copy);
-            return false;
+            return Error::NONE;
         }
 
         T* begin() {
@@ -63,48 +59,37 @@ namespace Core {
             return data + length;
         }
 
-        // returns true on error and calls the error callback
-        check_return bool reserve(int n) {
+        check_return Error reserve(int n) {
             if(n <= capacity) {
-                return false;
+                return Error::NONE;
             }
             List copy;
-            copy.data = allocate(n);
-            if(copy.data == nullptr) {
-                return true;
-            }
+            CORE_RETURN_ERROR(allocate(copy.data, n));
             copy.capacity = n;
             for(int i = 0; i < length; i++) {
                 copy.unsafeAdd(Core::move(data[i]));
             }
             swap(copy);
-            return false;
+            return Error::NONE;
         }
 
-        // returns true on error and calls the error callback
-        check_return bool shrink() {
+        check_return Error shrink() {
             if(length == capacity) {
-                return false;
+                return Error::NONE;
             }
             List copy;
-            copy.data = allocate(length);
-            if(copy.data == nullptr) {
-                return true;
-            }
+            CORE_RETURN_ERROR(allocate(copy.data, length));
             copy.capacity = length;
             for(int i = 0; i < length; i++) {
                 copy.unsafeAdd(Core::move(data[i]));
             }
             swap(copy);
-            return false;
+            return Error::NONE;
         }
 
-        // returns true on error and calls the error callback
-        check_return bool resize(int n, const T& t) {
+        check_return Error resize(int n, const T& t) {
             if(length < n) {
-                if(reserve(n)) {
-                    return true;
-                }
+                CORE_RETURN_ERROR(reserve(n));
                 for(int i = length; i < n; i++) {
                     unsafeAdd(t);
                 }
@@ -114,15 +99,12 @@ namespace Core {
                 }
                 length = n;
             }
-            return false;
+            return Error::NONE;
         }
 
-        // returns true on error and calls the error callback
-        check_return bool resize(int n) {
+        check_return Error resize(int n) {
             if(length < n) {
-                if(reserve(n)) {
-                    return true;
-                }
+                CORE_RETURN_ERROR(reserve(n));
                 for(int i = length; i < n; i++) {
                     unsafeAdd(T());
                 }
@@ -132,16 +114,20 @@ namespace Core {
                 }
                 length = n;
             }
-            return false;
+            return Error::NONE;
         }
 
-        // returns a nullptr on error and calls the error callback
         template<typename... Args>
-        check_return T* add(Args&&... args) {
-            if(ensureCapacity()) {
-                return nullptr;
-            }
-            return unsafeAdd(Core::forward<Args>(args)...);
+        check_return Error put(T*& t, Args&&... args) {
+            CORE_RETURN_ERROR(ensureCapacity());
+            t = unsafeAdd(Core::forward<Args>(args)...);
+            return Error::NONE;
+        }
+
+        template<typename... Args>
+        check_return Error add(Args&&... args) {
+            T* t = nullptr;
+            return put(t, Core::forward<Args>(args)...);
         }
 
         T& operator[](int index) {
@@ -167,50 +153,43 @@ namespace Core {
             length = 0;
         }
 
-        // returns true on error and calls the error callback
-        check_return bool removeBySwap(int index) {
+        check_return Error removeBySwap(int index) {
             if(index < 0 || index >= length) {
-                return CORE_ERROR(Error::INVALID_REMOVE_INDEX);
+                return Error::INVALID_INDEX;
             }
             length--;
             if(index != length) {
                 data[index] = Core::move(data[length]);
             }
             data[length].~T();
-            return false;
+            return Error::NONE;
         }
 
-        // returns true on error and calls the error callback
-        check_return bool remove(int index) {
+        check_return Error remove(int index) {
             if(index < 0 || index >= length) {
-                return CORE_ERROR(Error::INVALID_REMOVE_INDEX);
+                return Error::INVALID_INDEX;
             }
             length--;
             for(int i = index; i < length; i++) {
                 data[i] = Core::move(data[i + 1]);
             }
             data[length].~T();
-            return false;
+            return Error::NONE;
         }
 
-        // returns true on error and calls the error callback
-        check_return bool removeLast() {
+        check_return Error removeLast() {
             return removeBySwap(length - 1);
         }
 
-        // returns true on error and calls the error callback
         template<int L>
-        check_return bool toString(ArrayString<L>& s) const {
-            if(s.append("[")) {
-                return true;
-            }
+        check_return Error toString(ArrayString<L>& s) const {
+            CORE_RETURN_ERROR(s.append("["));
             for(int i = 0; i < length - 1; i++) {
-                if(s.append(data[i]) || s.append(", ")) {
-                    return true;
-                }
+                CORE_RETURN_ERROR(s.append(data[i]));
+                CORE_RETURN_ERROR(s.append(", "));
             }
-            if(length > 0 && s.append(data[length - 1])) {
-                return true;
+            if(length > 0) {
+                CORE_RETURN_ERROR(s.append(data[length - 1]));
             }
             return s.append("]");
         }
@@ -220,14 +199,12 @@ namespace Core {
             char data[sizeof(T)];
         };
 
-        static T* allocate(int n) {
+        static Error allocate(T*& t, int n) {
             if(n <= 0) {
-                CORE_ERROR(Error::NEGATIVE_ARGUMENT);
-                return nullptr;
+                return Error::NEGATIVE_ARGUMENT;
             }
-            T* t = reinterpret_cast<T*>(new Aligned[static_cast<size_t>(n)]);
-            CORE_ERROR(Error::OUT_OF_MEMORY, t == nullptr);
-            return t;
+            t = reinterpret_cast<T*>(new Aligned[static_cast<size_t>(n)]);
+            return t == nullptr ? Error::OUT_OF_MEMORY : Error::NONE;
         }
 
         void swap(List& other) {
@@ -236,12 +213,10 @@ namespace Core {
             Core::swap(data, other.data);
         }
 
-        // returns true on error and calls the error callback
-        check_return bool ensureCapacity() {
-            if(length >= capacity) {
-                return reserve(capacity + Core::Math::max(4, capacity / 4));
-            }
-            return false;
+        check_return Error ensureCapacity() {
+            return length >= capacity
+                       ? reserve(capacity + Core::Math::max(4, capacity / 4))
+                       : Error::NONE;
         }
 
         // does not check for capacity

+ 19 - 20
data/RingBuffer.h

@@ -51,17 +51,21 @@ namespace Core {
             return *this;
         }
 
-        // returns a nullptr on error and calls the error callback
         template<typename... Args>
-        check_return T* add(Args&&... args) {
+        check_return Error put(T*& t, Args&&... args) {
             if(getLength() >= N) {
-                CORE_ERROR(Error::CAPACITY_REACHED);
-                return nullptr;
+                return Error::CAPACITY_REACHED;
             }
-            T* t = new(data + writeIndex) T(Core::forward<Args>(args)...);
+            t = new(data + writeIndex) T(Core::forward<Args>(args)...);
             writeIndex = (writeIndex + 1) % N;
             values++;
-            return t;
+            return Error::NONE;
+        }
+
+        template<typename... Args>
+        check_return Error add(Args&&... args) {
+            T* t = nullptr;
+            return put(t, Core::forward<Args>(args)...);
         }
 
         T& operator[](int index) {
@@ -89,30 +93,25 @@ namespace Core {
             values = 0;
         }
 
-        // returns true on error and calls the error callback
-        check_return bool remove() {
+        check_return Error remove() {
             if(!canRemove()) {
-                return CORE_ERROR(Error::NOT_FOUND);
+                return Error::INVALID_STATE;
             }
             values--;
             (*this)[0].~T();
             readIndex = (readIndex + 1) % N;
-            return false;
+            return Error::NONE;
         }
 
-        // returns true on error and calls the error callback
         template<int L>
-        check_return bool toString(ArrayString<L>& s) const {
-            if(s.append("[")) {
-                return true;
-            }
+        check_return Error toString(ArrayString<L>& s) const {
+            CORE_RETURN_ERROR(s.append("["));
             for(int i = 0; i < getLength() - 1; i++) {
-                if(s.append((*this)[i]) || s.append(", ")) {
-                    return true;
-                }
+                CORE_RETURN_ERROR(s.append((*this)[i]));
+                CORE_RETURN_ERROR(s.append(", "));
             }
-            if(getLength() > 0 && s.append((*this)[getLength() - 1])) {
-                return true;
+            if(getLength() > 0) {
+                CORE_RETURN_ERROR(s.append((*this)[getLength() - 1]));
             }
             return s.append("]");
         }

+ 3 - 7
data/Stack.h

@@ -11,9 +11,8 @@ namespace Core {
             S data;
 
         public:
-            // returns a nullptr on error and calls the error callback
             template<typename... Args>
-            check_return T* push(Args&&... args) {
+            check_return Error push(Args&&... args) {
                 return data.add(Core::forward<Args>(args)...);
             }
 
@@ -21,9 +20,7 @@ namespace Core {
                 data.clear();
             }
 
-            // returns true on error and calls the error callback
-            check_return bool pop() {
-                // removeBySwap is checked
+            check_return Error pop() {
                 return data.removeBySwap(data.getLength() - 1);
             }
 
@@ -39,9 +36,8 @@ namespace Core {
                 return data[data.getLength() - 1];
             }
 
-            // returns true on error and calls the error callback
             template<int L>
-            check_return bool toString(ArrayString<L>& s) const {
+            check_return Error toString(ArrayString<L>& s) const {
                 return s.append(data);
             }
         };

+ 7 - 4
math/Box.h

@@ -22,11 +22,14 @@ namespace Core {
         const Vector3& getMin() const;
         const Vector3& getMax() const;
 
-        // returns true on error and calls the error callback
         template<int L>
-        check_return bool toString(ArrayString<L>& s) const {
-            return s.append("Box(") || s.append(min) || s.append(", ") ||
-                   s.append(max) || s.append(")");
+        check_return Error toString(ArrayString<L>& s) const {
+            CORE_RETURN_ERROR(s.append("Box("));
+            CORE_RETURN_ERROR(s.append(min));
+            CORE_RETURN_ERROR(s.append(", "));
+            CORE_RETURN_ERROR(s.append(max));
+            CORE_RETURN_ERROR(s.append(")"));
+            return Error::NONE;
         }
     };
 }

+ 9 - 6
math/Frustum.h

@@ -24,13 +24,16 @@ namespace Core {
         bool isInside(const Vector3& pos) const;
         bool isInside(const Vector3& pos, float radius) const;
 
-        // returns true on error and calls the error callback
         template<int L>
-        check_return bool toString(ArrayString<L>& s) const {
-            return s.append("(tan = ") || s.append(tan) ||
-                   s.append(", nearClip = ") || s.append(nearClip) ||
-                   s.append(", farClip = ") || s.append(farClip) ||
-                   s.append(')');
+        check_return Error toString(ArrayString<L>& s) const {
+            CORE_RETURN_ERROR(s.append("(tan = "));
+            CORE_RETURN_ERROR(s.append(tan));
+            CORE_RETURN_ERROR(s.append(", nearClip = "));
+            CORE_RETURN_ERROR(s.append(nearClip));
+            CORE_RETURN_ERROR(s.append(", farClip = "));
+            CORE_RETURN_ERROR(s.append(farClip));
+            CORE_RETURN_ERROR(s.append(')'));
+            return Error::NONE;
         }
     };
 }

+ 11 - 5
math/Matrix.h

@@ -37,12 +37,18 @@ namespace Core {
         Matrix& rotateZ(float degrees);
         Matrix& rotate(const Quaternion& q);
 
-        // returns true on error and calls the error callback
         template<int L>
-        check_return bool toString(ArrayString<L>& s) const {
-            return s.append('[') || s.append(data[0]) || s.append(", ") ||
-                   s.append(data[1]) || s.append(", ") || s.append(data[2]) ||
-                   s.append(", ") || s.append(data[3]) || s.append("]");
+        check_return Error toString(ArrayString<L>& s) const {
+            CORE_RETURN_ERROR(s.append('['));
+            CORE_RETURN_ERROR(s.append(data[0]));
+            CORE_RETURN_ERROR(s.append(", "));
+            CORE_RETURN_ERROR(s.append(data[1]));
+            CORE_RETURN_ERROR(s.append(", "));
+            CORE_RETURN_ERROR(s.append(data[2]));
+            CORE_RETURN_ERROR(s.append(", "));
+            CORE_RETURN_ERROR(s.append(data[3]));
+            CORE_RETURN_ERROR(s.append("]"));
+            return Error::NONE;
         }
 
     private:

+ 5 - 8
math/MatrixStack.h

@@ -14,17 +14,15 @@ namespace Core {
             (void)stack.add(Matrix());
         }
 
-        // returns true on error and calls the error callback
-        check_return bool pop() {
+        check_return Error pop() {
             if(stack.getLength() <= 1) {
-                return CORE_ERROR(Error::NOT_FOUND);
+                return Error::INVALID_STATE;
             }
             return stack.removeLast();
         }
 
-        // returns true on error and calls the error callback
-        check_return bool push() {
-            return stack.add(peek()) == nullptr;
+        check_return Error push() {
+            return stack.add(peek());
         }
 
         Matrix& peek() {
@@ -40,9 +38,8 @@ namespace Core {
             (void)stack.add(Matrix());
         }
 
-        // returns true on error and calls the error callback
         template<int L>
-        check_return bool toString(ArrayString<L>& s) const {
+        check_return Error toString(ArrayString<L>& s) const {
             return s.append(stack);
         }
     };

+ 11 - 5
math/Plane.h

@@ -14,12 +14,18 @@ namespace Core {
         Plane(const Vector3& a, const Vector3& b, const Vector3& c);
         float getSignedDistance(const Vector3& v) const;
 
-        // returns true on error and calls the error callback
         template<int L>
-        check_return bool toString(ArrayString<L>& s) const {
-            return s.append("(") || s.append(abc[0]) || s.append(" x + ") ||
-                   s.append(abc[1]) || s.append(" y + ") || s.append(abc[2]) ||
-                   s.append(" z + ") || s.append(d) || s.append(')');
+        check_return Error toString(ArrayString<L>& s) const {
+            CORE_RETURN_ERROR(s.append("("));
+            CORE_RETURN_ERROR(s.append(abc[0]));
+            CORE_RETURN_ERROR(s.append(" x + "));
+            CORE_RETURN_ERROR(s.append(abc[1]));
+            CORE_RETURN_ERROR(s.append(" y + "));
+            CORE_RETURN_ERROR(s.append(abc[2]));
+            CORE_RETURN_ERROR(s.append(" z + "));
+            CORE_RETURN_ERROR(s.append(d));
+            CORE_RETURN_ERROR(s.append(')'));
+            return Error::NONE;
         }
     };
 }

+ 11 - 5
math/Quaternion.h

@@ -18,12 +18,18 @@ namespace Core {
         Quaternion operator*(const Quaternion& other) const;
         Vector3 operator*(const Vector3& v) const;
 
-        // returns true on error and calls the error callback
         template<int L>
-        check_return bool toString(ArrayString<L>& s) const {
-            return s.append("(") || s.append(xyz[0]) || s.append(" i + ") ||
-                   s.append(xyz[1]) || s.append(" j + ") || s.append(xyz[2]) ||
-                   s.append(" k + ") || s.append(w) || s.append(')');
+        check_return Error toString(ArrayString<L>& s) const {
+            CORE_RETURN_ERROR(s.append("("));
+            CORE_RETURN_ERROR(s.append(xyz[0]));
+            CORE_RETURN_ERROR(s.append(" i + "));
+            CORE_RETURN_ERROR(s.append(xyz[1]));
+            CORE_RETURN_ERROR(s.append(" j + "));
+            CORE_RETURN_ERROR(s.append(xyz[2]));
+            CORE_RETURN_ERROR(s.append(" k + "));
+            CORE_RETURN_ERROR(s.append(w));
+            CORE_RETURN_ERROR(s.append(')'));
+            return Error::NONE;
         }
     };
 }

+ 6 - 10
math/Vector.h

@@ -169,19 +169,15 @@ namespace Core {
             return cast;
         }
 
-        // returns true on error and calls the error callback
         template<int L>
-        check_return bool toString(ArrayString<L>& s) const {
-            if(s.append("[")) {
-                return true;
-            }
+        check_return Error toString(ArrayString<L>& s) const {
+            CORE_RETURN_ERROR(s.append("["));
             for(int i = 0; i < N - 1; i++) {
-                if(s.append(values[i]) || s.append(", ")) {
-                    return true;
-                }
+                CORE_RETURN_ERROR(s.append(values[i]));
+                CORE_RETURN_ERROR(s.append(", "));
             }
-            if(N > 0 && s.append(values[N - 1])) {
-                return true;
+            if(N > 0) {
+                CORE_RETURN_ERROR(s.append(values[N - 1]));
             }
             return s.append("]");
         }

+ 3 - 14
test/Main.cpp

@@ -32,24 +32,13 @@
 static void onExit(int code, void* data) {
     unsigned int i = *static_cast<unsigned int*>(data);
     Core::ArrayString<1024> s;
-    CORE_TEST_FALSE(s.append("Hello from exit #: #"));
-    CORE_TEST_FALSE(s.format(code, i));
-    CORE_TEST_FALSE(s.printLine());
+    CORE_TEST_ERROR(s.append("Hello from exit #: #"));
+    CORE_TEST_ERROR(s.format(code, i));
+    CORE_TEST_ERROR(s.printLine());
     Core::Test::finalize();
 }
 
-static void onError(const char* file, int line, Core::Error e, void*) {
-    if(e == Core::Error::CAPACITY_REACHED ||
-       e == Core::Error::INVALID_REMOVE_INDEX) {
-        return;
-    }
-    CORE_LOG_ERROR("Error in #:# - #:#", file, line, static_cast<int>(e),
-                   Core::getErrorName(e));
-}
-
 int main() {
-    Core::setErrorHandler(onError, nullptr);
-
     Core::ArrayListTests::test();
     Core::ArrayStringTests::test();
     Core::ArrayTests::test();

+ 7 - 8
test/Test.cpp

@@ -5,18 +5,17 @@ Core::HashMap<Core::Test::Internal::FileName, Core::Test::Internal::Result>
 
 bool Core::Test::Internal::checkFloat(const char* file, int line, float wanted,
                                       float actual, float error) {
+    Error e = Error::NONE;
     FileName fileName;
-    if(fileName.append(file)) {
-        CORE_LOG_WARNING("cannot append file name: #", file);
+    if(checkError(e, fileName.append(file))) {
+        CORE_LOG_WARNING("cannot append file name '#' with error '#'", file, e);
         return false;
     }
     Result* result = results.search(fileName);
-    if(result == nullptr) {
-        result = results.add(fileName, Result());
-        if(result == nullptr) {
-            CORE_LOG_WARNING("cannot add test result for #", file);
-            return false;
-        }
+    if(result == nullptr &&
+       checkError(e, results.tryEmplace(result, fileName))) {
+        CORE_LOG_WARNING("cannot add test result for #, error '#'", file, e);
+        return false;
     }
     result->tests++;
     float diff = wanted - actual;

+ 15 - 12
test/Test.h

@@ -17,18 +17,19 @@ namespace Core::Test {
         template<typename T>
         bool checkEqual(const char* file, int line, const T& wanted,
                         const T& actual) {
+            Error e = Error::NONE;
             FileName fileName;
-            if(fileName.append(file)) {
-                CORE_LOG_WARNING("cannot append file name: #", file);
+            if(checkError(e, fileName.append(file))) {
+                CORE_LOG_WARNING("cannot append file name '#' with error '#'",
+                                 file, e);
                 return false;
             }
             Result* result = results.search(fileName);
-            if(result == nullptr) {
-                result = results.tryEmplace(fileName);
-                if(result == nullptr) {
-                    CORE_LOG_WARNING("cannot add test result for #", file);
-                    return false;
-                }
+            if(result == nullptr &&
+               checkError(e, results.tryEmplace(result, fileName))) {
+                CORE_LOG_WARNING("cannot add test result for #, error '#'",
+                                 file, e);
+                return false;
             }
             result->tests++;
             if(wanted == actual) {
@@ -43,14 +44,15 @@ namespace Core::Test {
         template<typename A, typename B>
         bool checkString(const char* file, int line, const A& wanted,
                          const B& actual) {
+            Error e = Error::NONE;
             ArrayString<2048> a;
-            if(a.append(wanted)) {
-                CORE_LOG_WARNING("too small buffer");
+            if(checkError(e, a.append(wanted))) {
+                CORE_LOG_WARNING("#", e);
                 return false;
             }
             ArrayString<2048> b;
-            if(b.append(actual)) {
-                CORE_LOG_WARNING("too small buffer");
+            if(checkError(e, b.append(actual))) {
+                CORE_LOG_WARNING("#", e);
                 return false;
             }
             return checkEqual(file, line, a, b);
@@ -82,6 +84,7 @@ namespace Core::Test {
     Core::Test::Internal::checkString(__FILE__, __LINE__, wanted, actual);
 #define CORE_TEST_FALSE(actual) CORE_TEST_EQUAL(false, actual);
 #define CORE_TEST_TRUE(actual) CORE_TEST_EQUAL(true, actual);
+#define CORE_TEST_ERROR(actual) CORE_TEST_EQUAL(Core::Error::NONE, actual);
 #define CORE_TEST_NULL(actual) CORE_TEST_EQUAL(true, actual == nullptr);
 #define CORE_TEST_NOT_NULL(actual) CORE_TEST_EQUAL(true, actual != nullptr);
 #define CORE_TEST_FLOAT(wanted, actual, error)                                 \

+ 31 - 31
tests/ArrayListTests.cpp

@@ -7,7 +7,7 @@ using IntList = Core::ArrayList<int, 20>;
 
 static void testAdd() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(5));
+    CORE_TEST_ERROR(list.add(5));
 
     CORE_TEST_EQUAL(5, list[0]);
     CORE_TEST_EQUAL(1, list.getLength());
@@ -15,9 +15,9 @@ static void testAdd() {
 
 static void testMultipleAdd() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(4));
-    CORE_TEST_NOT_NULL(list.add(3));
-    CORE_TEST_NOT_NULL(list.add(2));
+    CORE_TEST_ERROR(list.add(4));
+    CORE_TEST_ERROR(list.add(3));
+    CORE_TEST_ERROR(list.add(2));
     CORE_TEST_EQUAL(4, list[0]);
     CORE_TEST_EQUAL(3, list[1]);
     CORE_TEST_EQUAL(2, list[2]);
@@ -26,15 +26,15 @@ static void testMultipleAdd() {
 
 static void testAddReplace() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(5));
+    CORE_TEST_ERROR(list.add(5));
     list[0] = 3;
     CORE_TEST_EQUAL(3, list[0]);
 }
 
 static void testClear() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(5));
-    CORE_TEST_NOT_NULL(list.add(4));
+    CORE_TEST_ERROR(list.add(5));
+    CORE_TEST_ERROR(list.add(4));
     list.clear();
     CORE_TEST_EQUAL(0, list.getLength());
 }
@@ -42,10 +42,10 @@ static void testClear() {
 static void testOverflow() {
     IntList list;
     for(int i = 0; i < 20; i++) {
-        CORE_TEST_NOT_NULL(list.add(i));
+        CORE_TEST_ERROR(list.add(i));
     }
     for(int i = 0; i < 100000; i++) {
-        CORE_TEST_NULL(list.add(i));
+        CORE_TEST_EQUAL(Core::Error::CAPACITY_REACHED, list.add(i));
     }
     for(int i = 0; i < list.getLength(); i++) {
         CORE_TEST_EQUAL(i, list[i]);
@@ -54,9 +54,9 @@ static void testOverflow() {
 
 static void testCopy() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(1));
-    CORE_TEST_NOT_NULL(list.add(2));
-    CORE_TEST_NOT_NULL(list.add(3));
+    CORE_TEST_ERROR(list.add(1));
+    CORE_TEST_ERROR(list.add(2));
+    CORE_TEST_ERROR(list.add(3));
 
     IntList copy(list);
     CORE_TEST_EQUAL(list.getLength(), copy.getLength());
@@ -67,9 +67,9 @@ static void testCopy() {
 
 static void testCopyAssignment() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(1));
-    CORE_TEST_NOT_NULL(list.add(2));
-    CORE_TEST_NOT_NULL(list.add(3));
+    CORE_TEST_ERROR(list.add(1));
+    CORE_TEST_ERROR(list.add(2));
+    CORE_TEST_ERROR(list.add(3));
 
     IntList copy;
     copy = list;
@@ -81,9 +81,9 @@ static void testCopyAssignment() {
 
 static void testMove() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(1));
-    CORE_TEST_NOT_NULL(list.add(2));
-    CORE_TEST_NOT_NULL(list.add(3));
+    CORE_TEST_ERROR(list.add(1));
+    CORE_TEST_ERROR(list.add(2));
+    CORE_TEST_ERROR(list.add(3));
 
     IntList move(Core::move(list));
     CORE_TEST_EQUAL(0, list.getLength());
@@ -95,9 +95,9 @@ static void testMove() {
 
 static void testMoveAssignment() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(1));
-    CORE_TEST_NOT_NULL(list.add(2));
-    CORE_TEST_NOT_NULL(list.add(3));
+    CORE_TEST_ERROR(list.add(1));
+    CORE_TEST_ERROR(list.add(2));
+    CORE_TEST_ERROR(list.add(3));
 
     IntList move;
     move = Core::move(list);
@@ -110,15 +110,15 @@ static void testMoveAssignment() {
 
 static void testToString1() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(1));
-    CORE_TEST_NOT_NULL(list.add(243));
-    CORE_TEST_NOT_NULL(list.add(-423));
+    CORE_TEST_ERROR(list.add(1));
+    CORE_TEST_ERROR(list.add(243));
+    CORE_TEST_ERROR(list.add(-423));
     CORE_TEST_STRING("[1, 243, -423]", list);
 }
 
 static void testToString2() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(1));
+    CORE_TEST_ERROR(list.add(1));
     CORE_TEST_STRING("[1]", list);
 }
 
@@ -129,17 +129,17 @@ static void testToString3() {
 
 static void testRemove() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(4));
-    CORE_TEST_NOT_NULL(list.add(3));
-    CORE_TEST_NOT_NULL(list.add(2));
-    CORE_TEST_FALSE(list.removeBySwap(0));
+    CORE_TEST_ERROR(list.add(4));
+    CORE_TEST_ERROR(list.add(3));
+    CORE_TEST_ERROR(list.add(2));
+    CORE_TEST_ERROR(list.removeBySwap(0));
     CORE_TEST_EQUAL(2, list[0]);
     CORE_TEST_EQUAL(3, list[1]);
     CORE_TEST_EQUAL(2, list.getLength());
-    CORE_TEST_FALSE(list.removeBySwap(1));
+    CORE_TEST_ERROR(list.removeBySwap(1));
     CORE_TEST_EQUAL(2, list[0]);
     CORE_TEST_EQUAL(1, list.getLength());
-    CORE_TEST_FALSE(list.removeBySwap(0));
+    CORE_TEST_ERROR(list.removeBySwap(0));
     CORE_TEST_EQUAL(0, list.getLength());
 }
 

+ 72 - 72
tests/ArrayStringTests.cpp

@@ -8,7 +8,7 @@ using String = Core::ArrayString<128>;
 
 static String build(const char* cs) {
     String s;
-    CORE_TEST_FALSE(s.append(cs));
+    CORE_TEST_ERROR(s.append(cs));
     return s;
 }
 
@@ -42,16 +42,16 @@ static void testInequality() {
 
 static void testStringAppend() {
     String s = build("test");
-    CORE_TEST_FALSE(s.append("22"));
-    CORE_TEST_FALSE(s.append("333"));
-    CORE_TEST_FALSE(s.append("4444"));
+    CORE_TEST_ERROR(s.append("22"));
+    CORE_TEST_ERROR(s.append("333"));
+    CORE_TEST_ERROR(s.append("4444"));
     CORE_TEST_EQUAL(build("test223334444"), s);
 }
 
 static void testStringAppendOverflow() {
     Core::ArrayString<20> s;
-    CORE_TEST_FALSE(s.append("te"));
-    CORE_TEST_TRUE(s.append("23334444"));
+    CORE_TEST_ERROR(s.append("te"));
+    CORE_TEST_EQUAL(Core::Error::CAPACITY_REACHED, s.append("23334444"));
     CORE_TEST_TRUE(build("te23334444") != s);
 }
 
@@ -66,14 +66,14 @@ static void testCharacters() {
 static void testLength() {
     String s = build("test");
     CORE_TEST_EQUAL(4, s.getLength());
-    CORE_TEST_FALSE(s.append("aaa"));
+    CORE_TEST_ERROR(s.append("aaa"));
     CORE_TEST_EQUAL(7, s.getLength());
 }
 
 static void testChar() {
     String s = build("test");
     for(char i = 'a'; i < 'd'; i++) {
-        CORE_TEST_FALSE(s.append(i));
+        CORE_TEST_ERROR(s.append(i));
     }
     CORE_TEST_EQUAL(build("testabc"), s);
 }
@@ -81,7 +81,7 @@ static void testChar() {
 static void testSignedChar() {
     String s = build("test");
     for(signed char i = 'b'; i < 'e'; i++) {
-        CORE_TEST_FALSE(s.append(i));
+        CORE_TEST_ERROR(s.append(i));
     }
     CORE_TEST_EQUAL(build("testbcd"), s);
 }
@@ -89,7 +89,7 @@ static void testSignedChar() {
 static void testUnsignedChar() {
     String s = build("test");
     for(unsigned char i = 'c'; i < 'f'; i++) {
-        CORE_TEST_FALSE(s.append(i));
+        CORE_TEST_ERROR(s.append(i));
     }
     CORE_TEST_EQUAL(build("testcde"), s);
 }
@@ -97,7 +97,7 @@ static void testUnsignedChar() {
 static void testSignedShort() {
     String s = build("test");
     for(signed short i = 100; i < 103; i++) {
-        CORE_TEST_FALSE(s.append(i));
+        CORE_TEST_ERROR(s.append(i));
     }
     CORE_TEST_EQUAL(build("test100101102"), s);
 }
@@ -105,7 +105,7 @@ static void testSignedShort() {
 static void testUnsignedShort() {
     String s = build("test");
     for(unsigned short i = 101; i < 104; i++) {
-        CORE_TEST_FALSE(s.append(i));
+        CORE_TEST_ERROR(s.append(i));
     }
     CORE_TEST_EQUAL(build("test101102103"), s);
 }
@@ -113,7 +113,7 @@ static void testUnsignedShort() {
 static void testSignedInt() {
     String s = build("test");
     for(signed int i = 102; i < 105; i++) {
-        CORE_TEST_FALSE(s.append(i));
+        CORE_TEST_ERROR(s.append(i));
     }
     CORE_TEST_EQUAL(build("test102103104"), s);
 }
@@ -121,7 +121,7 @@ static void testSignedInt() {
 static void testUnsignedInt() {
     String s = build("test");
     for(unsigned int i = 103; i < 106; i++) {
-        CORE_TEST_FALSE(s.append(i));
+        CORE_TEST_ERROR(s.append(i));
     }
     CORE_TEST_EQUAL(build("test103104105"), s);
 }
@@ -129,7 +129,7 @@ static void testUnsignedInt() {
 static void testSignedLong() {
     String s = build("test");
     for(signed long i = 104; i < 107; i++) {
-        CORE_TEST_FALSE(s.append(i));
+        CORE_TEST_ERROR(s.append(i));
     }
     CORE_TEST_EQUAL(build("test104105106"), s);
 }
@@ -137,7 +137,7 @@ static void testSignedLong() {
 static void testUnsignedLong() {
     String s = build("test");
     for(unsigned long i = 105; i < 108; i++) {
-        CORE_TEST_FALSE(s.append(i));
+        CORE_TEST_ERROR(s.append(i));
     }
     CORE_TEST_EQUAL(build("test105106107"), s);
 }
@@ -145,7 +145,7 @@ static void testUnsignedLong() {
 static void testSignedLongLong() {
     String s = build("test");
     for(signed long long i = 106; i < 109; i++) {
-        CORE_TEST_FALSE(s.append(i));
+        CORE_TEST_ERROR(s.append(i));
     }
     CORE_TEST_EQUAL(build("test106107108"), s);
 }
@@ -153,7 +153,7 @@ static void testSignedLongLong() {
 static void testUnsignedLongLong() {
     String s = build("test");
     for(unsigned long long i = 107; i < 110; i++) {
-        CORE_TEST_FALSE(s.append(i));
+        CORE_TEST_ERROR(s.append(i));
     }
     CORE_TEST_EQUAL(build("test107108109"), s);
 }
@@ -161,7 +161,7 @@ static void testUnsignedLongLong() {
 static void testFloat() {
     String s = build("test");
     for(float i = 108; i < 111; i++) {
-        CORE_TEST_FALSE(s.append(i));
+        CORE_TEST_ERROR(s.append(i));
     }
     CORE_TEST_EQUAL(build("test108.00109.00110.00"), s);
 }
@@ -169,7 +169,7 @@ static void testFloat() {
 static void testDouble() {
     String s = build("test");
     for(double i = 109; i < 112; i++) {
-        CORE_TEST_FALSE(s.append(i));
+        CORE_TEST_ERROR(s.append(i));
     }
     CORE_TEST_EQUAL(build("test109.00110.00111.00"), s);
 }
@@ -177,26 +177,26 @@ static void testDouble() {
 static void testLongDouble() {
     String s = build("test");
     for(long double i = 110; i < 113; i++) {
-        CORE_TEST_FALSE(s.append(i));
+        CORE_TEST_ERROR(s.append(i));
     }
     CORE_TEST_EQUAL(build("test110.00111.00112.00"), s);
 }
 
 static void testBool() {
     String s = build("test");
-    CORE_TEST_FALSE(s.append(true));
-    CORE_TEST_FALSE(s.append(false));
-    CORE_TEST_FALSE(s.append(true));
+    CORE_TEST_ERROR(s.append(true));
+    CORE_TEST_ERROR(s.append(false));
+    CORE_TEST_ERROR(s.append(true));
     CORE_TEST_EQUAL(build("testtruefalsetrue"), s);
 }
 
 static void testIntOverflow() {
     Core::ArrayString<20> s;
-    CORE_TEST_TRUE(s.append(123456));
+    CORE_TEST_EQUAL(Core::Error::CAPACITY_REACHED, s.append(123456));
 
     String o;
     for(int i = 0; i < s.getCapacity(); i++) {
-        CORE_TEST_FALSE(o.append(i + 1));
+        CORE_TEST_ERROR(o.append(i + 1));
     }
 
     CORE_TEST_TRUE(o == s);
@@ -204,29 +204,29 @@ static void testIntOverflow() {
 
 static void testUnicode() {
     String s;
-    CORE_TEST_FALSE(s.appendUnicode('\u0040'));
-    CORE_TEST_FALSE(s.appendUnicode(L'\u0400'));
-    CORE_TEST_FALSE(s.appendUnicode(L'\u8000'));
-    CORE_TEST_FALSE(s.appendUnicode(U'\U00100000'));
+    CORE_TEST_ERROR(s.appendUnicode('\u0040'));
+    CORE_TEST_ERROR(s.appendUnicode(L'\u0400'));
+    CORE_TEST_ERROR(s.appendUnicode(L'\u8000'));
+    CORE_TEST_ERROR(s.appendUnicode(U'\U00100000'));
     CORE_TEST_EQUAL(build("\u0040\u0400\u8000\U00100000"), s);
 }
 
 static void testClear() {
     String s = build("test");
-    CORE_TEST_FALSE(s.append(1234));
+    CORE_TEST_ERROR(s.append(1234));
     s.clear();
-    CORE_TEST_FALSE(s.append("wusi"));
-    CORE_TEST_FALSE(s.append("1234"));
+    CORE_TEST_ERROR(s.append("wusi"));
+    CORE_TEST_ERROR(s.append("1234"));
     CORE_TEST_EQUAL(build("wusi1234"), s);
 }
 
 static void testHashCode() {
     String s;
-    CORE_TEST_FALSE(s.append("a"));
-    CORE_TEST_FALSE(s.append("bc"));
-    CORE_TEST_FALSE(s.append(20));
-    CORE_TEST_FALSE(s.append(25.5f));
-    CORE_TEST_FALSE(s.append(true));
+    CORE_TEST_ERROR(s.append("a"));
+    CORE_TEST_ERROR(s.append("bc"));
+    CORE_TEST_ERROR(s.append(20));
+    CORE_TEST_ERROR(s.append(25.5f));
+    CORE_TEST_ERROR(s.append(true));
     CORE_TEST_EQUAL(build("abc2025.50true").hashCode(), s.hashCode());
     s.clear();
     CORE_TEST_EQUAL(String().hashCode(), s.hashCode());
@@ -234,17 +234,17 @@ static void testHashCode() {
 
 static void testAddSelf() {
     String s;
-    CORE_TEST_FALSE(s.append("test1"));
-    CORE_TEST_FALSE(s.append(s));
-    CORE_TEST_FALSE(s.append(s));
+    CORE_TEST_ERROR(s.append("test1"));
+    CORE_TEST_ERROR(s.append(s));
+    CORE_TEST_ERROR(s.append(s));
     CORE_TEST_EQUAL(build("test1test1test1test1"), s);
 }
 
 static void testAsHashMapKey() {
     Core::HashMap<String, int> map;
-    CORE_TEST_NOT_NULL(map.add(build("wusi"), 3));
-    CORE_TEST_NOT_NULL(map.add(build("hiThere"), 7));
-    CORE_TEST_NOT_NULL(map.add(build("baum123"), 5));
+    CORE_TEST_ERROR(map.add(build("wusi"), 3));
+    CORE_TEST_ERROR(map.add(build("hiThere"), 7));
+    CORE_TEST_ERROR(map.add(build("baum123"), 5));
 
     int* a = map.search(build("wusi"));
     int* b = map.search(build("hiThere"));
@@ -265,19 +265,19 @@ static void testAsHashMapKey() {
 
 static void testStartsWith() {
     String s;
-    CORE_TEST_FALSE(s.append("0123456789"));
+    CORE_TEST_ERROR(s.append("0123456789"));
 
     String s2;
-    CORE_TEST_FALSE(s2.append("123"));
+    CORE_TEST_ERROR(s2.append("123"));
     String s3;
-    CORE_TEST_FALSE(s3.append("234"));
+    CORE_TEST_ERROR(s3.append("234"));
     String s4;
-    CORE_TEST_FALSE(s4.append("789"));
+    CORE_TEST_ERROR(s4.append("789"));
     String s5;
-    CORE_TEST_FALSE(s5.append("124"));
+    CORE_TEST_ERROR(s5.append("124"));
     String s6;
     String s7;
-    CORE_TEST_FALSE(s7.append("7891"));
+    CORE_TEST_ERROR(s7.append("7891"));
 
     CORE_TEST_FALSE(s.startsWidth(s2));
     CORE_TEST_TRUE(s.startsWidth(s2, 1));
@@ -300,19 +300,19 @@ static void testStartsWith() {
 
 static void testSearch() {
     String s;
-    CORE_TEST_FALSE(s.append("0123456789"));
+    CORE_TEST_ERROR(s.append("0123456789"));
 
     String s2;
-    CORE_TEST_FALSE(s2.append("123"));
+    CORE_TEST_ERROR(s2.append("123"));
     String s3;
-    CORE_TEST_FALSE(s3.append("234"));
+    CORE_TEST_ERROR(s3.append("234"));
     String s4;
-    CORE_TEST_FALSE(s4.append("789"));
+    CORE_TEST_ERROR(s4.append("789"));
     String s5;
-    CORE_TEST_FALSE(s5.append("124"));
+    CORE_TEST_ERROR(s5.append("124"));
     String s6;
     String s7;
-    CORE_TEST_FALSE(s7.append("7891"));
+    CORE_TEST_ERROR(s7.append("7891"));
 
     CORE_TEST_EQUAL(1, s.search(s2));
     CORE_TEST_EQUAL(2, s.search(s3));
@@ -331,19 +331,19 @@ static void testSearch() {
 
 static void testContains() {
     String s;
-    CORE_TEST_FALSE(s.append("0123456789"));
+    CORE_TEST_ERROR(s.append("0123456789"));
 
     String s2;
-    CORE_TEST_FALSE(s2.append("123"));
+    CORE_TEST_ERROR(s2.append("123"));
     String s3;
-    CORE_TEST_FALSE(s3.append("234"));
+    CORE_TEST_ERROR(s3.append("234"));
     String s4;
-    CORE_TEST_FALSE(s4.append("789"));
+    CORE_TEST_ERROR(s4.append("789"));
     String s5;
-    CORE_TEST_FALSE(s5.append("124"));
+    CORE_TEST_ERROR(s5.append("124"));
     String s6;
     String s7;
-    CORE_TEST_FALSE(s7.append("7891"));
+    CORE_TEST_ERROR(s7.append("7891"));
 
     CORE_TEST_TRUE(s.contains(s2));
     CORE_TEST_TRUE(s.contains(s3));
@@ -355,7 +355,7 @@ static void testContains() {
 
 static void testSearchChar() {
     String s;
-    CORE_TEST_FALSE(s.append("01üää3ä"));
+    CORE_TEST_ERROR(s.append("01üää3ä"));
 
     CORE_TEST_EQUAL(0, s.search(U'0'));
     CORE_TEST_EQUAL(1, s.search(U'1'));
@@ -368,7 +368,7 @@ static void testSearchChar() {
 
 static void testContainsChar() {
     String s;
-    CORE_TEST_FALSE(s.append("01üää3ä"));
+    CORE_TEST_ERROR(s.append("01üää3ä"));
 
     CORE_TEST_TRUE(s.contains(U'0'));
     CORE_TEST_TRUE(s.contains(U'1'));
@@ -379,7 +379,7 @@ static void testContainsChar() {
 
 static void testSubString() {
     String s;
-    CORE_TEST_FALSE(s.append("01üää3ä"));
+    CORE_TEST_ERROR(s.append("01üää3ä"));
 
     CORE_TEST_STRING("01üää3ä", s.substring(-2));
     CORE_TEST_STRING("1üää3ä", s.substring(1));
@@ -397,26 +397,26 @@ static void testSubString() {
 
 static void testReplace() {
     String s;
-    CORE_TEST_FALSE(s.append("0äääää1üää3ä"));
+    CORE_TEST_ERROR(s.append("0äääää1üää3ä"));
 
     String search;
-    CORE_TEST_FALSE(search.append("ää"));
+    CORE_TEST_ERROR(search.append("ää"));
 
     String replace;
-    CORE_TEST_FALSE(replace.append("ABCD"));
+    CORE_TEST_ERROR(replace.append("ABCD"));
 
-    CORE_TEST_FALSE(s.replace(search, replace));
+    CORE_TEST_ERROR(s.replace(search, replace));
 
     CORE_TEST_STRING("0ABCDABCDä1üABCD3ä", s);
 
     String s2;
-    CORE_TEST_FALSE(s2.append("0ABCDABCDä1üABCD3ä"));
+    CORE_TEST_ERROR(s2.append("0ABCDABCDä1üABCD3ä"));
     CORE_TEST_EQUAL(s2.hashCode(), s.hashCode());
 }
 
 static void testReplaceChar() {
     String s;
-    CORE_TEST_FALSE(s.append("01üää3ä"));
+    CORE_TEST_ERROR(s.append("01üää3ä"));
     s.replace(U'0', U'A');
     CORE_TEST_STRING("A1üää3ä", s);
     s.replace(U'1', U'B');
@@ -429,7 +429,7 @@ static void testReplaceChar() {
     CORE_TEST_STRING("ABCDDED", s);
 
     String s2;
-    CORE_TEST_FALSE(s2.append("ABCDDED"));
+    CORE_TEST_ERROR(s2.append("ABCDDED"));
     CORE_TEST_EQUAL(s2.hashCode(), s.hashCode());
 }
 

+ 9 - 9
tests/BitArrayTests.cpp

@@ -5,7 +5,7 @@
 
 static void testSetRead() {
     Core::BitArray bits;
-    CORE_TEST_FALSE(bits.resize(4, 3));
+    CORE_TEST_ERROR(bits.resize(4, 3));
     bits.set(0, 1).set(1, 2).set(2, 3).set(3, 4);
     CORE_TEST_EQUAL(1, bits.get(0));
     CORE_TEST_EQUAL(2, bits.get(1));
@@ -24,7 +24,7 @@ static void testOutOfBoundsSetRead() {
 
 static void testBigSetRead() {
     Core::BitArray bits;
-    CORE_TEST_FALSE(bits.resize(100, 13));
+    CORE_TEST_ERROR(bits.resize(100, 13));
     for(int i = 0; i < bits.getLength(); i++) {
         bits.set(i, i);
     }
@@ -37,7 +37,7 @@ static void testRandomSetReadResize() {
     const int length = 100;
     int data[length];
     Core::BitArray bits;
-    CORE_TEST_FALSE(bits.resize(100, 13));
+    CORE_TEST_ERROR(bits.resize(100, 13));
     int seed = 534;
     for(int k = 0; k < 20; k++) {
         for(int i = 0; i < bits.getLength(); i++) {
@@ -49,7 +49,7 @@ static void testRandomSetReadResize() {
     for(int i = 0; i < bits.getLength(); i++) {
         CORE_TEST_EQUAL(data[i], bits.get(i));
     }
-    CORE_TEST_FALSE(bits.resize(bits.getLength(), bits.getBits() + 1));
+    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++) {
@@ -59,10 +59,10 @@ static void testRandomSetReadResize() {
 
 static void testReadOnly() {
     Core::BitArray bits;
-    CORE_TEST_FALSE(bits.resize(4, 3));
+    CORE_TEST_ERROR(bits.resize(4, 3));
     bits.set(0, 1).set(1, 2).set(2, 3).set(3, 4);
     Core::BitArray copy;
-    CORE_TEST_FALSE(copy.copyFrom(bits));
+    CORE_TEST_ERROR(copy.copyFrom(bits));
     const Core::BitArray bits2 = Core::move(copy);
     CORE_TEST_EQUAL(1, bits2.get(0));
     CORE_TEST_EQUAL(2, bits2.get(1));
@@ -72,7 +72,7 @@ static void testReadOnly() {
 
 static void testSelect() {
     Core::BitArray bits;
-    CORE_TEST_FALSE(bits.resize(90, 1));
+    CORE_TEST_ERROR(bits.resize(90, 1));
     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);
@@ -90,14 +90,14 @@ static void testSelect() {
 
 static void testToString1() {
     Core::BitArray bits;
-    CORE_TEST_FALSE(bits.resize(4, 3));
+    CORE_TEST_ERROR(bits.resize(4, 3));
     bits.set(0, 1).set(1, 2).set(2, 3).set(3, 4);
     CORE_TEST_STRING("[1, 2, 3, 4]", bits);
 }
 
 static void testToString2() {
     Core::BitArray bits;
-    CORE_TEST_FALSE(bits.resize(1, 3));
+    CORE_TEST_ERROR(bits.resize(1, 3));
     bits.set(0, 1);
     CORE_TEST_STRING("[1]", bits);
 }

+ 17 - 17
tests/BufferTests.cpp

@@ -9,10 +9,10 @@ static constexpr int SIZE_TYPES =
 static void testAdd() {
     Core::Buffer buffer(10);
     for(int i = 0; i < 100000; i++) {
-        CORE_TEST_FALSE(buffer.add(5));
-        CORE_TEST_FALSE(buffer.add(5L));
-        CORE_TEST_FALSE(buffer.add(5.0f));
-        CORE_TEST_FALSE(buffer.add(5.0));
+        CORE_TEST_ERROR(buffer.add(5));
+        CORE_TEST_ERROR(buffer.add(5L));
+        CORE_TEST_ERROR(buffer.add(5.0f));
+        CORE_TEST_ERROR(buffer.add(5.0));
     }
     CORE_TEST_EQUAL(SIZE_TYPES * 100000, buffer.getLength());
 }
@@ -20,13 +20,13 @@ static void testAdd() {
 static void testCopy() {
     Core::Buffer buffer(10);
     for(int i = 0; i < 10; i++) {
-        CORE_TEST_FALSE(buffer.add(5));
-        CORE_TEST_FALSE(buffer.add(5L));
-        CORE_TEST_FALSE(buffer.add(5.0f));
-        CORE_TEST_FALSE(buffer.add(5.0));
+        CORE_TEST_ERROR(buffer.add(5));
+        CORE_TEST_ERROR(buffer.add(5L));
+        CORE_TEST_ERROR(buffer.add(5.0f));
+        CORE_TEST_ERROR(buffer.add(5.0));
     }
     Core::Buffer buffer2;
-    CORE_TEST_FALSE(buffer2.copyFrom(buffer));
+    CORE_TEST_ERROR(buffer2.copyFrom(buffer));
     if(CORE_TEST_EQUAL(SIZE_TYPES * 10, buffer.getLength()) &&
        CORE_TEST_EQUAL(SIZE_TYPES * 10, buffer2.getLength())) {
         CORE_TEST_TRUE(Core::memoryCompare(buffer, buffer2, SIZE_TYPES * 10));
@@ -36,10 +36,10 @@ static void testCopy() {
 static void testMoveConstruct() {
     Core::Buffer buffer(10);
     for(int i = 0; i < 10; i++) {
-        CORE_TEST_FALSE(buffer.add(5));
-        CORE_TEST_FALSE(buffer.add(5L));
-        CORE_TEST_FALSE(buffer.add(5.0f));
-        CORE_TEST_FALSE(buffer.add(5.0));
+        CORE_TEST_ERROR(buffer.add(5));
+        CORE_TEST_ERROR(buffer.add(5L));
+        CORE_TEST_ERROR(buffer.add(5.0f));
+        CORE_TEST_ERROR(buffer.add(5.0));
     }
     Core::Buffer buffer2(Core::move(buffer));
 
@@ -50,10 +50,10 @@ static void testMoveConstruct() {
 static void testMove() {
     Core::Buffer buffer(10);
     for(int i = 0; i < 10; i++) {
-        CORE_TEST_FALSE(buffer.add(5));
-        CORE_TEST_FALSE(buffer.add(5L));
-        CORE_TEST_FALSE(buffer.add(5.0f));
-        CORE_TEST_FALSE(buffer.add(5.0));
+        CORE_TEST_ERROR(buffer.add(5));
+        CORE_TEST_ERROR(buffer.add(5L));
+        CORE_TEST_ERROR(buffer.add(5.0f));
+        CORE_TEST_ERROR(buffer.add(5.0));
     }
     Core::Buffer buffer2(3);
     buffer2 = Core::move(buffer);

+ 8 - 8
tests/ClockTests.cpp

@@ -9,10 +9,10 @@ static void testUpdate() {
     Core::Clock::Nanos n2 = 0;
     Core::Clock::Nanos n3 = 0;
     Core::Clock::Nanos n4 = 0;
-    CORE_TEST_FALSE(c.update(n1));
-    CORE_TEST_FALSE(c.update(n2));
-    CORE_TEST_FALSE(c.update(n3));
-    CORE_TEST_FALSE(c.update(n4));
+    CORE_TEST_ERROR(c.update(n1));
+    CORE_TEST_ERROR(c.update(n2));
+    CORE_TEST_ERROR(c.update(n3));
+    CORE_TEST_ERROR(c.update(n4));
     CORE_TEST_TRUE(n1 == 0);
     CORE_TEST_TRUE(n2 > 0);
     CORE_TEST_TRUE(n3 > 0);
@@ -23,7 +23,7 @@ static void testUpdatesPerSecond() {
     Core::Clock c;
     for(int i = 0; i < 1000; i++) {
         Core::Clock::Nanos n = 0;
-        CORE_TEST_FALSE(c.update(n));
+        CORE_TEST_ERROR(c.update(n));
     }
     CORE_TEST_TRUE(c.getUpdatesPerSecond() > 0.0f);
 }
@@ -31,10 +31,10 @@ static void testUpdatesPerSecond() {
 static void testWait(Core::Clock::Nanos wait) {
     Core::Clock c;
     Core::Clock::Nanos n = 0;
-    CORE_TEST_FALSE(c.update(n));
-    CORE_TEST_FALSE(c.wait(wait));
+    CORE_TEST_ERROR(c.update(n));
+    CORE_TEST_ERROR(c.wait(wait));
     Core::Clock::Nanos n2 = 0;
-    CORE_TEST_FALSE(c.update(n2));
+    CORE_TEST_ERROR(c.update(n2));
     CORE_TEST_TRUE(n2 >= wait && n2 <= wait * 11 / 10);
 }
 

+ 22 - 16
tests/ComponentsTests.cpp

@@ -7,9 +7,12 @@ using IntComponent = Core::Components<int>;
 
 static void testAddForEach() {
     IntComponent c;
-    int* i1 = c.add(1, 10);
-    int* i2 = c.add(5, 20);
-    int* i3 = c.add(10, 30);
+    int* i1 = nullptr;
+    int* i2 = nullptr;
+    int* i3 = nullptr;
+    CORE_TEST_ERROR(c.put(i1, 1, 10));
+    CORE_TEST_ERROR(c.put(i2, 5, 20));
+    CORE_TEST_ERROR(c.put(i3, 10, 30));
 
     CORE_TEST_NOT_NULL(i1);
     CORE_TEST_NOT_NULL(i2);
@@ -47,9 +50,12 @@ static void testAddForEach() {
 
 static void testAddComponentForEach() {
     IntComponent c;
-    int* i1 = c.add(1, 10);
-    int* i2 = c.add(5, 20);
-    int* i3 = c.add(10, 30);
+    int* i1 = nullptr;
+    int* i2 = nullptr;
+    int* i3 = nullptr;
+    CORE_TEST_ERROR(c.put(i1, 1, 10));
+    CORE_TEST_ERROR(c.put(i2, 5, 20));
+    CORE_TEST_ERROR(c.put(i3, 10, 30));
 
     CORE_TEST_NOT_NULL(i1);
     CORE_TEST_NOT_NULL(i2);
@@ -100,16 +106,16 @@ static void testAddComponentForEach() {
 
 static void testRemove() {
     IntComponent c;
-    CORE_TEST_NOT_NULL(c.add(1, 10));
-    CORE_TEST_NOT_NULL(c.add(5, 20));
-    CORE_TEST_NOT_NULL(c.add(10, 30));
+    CORE_TEST_ERROR(c.add(1, 10));
+    CORE_TEST_ERROR(c.add(5, 20));
+    CORE_TEST_ERROR(c.add(10, 30));
 
-    CORE_TEST_TRUE(c.remove(20));
-    CORE_TEST_FALSE(c.remove(5));
-    CORE_TEST_TRUE(c.remove(30));
+    CORE_TEST_EQUAL(Core::Error::NOT_FOUND, c.remove(20));
+    CORE_TEST_ERROR(c.remove(5));
+    CORE_TEST_EQUAL(Core::Error::NOT_FOUND, c.remove(30));
 
-    CORE_TEST_NOT_NULL(c.add(20, 40));
-    CORE_TEST_FALSE(c.remove(20));
+    CORE_TEST_ERROR(c.add(20, 40));
+    CORE_TEST_ERROR(c.remove(20));
 
     int* i1 = c.search(1);
     int* i2 = c.search(5);
@@ -124,7 +130,7 @@ static void testRemove() {
         CORE_TEST_EQUAL(30, *i3);
     }
 
-    CORE_TEST_FALSE(c.remove(10));
+    CORE_TEST_ERROR(c.remove(10));
 
     i1 = c.search(1);
     i2 = c.search(5);
@@ -138,7 +144,7 @@ static void testRemove() {
         CORE_TEST_EQUAL(10, *i1);
     }
 
-    CORE_TEST_FALSE(c.remove(1));
+    CORE_TEST_ERROR(c.remove(1));
 
     CORE_TEST_NULL(c.search(1));
     CORE_TEST_NULL(c.search(5));

+ 51 - 49
tests/HashMapTests.cpp

@@ -7,7 +7,7 @@ using IntMap = Core::HashMap<int, int>;
 
 static void testAdd() {
     IntMap map;
-    CORE_TEST_NOT_NULL(map.add(5, 4));
+    CORE_TEST_ERROR(map.add(5, 4));
     int* value = map.search(5);
     CORE_TEST_NOT_NULL(value);
     if(value != nullptr) {
@@ -17,9 +17,9 @@ static void testAdd() {
 
 static void testMultipleAdd() {
     IntMap map;
-    CORE_TEST_NOT_NULL(map.add(5, 4));
-    CORE_TEST_NOT_NULL(map.add(10, 3));
-    CORE_TEST_NOT_NULL(map.add(15, 2));
+    CORE_TEST_ERROR(map.add(5, 4));
+    CORE_TEST_ERROR(map.add(10, 3));
+    CORE_TEST_ERROR(map.add(15, 2));
     CORE_TEST_TRUE(map.contains(5));
     CORE_TEST_TRUE(map.contains(10));
     CORE_TEST_TRUE(map.contains(15));
@@ -43,8 +43,8 @@ static void testSearch() {
 
 static void testAddReplace() {
     IntMap map;
-    CORE_TEST_NOT_NULL(map.add(5, 4));
-    CORE_TEST_NOT_NULL(map.add(5, 10));
+    CORE_TEST_ERROR(map.add(5, 4));
+    CORE_TEST_ERROR(map.add(5, 10));
     CORE_TEST_TRUE(map.contains(5));
     int* a = map.search(5);
     CORE_TEST_NOT_NULL(a);
@@ -55,8 +55,8 @@ static void testAddReplace() {
 
 static void testClear() {
     IntMap map;
-    CORE_TEST_NOT_NULL(map.add(5, 4));
-    CORE_TEST_NOT_NULL(map.add(4, 10));
+    CORE_TEST_ERROR(map.add(5, 4));
+    CORE_TEST_ERROR(map.add(4, 10));
     map.clear();
     CORE_TEST_FALSE(map.contains(5));
     CORE_TEST_FALSE(map.contains(4));
@@ -65,7 +65,7 @@ static void testClear() {
 static void testOverflow() {
     IntMap map;
     for(int i = 0; i < 100000; i++) {
-        CORE_TEST_NOT_NULL(map.add(i, i));
+        CORE_TEST_ERROR(map.add(i, i));
     }
     for(int i = 0; i < 100000; i++) {
         CORE_TEST_TRUE(map.contains(i));
@@ -90,20 +90,25 @@ struct A final {
     }
 
     template<int N>
-    check_return bool toString(Core::ArrayString<N>& s) const {
-        return s.append("A(") || s.append(a) || s.append(", ") || s.append(b) ||
-               s.append(")");
+    check_return Core::Error toString(Core::ArrayString<N>& s) const {
+        CORE_RETURN_ERROR(s.append("A("));
+        CORE_RETURN_ERROR(s.append(a));
+        CORE_RETURN_ERROR(s.append(", "));
+        CORE_RETURN_ERROR(s.append(b));
+        CORE_RETURN_ERROR(s.append(")"));
+        return Core::Error::NONE;
     }
 };
 
 static void testEmplace() {
     Core::HashMap<int, A> map;
 
-    CORE_TEST_NOT_NULL(map.tryEmplace(0, 3, 4));
-    CORE_TEST_NOT_NULL(map.tryEmplace(3, 4, 5));
-    CORE_TEST_NOT_NULL(map.tryEmplace(20, 5, 6));
-    CORE_TEST_NULL(map.tryEmplace(3, 6, 7));
-    CORE_TEST_NULL(map.tryEmplace(20, 7, 8));
+    A* ar = nullptr;
+    CORE_TEST_ERROR(map.tryEmplace(ar, 0, 3, 4));
+    CORE_TEST_ERROR(map.tryEmplace(ar, 3, 4, 5));
+    CORE_TEST_ERROR(map.tryEmplace(ar, 20, 5, 6));
+    CORE_TEST_EQUAL(Core::Error::EXISTING_KEY, map.tryEmplace(ar, 3, 6, 7));
+    CORE_TEST_EQUAL(Core::Error::EXISTING_KEY, map.tryEmplace(ar, 20, 7, 8));
 
     A* a = map.search(0);
     A* b = map.search(3);
@@ -122,15 +127,15 @@ static void testEmplace() {
 
 static void testToString1() {
     IntMap map;
-    CORE_TEST_NOT_NULL(map.add(1, 3));
-    CORE_TEST_NOT_NULL(map.add(2, 4));
-    CORE_TEST_NOT_NULL(map.add(3, 5));
+    CORE_TEST_ERROR(map.add(1, 3));
+    CORE_TEST_ERROR(map.add(2, 4));
+    CORE_TEST_ERROR(map.add(3, 5));
     CORE_TEST_STRING("[1 = 3, 2 = 4, 3 = 5]", map);
 }
 
 static void testToString2() {
     IntMap map;
-    CORE_TEST_NOT_NULL(map.add(1, 3));
+    CORE_TEST_ERROR(map.add(1, 3));
     CORE_TEST_STRING("[1 = 3]", map);
 }
 
@@ -141,11 +146,11 @@ static void testToString3() {
 
 static void testCopy() {
     IntMap map;
-    CORE_TEST_NOT_NULL(map.add(1, 3));
-    CORE_TEST_NOT_NULL(map.add(2, 4));
-    CORE_TEST_NOT_NULL(map.add(3, 5));
+    CORE_TEST_ERROR(map.add(1, 3));
+    CORE_TEST_ERROR(map.add(2, 4));
+    CORE_TEST_ERROR(map.add(3, 5));
     IntMap copy;
-    CORE_TEST_FALSE(copy.copyFrom(map));
+    CORE_TEST_ERROR(copy.copyFrom(map));
 
     int* a[6] = {map.search(1),  map.search(2),  map.search(3),
                  copy.search(1), copy.search(2), copy.search(3)};
@@ -160,9 +165,9 @@ static void testCopy() {
 
 static void testMove() {
     IntMap map;
-    CORE_TEST_NOT_NULL(map.add(1, 3));
-    CORE_TEST_NOT_NULL(map.add(2, 4));
-    CORE_TEST_NOT_NULL(map.add(3, 5));
+    CORE_TEST_ERROR(map.add(1, 3));
+    CORE_TEST_ERROR(map.add(2, 4));
+    CORE_TEST_ERROR(map.add(3, 5));
     IntMap move(Core::move(map));
 
     int* a = move.search(1);
@@ -182,9 +187,9 @@ static void testMove() {
 
 static void testMoveAssignment() {
     IntMap map;
-    CORE_TEST_NOT_NULL(map.add(1, 3));
-    CORE_TEST_NOT_NULL(map.add(2, 4));
-    CORE_TEST_NOT_NULL(map.add(3, 5));
+    CORE_TEST_ERROR(map.add(1, 3));
+    CORE_TEST_ERROR(map.add(2, 4));
+    CORE_TEST_ERROR(map.add(3, 5));
 
     IntMap move;
     move = Core::move(map);
@@ -206,12 +211,12 @@ static void testMoveAssignment() {
 
 static void testRemove() {
     IntMap map;
-    CORE_TEST_NOT_NULL(map.add(1, 3));
-    CORE_TEST_NOT_NULL(map.add(2, 4));
-    CORE_TEST_NOT_NULL(map.add(3, 5));
+    CORE_TEST_ERROR(map.add(1, 3));
+    CORE_TEST_ERROR(map.add(2, 4));
+    CORE_TEST_ERROR(map.add(3, 5));
 
-    bool remove1 = map.remove(2);
-    bool remove2 = map.remove(7);
+    CORE_TEST_ERROR(map.remove(2));
+    CORE_TEST_EQUAL(Core::Error::NOT_FOUND, map.remove(7));
 
     int* a = map.search(1);
     int* b = map.search(2);
@@ -221,9 +226,6 @@ static void testRemove() {
     CORE_TEST_NULL(b);
     CORE_TEST_NOT_NULL(c);
 
-    CORE_TEST_FALSE(remove1);
-    CORE_TEST_TRUE(remove2);
-
     if(a != nullptr && c != nullptr) {
         CORE_TEST_EQUAL(3, *a);
         CORE_TEST_EQUAL(5, *c);
@@ -232,9 +234,9 @@ static void testRemove() {
 
 static void testEntryForEach() {
     IntMap map;
-    CORE_TEST_NOT_NULL(map.add(5, 4));
-    CORE_TEST_NOT_NULL(map.add(10, 3));
-    CORE_TEST_NOT_NULL(map.add(15, 2));
+    CORE_TEST_ERROR(map.add(5, 4));
+    CORE_TEST_ERROR(map.add(10, 3));
+    CORE_TEST_ERROR(map.add(15, 2));
 
     int counter = 0;
     for(auto& entry : map.entries()) {
@@ -252,9 +254,9 @@ static void testEntryForEach() {
 
 static void testKeyForEach() {
     IntMap map;
-    CORE_TEST_NOT_NULL(map.add(5, 4));
-    CORE_TEST_NOT_NULL(map.add(10, 3));
-    CORE_TEST_NOT_NULL(map.add(15, 2));
+    CORE_TEST_ERROR(map.add(5, 4));
+    CORE_TEST_ERROR(map.add(10, 3));
+    CORE_TEST_ERROR(map.add(15, 2));
 
     int counter = 0;
     for(const int& key : map.keys()) {
@@ -272,9 +274,9 @@ static void testKeyForEach() {
 
 static void testValueForEach() {
     IntMap map;
-    CORE_TEST_NOT_NULL(map.add(5, 4));
-    CORE_TEST_NOT_NULL(map.add(10, 3));
-    CORE_TEST_NOT_NULL(map.add(15, 2));
+    CORE_TEST_ERROR(map.add(5, 4));
+    CORE_TEST_ERROR(map.add(10, 3));
+    CORE_TEST_ERROR(map.add(15, 2));
 
     int counter = 0;
     for(int& value : map.values()) {
@@ -293,7 +295,7 @@ static void testValueForEach() {
 template<typename T>
 static void testType() {
     Core::HashMap<T, int> m;
-    CORE_TEST_NOT_NULL(m.add(T(), 3));
+    CORE_TEST_ERROR(m.add(T(), 3));
 }
 
 static void testTypes() {

+ 38 - 34
tests/LinkedListTests.cpp

@@ -17,12 +17,12 @@ using IntList = Core::LinkedList<int>;
 
 static void testWithoutCopyOrMove() {
     Core::LinkedList<LinkedListTester> list;
-    CORE_TEST_NOT_NULL(list.add(3));
+    CORE_TEST_ERROR(list.add(3));
 }
 
 static void testAdd() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(5));
+    CORE_TEST_ERROR(list.add(5));
     auto iter = list.begin();
     CORE_TEST_EQUAL(5, *iter);
     CORE_TEST_EQUAL(1, list.getLength());
@@ -30,9 +30,9 @@ static void testAdd() {
 
 static void testMultipleAdd() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(4));
-    CORE_TEST_NOT_NULL(list.add(3));
-    CORE_TEST_NOT_NULL(list.add(2));
+    CORE_TEST_ERROR(list.add(4));
+    CORE_TEST_ERROR(list.add(3));
+    CORE_TEST_ERROR(list.add(2));
     auto iter = list.begin();
     CORE_TEST_EQUAL(4, *iter);
     CORE_TEST_EQUAL(3, *(++iter));
@@ -42,8 +42,8 @@ static void testMultipleAdd() {
 
 static void testClear() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(5));
-    CORE_TEST_NOT_NULL(list.add(4));
+    CORE_TEST_ERROR(list.add(5));
+    CORE_TEST_ERROR(list.add(4));
     list.clear();
     CORE_TEST_EQUAL(0, list.getLength());
     CORE_TEST_FALSE(list.begin() != list.end());
@@ -52,7 +52,7 @@ static void testClear() {
 static void testBigAdd() {
     IntList list;
     for(int i = 0; i < 100000; i++) {
-        CORE_TEST_NOT_NULL(list.add(i));
+        CORE_TEST_ERROR(list.add(i));
     }
     auto iter = list.begin();
     for(int i = 0; i < list.getLength(); i++) {
@@ -64,12 +64,12 @@ static void testBigAdd() {
 
 static void testCopy() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(1));
-    CORE_TEST_NOT_NULL(list.add(2));
-    CORE_TEST_NOT_NULL(list.add(3));
+    CORE_TEST_ERROR(list.add(1));
+    CORE_TEST_ERROR(list.add(2));
+    CORE_TEST_ERROR(list.add(3));
 
     IntList copy;
-    CORE_TEST_FALSE(copy.copyFrom(list));
+    CORE_TEST_ERROR(copy.copyFrom(list));
     CORE_TEST_EQUAL(list.getLength(), copy.getLength());
     auto iterA = list.begin();
     auto iterB = copy.begin();
@@ -82,9 +82,9 @@ static void testCopy() {
 
 static void testMove() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(1));
-    CORE_TEST_NOT_NULL(list.add(2));
-    CORE_TEST_NOT_NULL(list.add(3));
+    CORE_TEST_ERROR(list.add(1));
+    CORE_TEST_ERROR(list.add(2));
+    CORE_TEST_ERROR(list.add(3));
 
     const IntList move(Core::move(list));
     CORE_TEST_EQUAL(0, list.getLength());
@@ -97,9 +97,9 @@ static void testMove() {
 
 static void testMoveAssignment() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(1));
-    CORE_TEST_NOT_NULL(list.add(2));
-    CORE_TEST_NOT_NULL(list.add(3));
+    CORE_TEST_ERROR(list.add(1));
+    CORE_TEST_ERROR(list.add(2));
+    CORE_TEST_ERROR(list.add(3));
 
     IntList move;
     move = Core::move(list);
@@ -113,15 +113,15 @@ static void testMoveAssignment() {
 
 static void testToString1() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(1));
-    CORE_TEST_NOT_NULL(list.add(243));
-    CORE_TEST_NOT_NULL(list.add(-423));
+    CORE_TEST_ERROR(list.add(1));
+    CORE_TEST_ERROR(list.add(243));
+    CORE_TEST_ERROR(list.add(-423));
     CORE_TEST_STRING("[1, 243, -423]", list);
 }
 
 static void testToString2() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(1));
+    CORE_TEST_ERROR(list.add(1));
     CORE_TEST_STRING("[1]", list);
 }
 
@@ -132,10 +132,14 @@ static void testToString3() {
 
 static void testRemove() {
     IntList list;
-    IntList::Node* a = list.add(4);
-    IntList::Node* b = list.add(3);
-    IntList::Node* c = list.add(2);
-    IntList::Node* d = list.add(1);
+    IntList::Node* a = nullptr;
+    IntList::Node* b = nullptr;
+    IntList::Node* c = nullptr;
+    IntList::Node* d = nullptr;
+    CORE_TEST_ERROR(list.put(a, 4));
+    CORE_TEST_ERROR(list.put(b, 3));
+    CORE_TEST_ERROR(list.put(c, 2));
+    CORE_TEST_ERROR(list.put(d, 1));
     CORE_TEST_NOT_NULL(a);
     CORE_TEST_NOT_NULL(b);
     CORE_TEST_NOT_NULL(c);
@@ -171,10 +175,10 @@ static void testRemove() {
 
 static void testRemoveFirst() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(4));
-    CORE_TEST_NOT_NULL(list.add(3));
-    CORE_TEST_NOT_NULL(list.add(2));
-    CORE_TEST_NOT_NULL(list.add(1));
+    CORE_TEST_ERROR(list.add(4));
+    CORE_TEST_ERROR(list.add(3));
+    CORE_TEST_ERROR(list.add(2));
+    CORE_TEST_ERROR(list.add(1));
 
     list.removeFirst();
     auto iter = list.begin();
@@ -205,10 +209,10 @@ static void testRemoveFirst() {
 
 static void testRemoveLast() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(4));
-    CORE_TEST_NOT_NULL(list.add(3));
-    CORE_TEST_NOT_NULL(list.add(2));
-    CORE_TEST_NOT_NULL(list.add(1));
+    CORE_TEST_ERROR(list.add(4));
+    CORE_TEST_ERROR(list.add(3));
+    CORE_TEST_ERROR(list.add(2));
+    CORE_TEST_ERROR(list.add(1));
 
     list.removeLast();
     auto iter = list.begin();

+ 46 - 46
tests/ListTests.cpp

@@ -7,16 +7,16 @@ using IntList = Core::List<int>;
 
 static void testAdd() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(5));
+    CORE_TEST_ERROR(list.add(5));
     CORE_TEST_EQUAL(5, list[0]);
     CORE_TEST_EQUAL(1, list.getLength());
 }
 
 static void testMultipleAdd() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(4));
-    CORE_TEST_NOT_NULL(list.add(3));
-    CORE_TEST_NOT_NULL(list.add(2));
+    CORE_TEST_ERROR(list.add(4));
+    CORE_TEST_ERROR(list.add(3));
+    CORE_TEST_ERROR(list.add(2));
     CORE_TEST_EQUAL(4, list[0]);
     CORE_TEST_EQUAL(3, list[1]);
     CORE_TEST_EQUAL(2, list[2]);
@@ -25,26 +25,26 @@ static void testMultipleAdd() {
 
 static void testAddReplace() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(5));
+    CORE_TEST_ERROR(list.add(5));
     list[0] = 3;
     CORE_TEST_EQUAL(3, list[0]);
 }
 
 static void testClear() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(5));
-    CORE_TEST_NOT_NULL(list.add(4));
+    CORE_TEST_ERROR(list.add(5));
+    CORE_TEST_ERROR(list.add(4));
     list.clear();
     CORE_TEST_EQUAL(0, list.getLength());
 }
 
 static void testShrink() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(5));
-    CORE_TEST_NOT_NULL(list.add(4));
-    CORE_TEST_NOT_NULL(list.add(3));
+    CORE_TEST_ERROR(list.add(5));
+    CORE_TEST_ERROR(list.add(4));
+    CORE_TEST_ERROR(list.add(3));
     CORE_TEST_TRUE(list.getCapacity() >= 3);
-    CORE_TEST_FALSE(list.shrink());
+    CORE_TEST_ERROR(list.shrink());
     CORE_TEST_TRUE(list.getLength() == 3);
     CORE_TEST_TRUE(list.getCapacity() == 3);
     CORE_TEST_EQUAL(5, list[0]);
@@ -55,7 +55,7 @@ static void testShrink() {
 static void testBigAdd() {
     IntList list;
     for(int i = 0; i < 100000; i++) {
-        CORE_TEST_NOT_NULL(list.add(i));
+        CORE_TEST_ERROR(list.add(i));
     }
     for(int i = 0; i < list.getLength(); i++) {
         CORE_TEST_EQUAL(i, list[i]);
@@ -65,12 +65,12 @@ static void testBigAdd() {
 
 static void testCopy() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(1));
-    CORE_TEST_NOT_NULL(list.add(2));
-    CORE_TEST_NOT_NULL(list.add(3));
+    CORE_TEST_ERROR(list.add(1));
+    CORE_TEST_ERROR(list.add(2));
+    CORE_TEST_ERROR(list.add(3));
 
     IntList copy;
-    CORE_TEST_FALSE(copy.copyFrom(list));
+    CORE_TEST_ERROR(copy.copyFrom(list));
     CORE_TEST_EQUAL(list.getLength(), copy.getLength());
     for(int i = 0; i < copy.getLength() && i < list.getLength(); i++) {
         CORE_TEST_EQUAL(list[i], copy[i]);
@@ -79,9 +79,9 @@ static void testCopy() {
 
 static void testMove() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(1));
-    CORE_TEST_NOT_NULL(list.add(2));
-    CORE_TEST_NOT_NULL(list.add(3));
+    CORE_TEST_ERROR(list.add(1));
+    CORE_TEST_ERROR(list.add(2));
+    CORE_TEST_ERROR(list.add(3));
 
     IntList move(Core::move(list));
     CORE_TEST_EQUAL(0, list.getLength());
@@ -93,9 +93,9 @@ static void testMove() {
 
 static void testMoveAssignment() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(1));
-    CORE_TEST_NOT_NULL(list.add(2));
-    CORE_TEST_NOT_NULL(list.add(3));
+    CORE_TEST_ERROR(list.add(1));
+    CORE_TEST_ERROR(list.add(2));
+    CORE_TEST_ERROR(list.add(3));
 
     IntList move;
     move = Core::move(list);
@@ -108,15 +108,15 @@ static void testMoveAssignment() {
 
 static void testToString1() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(1));
-    CORE_TEST_NOT_NULL(list.add(243));
-    CORE_TEST_NOT_NULL(list.add(-423));
+    CORE_TEST_ERROR(list.add(1));
+    CORE_TEST_ERROR(list.add(243));
+    CORE_TEST_ERROR(list.add(-423));
     CORE_TEST_STRING("[1, 243, -423]", list);
 }
 
 static void testToString2() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(1));
+    CORE_TEST_ERROR(list.add(1));
     CORE_TEST_STRING("[1]", list);
 }
 
@@ -127,45 +127,45 @@ static void testToString3() {
 
 static void testRemoveBySwap() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(4));
-    CORE_TEST_NOT_NULL(list.add(3));
-    CORE_TEST_NOT_NULL(list.add(2));
-    CORE_TEST_TRUE(list.removeBySwap(-1));
-    CORE_TEST_FALSE(list.removeBySwap(0));
-    CORE_TEST_TRUE(list.removeBySwap(2));
+    CORE_TEST_ERROR(list.add(4));
+    CORE_TEST_ERROR(list.add(3));
+    CORE_TEST_ERROR(list.add(2));
+    CORE_TEST_EQUAL(Core::Error::INVALID_INDEX, list.removeBySwap(-1));
+    CORE_TEST_ERROR(list.removeBySwap(0));
+    CORE_TEST_EQUAL(Core::Error::INVALID_INDEX, list.removeBySwap(2));
     CORE_TEST_EQUAL(2, list[0]);
     CORE_TEST_EQUAL(3, list[1]);
     CORE_TEST_EQUAL(2, list.getLength());
-    CORE_TEST_FALSE(list.removeBySwap(1));
+    CORE_TEST_ERROR(list.removeBySwap(1));
     CORE_TEST_EQUAL(2, list[0]);
     CORE_TEST_EQUAL(1, list.getLength());
-    CORE_TEST_FALSE(list.removeBySwap(0));
+    CORE_TEST_ERROR(list.removeBySwap(0));
     CORE_TEST_EQUAL(0, list.getLength());
-    CORE_TEST_TRUE(list.removeBySwap(0));
+    CORE_TEST_EQUAL(Core::Error::INVALID_INDEX, list.removeBySwap(0));
 }
 
 static void testRemove() {
     IntList list;
-    CORE_TEST_NOT_NULL(list.add(4));
-    CORE_TEST_NOT_NULL(list.add(3));
-    CORE_TEST_NOT_NULL(list.add(2));
-    CORE_TEST_TRUE(list.remove(-1));
-    CORE_TEST_FALSE(list.remove(0));
-    CORE_TEST_TRUE(list.remove(2));
+    CORE_TEST_ERROR(list.add(4));
+    CORE_TEST_ERROR(list.add(3));
+    CORE_TEST_ERROR(list.add(2));
+    CORE_TEST_EQUAL(Core::Error::INVALID_INDEX, list.remove(-1));
+    CORE_TEST_ERROR(list.remove(0));
+    CORE_TEST_EQUAL(Core::Error::INVALID_INDEX, list.remove(2));
     CORE_TEST_EQUAL(3, list[0]);
     CORE_TEST_EQUAL(2, list[1]);
     CORE_TEST_EQUAL(2, list.getLength());
-    CORE_TEST_FALSE(list.remove(1));
+    CORE_TEST_ERROR(list.remove(1));
     CORE_TEST_EQUAL(3, list[0]);
     CORE_TEST_EQUAL(1, list.getLength());
-    CORE_TEST_FALSE(list.remove(0));
+    CORE_TEST_ERROR(list.remove(0));
     CORE_TEST_EQUAL(0, list.getLength());
-    CORE_TEST_TRUE(list.remove(0));
+    CORE_TEST_EQUAL(Core::Error::INVALID_INDEX, list.remove(0));
 }
 
 static void testResize() {
     IntList list;
-    CORE_TEST_FALSE(list.resize(5, 10));
+    CORE_TEST_ERROR(list.resize(5, 10));
     CORE_TEST_EQUAL(5, list.getLength());
     for(int i = 0; i < 5; i++) {
         CORE_TEST_EQUAL(10, list[i]);
@@ -174,7 +174,7 @@ static void testResize() {
 
 static void testDefaultResize() {
     IntList list;
-    CORE_TEST_FALSE(list.resize(5));
+    CORE_TEST_ERROR(list.resize(5));
     CORE_TEST_EQUAL(5, list.getLength());
     for(int i = 0; i < 5; i++) {
         CORE_TEST_EQUAL(0, list[i]);

+ 8 - 8
tests/MatrixStackTests.cpp

@@ -15,9 +15,9 @@ static void testInit() {
 
 static void testPop() {
     Matrices stack;
-    CORE_TEST_FALSE(stack.push());
+    CORE_TEST_ERROR(stack.push());
     stack.peek().scale(2.0f);
-    CORE_TEST_FALSE(stack.pop());
+    CORE_TEST_ERROR(stack.pop());
     Core::Matrix m;
     for(int i = 0; i < 16; i++) {
         CORE_TEST_FLOAT(m.getValues()[i], stack.peek().getValues()[i], 0.0f);
@@ -27,17 +27,17 @@ static void testPop() {
 static void testPush() {
     Matrices stack;
     for(int i = 0; i < 4; i++) {
-        CORE_TEST_FALSE(stack.push());
+        CORE_TEST_ERROR(stack.push());
     }
     for(int i = 0; i < 1000000; i++) {
-        CORE_TEST_TRUE(stack.push());
+        CORE_TEST_EQUAL(Core::Error::CAPACITY_REACHED, stack.push());
     }
 }
 
 static void testClear() {
     Matrices stack;
     stack.peek().scale(2.0f);
-    CORE_TEST_FALSE(stack.push());
+    CORE_TEST_ERROR(stack.push());
     stack.peek().scale(2.0f);
     stack.clear();
     Core::Matrix m;
@@ -49,9 +49,9 @@ static void testClear() {
 static void testToString1() {
     Matrices stack;
     stack.peek().scale(2.0f);
-    CORE_TEST_FALSE(stack.push());
+    CORE_TEST_ERROR(stack.push());
     stack.peek().scale(3.0f);
-    CORE_TEST_FALSE(stack.push());
+    CORE_TEST_ERROR(stack.push());
     stack.peek().scale(4.0f);
     CORE_TEST_STRING("["
                      "[[2.00, 0.00, 0.00, 0.00], "
@@ -73,7 +73,7 @@ static void testToString1() {
 static void testToString2() {
     Matrices stack;
     stack.peek().scale(2.0f);
-    CORE_TEST_FALSE(stack.push());
+    CORE_TEST_ERROR(stack.push());
     stack.peek().scale(3.0f);
     CORE_TEST_STRING("["
                      "[[2.00, 0.00, 0.00, 0.00], "

+ 1 - 1
tests/MatrixTests.cpp

@@ -132,7 +132,7 @@ static void testToString() {
     m.set(1, Core::Vector4(5.0f, 6.0f, 7.0f, 8.0f));
     m.set(2, Core::Vector4(9.0f, 10.0f, 11.0f, 12.0f));
     m.set(3, Core::Vector4(13.0f, 14.0f, 15.0f, 16.0f));
-    CORE_TEST_FALSE(s.append(m));
+    CORE_TEST_ERROR(s.append(m));
     CORE_TEST_STRING(
         "[[1.00, 2.00, 3.00, 4.00], [5.00, 6.00, 7.00, 8.00], "
         "[9.00, 10.00, 11.00, 12.00], [13.00, 14.00, 15.00, 16.00]]",

+ 50 - 51
tests/RingBufferTests.cpp

@@ -32,9 +32,8 @@ struct Tester final {
         sum -= id;
     }
 
-    // returns true on error
     template<int L>
-    check_return bool toString(Core::ArrayString<L>& s) const {
+    check_return Core::Error toString(Core::ArrayString<L>& s) const {
         return s.append(id);
     }
 };
@@ -51,68 +50,68 @@ static void testReadAndWrite() {
     Core::RingBuffer<int, 5> buffer;
     CORE_TEST_FALSE(buffer.canRemove());
     CORE_TEST_EQUAL(0, buffer.getLength());
-    CORE_TEST_NOT_NULL(buffer.add(4));
+    CORE_TEST_ERROR(buffer.add(4));
     CORE_TEST_EQUAL(1, buffer.getLength());
     CORE_TEST_TRUE(buffer.canRemove());
     CORE_TEST_EQUAL(4, buffer[0]);
-    CORE_TEST_FALSE(buffer.remove());
+    CORE_TEST_ERROR(buffer.remove());
     CORE_TEST_FALSE(buffer.canRemove());
     CORE_TEST_EQUAL(0, buffer.getLength());
 }
 
 static void testOverflow() {
     Core::RingBuffer<int, 3> buffer;
-    CORE_TEST_NOT_NULL(buffer.add(1));
-    CORE_TEST_NOT_NULL(buffer.add(2));
-    CORE_TEST_NOT_NULL(buffer.add(3));
-    CORE_TEST_NULL(buffer.add(4));
-    CORE_TEST_NULL(buffer.add(5));
+    CORE_TEST_ERROR(buffer.add(1));
+    CORE_TEST_ERROR(buffer.add(2));
+    CORE_TEST_ERROR(buffer.add(3));
+    CORE_TEST_EQUAL(Core::Error::CAPACITY_REACHED, buffer.add(4));
+    CORE_TEST_EQUAL(Core::Error::CAPACITY_REACHED, buffer.add(5));
     CORE_TEST_EQUAL(3, buffer.getLength());
     CORE_TEST_EQUAL(1, buffer[0]);
-    CORE_TEST_FALSE(buffer.remove());
+    CORE_TEST_ERROR(buffer.remove());
     CORE_TEST_EQUAL(2, buffer.getLength());
     CORE_TEST_EQUAL(2, buffer[0]);
-    CORE_TEST_FALSE(buffer.remove());
+    CORE_TEST_ERROR(buffer.remove());
     CORE_TEST_EQUAL(1, buffer.getLength());
     CORE_TEST_EQUAL(3, buffer[0]);
-    CORE_TEST_FALSE(buffer.remove());
+    CORE_TEST_ERROR(buffer.remove());
     CORE_TEST_FALSE(buffer.canRemove());
     CORE_TEST_EQUAL(0, buffer.getLength());
 }
 
 static void testRefill() {
     Core::RingBuffer<int, 3> buffer;
-    CORE_TEST_NOT_NULL(buffer.add(1));
-    CORE_TEST_NOT_NULL(buffer.add(2));
-    CORE_TEST_NOT_NULL(buffer.add(3));
-    CORE_TEST_NULL(buffer.add(4));
+    CORE_TEST_ERROR(buffer.add(1));
+    CORE_TEST_ERROR(buffer.add(2));
+    CORE_TEST_ERROR(buffer.add(3));
+    CORE_TEST_EQUAL(Core::Error::CAPACITY_REACHED, buffer.add(4));
     CORE_TEST_EQUAL(3, buffer.getLength());
     CORE_TEST_TRUE(buffer.canRemove());
     CORE_TEST_EQUAL(1, buffer[0]);
-    CORE_TEST_FALSE(buffer.remove());
+    CORE_TEST_ERROR(buffer.remove());
     CORE_TEST_EQUAL(2, buffer[0]);
-    CORE_TEST_FALSE(buffer.remove());
+    CORE_TEST_ERROR(buffer.remove());
     CORE_TEST_EQUAL(3, buffer[0]);
-    CORE_TEST_FALSE(buffer.remove());
+    CORE_TEST_ERROR(buffer.remove());
     CORE_TEST_EQUAL(0, buffer.getLength());
 
     CORE_TEST_FALSE(buffer.canRemove());
-    CORE_TEST_NOT_NULL(buffer.add(5));
-    CORE_TEST_NOT_NULL(buffer.add(6));
+    CORE_TEST_ERROR(buffer.add(5));
+    CORE_TEST_ERROR(buffer.add(6));
     CORE_TEST_EQUAL(2, buffer.getLength());
     CORE_TEST_TRUE(buffer.canRemove());
     CORE_TEST_EQUAL(5, buffer[0]);
-    CORE_TEST_FALSE(buffer.remove());
+    CORE_TEST_ERROR(buffer.remove());
     CORE_TEST_EQUAL(6, buffer[0]);
-    CORE_TEST_FALSE(buffer.remove());
+    CORE_TEST_ERROR(buffer.remove());
     CORE_TEST_FALSE(buffer.canRemove());
     CORE_TEST_EQUAL(0, buffer.getLength());
 }
 
 static void testClear() {
     Core::RingBuffer<int, 3> buffer;
-    CORE_TEST_NOT_NULL(buffer.add(1));
-    CORE_TEST_NOT_NULL(buffer.add(2));
+    CORE_TEST_ERROR(buffer.add(1));
+    CORE_TEST_ERROR(buffer.add(2));
     CORE_TEST_EQUAL(2, buffer.getLength());
     buffer.clear();
     CORE_TEST_FALSE(buffer.canRemove());
@@ -122,18 +121,18 @@ static void testClear() {
 static void testConstructDestruct() {
     resetTester();
     Core::RingBuffer<Tester, 3> buffer;
-    CORE_TEST_NOT_NULL(buffer.add());
+    CORE_TEST_ERROR(buffer.add());
     CORE_TEST_EQUAL(1, Tester::sum);
-    CORE_TEST_NOT_NULL(buffer.add());
+    CORE_TEST_ERROR(buffer.add());
     CORE_TEST_EQUAL(3, Tester::sum);
-    CORE_TEST_NOT_NULL(buffer.add());
+    CORE_TEST_ERROR(buffer.add());
     CORE_TEST_EQUAL(6, Tester::sum);
 
-    CORE_TEST_FALSE(buffer.remove());
+    CORE_TEST_ERROR(buffer.remove());
     CORE_TEST_EQUAL(5, Tester::sum);
-    CORE_TEST_FALSE(buffer.remove());
+    CORE_TEST_ERROR(buffer.remove());
     CORE_TEST_EQUAL(3, Tester::sum);
-    CORE_TEST_FALSE(buffer.remove());
+    CORE_TEST_ERROR(buffer.remove());
     CORE_TEST_EQUAL(0, Tester::sum);
 }
 
@@ -141,11 +140,11 @@ static void testCopyDestruct() {
     resetTester();
     {
         Core::RingBuffer<Tester, 3> buffer;
-        CORE_TEST_NOT_NULL(buffer.add());
+        CORE_TEST_ERROR(buffer.add());
         CORE_TEST_EQUAL(1, Tester::sum);
-        CORE_TEST_NOT_NULL(buffer.add());
+        CORE_TEST_ERROR(buffer.add());
         CORE_TEST_EQUAL(3, Tester::sum);
-        CORE_TEST_NOT_NULL(buffer.add());
+        CORE_TEST_ERROR(buffer.add());
         CORE_TEST_EQUAL(6, Tester::sum);
         {
             Core::RingBuffer<Tester, 3> copy = buffer;
@@ -160,11 +159,11 @@ static void testCopyAssignmentDestruct() {
     resetTester();
     {
         Core::RingBuffer<Tester, 3> buffer;
-        CORE_TEST_NOT_NULL(buffer.add());
+        CORE_TEST_ERROR(buffer.add());
         CORE_TEST_EQUAL(1, Tester::sum);
-        CORE_TEST_NOT_NULL(buffer.add());
+        CORE_TEST_ERROR(buffer.add());
         CORE_TEST_EQUAL(3, Tester::sum);
-        CORE_TEST_NOT_NULL(buffer.add());
+        CORE_TEST_ERROR(buffer.add());
         CORE_TEST_EQUAL(6, Tester::sum);
         {
             Core::RingBuffer<Tester, 3> copy;
@@ -180,11 +179,11 @@ static void testMoveDestruct() {
     resetTester();
     {
         Core::RingBuffer<Tester, 3> buffer;
-        CORE_TEST_NOT_NULL(buffer.add());
+        CORE_TEST_ERROR(buffer.add());
         CORE_TEST_EQUAL(1, Tester::sum);
-        CORE_TEST_NOT_NULL(buffer.add());
+        CORE_TEST_ERROR(buffer.add());
         CORE_TEST_EQUAL(3, Tester::sum);
-        CORE_TEST_NOT_NULL(buffer.add());
+        CORE_TEST_ERROR(buffer.add());
         CORE_TEST_EQUAL(6, Tester::sum);
         {
             Core::RingBuffer<Tester, 3> move = Core::move(buffer);
@@ -200,11 +199,11 @@ static void testMoveAssignmentDestruct() {
     resetTester();
     {
         Core::RingBuffer<Tester, 3> buffer;
-        CORE_TEST_NOT_NULL(buffer.add());
+        CORE_TEST_ERROR(buffer.add());
         CORE_TEST_EQUAL(1, Tester::sum);
-        CORE_TEST_NOT_NULL(buffer.add());
+        CORE_TEST_ERROR(buffer.add());
         CORE_TEST_EQUAL(3, Tester::sum);
-        CORE_TEST_NOT_NULL(buffer.add());
+        CORE_TEST_ERROR(buffer.add());
         CORE_TEST_EQUAL(6, Tester::sum);
         {
             Core::RingBuffer<Tester, 3> move;
@@ -221,34 +220,34 @@ static void testOverall() {
     resetTester();
     Core::RingBuffer<Tester, 3> buffer;
 
-    CORE_TEST_NOT_NULL(buffer.add());
-    CORE_TEST_NOT_NULL(buffer.add());
-    CORE_TEST_NOT_NULL(buffer.add());
+    CORE_TEST_ERROR(buffer.add());
+    CORE_TEST_ERROR(buffer.add());
+    CORE_TEST_ERROR(buffer.add());
     CORE_TEST_STRING("[1, 2, 3]", buffer);
     CORE_TEST_EQUAL(3, buffer.getLength());
     CORE_TEST_EQUAL(6, Tester::sum);
 
-    CORE_TEST_FALSE(buffer.remove());
+    CORE_TEST_ERROR(buffer.remove());
     CORE_TEST_STRING("[2, 3]", buffer);
     CORE_TEST_EQUAL(2, buffer.getLength());
     CORE_TEST_EQUAL(5, Tester::sum);
 
-    CORE_TEST_NOT_NULL(buffer.add());
+    CORE_TEST_ERROR(buffer.add());
     CORE_TEST_STRING("[2, 3, 4]", buffer);
     CORE_TEST_EQUAL(3, buffer.getLength());
     CORE_TEST_EQUAL(9, Tester::sum);
 
-    CORE_TEST_FALSE(buffer.remove());
+    CORE_TEST_ERROR(buffer.remove());
     CORE_TEST_STRING("[3, 4]", buffer);
     CORE_TEST_EQUAL(2, buffer.getLength());
     CORE_TEST_EQUAL(7, Tester::sum);
 
-    CORE_TEST_NOT_NULL(buffer.add());
+    CORE_TEST_ERROR(buffer.add());
     CORE_TEST_STRING("[3, 4, 5]", buffer);
     CORE_TEST_EQUAL(3, buffer.getLength());
     CORE_TEST_EQUAL(12, Tester::sum);
 
-    CORE_TEST_FALSE(buffer.remove());
+    CORE_TEST_ERROR(buffer.remove());
     CORE_TEST_STRING("[4, 5]", buffer);
     CORE_TEST_EQUAL(2, buffer.getLength());
     CORE_TEST_EQUAL(9, Tester::sum);

+ 13 - 13
tests/StackTests.cpp

@@ -6,15 +6,15 @@
 template<typename T>
 static void testPushPopPeek() {
     T stack;
-    CORE_TEST_NOT_NULL(stack.push(1));
-    CORE_TEST_NOT_NULL(stack.push(2));
-    CORE_TEST_NOT_NULL(stack.push(3));
+    CORE_TEST_ERROR(stack.push(1));
+    CORE_TEST_ERROR(stack.push(2));
+    CORE_TEST_ERROR(stack.push(3));
     CORE_TEST_EQUAL(3, stack.peek());
-    CORE_TEST_FALSE(stack.pop());
+    CORE_TEST_ERROR(stack.pop());
     CORE_TEST_EQUAL(2, stack.peek());
-    CORE_TEST_FALSE(stack.pop());
+    CORE_TEST_ERROR(stack.pop());
     CORE_TEST_EQUAL(1, stack.peek());
-    CORE_TEST_FALSE(stack.pop());
+    CORE_TEST_ERROR(stack.pop());
     CORE_TEST_TRUE(stack.isEmpty());
 }
 
@@ -22,10 +22,10 @@ template<typename T>
 static void testBigPushPop(int amount) {
     T stack;
     for(int i = 0; i < amount; i++) {
-        CORE_TEST_NOT_NULL(stack.push(i));
+        CORE_TEST_ERROR(stack.push(i));
     }
     for(int i = 0; i < amount; i++) {
-        CORE_TEST_FALSE(stack.pop());
+        CORE_TEST_ERROR(stack.pop());
     }
     CORE_TEST_TRUE(stack.isEmpty());
 }
@@ -33,16 +33,16 @@ static void testBigPushPop(int amount) {
 template<typename T>
 static void testToString1() {
     T stack;
-    CORE_TEST_NOT_NULL(stack.push(1));
-    CORE_TEST_NOT_NULL(stack.push(243));
-    CORE_TEST_NOT_NULL(stack.push(-423));
+    CORE_TEST_ERROR(stack.push(1));
+    CORE_TEST_ERROR(stack.push(243));
+    CORE_TEST_ERROR(stack.push(-423));
     CORE_TEST_STRING("[1, 243, -423]", stack);
 }
 
 template<typename T>
 static void testToString2() {
     T stack;
-    CORE_TEST_NOT_NULL(stack.push(1));
+    CORE_TEST_ERROR(stack.push(1));
     CORE_TEST_STRING("[1]", stack);
 }
 
@@ -56,7 +56,7 @@ template<typename T>
 static void testPop() {
     T stack;
     for(int i = 0; i < 100000; i++) {
-        CORE_TEST_TRUE(stack.pop());
+        CORE_TEST_EQUAL(Core::Error::INVALID_INDEX, stack.pop());
     }
 }
 

+ 8 - 7
tests/ThreadTests.cpp

@@ -16,25 +16,26 @@ static int run(void*) {
 
 static void testStart() {
     runDone = 0;
-    Core::Thread::Id id = Core::Thread::start(run, nullptr);
-    CORE_TEST_FALSE(id == Core::Thread::ERROR);
+    Core::Thread::Id id = Core::Thread::INVALID_ID;
+    CORE_TEST_ERROR(Core::Thread::start(id, run, nullptr))
     int returnValue = 0;
-    CORE_TEST_FALSE(Core::Thread::join(id, &returnValue));
+    CORE_TEST_ERROR(Core::Thread::join(id, &returnValue));
     CORE_TEST_EQUAL(1, runDone);
     CORE_TEST_EQUAL(7, returnValue);
 }
 
 static void testLambda() {
     IntHolder i(0);
-    Core::Thread::Id id = Core::Thread::start(
+    Core::Thread::Id id = Core::Thread::INVALID_ID;
+    CORE_TEST_ERROR(Core::Thread::start(
+        id,
         [](void* p) {
             IntHolder* ip = static_cast<IntHolder*>(p);
             ip->value = 2;
             return 0;
         },
-        &i);
-    CORE_TEST_FALSE(id == Core::Thread::ERROR);
-    CORE_TEST_FALSE(Core::Thread::join(id, nullptr));
+        &i));
+    CORE_TEST_ERROR(Core::Thread::join(id, nullptr));
     CORE_TEST_EQUAL(2, i.value);
 }
 

+ 4 - 4
tests/VectorTests.cpp

@@ -184,11 +184,11 @@ static void testCast() {
 
 static void testToString() {
     Core::ArrayString<200> s;
-    CORE_TEST_FALSE(s.append(Core::Vector<1, float>()));
-    CORE_TEST_FALSE(s.append(Core::Vector2(2.0f, 3.0f)));
-    CORE_TEST_FALSE(s.append(V3(4.0f, 5.0f, 6.0f)));
+    CORE_TEST_ERROR(s.append(Core::Vector<1, float>()));
+    CORE_TEST_ERROR(s.append(Core::Vector2(2.0f, 3.0f)));
+    CORE_TEST_ERROR(s.append(V3(4.0f, 5.0f, 6.0f)));
     Core::ArrayString<200> s2;
-    CORE_TEST_FALSE(s2.append("[0.00][2.00, 3.00][4.00, 5.00, 6.00]"));
+    CORE_TEST_ERROR(s2.append("[0.00][2.00, 3.00][4.00, 5.00, 6.00]"));
     CORE_TEST_EQUAL(s2, s);
 }
 

+ 9 - 11
thread/Thread.cpp

@@ -7,26 +7,24 @@
 static Core::HashMap<Core::Thread::Id, thrd_t> threads;
 static Core::Thread::Id idCounter = 0;
 
-Core::Thread::Id Core::Thread::start(Function f, void* p) {
-    Id id = idCounter++;
-    thrd_t* t = threads.tryEmplace(id);
-    if(t == nullptr) {
-        return ERROR;
-    }
+Core::Error Core::Thread::start(Id& id, Function f, void* p) {
+    id = idCounter++;
+    thrd_t* t = nullptr;
+    CORE_RETURN_ERROR(threads.tryEmplace(t, id));
     if(thrd_create(t, f, p) != thrd_success) {
         (void)threads.remove(id);
-        return CORE_ERROR(Core::Error::THREAD_ERROR);
+        return Error::THREAD_ERROR;
     }
-    return id;
+    return Error::NONE;
 }
 
-bool Core::Thread::join(Id id, int* returnValue) {
+Core::Error Core::Thread::join(Id id, int* returnValue) {
     thrd_t* t = threads.search(id);
     if(t == nullptr) {
-        return CORE_ERROR(Core::Error::INVALID_ID);
+        return Error::INVALID_ID;
     }
     if(thrd_join(*t, returnValue) != thrd_success) {
-        return CORE_ERROR(Core::Error::THREAD_ERROR);
+        return Error::THREAD_ERROR;
     }
     return threads.remove(id);
 }

+ 5 - 6
thread/Thread.h

@@ -1,16 +1,15 @@
 #ifndef CORE_THREAD_H
 #define CORE_THREAD_H
 
-#include "utils/Check.h"
+#include "utils/Utility.h"
 
 namespace Core::Thread {
     using Id = int;
-    constexpr Id ERROR = -1;
     using Function = int (*)(void*);
-    // returns Core::Thread::ERROR on error and calls the error callback
-    check_return Id start(Function f, void* p);
-    // returns true on error and calls the error callback
-    check_return bool join(Id id, int* returnValue = nullptr);
+    constexpr Id INVALID_ID = -1;
+
+    check_return Error start(Id& id, Function f, void* p);
+    check_return Error join(Id id, int* returnValue = nullptr);
 }
 
 #endif

+ 80 - 131
utils/ArrayString.h

@@ -24,7 +24,7 @@ namespace Core {
         bool operator==(const char* s) const {
             for(int i = 0; i < length; i++) {
                 u32 u = 0;
-                if(readUnicode(u, s) || data[i] != u) {
+                if(readUnicode(u, s) != Error::NONE || data[i] != u) {
                     return false;
                 }
             }
@@ -65,138 +65,116 @@ namespace Core {
             return DATA_LENGTH;
         }
 
-        // returns true on error and calls the error callback
-        check_return bool append(char c) {
+        check_return Error append(char c) {
             if(c < 0) {
-                return CORE_ERROR(Error::NEGATIVE_ARGUMENT);
+                return Error::NEGATIVE_ARGUMENT;
             }
             return appendUnicode(static_cast<u32>(c));
         }
 
-        // returns true on error and calls the error callback
-        check_return bool append(signed char c) {
+        check_return Error append(signed char c) {
             if(c < 0) {
-                return CORE_ERROR(Error::NEGATIVE_ARGUMENT);
+                return Error::NEGATIVE_ARGUMENT;
             }
             return appendUnicode(static_cast<u32>(c));
         }
 
-        // returns true on error and calls the error callback
-        check_return bool append(unsigned char c) {
+        check_return Error append(unsigned char c) {
             return appendUnicode(c);
         }
 
-        // returns true on error and calls the error callback
-        check_return bool append(const char* s) {
+        check_return Error append(const char* s) {
             while(true) {
                 u32 u = 0;
-                if(readUnicode(u, s)) {
-                    return true;
-                } else if(u == 0) {
-                    return false;
-                } else if(appendUnicode(u)) {
-                    return true;
+                CORE_RETURN_ERROR(readUnicode(u, s));
+                if(u == 0) {
+                    return Error::NONE;
                 }
+                CORE_RETURN_ERROR(appendUnicode(u));
             }
-            return false;
         }
 
-        // returns true on error and calls the error callback
-        check_return bool append(const signed char* s) {
+        check_return Error append(const signed char* s) {
             return append(reinterpret_cast<const char*>(s));
         }
 
-        // returns true on error and calls the error callback
-        check_return bool append(const unsigned char* s) {
+        check_return Error append(const unsigned char* s) {
             return append(reinterpret_cast<const char*>(s));
         }
 
-        // returns true on error and calls the error callback
-        check_return bool append(signed short s) {
+        check_return Error append(signed short s) {
             return convertAppend(s);
         }
 
-        // returns true on error and calls the error callback
-        check_return bool append(unsigned short s) {
+        check_return Error append(unsigned short s) {
             return convertAppend(s);
         }
 
-        // returns true on error and calls the error callback
-        check_return bool append(signed int i) {
+        check_return Error append(signed int i) {
             return convertAppend(i);
         }
 
-        // returns true on error and calls the error callback
-        check_return bool append(unsigned int i) {
+        check_return Error append(unsigned int i) {
             return convertAppend(i);
         }
 
-        // returns true on error and calls the error callback
-        check_return bool append(signed long l) {
+        check_return Error append(signed long l) {
             return convertAppend(l);
         }
 
-        // returns true on error and calls the error callback
-        check_return bool append(unsigned long l) {
+        check_return Error append(unsigned long l) {
             return convertAppend(l);
         }
 
-        // returns true on error and calls the error callback
-        check_return bool append(signed long long ll) {
+        check_return Error append(signed long long ll) {
             return convertAppend(ll);
         }
 
-        // returns true on error and calls the error callback
-        check_return bool append(unsigned long long ll) {
+        check_return Error append(unsigned long long ll) {
             return convertAppend(ll);
         }
 
-        // returns true on error and calls the error callback
-        check_return bool append(float f) {
+        check_return Error append(float f) {
             return convertAppend(static_cast<double>(f));
         }
 
-        // returns true on error and calls the error callback
-        check_return bool append(double d) {
+        check_return Error append(double d) {
             return convertAppend(d);
         }
 
-        // returns true on error and calls the error callback
-        check_return bool append(long double ld) {
+        check_return Error append(long double ld) {
             return convertAppend(ld);
         }
 
-        // returns true on error and calls the error callback
-        check_return bool append(bool b) {
+        check_return Error append(bool b) {
             return b ? append("true") : append("false");
         }
 
-        // returns true on error and calls the error callback
-        check_return bool appendUnicode(u32 c) {
+        check_return Error appendUnicode(u32 c) {
             if(length >= DATA_LENGTH) {
-                return CORE_ERROR(Error::CAPACITY_REACHED);
+                return Error::CAPACITY_REACHED;
             }
             data[length++] = c;
             addToHash(c);
-            return false;
+            return Error::NONE;
+        }
+
+        check_return Error append(Error e) {
+            return append(getErrorName(e));
         }
 
-        // returns true on error and calls the error callback
         template<typename T>
-        check_return bool append(const T& t) {
+        check_return Error append(const T& t) {
             return t.toString(*this);
         }
 
-        // returns true on error and calls the error callback
         template<int L>
-        check_return bool toString(ArrayString<L>& s) const {
+        check_return Error toString(ArrayString<L>& s) const {
             int l = length; // length changes if &s == this
             for(int i = 0; i < l; i++) {
-                if(s.appendUnicode(data[i])) {
-                    return true;
-                }
+                CORE_RETURN_ERROR(s.appendUnicode(data[i]));
             }
-            return false;
+            return Error::NONE;
         }
 
         void clear() {
@@ -209,51 +187,40 @@ namespace Core {
             return hash;
         }
 
-        // returns true on error and calls the error callback
-        check_return bool print() const {
+        check_return Error print() const {
             for(int i = 0; i < length; i++) {
                 u32 c = data[i];
                 if(c < (1 << 7)) {
-                    if(Core::putChar(static_cast<int>(c & 0x7F))) {
-                        return true;
-                    }
+                    CORE_RETURN_ERROR(printChar(c, 0, 0x7F, 0x0));
                 } else if(c < (1 << 11)) {
-                    if(printChar(c, 6, 0x1F, 0xC0) ||
-                       printChar(c, 0, 0x3F, 0x80)) {
-                        return true;
-                    }
+                    CORE_RETURN_ERROR(printChar(c, 6, 0x1F, 0xC0));
+                    CORE_RETURN_ERROR(printChar(c, 0, 0x3F, 0x80));
                 } else if(c < (1 << 16)) {
-                    if(printChar(c, 12, 0x0F, 0xE0) ||
-                       printChar(c, 6, 0x3F, 0x80) ||
-                       printChar(c, 0, 0x3F, 0x80)) {
-                        return true;
-                    }
+                    CORE_RETURN_ERROR(printChar(c, 12, 0x0F, 0xE0));
+                    CORE_RETURN_ERROR(printChar(c, 6, 0x3F, 0x80));
+                    CORE_RETURN_ERROR(printChar(c, 0, 0x3F, 0x80));
                 } else if(c < (1 << 21)) {
-                    if(printChar(c, 18, 0x07, 0xF0) ||
-                       printChar(c, 12, 0x3F, 0x80) ||
-                       printChar(c, 6, 0x3F, 0x80) ||
-                       printChar(c, 0, 0x3F, 0x80)) {
-                        return true;
-                    }
+                    CORE_RETURN_ERROR(printChar(c, 18, 0x07, 0xF0));
+                    CORE_RETURN_ERROR(printChar(c, 12, 0x3F, 0x80));
+                    CORE_RETURN_ERROR(printChar(c, 6, 0x3F, 0x80));
+                    CORE_RETURN_ERROR(printChar(c, 0, 0x3F, 0x80));
                 }
             }
-            return false;
+            return Error::NONE;
         }
 
-        // returns true on error and calls the error callback
-        check_return bool printLine() const {
-            return print() || Core::putChar('\n');
+        check_return Error printLine() const {
+            CORE_RETURN_ERROR(print());
+            CORE_RETURN_ERROR(Core::putChar('\n'));
+            return Error::NONE;
         }
 
-        // returns true on error and calls the error callback
         template<typename... Args>
-        check_return bool format(Args&&... args) {
+        check_return Error format(Args&&... args) {
             ArrayString s;
-            if(formatBuffer(s, 0, Core::forward<Args>(args)...)) {
-                return true;
-            }
+            CORE_RETURN_ERROR(formatBuffer(s, 0, Core::forward<Args>(args)...));
             *this = s;
-            return false;
+            return Error::NONE;
         }
 
         template<int L>
@@ -312,25 +279,21 @@ namespace Core {
         }
 
         template<int L1, int L2>
-        bool replace(const ArrayString<L1>& search,
-                     const ArrayString<L2>& replace) {
+        check_return Error replace(const ArrayString<L1>& search,
+                                   const ArrayString<L2>& replace) {
             ArrayString<N> s;
             int i = 0;
             while(i < length) {
                 if(startsWidth(search, i)) {
-                    if(s.append(replace)) {
-                        return true;
-                    }
+                    CORE_RETURN_ERROR(s.append(replace));
                     i += search.getLength();
                 } else {
-                    if(s.appendUnicode(data[i])) {
-                        return true;
-                    }
+                    CORE_RETURN_ERROR(s.appendUnicode(data[i]));
                     i++;
                 }
             }
             *this = s;
-            return false;
+            return Error::NONE;
         }
 
         void replace(u32 search, u32 replace) {
@@ -344,8 +307,7 @@ namespace Core {
         }
 
     private:
-        // returns true on error and calls the error callback
-        check_return static bool printChar(u32 u, u32 shift, u32 a, u32 o) {
+        check_return static Error printChar(u32 u, u32 shift, u32 a, u32 o) {
             return Core::putChar(static_cast<int>(((u >> shift) & a) | o));
         }
 
@@ -356,49 +318,47 @@ namespace Core {
             return static_cast<u32>(*(s++));
         }
 
-        // returns true on error and calls the error callback
-        static bool readUnicode(u32& u, const char*& s) {
+        static Error readUnicode(u32& u, const char*& s) {
             u = read(s);
             if((u & 0x80) == 0) {
-                return false;
+                return Error::NONE;
             }
             if((u & 0xE0) == 0xC0) {
                 u32 u2 = read(s);
                 if(u2 == 0) {
-                    return CORE_ERROR(Error::INVALID_CHAR);
+                    return Error::INVALID_CHAR;
                 }
                 u = ((u & 0x1F) << 6) | (u2 & 0x3F);
-                return false;
+                return Error::NONE;
             } else if((u & 0xF0) == 0xE0) {
                 u32 u2 = read(s);
                 u32 u3 = read(s);
                 if(u2 == 0 || u3 == 0) {
-                    return CORE_ERROR(Error::INVALID_CHAR);
+                    return Error::INVALID_CHAR;
                 }
                 u = ((u & 0xF) << 12) | ((u2 & 0x3F) << 6) | (u3 & 0x3F);
-                return false;
+                return Error::NONE;
             } else if((u & 0xF8) == 0xF0) {
                 u32 u2 = read(s);
                 u32 u3 = read(s);
                 u32 u4 = read(s);
                 if(u2 == 0 || u3 == 0 || u4 == 0) {
-                    return CORE_ERROR(Error::INVALID_CHAR);
+                    return Error::INVALID_CHAR;
                 }
                 u = ((u & 0x07) << 18) | ((u2 & 0x3F) << 12) |
                     ((u3 & 0x3F) << 6) | (u4 & 0x3F);
-                return false;
+                return Error::NONE;
             }
-            return CORE_ERROR(Error::INVALID_CHAR);
+            return Error::INVALID_CHAR;
         }
 
         void addToHash(u32 u) {
             hash = static_cast<u32>(2120251889) * hash + static_cast<u32>(u);
         }
 
-        // returns true on error and calls the error callback
         template<typename T, typename... Args>
-        check_return bool formatBuffer(ArrayString& s, int index, const T& t,
-                                       Args&&... args) {
+        check_return Error formatBuffer(ArrayString& s, int index, const T& t,
+                                        Args&&... args) {
             while(index < length) {
                 u32 u = data[index++];
                 if(u == '#') {
@@ -408,34 +368,23 @@ namespace Core {
                     }
                     index++;
                 }
-                if(s.appendUnicode(u)) {
-                    return true;
-                }
-            }
-            if(s.append(t)) {
-                return true;
+                CORE_RETURN_ERROR(s.appendUnicode(u));
             }
+            CORE_RETURN_ERROR(s.append(t));
             return formatBuffer(s, index, Core::forward<Args>(args)...);
         }
 
-        // returns true on error and calls the error callback
-        check_return bool formatBuffer(ArrayString& s, int index) {
+        check_return Error formatBuffer(ArrayString& s, int index) {
             while(index < length) {
-                if(s.appendUnicode(data[index++])) {
-                    return true;
-                }
+                CORE_RETURN_ERROR(s.appendUnicode(data[index++]));
             }
-            return false;
+            return Error::NONE;
         }
 
-        // returns true on error and calls the error callback
         template<typename T>
-        check_return bool convertAppend(T t) {
-            constexpr int BUFFER_SIZE = 64;
-            char buffer[BUFFER_SIZE];
-            if(Core::toString(t, buffer, BUFFER_SIZE)) {
-                return true;
-            }
+        check_return Error convertAppend(T t) {
+            char buffer[64];
+            CORE_RETURN_ERROR(Core::toString(t, buffer, CORE_SIZE(buffer)));
             return append(static_cast<const char*>(buffer));
         }
     };

+ 4 - 8
utils/Buffer.cpp

@@ -20,25 +20,21 @@ Core::Buffer& Core::Buffer::operator=(Buffer&& other) {
     return *this;
 }
 
-bool Core::Buffer::copyFrom(const Buffer& other) {
+Core::Error Core::Buffer::copyFrom(const Buffer& other) {
     clear();
     return add(other.getData(), other.length);
 }
 
-bool Core::Buffer::add(const void* data, int size) {
+Core::Error Core::Buffer::add(const void* data, int size) {
     if(length + size > capacity || buffer == nullptr) {
         while(length + size > capacity) {
             capacity += Math::max(4, capacity / 4);
         }
-        char* newBuffer = static_cast<char*>(reallocate(buffer, capacity));
-        if(newBuffer == nullptr) {
-            return true;
-        }
-        buffer = newBuffer;
+        CORE_RETURN_ERROR(reallocate(buffer, capacity));
     }
     memoryCopy(buffer + length, data, size);
     length += size;
-    return false;
+    return Error::NONE;
 }
 
 int Core::Buffer::getLength() const {

+ 4 - 7
utils/Buffer.h

@@ -1,7 +1,7 @@
 #ifndef CORE_BUFFER_H
 #define CORE_BUFFER_H
 
-#include "utils/Check.h"
+#include "utils/Utility.h"
 
 namespace Core {
     class Buffer final {
@@ -17,15 +17,12 @@ namespace Core {
         Buffer& operator=(const Buffer& other) = delete;
         Buffer& operator=(Buffer&& other);
 
-        // returns true on error and calls the error callback
-        check_return bool copyFrom(const Buffer& other);
+        check_return Error copyFrom(const Buffer& other);
 
-        // returns true on error and calls the error callback
-        check_return bool add(const void* data, int size);
+        check_return Error add(const void* data, int size);
 
-        // returns true on error and calls the error callback
         template<typename T>
-        check_return bool add(const T& t) {
+        check_return Error add(const T& t) {
             return add(&t, sizeof(T));
         }
 

+ 11 - 11
utils/Clock.cpp

@@ -6,14 +6,13 @@
 Core::Clock::Clock() : index(0), last(0), sum(0), time(0) {
 }
 
-bool Core::Clock::update(Clock::Nanos& n) {
+Core::Error Core::Clock::update(Clock::Nanos& n) {
     Nanos current = 0;
-    if(getNanos(current)) {
-        return true;
-    } else if(last == 0) {
+    CORE_RETURN_ERROR(getNanos(current));
+    if(last == 0) {
         last = current;
         n = 0;
-        return false;
+        return Error::NONE;
     }
     index = (index + 1) & (LENGTH - 1);
     sum -= time[index];
@@ -21,26 +20,27 @@ bool Core::Clock::update(Clock::Nanos& n) {
     sum += time[index];
     last = current;
     n = time[index];
-    return false;
+    return Error::NONE;
 }
 
 float Core::Clock::getUpdatesPerSecond() const {
     return (LENGTH * 1000000000.0f) / static_cast<float>(sum);
 }
 
-bool Core::Clock::getNanos(Clock::Nanos& n) {
+Core::Error Core::Clock::getNanos(Clock::Nanos& n) {
     struct timespec ts;
     if(timespec_get(&ts, TIME_UTC) == 0) {
-        return CORE_ERROR(Error::TIME_NOT_AVAILABLE);
+        return Error::TIME_NOT_AVAILABLE;
     }
     n = static_cast<Clock::Nanos>(ts.tv_sec) * 1'000'000'000L +
         static_cast<Clock::Nanos>(ts.tv_nsec);
-    return false;
+    return Error::NONE;
 }
 
-bool Core::Clock::wait(Nanos nanos) const {
+Core::Error Core::Clock::wait(Nanos nanos) const {
     struct timespec t;
     t.tv_nsec = nanos % 1'000'000'000;
     t.tv_sec = nanos / 1'000'000'000;
-    return CORE_ERROR(Error::SLEEP_INTERRUPTED, thrd_sleep(&t, nullptr) != 0);
+    return thrd_sleep(&t, nullptr) != 0 ? Error::SLEEP_INTERRUPTED
+                                        : Error::NONE;
 }

+ 3 - 6
utils/Clock.h

@@ -19,15 +19,12 @@ namespace Core {
     public:
         Clock();
 
-        // returns true on error and calls the error callback
         // the first invocation will always return 0 nanos
-        check_return bool update(Nanos& n);
+        check_return Error update(Nanos& n);
         float getUpdatesPerSecond() const;
-        // returns true on error and calls the error callback
-        check_return bool wait(Nanos nanos) const;
+        check_return Error wait(Nanos nanos) const;
 
-        // returns true on error and calls the error callback
-        check_return static bool getNanos(Nanos& n);
+        check_return static Error getNanos(Nanos& n);
     };
 }
 

+ 8 - 7
utils/Logger.h

@@ -16,13 +16,14 @@ namespace Core::Logger {
         }
         file = Core::getFileName(file);
         Core::ArrayString<2048> s;
-        if(s.append(start) || s.append("#:# | ") || s.format(file, line)) {
-            CORE_EXIT(1);
-        } else if(s.append(format)) {
-            CORE_EXIT(1);
-        } else if(s.format(Core::forward<Args>(args)...)) {
-            CORE_EXIT(1);
-        } else if(s.append("\33[39;49m\n") || s.print()) {
+        Error e = Error::NONE;
+        if(checkError(e, s.append(start)) ||
+           checkError(e, s.append("#:# | ")) ||
+           checkError(e, s.format(file, line)) ||
+           checkError(e, s.append(format)) ||
+           checkError(e, s.format(Core::forward<Args>(args)...)) ||
+           checkError(e, s.append("\33[39;49m\n")) ||
+           checkError(e, s.print())) {
             CORE_EXIT(1);
         }
     }

+ 21 - 28
utils/Utility.cpp

@@ -4,8 +4,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-static Core::ErrorHandler errorHandler = nullptr;
-static void* errorData = nullptr;
 static Core::ExitHandler exitHandler = nullptr;
 static void* exitData = nullptr;
 
@@ -18,28 +16,17 @@ const char* Core::getErrorName(Error e) {
         case Error::OUT_OF_MEMORY: return "OUT_OF_MEMORY";
         case Error::INVALID_CHAR: return "INVALID_CHAR";
         case Error::NOT_FOUND: return "NOT_FOUND";
+        case Error::INVALID_STATE: return "INVALID_STATE";
         case Error::INVALID_INDEX: return "INVALID_INDEX";
-        case Error::INVALID_REMOVE_INDEX: return "INVALID_REMOVE_INDEX";
         case Error::TIME_NOT_AVAILABLE: return "TIME_NOT_AVAILABLE";
         case Error::SLEEP_INTERRUPTED: return "SLEEP_INTERRUPTED";
         case Error::THREAD_ERROR: return "THREAD_ERROR";
         case Error::INVALID_ID: return "INVALID_ID";
+        case Error::EXISTING_KEY: return "EXISTING_KEY";
     }
     return "?";
 }
 
-bool Core::handleError(const char* file, int line, Error e, bool check) {
-    if(check && errorHandler != nullptr) {
-        errorHandler(file, line, e, errorData);
-    }
-    return check;
-}
-
-void Core::setErrorHandler(ErrorHandler eh, void* data) {
-    errorHandler = eh;
-    errorData = data;
-}
-
 void* operator new(size_t bytes) noexcept {
     return malloc(bytes);
 }
@@ -78,7 +65,8 @@ void* operator new(size_t bytes, void* p) noexcept {
 
 void Core::exitWithHandler(const char* file, int line, int value) {
     if(value != 0) {
-        printf("\33[1;31mExit from %s:%d\33[39;49m\n", file, line);
+        printf("\33[1;31mExit from %s:%d with value %d\33[39;49m\n", file, line,
+               value);
     }
     if(exitHandler != nullptr) {
         exitHandler(value, exitData);
@@ -92,13 +80,14 @@ void Core::setExitHandler(ExitHandler eh, void* data) {
 }
 
 #define CORE_TO_STRING(type, cast, format)                                     \
-    check_return bool Core::toString(type t, char* buffer, int size) {         \
+    check_return Core::Error Core::toString(type t, char* buffer, int size) {  \
         if(size < 0) {                                                         \
-            return CORE_ERROR(Error::NEGATIVE_ARGUMENT);                       \
+            return Error::NEGATIVE_ARGUMENT;                                   \
         }                                                                      \
-        return CORE_ERROR(Error::CAPACITY_REACHED,                             \
-                          snprintf(buffer, static_cast<unsigned int>(size),    \
-                                   format, static_cast<cast>(t)) >= size);     \
+        return snprintf(buffer, static_cast<unsigned int>(size), format,       \
+                        static_cast<cast>(t)) >= size                          \
+                   ? Error::CAPACITY_REACHED                                   \
+                   : Error::NONE;                                              \
     }
 
 CORE_TO_STRING(signed short, signed short, "%hd")
@@ -113,8 +102,8 @@ CORE_TO_STRING(float, double, "%.2f")
 CORE_TO_STRING(double, double, "%.2lf")
 CORE_TO_STRING(long double, long double, "%.2Lf")
 
-bool Core::putChar(int c) {
-    return CORE_ERROR(Error::BLOCKED_STDOUT, putchar(c) == EOF);
+Core::Error Core::putChar(int c) {
+    return putchar(c) == EOF ? Error::BLOCKED_STDOUT : Error::NONE;
 }
 
 void Core::memorySet(void* p, int c, int n) {
@@ -135,14 +124,18 @@ bool Core::memoryCompare(const void* a, const void* b, int n) {
     return n <= 0 ? true : memcmp(a, b, static_cast<unsigned int>(n)) == 0;
 }
 
-void* Core::reallocate(void* p, int n) {
+Core::Error Core::reallocate(char*& p, int n) {
     if(n <= 0) {
         free(p);
-        return nullptr;
+        p = nullptr;
+        return Error::NONE;
+    }
+    char* newP = static_cast<char*>(realloc(p, static_cast<unsigned int>(n)));
+    if(newP == nullptr) {
+        return Error::OUT_OF_MEMORY;
     }
-    void* newP = realloc(p, static_cast<unsigned int>(n));
-    CORE_ERROR(Error::OUT_OF_MEMORY, newP == nullptr);
-    return newP;
+    p = newP;
+    return Error::NONE;
 }
 
 void Core::free(void* p) {

+ 29 - 34
utils/Utility.h

@@ -7,27 +7,34 @@
 
 namespace Core {
     enum class Error {
-        NONE,
+        NONE = 0,
         NEGATIVE_ARGUMENT,
         CAPACITY_REACHED,
         BLOCKED_STDOUT,
         OUT_OF_MEMORY,
         INVALID_CHAR,
         NOT_FOUND,
+        INVALID_STATE,
         INVALID_INDEX,
-        INVALID_REMOVE_INDEX,
         TIME_NOT_AVAILABLE,
         SLEEP_INTERRUPTED,
         THREAD_ERROR,
-        INVALID_ID
+        INVALID_ID,
+        EXISTING_KEY
     };
     const char* getErrorName(Error e);
 
-    using ErrorHandler = void (*)(const char*, int, Error, void*);
-    bool handleError(const char* file, int line, Error e, bool check = true);
-    void setErrorHandler(ErrorHandler eh, void* data);
-#define CORE_ERROR(error, ...)                                                 \
-    Core::handleError(__FILE__, __LINE__, error __VA_OPT__(, ) __VA_ARGS__)
+    inline bool checkError(Error& storage, Error e) {
+        return (storage = e) != Error::NONE;
+    }
+
+#define CORE_RETURN_ERROR(checked)                                             \
+    {                                                                          \
+        Core::Error error = Core::Error::NONE;                                 \
+        if(checkError(error, checked)) {                                       \
+            return error;                                                      \
+        }                                                                      \
+    }
 
     namespace Internal {
         template<typename T>
@@ -146,36 +153,24 @@ namespace Core {
 #define CORE_EXIT(exitValue)                                                   \
     Core::exitWithHandler(__FILE__, __LINE__, exitValue)
 
-    // returns true on error and calls the error callback
-    check_return bool toString(signed short s, char* buffer, int size);
-    // returns true on error and calls the error callback
-    check_return bool toString(unsigned short s, char* buffer, int size);
-    // returns true on error and calls the error callback
-    check_return bool toString(signed int i, char* buffer, int size);
-    // returns true on error and calls the error callback
-    check_return bool toString(unsigned int i, char* buffer, int size);
-    // returns true on error and calls the error callback
-    check_return bool toString(signed long l, char* buffer, int size);
-    // returns true on error and calls the error callback
-    check_return bool toString(unsigned long l, char* buffer, int size);
-    // returns true on error and calls the error callback
-    check_return bool toString(signed long long ll, char* buffer, int size);
-    // returns true on error and calls the error callback
-    check_return bool toString(unsigned long long ll, char* buffer, int size);
-    // returns true on error and calls the error callback
-    check_return bool toString(float f, char* buffer, int size);
-    // returns true on error and calls the error callback
-    check_return bool toString(double d, char* buffer, int size);
-    // returns true on error and calls the error callback
-    check_return bool toString(long double ld, char* buffer, int size);
-
-    // returns true on error and calls the error callback
-    check_return bool putChar(int c);
+    check_return Error toString(signed short s, char* buffer, int size);
+    check_return Error toString(unsigned short s, char* buffer, int size);
+    check_return Error toString(signed int i, char* buffer, int size);
+    check_return Error toString(unsigned int i, char* buffer, int size);
+    check_return Error toString(signed long l, char* buffer, int size);
+    check_return Error toString(unsigned long l, char* buffer, int size);
+    check_return Error toString(signed long long ll, char* buffer, int size);
+    check_return Error toString(unsigned long long ll, char* buffer, int size);
+    check_return Error toString(float f, char* buffer, int size);
+    check_return Error toString(double d, char* buffer, int size);
+    check_return Error toString(long double ld, char* buffer, int size);
+
+    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);
-    void* reallocate(void* p, int n);
+    check_return Error reallocate(char*& p, int n);
     void free(void* p);
 
     const char* getFileName(const char* path);