Преглед на файлове

Improved exception handling

Kajetan Johannes Hammerle преди 4 дни
родител
ревизия
07a18afa8b
променени са 61 файла, в които са добавени 1003 реда и са изтрити 627 реда
  1. 4 4
      modules/AlignedData.cppm
  2. 9 8
      modules/Array.cppm
  3. 27 25
      modules/ArrayList.cppm
  4. 2 2
      modules/Assert.cppm
  5. 13 13
      modules/BitArray.cppm
  6. 9 9
      modules/Box.cppm
  7. 9 9
      modules/Buffer.cppm
  8. 6 6
      modules/Clock.cppm
  9. 5 5
      modules/Color.cppm
  10. 18 18
      modules/Components.cppm
  11. 1 1
      modules/File.cppm
  12. 5 5
      modules/Frustum.cppm
  13. 47 38
      modules/HashMap.cppm
  14. 9 9
      modules/HashedString.cppm
  15. 32 30
      modules/List.cppm
  16. 12 10
      modules/Logger.cppm
  17. 11 10
      modules/Math.cppm
  18. 21 21
      modules/Matrix.cppm
  19. 10 4
      modules/Meta.cppm
  20. 4 4
      modules/Plane.cppm
  21. 7 7
      modules/Quaternion.cppm
  22. 18 20
      modules/Queue.cppm
  23. 8 8
      modules/Random.cppm
  24. 3 3
      modules/ReadLine.cppm
  25. 2 2
      modules/Std.cppm
  26. 17 17
      modules/Terminal.cppm
  27. 0 2
      modules/TerminalConstants.cppm
  28. 11 10
      modules/Test.cppm
  29. 7 7
      modules/Thread.cppm
  30. 20 18
      modules/ToString.cppm
  31. 4 4
      modules/Unicode.cppm
  32. 7 7
      modules/UniquePointer.cppm
  33. 36 26
      modules/Utility.cppm
  34. 33 33
      modules/Vector.cppm
  35. 9 9
      modules/View.cppm
  36. 17 17
      src/BitArray.cpp
  37. 10 9
      src/Box.cpp
  38. 8 8
      src/Buffer.cpp
  39. 7 7
      src/Clock.cpp
  40. 3 7
      src/ErrorSimulator.cppm
  41. 3 2
      src/File.cpp
  42. 5 5
      src/Frustum.cpp
  43. 3 3
      src/Logger.cpp
  44. 21 21
      src/Matrix.cpp
  45. 4 4
      src/Plane.cpp
  46. 9 7
      src/Quaternion.cpp
  47. 9 9
      src/Random.cpp
  48. 19 19
      src/ReadLine.cpp
  49. 21 21
      src/Terminal.cpp
  50. 9 7
      src/Test.cpp
  51. 26 16
      src/Thread.cpp
  52. 17 16
      src/ToString.cpp
  53. 4 4
      src/Unicode.cpp
  54. 22 21
      src/Utility.cpp
  55. 2 2
      src/Vector.cpp
  56. 9 9
      src/View.cpp
  57. 3 2
      test/modules/ArrayListTests.cpp
  58. 1 1
      test/modules/HashMapTests.cpp
  59. 1 1
      test/modules/ListTests.cpp
  60. 5 5
      test/modules/QueueTests.cpp
  61. 329 0
      wusi

+ 4 - 4
modules/AlignedData.cppm

@@ -9,20 +9,20 @@ export namespace Core {
 
     public:
         template<typename T>
-        constexpr T* as() {
+        constexpr T* as() noexcept {
             return reinterpret_cast<T*>(this);
         }
 
         template<typename T>
-        constexpr const T* as() const {
+        constexpr const T* as() const noexcept {
             return reinterpret_cast<T*>(this);
         }
 
-        static consteval size_t getSize() {
+        static consteval size_t getSize() noexcept {
             return SIZE;
         }
 
-        static consteval size_t getAlignment() {
+        static consteval size_t getAlignment() noexcept {
             return ALIGNMENT;
         }
     };

+ 9 - 8
modules/Array.cppm

@@ -7,37 +7,38 @@ namespace Core {
     struct Array final {
         T data[N] = {};
 
-        constexpr void fill(const T& t) {
+        constexpr void fill(const T& t) noexcept {
+            static_assert(noexcept(data[0] = t), "copy is unsafe");
             for(size_t i = 0; i < N; i++) {
                 data[i] = t;
             }
         }
 
-        constexpr T& operator[](size_t index) {
+        constexpr T& operator[](size_t index) noexcept {
             return data[index];
         }
 
-        constexpr const T& operator[](size_t index) const {
+        constexpr const T& operator[](size_t index) const noexcept {
             return data[index];
         }
 
-        constexpr T* begin() {
+        constexpr T* begin() noexcept {
             return data;
         }
 
-        constexpr T* end() {
+        constexpr T* end() noexcept {
             return data + N;
         }
 
-        constexpr const T* begin() const {
+        constexpr const T* begin() const noexcept {
             return data;
         }
 
-        constexpr const T* end() const {
+        constexpr const T* end() const noexcept {
             return data + N;
         }
 
-        static constexpr size_t getLength() {
+        static constexpr size_t getLength() noexcept {
             return N;
         }
     };

+ 27 - 25
modules/ArrayList.cppm

@@ -8,16 +8,16 @@ import Core.Types;
 import Core.Assert;
 
 export namespace Core {
-    template<typename T, size_t N>
+    template<Moveable T, size_t N>
     class ArrayList final {
         AlignedType<T> data[N];
         size_t length;
 
     public:
-        ArrayList() : length(0) {
+        ArrayList() noexcept : length(0) {
         }
 
-        ArrayList(const ArrayList& other) : ArrayList() {
+        ArrayList(const ArrayList& other) noexcept : ArrayList() {
             copy(other);
         }
 
@@ -26,11 +26,11 @@ export namespace Core {
             other.clear();
         }
 
-        ~ArrayList() {
+        ~ArrayList() noexcept {
             clear();
         }
 
-        ArrayList& operator=(const ArrayList& other) {
+        ArrayList& operator=(const ArrayList& other) noexcept {
             if(&other != this) {
                 clear();
                 copy(other);
@@ -47,38 +47,40 @@ export namespace Core {
             return *this;
         }
 
-        T* begin() {
+        T* begin() noexcept {
             return reinterpret_cast<T*>(data);
         }
 
-        T* end() {
+        T* end() noexcept {
             return begin() + length;
         }
 
-        const T* begin() const {
+        const T* begin() const noexcept {
             return reinterpret_cast<const T*>(data);
         }
 
-        const T* end() const {
+        const T* end() const noexcept {
             return begin() + length;
         }
 
         template<typename... Args>
-        T* put(Args&&... args) {
+        T* put(Args&&... args) noexcept {
             if(length < N) {
+                static_assert(
+                    noexcept(new(begin()) T(Core::forward<Args>(args)...)));
                 return new(begin() + length++) T(Core::forward<Args>(args)...);
             }
             return nullptr;
         }
 
         template<typename... Args>
-        ArrayList& add(Args&&... args) {
+        ArrayList& add(Args&&... args) noexcept {
             put(Core::forward<Args>(args)...);
             return *this;
         }
 
         template<typename... Args>
-        T* putAt(size_t t, Args&&... args) {
+        T* putAt(size_t t, Args&&... args) noexcept {
             if(length >= N) {
                 return nullptr;
             } else if(t >= length) {
@@ -93,45 +95,45 @@ export namespace Core {
         }
 
         template<typename... Args>
-        ArrayList& addAt(size_t index, Args&&... args) {
+        ArrayList& addAt(size_t index, Args&&... args) noexcept {
             putAt(index, Core::forward<Args>(args)...);
             return *this;
         }
 
-        T& operator[](size_t index) {
+        T& operator[](size_t index) noexcept {
             return begin()[index];
         }
 
-        const T& operator[](size_t index) const {
+        const T& operator[](size_t index) const noexcept {
             return begin()[index];
         }
 
-        T& getLast() {
+        T& getLast() noexcept {
             assert(length > 0);
             return begin()[length - 1];
         }
 
-        const T& getLast() const {
+        const T& getLast() const noexcept {
             assert(length > 0);
             return begin()[length - 1];
         }
 
-        size_t getLength() const {
+        size_t getLength() const noexcept {
             return length;
         }
 
-        consteval size_t getCapacity() const {
+        consteval size_t getCapacity() const noexcept {
             return N;
         }
 
-        void clear() {
+        void clear() noexcept {
             for(size_t i = 0; i < length; i++) {
                 begin()[i].~T();
             }
             length = 0;
         }
 
-        void removeBySwap(size_t index) {
+        void removeBySwap(size_t index) noexcept {
             assert(index < length);
             length--;
             if(index != length) {
@@ -140,7 +142,7 @@ export namespace Core {
             begin()[length].~T();
         }
 
-        void remove(size_t index) {
+        void remove(size_t index) noexcept {
             assert(index < length);
             length--;
             T* currentT = begin() + index;
@@ -153,18 +155,18 @@ export namespace Core {
             endT->~T();
         }
 
-        void removeLast() {
+        void removeLast() noexcept {
             removeBySwap(length - 1);
         }
 
     private:
-        void copy(const ArrayList& other) {
+        void copy(const ArrayList& other) noexcept {
             for(size_t i = 0; i < other.length; i++) {
                 add(other[i]);
             }
         }
 
-        void move(ArrayList&& other) {
+        void move(ArrayList&& other) noexcept {
             for(size_t i = 0; i < other.length; i++) {
                 add(Core::move(other[i]));
             }

+ 2 - 2
modules/Assert.cppm

@@ -10,8 +10,8 @@ export namespace Core {
     }
 #else
     void inline assert(
-        bool b,
-        const std::source_location& l = std::source_location::current()) {
+        bool b, const std::source_location& l =
+                    std::source_location::current()) noexcept {
         if(!b) {
             Core::logError(
                 FormatLocation("Assert in function {}", l),

+ 13 - 13
modules/BitArray.cppm

@@ -11,22 +11,22 @@ export namespace Core {
         u64* data;
 
     public:
-        BitArray();
-        BitArray(const BitArray& other);
+        BitArray() noexcept;
+        BitArray(const BitArray& other) noexcept;
         BitArray(BitArray&& other) noexcept;
-        ~BitArray();
+        ~BitArray() noexcept;
         BitArray& operator=(BitArray other) noexcept;
 
-        BitArray& set(size_t index, u64 value);
-        u64 get(size_t index) const;
-        size_t getLength() const;
-        size_t getBits() const;
-        size_t getInternalByteSize() const;
-        i64 select(size_t index) const;
-        void resize(size_t newLength, size_t newBits);
-        void fill(u64 value);
-        size_t toString(StringBase& b) const;
-        void swap(BitArray& other);
+        BitArray& set(size_t index, u64 value) noexcept;
+        u64 get(size_t index) const noexcept;
+        size_t getLength() const noexcept;
+        size_t getBits() const noexcept;
+        size_t getInternalByteSize() const noexcept;
+        i64 select(size_t index) const noexcept;
+        void resize(size_t newLength, size_t newBits) noexcept;
+        void fill(u64 value) noexcept;
+        size_t toString(StringBase& b) const noexcept;
+        void swap(BitArray& other) noexcept;
     };
 
     static_assert(sizeof(BitArray) == 16, "invalid bit array size");

+ 9 - 9
modules/Box.cppm

@@ -7,19 +7,19 @@ export namespace Core {
         Vector3 min;
         Vector3 max;
 
-        Box(const Vector3& min, const Vector3& max);
+        Box(const Vector3& min, const Vector3& max) noexcept;
 
     public:
-        Box(const Vector3& size);
+        Box(const Vector3& size) noexcept;
 
-        Box offset(const Vector3& offset) const;
-        bool collidesWith(const Box& other) const;
-        Box expand(const Vector3& offset) const;
-        Box grow(const Vector3& growth) const;
+        Box offset(const Vector3& offset) const noexcept;
+        bool collidesWith(const Box& other) const noexcept;
+        Box expand(const Vector3& offset) const noexcept;
+        Box grow(const Vector3& growth) const noexcept;
 
-        const Vector3& getMin() const;
-        const Vector3& getMax() const;
+        const Vector3& getMin() const noexcept;
+        const Vector3& getMax() const noexcept;
 
-        size_t toString(StringBase& b) const;
+        size_t toString(StringBase& b) const noexcept;
     };
 }

+ 9 - 9
modules/Buffer.cppm

@@ -9,23 +9,23 @@ export namespace Core {
         char* buffer;
 
     public:
-        Buffer();
-        Buffer(const Buffer& other);
+        Buffer() noexcept;
+        Buffer(const Buffer& other) noexcept;
         Buffer(Buffer&& other) noexcept;
-        ~Buffer();
-        Buffer& operator=(const Buffer& other);
+        ~Buffer() noexcept;
+        Buffer& operator=(const Buffer& other) noexcept;
         Buffer& operator=(Buffer&& other) noexcept;
 
-        Buffer& add(const void* data, size_t size);
+        Buffer& add(const void* data, size_t size) noexcept;
 
         template<typename T>
-        Buffer& add(const T& t) {
+        Buffer& add(const T& t) noexcept {
             return add(&t, sizeof(T));
         }
 
-        size_t getLength() const;
-        const char* getData() const;
-        void clear();
+        size_t getLength() const noexcept;
+        const char* getData() const noexcept;
+        void clear() noexcept;
         void swap(Buffer& other) noexcept;
     };
 }

+ 6 - 6
modules/Clock.cppm

@@ -10,14 +10,14 @@ export namespace Core {
         Array<i64, 1 << 7> time;
 
     public:
-        Clock();
+        Clock() noexcept;
 
         // the first invocation will always return 0 nanos
-        i64 update();
-        float getUpdatesPerSecond() const;
+        i64 update() noexcept;
+        float getUpdatesPerSecond() const noexcept;
 
-        static bool sleepNanos(i64 nanos);
-        static bool sleepMillis(i64 millis);
-        static i64 getNanos();
+        static bool sleepNanos(i64 nanos) noexcept;
+        static bool sleepMillis(i64 millis) noexcept;
+        static i64 getNanos() noexcept;
     };
 }

+ 5 - 5
modules/Color.cppm

@@ -11,10 +11,10 @@ export namespace Core {
         ColorChannel data[N] = {};
 
     public:
-        Color() = default;
+        Color() noexcept = default;
 
         template<typename OT, typename... Args>
-        Color(OT a, Args&&... args) :
+        Color(OT a, Args&&... args) noexcept :
             data(
                 static_cast<ColorChannel>(a),
                 static_cast<ColorChannel>(args)...) {
@@ -23,15 +23,15 @@ export namespace Core {
                 "color channel parameters do not match its size");
         }
 
-        float asFloat(size_t index) const {
+        float asFloat(size_t index) const noexcept {
             return data[index] * (1.0f / 255.0f);
         }
 
-        ColorChannel& operator[](size_t index) {
+        ColorChannel& operator[](size_t index) noexcept {
             return data[index];
         }
 
-        const ColorChannel& operator[](size_t index) const {
+        const ColorChannel& operator[](size_t index) const noexcept {
             return data[index];
         }
     };

+ 18 - 18
modules/Components.cppm

@@ -10,7 +10,7 @@ import Core.Meta;
 export namespace Core {
     using Entity = size_t;
 
-    template<typename T>
+    template<Moveable T>
     class Components final {
         HashMap<Entity, size_t> entityToIndex{};
         List<Entity> indexToEntity{};
@@ -33,21 +33,21 @@ export namespace Core {
             ComponentIterator componentIterator{};
 
         public:
-            Iterator(EntityIterator e, ComponentIterator c) :
+            Iterator(EntityIterator e, ComponentIterator c) noexcept :
                 entityIterator(e), componentIterator(c) {
             }
 
-            Iterator& operator++() {
+            Iterator& operator++() noexcept {
                 ++entityIterator;
                 ++componentIterator;
                 return *this;
             }
 
-            bool operator!=(const Iterator& other) const {
+            bool operator!=(const Iterator& other) const noexcept {
                 return entityIterator != other.entityIterator;
             }
 
-            Node<Component> operator*() const {
+            Node<Component> operator*() const noexcept {
                 return {*entityIterator, *componentIterator};
             }
         };
@@ -56,18 +56,18 @@ export namespace Core {
         struct IteratorAdapter final {
             C& c;
 
-            Iterator<C> begin() {
+            Iterator<C> begin() noexcept {
                 return Iterator<C>(
                     c.indexToEntity.begin(), c.components.begin());
             }
 
-            Iterator<C> end() {
+            Iterator<C> end() noexcept {
                 return Iterator<C>(c.indexToEntity.end(), c.components.end());
             }
         };
 
         template<typename... Args>
-        bool put(T*& t, Entity e, Args&&... args) {
+        bool put(T*& t, Entity e, Args&&... args) noexcept {
             size_t index = components.getLength();
             size_t* indexP = nullptr;
             if(!entityToIndex.tryEmplace(indexP, e, index)) {
@@ -79,12 +79,12 @@ export namespace Core {
         }
 
         template<typename... Args>
-        bool add(Entity e, Args&&... args) {
+        bool add(Entity e, Args&&... args) noexcept {
             T* t = nullptr;
             return put(t, e, Core::forward<Args>(args)...);
         }
 
-        bool remove(Entity e) {
+        bool remove(Entity e) noexcept {
             size_t* indexP = entityToIndex.search(e);
             if(indexP == nullptr) {
                 return false;
@@ -103,12 +103,12 @@ export namespace Core {
             return true;
         }
 
-        T* search(Entity e) {
+        T* search(Entity e) noexcept {
             return const_cast<T*>(
                 static_cast<const Components*>(this)->search(e));
         }
 
-        const T* search(Entity e) const {
+        const T* search(Entity e) const noexcept {
             const size_t* index = entityToIndex.search(e);
             if(index == nullptr) {
                 return nullptr;
@@ -116,27 +116,27 @@ export namespace Core {
             return &(components[*index]);
         }
 
-        auto begin() {
+        auto begin() noexcept {
             return components.begin();
         }
 
-        auto begin() const {
+        auto begin() const noexcept {
             return components.begin();
         }
 
-        auto end() {
+        auto end() noexcept {
             return components.end();
         }
 
-        auto end() const {
+        auto end() const noexcept {
             return components.end();
         }
 
-        IteratorAdapter<Components> entities() {
+        IteratorAdapter<Components> entities() noexcept {
             return {*this};
         }
 
-        IteratorAdapter<const Components> entities() const {
+        IteratorAdapter<const Components> entities() const noexcept {
             return {*this};
         }
     };

+ 1 - 1
modules/File.cppm

@@ -3,5 +3,5 @@ export module Core.File;
 export import Core.List;
 
 export namespace Core {
-    bool readFile(List<char>& content, const char* path);
+    bool readFile(List<char>& content, const char* path) noexcept;
 }

+ 5 - 5
modules/Frustum.cppm

@@ -14,13 +14,13 @@ export namespace Core {
         float far;
 
     public:
-        Frustum(float fieldOfView, float nearClip, float farClip);
-        const Matrix& updateProjection(const IntVector2& size);
+        Frustum(float fieldOfView, float nearClip, float farClip) noexcept;
+        const Matrix& updateProjection(const IntVector2& size) noexcept;
         void updatePlanes(
             const Vector3& pos, const Vector3& right, const Vector3& up,
-            const Vector3& front, const IntVector2& size);
+            const Vector3& front, const IntVector2& size) noexcept;
 
-        bool isInside(const Vector3& pos) const;
-        bool isInside(const Vector3& pos, float radius) const;
+        bool isInside(const Vector3& pos) const noexcept;
+        bool isInside(const Vector3& pos, float radius) const noexcept;
     };
 }

+ 47 - 38
modules/HashMap.cppm

@@ -26,27 +26,27 @@ export namespace Core {
         return static_cast<size_t>(key);
     }
 
-    template<typename K, typename V>
+    template<Moveable K, Moveable V>
     struct HashMap final {
         template<typename Value>
         class Node final {
             friend HashMap;
-            friend List<Node>;
             K key;
 
         public:
             Value& value;
 
-            const K& getKey() const {
+            const K& getKey() const noexcept {
                 return key;
             }
 
-            size_t toString(StringBase& b) const {
+            size_t toString(StringBase& b) const noexcept {
                 return b.addFormat("{} = {}", key, value);
             }
 
         private:
-            Node(const K& key_, Value& value_) : key(key_), value(value_) {
+            Node(const K& key_, Value& value_) noexcept :
+                key(key_), value(value_) {
             }
         };
 
@@ -61,30 +61,31 @@ export namespace Core {
 
         public:
             Iterator(
-                const K* key, const K* endKey_, Value* value, bool invalidSet) :
+                const K* key, const K* endKey_, Value* value,
+                bool invalidSet) noexcept :
                 currentKey(key), endKey(endKey_), currentValue(value) {
                 if(!invalidSet) {
                     skip();
                 }
             }
 
-            Iterator& operator++() {
+            Iterator& operator++() noexcept {
                 ++currentKey;
                 ++currentValue;
                 skip();
                 return *this;
             }
 
-            bool operator!=(const Iterator& other) const {
+            bool operator!=(const Iterator& other) const noexcept {
                 return currentKey != other.currentKey;
             }
 
-            R operator*() const {
+            R operator*() const noexcept {
                 return A(*currentKey, *currentValue);
             }
 
         private:
-            void skip() {
+            void skip() noexcept {
                 while(currentKey != endKey && *currentKey == INVALID) {
                     ++currentKey;
                     ++currentValue;
@@ -93,16 +94,16 @@ export namespace Core {
         };
 
         template<typename Value>
-        static Node<Value> access(const K& key, Value& value) {
+        static Node<Value> access(const K& key, Value& value) noexcept {
             return Node<Value>(key, value);
         }
 
         template<typename Value>
-        static Value& accessValue(const K&, Value& value) {
+        static Value& accessValue(const K&, Value& value) noexcept {
             return value;
         }
 
-        static const K& accessKey(const K& key, const V&) {
+        static const K& accessKey(const K& key, const V&) noexcept {
             return key;
         }
 
@@ -122,13 +123,13 @@ export namespace Core {
         struct IteratorAdapter final {
             M& map;
 
-            I begin() const {
+            I begin() const noexcept {
                 return {
                     map.keys.begin(), map.keys.end(), map.values,
                     map.invalidSet};
             }
 
-            I end() const {
+            I end() const noexcept {
                 return {
                     map.keys.end(), map.keys.end(), nullptr, map.invalidSet};
             }
@@ -149,9 +150,9 @@ export namespace Core {
         bool invalidSet = false;
 
     public:
-        HashMap() = default;
+        HashMap() noexcept = default;
 
-        HashMap(const HashMap& other) {
+        HashMap(const HashMap& other) noexcept {
             for(const auto& e : other) {
                 add(e.getKey(), e.value);
             }
@@ -161,7 +162,7 @@ export namespace Core {
             swap(other);
         }
 
-        ~HashMap() {
+        ~HashMap() noexcept {
             size_t length = keys.getLength();
             if(length > 0) {
                 for(size_t i = 1; i < length; i++) {
@@ -182,7 +183,7 @@ export namespace Core {
             return *this;
         }
 
-        void rehash(size_t minCapacity) {
+        void rehash(size_t minCapacity) noexcept {
             if(minCapacity <= keys.getLength()) {
                 return;
             }
@@ -207,7 +208,7 @@ export namespace Core {
         }
 
         template<typename... Args>
-        bool tryEmplace(V*& v, const K& key, Args&&... args) {
+        bool tryEmplace(V*& v, const K& key, Args&&... args) noexcept {
             size_t index = 0;
             if(key == INVALID) {
                 if(invalidSet) {
@@ -222,6 +223,8 @@ export namespace Core {
                 }
             }
             keys[index] = key;
+            static_assert(
+                noexcept(new(values + index) V(Core::forward<Args>(args)...)));
             v = new(values + index) V(Core::forward<Args>(args)...);
             entries++;
             markSlot(key);
@@ -229,10 +232,12 @@ export namespace Core {
         }
 
         template<typename VA>
-        V& put(const K& key, VA&& value) {
+        V& put(const K& key, VA&& value) noexcept {
             size_t index = 0;
             if(key == INVALID) {
                 if(invalidSet) {
+                    static_assert(
+                        noexcept(values[0] = Core::forward<VA>(value)));
                     return (values[0] = Core::forward<VA>(value));
                 }
                 rehash(1);
@@ -240,9 +245,13 @@ export namespace Core {
             } else {
                 index = searchSlot(key);
                 if(keys[index] == key) {
+                    static_assert(
+                        noexcept(values[index] = Core::forward<VA>(value)));
                     return (values[index] = Core::forward<VA>(value));
                 }
             }
+            static_assert(
+                noexcept(new(values + index) V(Core::forward<VA>(value))));
             new(values + index) V(Core::forward<VA>(value));
             entries++;
             keys[index] = key;
@@ -251,12 +260,12 @@ export namespace Core {
         }
 
         template<typename VA>
-        HashMap& add(const K& key, VA&& value) {
+        HashMap& add(const K& key, VA&& value) noexcept {
             put(key, Core::forward<VA>(value));
             return *this;
         }
 
-        bool remove(const K& key) {
+        bool remove(const K& key) noexcept {
             size_t index = 0;
             if(key == INVALID) {
                 if(!invalidSet) {
@@ -276,49 +285,49 @@ export namespace Core {
             return true;
         }
 
-        const V* search(const K& key) const {
+        const V* search(const K& key) const noexcept {
             return searchValue<const V>(key);
         }
 
-        V* search(const K& key) {
+        V* search(const K& key) noexcept {
             return searchValue<V>(key);
         }
 
-        bool contains(const K& key) const {
+        bool contains(const K& key) const noexcept {
             return search(key) != nullptr;
         }
 
-        HashMap& clear() {
+        HashMap& clear() noexcept {
             HashMap<K, V> map;
             swap(map);
             return *this;
         }
 
-        ConstKeyIteratorAdapter getKeys() const {
+        ConstKeyIteratorAdapter getKeys() const noexcept {
             return {*this};
         }
 
-        ValueIteratorAdapter getValues() {
+        ValueIteratorAdapter getValues() noexcept {
             return {*this};
         }
 
-        ConstValueIteratorAdapter getValues() const {
+        ConstValueIteratorAdapter getValues() const noexcept {
             return {*this};
         }
 
-        EntryIterator begin() {
+        EntryIterator begin() noexcept {
             return {keys.begin(), keys.end(), values, invalidSet};
         }
 
-        EntryIterator end() {
+        EntryIterator end() noexcept {
             return {keys.end(), keys.end(), nullptr, invalidSet};
         }
 
-        ConstEntryIterator begin() const {
+        ConstEntryIterator begin() const noexcept {
             return {keys.begin(), keys.end(), values, invalidSet};
         }
 
-        ConstEntryIterator end() const {
+        ConstEntryIterator end() const noexcept {
             return {keys.end(), keys.end(), nullptr, invalidSet};
         }
 
@@ -343,7 +352,7 @@ export namespace Core {
             } while(false)
         // clang-format on
 
-        size_t searchSlot(const K& key) {
+        size_t searchSlot(const K& key) noexcept {
             rehash(1);
             while(true) {
                 // rehash on bad clustering
@@ -357,7 +366,7 @@ export namespace Core {
             }
         }
 
-        void markSlot(const K& key) {
+        void markSlot(const K& key) noexcept {
             FOR_EACH_HASH_START();
             if(keys[hash] == key) {
                 return;
@@ -366,7 +375,7 @@ export namespace Core {
             FOR_EACH_HASH_STOP();
         }
 
-        void demarkSlot(const K& key) {
+        void demarkSlot(const K& key) noexcept {
             FOR_EACH_HASH_START();
             if(keys[hash] == key) {
                 return;
@@ -376,7 +385,7 @@ export namespace Core {
         }
 
         template<typename Value>
-        Value* searchValue(const K& key) const {
+        Value* searchValue(const K& key) const noexcept {
             if(keys.getLength() != 0) {
                 if(key == INVALID) {
                     return invalidSet ? values : nullptr;

+ 9 - 9
modules/HashedString.cppm

@@ -11,7 +11,7 @@ export namespace Core {
         size_t hash = 0;
     };
 
-    constexpr StringHash hashString(const char* s) {
+    constexpr StringHash hashString(const char* s) noexcept {
         StringHash h;
         while(*s != '\0') {
             h.length++;
@@ -26,36 +26,36 @@ export namespace Core {
         char data[N];
 
     public:
-        HashedString() : hash(), data{} {
+        HashedString() noexcept : hash(), data{} {
         }
 
-        HashedString(const char* s) : hash(hashString(s)) {
+        HashedString(const char* s) noexcept : hash(hashString(s)) {
             Core::StringBase(data, N).add(s);
         }
 
-        bool operator==(const HashedString& other) const {
+        bool operator==(const HashedString& other) const noexcept {
             return hash.length == other.hash.length &&
                    hash.hash == other.hash.hash &&
                    strcmp(data, other.data) == 0;
         }
 
-        bool operator!=(const HashedString& other) const {
+        bool operator!=(const HashedString& other) const noexcept {
             return !(*this == other);
         }
 
-        size_t getLength() const {
+        size_t getLength() const noexcept {
             return hash.length;
         }
 
-        constexpr size_t getCapacity() const {
+        constexpr size_t getCapacity() const noexcept {
             return N - 1;
         }
 
-        size_t hashCode() const {
+        size_t hashCode() const noexcept {
             return hash.hash;
         }
 
-        operator const char*() const {
+        operator const char*() const noexcept {
             return data;
         }
     };

+ 32 - 30
modules/List.cppm

@@ -10,17 +10,17 @@ import Core.ToString;
 import Core.Assert;
 
 export namespace Core {
-    template<typename T>
+    template<Moveable T>
     class List final {
         size_t length;
         size_t capacity;
         T* data;
 
     public:
-        List() : length(0), capacity(0), data(nullptr) {
+        List() noexcept : length(0), capacity(0), data(nullptr) {
         }
 
-        List(const List& other) :
+        List(const List& other) noexcept :
             length(0), capacity(other.capacity),
             data(allocate(other.capacity)) {
             for(const T& t : other) {
@@ -32,7 +32,7 @@ export namespace Core {
             swap(other);
         }
 
-        ~List() {
+        ~List() noexcept {
             clear();
             deleteWithSourceN<AlignedType<T>>(
                 reinterpret_cast<AlignedType<T>*>(data));
@@ -43,35 +43,35 @@ export namespace Core {
             return *this;
         }
 
-        T* begin() {
+        T* begin() noexcept {
             return data;
         }
 
-        T* end() {
+        T* end() noexcept {
             return data + length;
         }
 
-        const T* begin() const {
+        const T* begin() const noexcept {
             return data;
         }
 
-        const T* end() const {
+        const T* end() const noexcept {
             return data + length;
         }
 
-        void reserve(size_t n) {
+        void reserve(size_t n) noexcept {
             if(n > capacity) {
                 setSize(n);
             }
         }
 
-        void shrink() {
+        void shrink() noexcept {
             if(length != capacity) {
                 setSize(length);
             }
         }
 
-        void resize(size_t n, const T& t) {
+        void resize(size_t n, const T& t) noexcept {
             if(length < n) {
                 reserve(n);
                 for(size_t i = n - length; i != 0; i--) {
@@ -85,7 +85,7 @@ export namespace Core {
             }
         }
 
-        void resize(size_t n) {
+        void resize(size_t n) noexcept {
             if(length < n) {
                 reserve(n);
                 for(size_t i = n - length; i != 0; i--) {
@@ -100,19 +100,19 @@ export namespace Core {
         }
 
         template<typename... Args>
-        T& put(Args&&... args) {
+        T& put(Args&&... args) noexcept {
             ensureCapacity();
             return *unsafeAdd(Core::forward<Args>(args)...);
         }
 
         template<typename... Args>
-        List& add(Args&&... args) {
+        List& add(Args&&... args) noexcept {
             put(Core::forward<Args>(args)...);
             return *this;
         }
 
         template<typename... Args>
-        T& putAt(size_t t, Args&&... args) {
+        T& putAt(size_t t, Args&&... args) noexcept {
             if(t >= length) {
                 return put(Core::forward<Args>(args)...);
             }
@@ -127,47 +127,47 @@ export namespace Core {
         }
 
         template<typename... Args>
-        List& addAt(size_t index, Args&&... args) {
+        List& addAt(size_t index, Args&&... args) noexcept {
             putAt(index, Core::forward<Args>(args)...);
             return *this;
         }
 
-        T& operator[](size_t index) {
+        T& operator[](size_t index) noexcept {
             assert(index < length);
             return data[index];
         }
 
-        const T& operator[](size_t index) const {
+        const T& operator[](size_t index) const noexcept {
             assert(index < length);
             return data[index];
         }
 
-        T& getLast() {
+        T& getLast() noexcept {
             assert(length > 0);
             return data[length - 1];
         }
 
-        const T& getLast() const {
+        const T& getLast() const noexcept {
             assert(length > 0);
             return data[length - 1];
         }
 
-        size_t getLength() const {
+        size_t getLength() const noexcept {
             return length;
         }
 
-        size_t getCapacity() const {
+        size_t getCapacity() const noexcept {
             return capacity;
         }
 
-        void clear() {
+        void clear() noexcept {
             for(T& t : *this) {
                 t.~T();
             }
             length = 0;
         }
 
-        void removeBySwap(size_t index) {
+        void removeBySwap(size_t index) noexcept {
             assert(index < length);
             length--;
             if(index != length) {
@@ -176,7 +176,7 @@ export namespace Core {
             data[length].~T();
         }
 
-        void remove(size_t index) {
+        void remove(size_t index) noexcept {
             assert(index < length);
             length--;
             T* currentT = begin() + index;
@@ -189,7 +189,7 @@ export namespace Core {
             endT->~T();
         }
 
-        void removeLast() {
+        void removeLast() noexcept {
             removeBySwap(length - 1);
         }
 
@@ -200,14 +200,14 @@ export namespace Core {
         }
 
     private:
-        static T* allocate(size_t n) {
+        static T* allocate(size_t n) noexcept {
             if(n <= 0) {
                 return nullptr;
             }
             return reinterpret_cast<T*>(newWithSourceN<AlignedType<T>>(n));
         }
 
-        void ensureCapacity() {
+        void ensureCapacity() noexcept {
             if(length >= capacity) {
                 reserve(capacity + Core::max(4lu, capacity / 4));
             }
@@ -215,11 +215,13 @@ export namespace Core {
 
         // does not check for capacity
         template<typename... Args>
-        T* unsafeAdd(Args&&... args) {
+        T* unsafeAdd(Args&&... args) noexcept {
+            static_assert(
+                noexcept(new(data + length++) T(Core::forward<Args>(args)...)));
             return new(data + length++) T(Core::forward<Args>(args)...);
         }
 
-        void setSize(size_t n) {
+        void setSize(size_t n) noexcept {
             List copy;
             copy.data = allocate(n);
             copy.capacity = n;

+ 12 - 10
modules/Logger.cppm

@@ -15,30 +15,32 @@ export namespace Core {
     using ReportHandler = void (*)(
         LogLevel l, const std::source_location& sl, void* data,
         const char* message);
-    void callReportHandler(LogLevel l, const char* report, SOURCE);
-    void setReportHandler(ReportHandler h, void* data);
+    void callReportHandler(LogLevel l, const char* report, SOURCE) noexcept;
+    void setReportHandler(ReportHandler h, void* data) noexcept;
 
     struct FormatLocation final {
         const char* format;
         std::source_location location;
 
-        FormatLocation(const char* f, SOURCE) : format(f), location(sl) {
+        FormatLocation(const char* f, SOURCE) noexcept :
+            format(f), location(sl) {
         }
     };
 
     template<typename... Args>
-    void report(LogLevel l, const FormatLocation& format, Args&&... args) {
+    void report(
+        LogLevel l, const FormatLocation& format, Args&&... args) noexcept {
         String<512> s;
         s.addFormat(format.format, Core::forward<Args>(args)...);
         callReportHandler(l, s, format.location);
     }
 
-    const char* getShortFileName(const char* s);
+    const char* getShortFileName(const char* s) noexcept;
 
     template<typename... Args>
     void log(
         LogLevel l, const char* prefix, const FormatLocation& format,
-        Args&&... args) {
+        Args&&... args) noexcept {
         if(logLevel < l) {
             return;
         }
@@ -52,7 +54,7 @@ export namespace Core {
     }
 
     template<typename... Args>
-    void logError(const FormatLocation& format, Args&&... args) {
+    void logError(const FormatLocation& format, Args&&... args) noexcept {
         if constexpr(LOG_LEVEL >= 1) {
             String<32> s;
             s.addFormat("{}[ERROR] ", Terminal::FG_RED);
@@ -61,7 +63,7 @@ export namespace Core {
     }
 
     template<typename... Args>
-    void logWarning(const FormatLocation& format, Args&&... args) {
+    void logWarning(const FormatLocation& format, Args&&... args) noexcept {
         if constexpr(LOG_LEVEL >= 2) {
             String<32> s;
             s.addFormat("{}[WARNING] ", Terminal::FG_BRIGHT_YELLOW);
@@ -70,7 +72,7 @@ export namespace Core {
     }
 
     template<typename... Args>
-    void logInfo(const FormatLocation& format, Args&&... args) {
+    void logInfo(const FormatLocation& format, Args&&... args) noexcept {
         if constexpr(LOG_LEVEL >= 3) {
             String<32> s;
             s.addFormat("{}[INFO] ", Terminal::BOLD);
@@ -79,7 +81,7 @@ export namespace Core {
     }
 
     template<typename... Args>
-    void logDebug(const FormatLocation& format, Args&&... args) {
+    void logDebug(const FormatLocation& format, Args&&... args) noexcept {
         if constexpr(LOG_LEVEL >= 4) {
             String<32> s;
             s.addFormat(

+ 11 - 10
modules/Math.cppm

@@ -4,16 +4,16 @@ import Core.Meta;
 
 export namespace Core {
     template<typename T>
-    T interpolate(const T& a, const T& b, float f) {
+    T interpolate(const T& a, const T& b, float f) noexcept {
         return a * (1.0f - f) + b * f;
     }
 
-    constexpr bool isPowerOf2(int i) {
+    constexpr bool isPowerOf2(int i) noexcept {
         return (i & (i - 1)) == 0;
     }
 
     template<typename T>
-    constexpr T roundUpLog2(T i) {
+    constexpr T roundUpLog2(T i) noexcept {
         if(i <= 0) {
             return 0;
         }
@@ -25,29 +25,30 @@ export namespace Core {
     }
 
     template<typename T>
-    constexpr const T& min(const T& t) {
+    constexpr const T& min(const T& t) noexcept {
         return t;
     }
 
     template<typename T, typename... Args>
-    constexpr const T& min(const T& t, Args&&... args) {
+    constexpr const T& min(const T& t, Args&&... args) noexcept {
         const T& o = min(Core::forward<Args>(args)...);
         return t < o ? t : o;
     }
 
     template<typename T>
-    constexpr const T& max(const T& t) {
+    constexpr const T& max(const T& t) noexcept {
         return t;
     }
 
     template<typename T, typename... Args>
-    constexpr const T& max(const T& t, Args&&... args) {
+    constexpr const T& max(const T& t, Args&&... args) noexcept {
         const T& o = max(Core::forward<Args>(args)...);
         return o < t ? t : o;
     }
 
     template<typename T>
-    constexpr const T& clamp(const T& t, const T& borderA, const T& borderB) {
+    constexpr const T& clamp(
+        const T& t, const T& borderA, const T& borderB) noexcept {
         const T& low = min(borderA, borderB);
         const T& high = max(borderA, borderB);
         return max(low, min(high, t));
@@ -56,12 +57,12 @@ export namespace Core {
     inline constexpr float PI = 3.14159265358979323846f;
 
     template<typename T>
-    constexpr T radianToDegree(const T& radians) {
+    constexpr T radianToDegree(const T& radians) noexcept {
         return radians * static_cast<T>(180.0f / PI);
     }
 
     template<typename T>
-    constexpr T degreeToRadian(const T& radians) {
+    constexpr T degreeToRadian(const T& radians) noexcept {
         return radians * static_cast<T>(PI / 180.0f);
     }
 }

+ 21 - 21
modules/Matrix.cppm

@@ -7,28 +7,28 @@ export namespace Core {
         Vector4 data[4];
 
     public:
-        Matrix();
-        Matrix& unit();
-        Matrix& set(size_t index, const Vector4& v);
-        Matrix transpose() const;
-        const float* getValues() const;
-        Matrix& operator*=(const Matrix& other);
-        Matrix operator*(const Matrix& other) const;
-        Vector3 operator*(const Vector3& v) const;
-        Matrix& scale(const Vector3& v);
-        Matrix& scale(float f);
-        Matrix& translate(const Vector3& v);
-        Matrix& translateX(float tx);
-        Matrix& translateY(float ty);
-        Matrix& translateZ(float tz);
-        Matrix& translateTo(const Vector3& v);
-        Matrix& rotateX(float radians);
-        Matrix& rotateY(float radians);
-        Matrix& rotateZ(float radians);
-        Matrix& rotate(const Quaternion& q);
-        size_t toString(StringBase& b) const;
+        Matrix() noexcept;
+        Matrix& unit() noexcept;
+        Matrix& set(size_t index, const Vector4& v) noexcept;
+        Matrix transpose() const noexcept;
+        const float* getValues() const noexcept;
+        Matrix& operator*=(const Matrix& other) noexcept;
+        Matrix operator*(const Matrix& other) const noexcept;
+        Vector3 operator*(const Vector3& v) const noexcept;
+        Matrix& scale(const Vector3& v) noexcept;
+        Matrix& scale(float f) noexcept;
+        Matrix& translate(const Vector3& v) noexcept;
+        Matrix& translateX(float tx) noexcept;
+        Matrix& translateY(float ty) noexcept;
+        Matrix& translateZ(float tz) noexcept;
+        Matrix& translateTo(const Vector3& v) noexcept;
+        Matrix& rotateX(float radians) noexcept;
+        Matrix& rotateY(float radians) noexcept;
+        Matrix& rotateZ(float radians) noexcept;
+        Matrix& rotate(const Quaternion& q) noexcept;
+        size_t toString(StringBase& b) const noexcept;
 
     private:
-        Matrix& rotate(float degrees, int a, int b);
+        Matrix& rotate(float degrees, int a, int b) noexcept;
     };
 }

+ 10 - 4
modules/Meta.cppm

@@ -67,21 +67,27 @@ export namespace Core {
     using If = BaseIf<C, A, B>::Type;
 
     template<typename T>
-    constexpr RemoveReference<T>&& move(T&& t) {
+    constexpr RemoveReference<T>&& move(T&& t) noexcept {
         return static_cast<RemoveReference<T>&&>(t);
     }
 
     template<typename T>
-    constexpr T&& forward(RemoveReference<T>& t) {
+    concept Moveable = requires(T t) {
+        requires noexcept(T(Core::move(t)));
+        requires noexcept(t = T(Core::move(t)));
+    };
+
+    template<typename T>
+    constexpr T&& forward(RemoveReference<T>& t) noexcept {
         return static_cast<T&&>(t);
     }
 
     template<typename T>
-    constexpr T&& forward(RemoveReference<T>&& t) {
+    constexpr T&& forward(RemoveReference<T>&& t) noexcept {
         return static_cast<T&&>(t);
     }
 
-    template<typename T>
+    template<Moveable T>
     void swap(T& a, T& b) noexcept {
         T tmp = Core::move(a);
         a = Core::move(b);

+ 4 - 4
modules/Plane.cppm

@@ -8,9 +8,9 @@ export namespace Core {
         float d;
 
     public:
-        Plane();
-        Plane(const Vector3& a, const Vector3& b, const Vector3& c);
-        float signedDistance(const Vector3& v) const;
-        size_t toString(StringBase& b) const;
+        Plane() noexcept;
+        Plane(const Vector3& a, const Vector3& b, const Vector3& c) noexcept;
+        float signedDistance(const Vector3& v) const noexcept;
+        size_t toString(StringBase& b) const noexcept;
     };
 }

+ 7 - 7
modules/Quaternion.cppm

@@ -7,12 +7,12 @@ export namespace Core {
         Vector4 v;
 
     public:
-        Quaternion();
-        Quaternion(const Vector3& axis, float angle);
-        Quaternion lerp(float f, const Quaternion& other) const;
-        Quaternion& operator*=(const Quaternion& other);
-        Quaternion operator*(const Quaternion& other) const;
-        Vector3 operator*(const Vector3& v) const;
-        size_t toString(StringBase& b) const;
+        Quaternion() noexcept;
+        Quaternion(const Vector3& axis, float angle) noexcept;
+        Quaternion lerp(float f, const Quaternion& other) const noexcept;
+        Quaternion& operator*=(const Quaternion& other) noexcept;
+        Quaternion operator*(const Quaternion& other) const noexcept;
+        Vector3 operator*(const Vector3& v) const noexcept;
+        size_t toString(StringBase& b) const noexcept;
     };
 }

+ 18 - 20
modules/Queue.cppm

@@ -1,7 +1,3 @@
-module;
-
-#include <iostream>
-
 export module Core.Queue;
 
 export import Core.New;
@@ -13,7 +9,7 @@ import Core.Utility;
 import Core.Assert;
 
 export namespace Core {
-    template<typename T, size_t N>
+    template<Moveable T, size_t N>
     class Queue final {
         AlignedType<T> data[N];
         size_t writeIndex = 0;
@@ -21,9 +17,9 @@ export namespace Core {
         size_t values = 0;
 
     public:
-        Queue() = default;
+        Queue() noexcept = default;
 
-        Queue(const Queue& other) {
+        Queue(const Queue& other) noexcept {
             copy(other);
         }
 
@@ -32,11 +28,11 @@ export namespace Core {
             other.clear();
         }
 
-        ~Queue() {
+        ~Queue() noexcept {
             clear();
         }
 
-        Queue& operator=(const Queue& other) {
+        Queue& operator=(const Queue& other) noexcept {
             if(&other != this) {
                 clear();
                 copy(other);
@@ -54,10 +50,12 @@ export namespace Core {
         }
 
         template<typename... Args>
-        T* put(Args&&... args) {
+        T* put(Args&&... args) noexcept {
             if(getLength() >= N) {
                 return nullptr;
             }
+            static_assert(noexcept(new(data + writeIndex)
+                                       T(Core::forward<Args>(args)...)));
             T* t = new(data + writeIndex) T(Core::forward<Args>(args)...);
             writeIndex = (writeIndex + 1) % N;
             values++;
@@ -65,28 +63,28 @@ export namespace Core {
         }
 
         template<typename... Args>
-        Queue& add(Args&&... args) {
+        Queue& add(Args&&... args) noexcept {
             put(Core::forward<Args>(args)...);
             return *this;
         }
 
-        T& operator[](size_t index) {
+        T& operator[](size_t index) noexcept {
             return reinterpret_cast<T*>(data)[(index + readIndex) % N];
         }
 
-        const T& operator[](size_t index) const {
+        const T& operator[](size_t index) const noexcept {
             return reinterpret_cast<const T*>(data)[(index + readIndex) % N];
         }
 
-        size_t getLength() const {
+        size_t getLength() const noexcept {
             return values;
         }
 
-        bool canRemove() const {
+        bool canRemove() const noexcept {
             return getLength() > 0;
         }
 
-        void clear() {
+        void clear() noexcept {
             for(size_t i = 0; i < getLength(); i++) {
                 (*this)[i].~T();
             }
@@ -95,14 +93,14 @@ export namespace Core {
             values = 0;
         }
 
-        void remove() {
+        void remove() noexcept {
             assert(canRemove());
             values--;
             (*this)[0].~T();
             readIndex = (readIndex + 1) % N;
         }
 
-        size_t toString(StringBase& b) const {
+        size_t toString(StringBase& b) const noexcept {
             size_t oldtotal = b.getTotal();
             b.add("[");
             size_t end = getLength();
@@ -119,13 +117,13 @@ export namespace Core {
         }
 
     private:
-        void copy(const Queue& other) {
+        void copy(const Queue& other) noexcept {
             for(size_t i = 0; i < other.getLength(); i++) {
                 add(other[i]);
             }
         }
 
-        void move(Queue&& other) {
+        void move(Queue&& other) noexcept {
             for(size_t i = 0; i < other.getLength(); i++) {
                 add(Core::move(other[i]));
             }

+ 8 - 8
modules/Random.cppm

@@ -8,16 +8,16 @@ export namespace Core {
         size_t index;
 
     public:
-        Random(u32 seed);
+        Random(u32 seed) noexcept;
 
-        u32 nextU32();
-        u32 nextU32(u32 min, u32 exclusiveMax);
-        i32 nextI32(i32 min, i32 exclusiveMax);
-        size_t nextSize(size_t min, size_t exclusiveMax);
-        bool nextBool();
-        float nextFloat();
+        u32 nextU32() noexcept;
+        u32 nextU32(u32 min, u32 exclusiveMax) noexcept;
+        i32 nextI32(i32 min, i32 exclusiveMax) noexcept;
+        size_t nextSize(size_t min, size_t exclusiveMax) noexcept;
+        bool nextBool() noexcept;
+        float nextFloat() noexcept;
 
     private:
-        void update();
+        void update() noexcept;
     };
 }

+ 3 - 3
modules/ReadLine.cppm

@@ -3,7 +3,7 @@ export module Core.ReadLine;
 export import Core.Types;
 
 export namespace Core {
-    bool startReadLine();
-    bool readLine(char* buffer, size_t n);
-    void stopReadLine();
+    bool startReadLine() noexcept;
+    bool readLine(char* buffer, size_t n) noexcept;
+    void stopReadLine() noexcept;
 }

+ 2 - 2
modules/Std.cppm

@@ -36,8 +36,8 @@ export using ::strstr;
 export using ::tanf;
 // NOLINTEND(misc-unused-using-decls)
 
-export void setDefaultLocal();
+export void setDefaultLocal() noexcept;
 
-void setDefaultLocal() {
+void setDefaultLocal() noexcept {
     setlocale(LC_ALL, "en_US.utf8");
 }

+ 17 - 17
modules/Terminal.cppm

@@ -3,24 +3,24 @@ export module Core.Terminal;
 export import Core.Vector;
 
 export namespace Core {
-    void enterAlternativeTerminal();
-    void leaveAlternativeTerminal();
-    IntVector2 getTerminalSize();
-    void clearTerminal();
-    void clearTerminalLine();
+    void enterAlternativeTerminal() noexcept;
+    void leaveAlternativeTerminal() noexcept;
+    IntVector2 getTerminalSize() noexcept;
+    void clearTerminal() noexcept;
+    void clearTerminalLine() noexcept;
 
-    void hideCursor();
-    void showCursor();
-    void resetCursor();
-    void moveCursorLeft(int i);
-    void moveCursorRight(int i);
-    void moveCursorUp(int i);
-    void moveCursorDown(int i);
+    void hideCursor() noexcept;
+    void showCursor() noexcept;
+    void resetCursor() noexcept;
+    void moveCursorLeft(int i) noexcept;
+    void moveCursorRight(int i) noexcept;
+    void moveCursorUp(int i) noexcept;
+    void moveCursorDown(int i) noexcept;
 
-    bool enterRawTerminal();
-    bool leaveRawTerminal();
-    u64 getRawChar();
-    bool isSpecialChar(u64 u);
+    bool enterRawTerminal() noexcept;
+    bool leaveRawTerminal() noexcept;
+    u64 getRawChar() noexcept;
+    bool isSpecialChar(u64 u) noexcept;
 
     struct SpecialChar {
         u64 key = 0;
@@ -29,5 +29,5 @@ export namespace Core {
         bool alt = 0;
     };
 
-    SpecialChar convertToSpecialChar(u64 u);
+    SpecialChar convertToSpecialChar(u64 u) noexcept;
 }

+ 0 - 2
modules/TerminalConstants.cppm

@@ -1,7 +1,5 @@
 export module Core.TerminalConstants;
 
-export import Core.Vector;
-
 #define ESC "\33["
 
 export namespace Core {

+ 11 - 10
modules/Test.cppm

@@ -3,16 +3,17 @@ export module Core.Test;
 import Core.Logger;
 import Core.TerminalConstants;
 import Core.ToString;
+import Core.Types;
 import Core.Std;
 
 #define SOURCE const std::source_location& l = std::source_location::current()
 
 export namespace Core {
-    void finalizeTests(void);
-    bool addTestResult(const char* file, bool comparison);
+    void finalizeTests(void) noexcept;
+    bool addTestResult(const char* file, bool comparison) noexcept;
 
     template<typename A, typename B>
-    bool test(const A& wanted, const B& actual, SOURCE) {
+    bool test(const A& wanted, const B& actual, SOURCE) noexcept {
         const char* file = getShortFileName(l.file_name());
         if(addTestResult(file, static_cast<const B&>(wanted) == actual)) {
             return true;
@@ -24,19 +25,19 @@ export namespace Core {
     }
 
     template<typename T>
-    bool testTrue(const T& actual, SOURCE) {
+    bool testTrue(const T& actual, SOURCE) noexcept {
         return test<T>(true, actual, l);
     }
 
     template<typename T>
-    bool testFalse(const T& actual, SOURCE) {
+    bool testFalse(const T& actual, SOURCE) noexcept {
         return test<T>(false, actual, l);
     }
 
-    bool testString(const char* wanted, const char* actual, SOURCE);
+    bool testString(const char* wanted, const char* actual, SOURCE) noexcept;
 
     template<typename A, typename B>
-    bool testString(const A& wanted, const B& actual, SOURCE) {
+    bool testString(const A& wanted, const B& actual, SOURCE) noexcept {
         String<512> wantedString;
         size_t lw = wantedString.add(wanted);
         String<512> actualString;
@@ -47,7 +48,7 @@ export namespace Core {
             static_cast<const char*>(actualString), l);
     }
 
-    bool testFloat(float wanted, float actual, float error, SOURCE);
-    bool testNull(const void* p, SOURCE);
-    bool testNotNull(const void* p, SOURCE);
+    bool testFloat(float wanted, float actual, float error, SOURCE) noexcept;
+    bool testNull(const void* p, SOURCE) noexcept;
+    bool testNotNull(const void* p, SOURCE) noexcept;
 }

+ 7 - 7
modules/Thread.cppm

@@ -23,10 +23,10 @@ export namespace Core {
         Mutex& mutex;
 
     public:
-        MutexGuard(Mutex& m);
+        MutexGuard(Mutex& m) noexcept;
         MutexGuard(const MutexGuard&) = delete;
         MutexGuard(MutexGuard&&) = delete;
-        ~MutexGuard();
+        ~MutexGuard() noexcept;
         MutexGuard& operator=(const MutexGuard&) = delete;
         MutexGuard& operator=(MutexGuard&&) = delete;
     };
@@ -37,14 +37,14 @@ export namespace Core {
     public:
         using Function = void (*)(void*);
 
-        Thread();
+        Thread() noexcept;
         Thread(const Thread& other) = delete;
         Thread(Thread&& other) noexcept;
-        ~Thread();
+        ~Thread() noexcept;
         Thread& operator=(const Thread& other) = delete;
         Thread& operator=(Thread&& other) noexcept;
-        void swap(Thread& other);
-        bool start(Function f, void* p);
-        bool join();
+        void swap(Thread& other) noexcept;
+        bool start(Function f, void* p) noexcept;
+        bool join() noexcept;
     };
 }

+ 20 - 18
modules/ToString.cppm

@@ -18,10 +18,10 @@ export namespace Core {
         char* buffer = nullptr;
 
     public:
-        StringBase() {
+        StringBase() noexcept {
         }
 
-        StringBase(char* s, size_t n) : capacity(n), buffer(s) {
+        StringBase(char* s, size_t n) noexcept : capacity(n), buffer(s) {
         }
 
         StringBase(StringBase&& other) = default;
@@ -29,31 +29,31 @@ export namespace Core {
         StringBase& operator=(StringBase&& other) = default;
         StringBase& operator=(const StringBase& other) = delete;
 
-        operator const char*() const {
+        operator const char*() const noexcept {
             return buffer;
         }
 
-        void clear() {
+        void clear() noexcept {
             index = 0;
             if(buffer != nullptr) {
                 *buffer = '\0';
             }
         }
 
-        size_t getCapacity() const {
+        size_t getCapacity() const noexcept {
             return index >= capacity ? 0 : capacity - index;
         }
 
-        size_t getTotal() const {
+        size_t getTotal() const noexcept {
             return index;
         }
 
-        char* getCurrent() const {
+        char* getCurrent() const noexcept {
             return buffer + min(index, capacity);
         }
 
         template<typename... Args>
-        size_t addFormat(const char* format, Args&&... args) {
+        size_t addFormat(const char* format, Args&&... args) noexcept {
             size_t oldIndex = index;
             (
                 [&] {
@@ -71,24 +71,25 @@ export namespace Core {
         }
 
         template<typename... Args>
-        size_t format(const char* format, Args&&... args) {
+        size_t format(const char* format, Args&&... args) noexcept {
             clear();
             return addFormat<Args...>(format, Core::forward<Args>(args)...);
         }
 
         template<typename T>
-        size_t add(const T& t) {
+        size_t add(const T& t) noexcept {
             size_t oldIndex = index;
             switcher(t);
             return index - oldIndex;
         }
 
-        void print() const;
+        void print() const noexcept;
 
     private:
-        void copyFormatUntil(const char*& format, StringFormat& f);
+        void copyFormatUntil(const char*& format, StringFormat& f) noexcept;
 
-#define TO_STRING(type) void toString(type t, const StringFormat& format)
+#define TO_STRING(type)                                        \
+    void toString(type t, const StringFormat& format) noexcept
 
         TO_STRING(signed char);
         TO_STRING(char);
@@ -109,7 +110,7 @@ export namespace Core {
         TO_STRING(bool);
 
         template<typename T>
-        void switcher(const T& t, const StringFormat& format = {}) {
+        void switcher(const T& t, const StringFormat& format = {}) noexcept {
             size_t oldIndex = index;
             if constexpr(Core::Iterable<T>) {
                 switcher("[");
@@ -134,20 +135,21 @@ export namespace Core {
         }
 
         void applyPostFormat(
-            size_t startIndex, size_t length, const StringFormat& format);
-        void insertSpace(size_t startIndex);
+            size_t startIndex, size_t length,
+            const StringFormat& format) noexcept;
+        void insertSpace(size_t startIndex) noexcept;
     };
 
     template<size_t N>
     struct String : public StringBase {
         char data[N]{};
 
-        String() : StringBase(data, N) {
+        String() noexcept : StringBase(data, N) {
         }
     };
 
     template<typename... Args>
-    void print(const char* format, Args&&... args) {
+    void print(const char* format, Args&&... args) noexcept {
         String<256> s;
         s.addFormat(format, Core::forward<Args>(args)...);
         s.print();

+ 4 - 4
modules/Unicode.cppm

@@ -8,8 +8,8 @@ export namespace Core {
         u32 length = 0;
     };
 
-    UTF8 convertUnicodeToUTF8(u32 c);
-    u32 convertUTF8toUnicode(UTF8 c);
-    bool isUTF8Remainder(u8 c);
-    u32 getUTF8Length(u8 c);
+    UTF8 convertUnicodeToUTF8(u32 c) noexcept;
+    u32 convertUTF8toUnicode(UTF8 c) noexcept;
+    bool isUTF8Remainder(u8 c) noexcept;
+    u32 getUTF8Length(u8 c) noexcept;
 }

+ 7 - 7
modules/UniquePointer.cppm

@@ -6,13 +6,13 @@ export namespace Core {
         T* t;
 
     public:
-        UniquePointer(T* t_) : t(t_) {
+        UniquePointer(T* t_) noexcept : t(t_) {
         }
 
-        UniquePointer() : UniquePointer(nullptr) {
+        UniquePointer() noexcept : UniquePointer(nullptr) {
         }
 
-        ~UniquePointer() {
+        ~UniquePointer() noexcept {
             delete t;
         }
 
@@ -32,19 +32,19 @@ export namespace Core {
             return *this;
         }
 
-        T* operator->() {
+        T* operator->() noexcept {
             return t;
         }
 
-        const T* operator->() const {
+        const T* operator->() const noexcept {
             return t;
         }
 
-        operator T*() {
+        operator T*() noexcept {
             return t;
         }
 
-        operator const T*() const {
+        operator const T*() const noexcept {
             return t;
         }
     };

+ 36 - 26
modules/Utility.cppm

@@ -1,9 +1,14 @@
+module;
+
+#include <new>
+
 export module Core.Utility;
 
 export import Core.Types;
 
 import Core.Meta;
 import Core.Std;
+import Core.New;
 
 #define SOURCE const std::source_location& l = std::source_location::current()
 
@@ -12,15 +17,14 @@ export namespace std {
 }
 
 #ifdef CHECK_MEMORY
-export void* operator new(size_t count, const std::source_location& l);
-export void* operator new[](size_t count, const std::source_location& l);
+export void* operator new(size_t count, const std::source_location& l) noexcept;
+export void* operator new[](
+    size_t count, const std::source_location& l) noexcept;
 #endif
 
-export using ::operator new;
-
 export namespace Core {
     template<typename T, typename C = int>
-    C popCount(const T& t) {
+    C popCount(const T& t) noexcept {
         static constexpr C map[16] = {0, 1, 1, 2, 1, 2, 2, 3,
                                       1, 2, 2, 3, 2, 3, 3, 4};
         C sum = 0;
@@ -31,58 +35,64 @@ export namespace Core {
     }
 
     using ExitHandler = void (*)(int, void*);
-    [[noreturn]] void exitWithHandler(int value, SOURCE);
-    void setExitHandler(ExitHandler h, void* data);
+    [[noreturn]] void exitWithHandler(int value, SOURCE) noexcept;
+    void setExitHandler(ExitHandler h, void* data) noexcept;
 
     using OutOfMemoryHandler = void (*)(void*);
-    void setOutOfMemoryHandler(OutOfMemoryHandler h, void* data);
+    void setOutOfMemoryHandler(OutOfMemoryHandler h, void* data) noexcept;
 
 #ifdef CHECK_MEMORY
-    void* allocateRaw(size_t n, SOURCE);
-    void* zeroAllocateRaw(size_t n, SOURCE);
-    void* reallocateRaw(void* p, size_t n, SOURCE);
-    void deallocateRaw(void* p, SOURCE);
+    void* allocateRaw(size_t n, SOURCE) noexcept;
+    void* zeroAllocateRaw(size_t n, SOURCE) noexcept;
+    void* reallocateRaw(void* p, size_t n, SOURCE) noexcept;
+    void deallocateRaw(void* p, SOURCE) noexcept;
 
     template<typename T, typename... Args>
-    T* newWithSource(Args&&... args) {
+    T* newWithSource(Args&&... args) noexcept {
+        static_assert(noexcept(new(std::source_location::current())
+                                   T(Core::forward<Args>(args)...)));
         return new(std::source_location::current())
             T(Core::forward<Args>(args)...);
     }
 
     template<typename T>
-    T* newWithSourceN(size_t n) {
+    T* newWithSourceN(size_t n) noexcept {
+        static_assert(noexcept(new(std::source_location::current()) T[n]));
         return new(std::source_location::current()) T[n];
     }
 #else
-    void* allocateRaw(size_t n);
-    void* zeroAllocateRaw(size_t n);
-    void* reallocateRaw(void* p, size_t n);
-    void deallocateRaw(void* p);
+    void* allocateRaw(size_t n) noexcept;
+    void* zeroAllocateRaw(size_t n) noexcept;
+    void* reallocateRaw(void* p, size_t n) noexcept;
+    void deallocateRaw(void* p) noexcept;
 
     template<typename T, typename... Args>
-    T* newWithSource(Args&&... args) {
-        return new T(Core::forward<Args>(args)...);
+    T* newWithSource(Args&&... args) noexcept {
+        static_assert(
+            noexcept(new(std::nothrow) T(Core::forward<Args>(args)...)));
+        return new(std::nothrow) T(Core::forward<Args>(args)...);
     }
 
     template<typename T>
-    T* newWithSourceN(size_t n) {
-        return new T[n];
+    T* newWithSourceN(size_t n) noexcept {
+        static_assert(noexcept(new(std::nothrow) T[n]));
+        return new(std::nothrow) T[n];
     }
 #endif
-    void printMemoryReport();
+    void printMemoryReport() noexcept;
 
     template<typename T>
-    void deleteWithSource(T* p) {
+    void deleteWithSource(T* p) noexcept {
         delete p;
     }
 
     template<typename T>
-    void deleteWithSourceN(T* p) {
+    void deleteWithSourceN(T* p) noexcept {
         delete[] p;
     }
 
     template<typename T>
-    void bubbleSort(T* data, size_t n) {
+    void bubbleSort(T* data, size_t n) noexcept {
         bool swapped = true;
         while(swapped && n > 0) {
             swapped = false;

+ 33 - 33
modules/Vector.cppm

@@ -13,41 +13,41 @@ export namespace Core {
         T values[N];
 
     public:
-        Vector() {
+        Vector() noexcept {
             for(size_t i = 0; i < N; i++) {
                 values[i] = static_cast<T>(0);
             }
         }
 
         template<typename OT, typename... Args>
-        Vector(OT a, Args&&... args) :
+        Vector(OT a, Args&&... args) noexcept :
             values(static_cast<T>(a), static_cast<T>(args)...) {
             static_assert(
                 sizeof...(args) + 1 == N,
                 "vector parameters do not match its size");
         }
 
-        Vector& operator+=(const Vector& other) {
+        Vector& operator+=(const Vector& other) noexcept {
             for(size_t i = 0; i < N; i++) {
                 values[i] += other.values[i];
             }
             return *this;
         }
 
-        Vector operator+(const Vector& other) const {
+        Vector operator+(const Vector& other) const noexcept {
             Vector v = *this;
             v += other;
             return v;
         }
 
-        Vector& operator-=(const Vector& other) {
+        Vector& operator-=(const Vector& other) noexcept {
             for(size_t i = 0; i < N; i++) {
                 values[i] -= other.values[i];
             }
             return *this;
         }
 
-        Vector operator-() const {
+        Vector operator-() const noexcept {
             Vector v = *this;
             for(size_t i = 0; i < N; i++) {
                 v.values[i] = -v.values[i];
@@ -55,65 +55,65 @@ export namespace Core {
             return v;
         }
 
-        Vector operator-(const Vector& other) const {
+        Vector operator-(const Vector& other) const noexcept {
             Vector v = *this;
             v -= other;
             return v;
         }
 
-        Vector& operator*=(T factor) {
+        Vector& operator*=(T factor) noexcept {
             for(size_t i = 0; i < N; i++) {
                 values[i] *= factor;
             }
             return *this;
         }
 
-        Vector& operator*=(const Vector& other) {
+        Vector& operator*=(const Vector& other) noexcept {
             for(size_t i = 0; i < N; i++) {
                 values[i] *= other.values[i];
             }
             return *this;
         }
 
-        Vector operator*(T factor) const {
+        Vector operator*(T factor) const noexcept {
             Vector v = *this;
             v *= factor;
             return v;
         }
 
-        Vector operator*(const Vector& other) const {
+        Vector operator*(const Vector& other) const noexcept {
             Vector v = *this;
             v *= other;
             return v;
         }
 
-        Vector& operator/=(T factor) {
+        Vector& operator/=(T factor) noexcept {
             for(size_t i = 0; i < N; i++) {
                 values[i] /= factor;
             }
             return *this;
         }
 
-        Vector& operator/=(const Vector& other) {
+        Vector& operator/=(const Vector& other) noexcept {
             for(size_t i = 0; i < N; i++) {
                 values[i] /= other.values[i];
             }
             return *this;
         }
 
-        Vector operator/(T factor) const {
+        Vector operator/(T factor) const noexcept {
             Vector v = *this;
             v /= factor;
             return v;
         }
 
-        Vector operator/(const Vector& other) const {
+        Vector operator/(const Vector& other) const noexcept {
             Vector v = *this;
             v /= other;
             return v;
         }
 
-        T dot(const Vector& v) const {
+        T dot(const Vector& v) const noexcept {
             T length = 0.0f;
             for(size_t i = 0; i < N; i++) {
                 length += values[i] * v.values[i];
@@ -121,15 +121,15 @@ export namespace Core {
             return length;
         }
 
-        T squareLength() const {
+        T squareLength() const noexcept {
             return dot(*this);
         }
 
-        float length() const {
+        float length() const noexcept {
             return sqrtf(static_cast<float>(squareLength()));
         }
 
-        Vector& normalize() {
+        Vector& normalize() noexcept {
             if constexpr(Core::IsSame<float, T> || Core::IsSame<double, T>) {
                 *this *= 1.0f / length();
             } else {
@@ -138,16 +138,16 @@ export namespace Core {
             return *this;
         }
 
-        T& operator[](size_t index) {
+        T& operator[](size_t index) noexcept {
             return values[index];
         }
 
-        const T& operator[](size_t index) const {
+        const T& operator[](size_t index) const noexcept {
             return values[index];
         }
 
         template<typename C>
-        Vector<N, C> to() const {
+        Vector<N, C> to() const noexcept {
             Vector<N, C> cast;
             for(size_t i = 0; i < N; i++) {
                 cast[i] = static_cast<C>(values[i]);
@@ -155,15 +155,15 @@ export namespace Core {
             return cast;
         }
 
-        Vector<N, int> toInt() const {
+        Vector<N, int> toInt() const noexcept {
             return to<int>();
         }
 
-        Vector<N, float> toFloat() const {
+        Vector<N, float> toFloat() const noexcept {
             return to<float>();
         }
 
-        size_t toString(StringBase& b) const {
+        size_t toString(StringBase& b) const noexcept {
             b.add("[");
             for(size_t i = 0; i < N - 1; i++) {
                 b.add(values[i]);
@@ -176,7 +176,7 @@ export namespace Core {
             return b.getTotal();
         }
 
-        bool operator==(const Vector& other) const {
+        bool operator==(const Vector& other) const noexcept {
             for(size_t i = 0; i < N; i++) {
                 if(notEqual(values[i], other.values[i])) {
                     return false;
@@ -186,22 +186,22 @@ export namespace Core {
         }
 
         template<Core::If<N >= 3, int, void*> = 0>
-        auto& xyz() {
+        auto& xyz() noexcept {
             return *reinterpret_cast<Vector<3, T>*>(this);
         }
 
         template<Core::If<N >= 3, int, void*> = 0>
-        const auto& xyz() const {
+        const auto& xyz() const noexcept {
             return *reinterpret_cast<const Vector<3, T>*>(this);
         }
 
     private:
         template<typename O>
-        static bool notEqual(const O& a, const O& b) {
+        static bool notEqual(const O& a, const O& b) noexcept {
             return a != b;
         }
 
-        static bool notEqual(float a, float b) {
+        static bool notEqual(float a, float b) noexcept {
             constexpr float e = 0.00001f;
             float diff = a - b;
             return diff < -e || diff > e;
@@ -230,11 +230,11 @@ export namespace Core {
     static_assert(
         alignof(IntVector2) == sizeof(int) * 2, "invalid IntVector2 alignment");
 
-    void setAngles(Vector3& v, float lengthAngle, float widthAngle);
-    Vector3 cross(const Vector3& a, const Vector3& b);
+    void setAngles(Vector3& v, float lengthAngle, float widthAngle) noexcept;
+    Vector3 cross(const Vector3& a, const Vector3& b) noexcept;
 }
 
 export template<size_t N, typename T>
-Core::Vector<N, T> operator*(T factor, const Core::Vector<N, T>& v) {
+Core::Vector<N, T> operator*(T factor, const Core::Vector<N, T>& v) noexcept {
     return v * factor;
 }

+ 9 - 9
modules/View.cppm

@@ -13,14 +13,14 @@ export namespace Core {
         Vector3 up{};
 
     public:
-        void updateDirections(float lengthAngle, float widthAngle);
-        void updateDirections(const Quaternion& q);
-        const Matrix& updateMatrix(const Vector3& pos);
-        const Vector3& getBack() const;
-        const Vector3& getDown() const;
-        const Vector3& getFront() const;
-        const Vector3& getLeft() const;
-        const Vector3& getRight() const;
-        const Vector3& getUp() const;
+        void updateDirections(float lengthAngle, float widthAngle) noexcept;
+        void updateDirections(const Quaternion& q) noexcept;
+        const Matrix& updateMatrix(const Vector3& pos) noexcept;
+        const Vector3& getBack() const noexcept;
+        const Vector3& getDown() const noexcept;
+        const Vector3& getFront() const noexcept;
+        const Vector3& getLeft() const noexcept;
+        const Vector3& getRight() const noexcept;
+        const Vector3& getUp() const noexcept;
     };
 }

+ 17 - 17
src/BitArray.cpp

@@ -11,7 +11,7 @@ using Core::BitArray;
 static constexpr size_t U64_BITS = 64;
 static constexpr size_t DIVIDE_BITS = 6;
 
-static u64 readBits(const u64* data, size_t index, u64 bits) {
+static u64 readBits(const u64* data, size_t index, u64 bits) noexcept {
     u64 dataIndexA = (index * bits) >> DIVIDE_BITS;
     u64 dataIndexB = ((index * bits) + (bits - 1lu)) >> DIVIDE_BITS;
     u64 shifts = (index * bits) & (U64_BITS - 1lu);
@@ -24,7 +24,7 @@ static u64 readBits(const u64* data, size_t index, u64 bits) {
     return r;
 }
 
-static void setBits(u64* data, size_t index, size_t bits, u64 value) {
+static void setBits(u64* data, size_t index, size_t bits, u64 value) noexcept {
     u64 mask = (1lu << bits) - 1lu;
     value &= mask;
     u64 dataIndexA = (index * bits) >> DIVIDE_BITS;
@@ -39,18 +39,18 @@ static void setBits(u64* data, size_t index, size_t bits, u64 value) {
     }
 }
 
-static u64 roundUpDivide(u64 a, u64 b) {
+static u64 roundUpDivide(u64 a, u64 b) noexcept {
     return a / b + ((a % b) != 0);
 }
 
-static size_t getArrayLength(size_t length, size_t bits) {
+static size_t getArrayLength(size_t length, size_t bits) noexcept {
     return roundUpDivide(length * bits, U64_BITS);
 }
 
-BitArray::BitArray() : length(0), bits(0), data(nullptr) {
+BitArray::BitArray() noexcept : length(0), bits(0), data(nullptr) {
 }
 
-BitArray::BitArray(const BitArray& other) : BitArray() {
+BitArray::BitArray(const BitArray& other) noexcept : BitArray() {
     resize(other.getLength(), other.getBits());
     size_t l = getLength();
     for(size_t i = 0; i < l; i++) {
@@ -62,7 +62,7 @@ BitArray::BitArray(BitArray&& other) noexcept : BitArray() {
     swap(other);
 }
 
-BitArray::~BitArray() {
+BitArray::~BitArray() noexcept {
     Core::deleteWithSourceN(data);
 }
 
@@ -71,35 +71,35 @@ BitArray& BitArray::operator=(BitArray other) noexcept {
     return *this;
 }
 
-BitArray& BitArray::set(size_t index, u64 value) {
+BitArray& BitArray::set(size_t index, u64 value) noexcept {
     assert(data != nullptr);
     assert(index < length);
     setBits(data, index, bits, value);
     return *this;
 }
 
-u64 BitArray::get(size_t index) const {
+u64 BitArray::get(size_t index) const noexcept {
     assert(data != nullptr);
     assert(index < length);
     return readBits(data, index, bits);
 }
 
-size_t BitArray::getLength() const {
+size_t BitArray::getLength() const noexcept {
     return length;
 }
 
-size_t BitArray::getBits() const {
+size_t BitArray::getBits() const noexcept {
     return bits;
 }
 
-size_t Core::BitArray::getInternalByteSize() const {
+size_t Core::BitArray::getInternalByteSize() const noexcept {
     if(getLength() <= 0 || getBits() <= 0) {
         return 0;
     }
     return getArrayLength(getLength(), getBits()) * sizeof(u64);
 }
 
-i64 BitArray::select(u64 index) const {
+i64 BitArray::select(u64 index) const noexcept {
     if(index <= 0) {
         return -1;
     }
@@ -123,14 +123,14 @@ i64 BitArray::select(u64 index) const {
     return -1;
 }
 
-void BitArray::fill(u64 value) {
+void BitArray::fill(u64 value) noexcept {
     size_t l = getLength();
     for(size_t i = 0; i < l; i++) {
         set(i, value);
     }
 }
 
-void BitArray::resize(size_t newLength, size_t newBits) {
+void BitArray::resize(size_t newLength, size_t newBits) noexcept {
     if(newLength == 0 || newBits == 0) {
         return;
     } else if(newBits > 64) {
@@ -153,7 +153,7 @@ void BitArray::resize(size_t newLength, size_t newBits) {
     bits = newBits & 0xFF;
 }
 
-size_t BitArray::toString(StringBase& b) const {
+size_t BitArray::toString(StringBase& b) const noexcept {
     b.add("[");
     size_t l = length;
     if(l > 0) {
@@ -168,7 +168,7 @@ size_t BitArray::toString(StringBase& b) const {
     return b.getTotal();
 }
 
-void BitArray::swap(BitArray& other) {
+void BitArray::swap(BitArray& other) noexcept {
     u64 l = length;
     u64 b = bits;
     length = other.length;

+ 10 - 9
src/Box.cpp

@@ -5,10 +5,11 @@ import Core.ToString;
 
 using Core::Box;
 
-Box::Box(const Vector3& min_, const Vector3& max_) : min(min_), max(max_) {
+Box::Box(const Vector3& min_, const Vector3& max_) noexcept :
+    min(min_), max(max_) {
 }
 
-Box::Box(const Vector3& size) : min(), max() {
+Box::Box(const Vector3& size) noexcept : min(), max() {
     for(size_t i = 0; i < 3; i++) {
         if(size[i] < 0.0f) {
             min[i] = size[i];
@@ -18,17 +19,17 @@ Box::Box(const Vector3& size) : min(), max() {
     }
 }
 
-Box Box::offset(const Vector3& offset) const {
+Box Box::offset(const Vector3& offset) const noexcept {
     return Box(min + offset, max + offset);
 }
 
-bool Box::collidesWith(const Box& other) const {
+bool Box::collidesWith(const Box& other) const noexcept {
     return max[0] > other.min[0] && min[0] < other.max[0] &&
            max[1] > other.min[1] && min[1] < other.max[1] &&
            max[2] > other.min[2] && min[2] < other.max[2];
 }
 
-Box Box::expand(const Vector3& offset) const {
+Box Box::expand(const Vector3& offset) const noexcept {
     Vector3 add(
         offset[0] > 0.0f ? offset[0] : 0.0f,
         offset[1] > 0.0f ? offset[1] : 0.0f,
@@ -40,7 +41,7 @@ Box Box::expand(const Vector3& offset) const {
     return Box(min + sub, max + add);
 }
 
-Box Box::grow(const Vector3& growth) const {
+Box Box::grow(const Vector3& growth) const noexcept {
     Vector3 half = growth * 0.5f;
     Vector3 nMin = min - half;
     Vector3 nMax = max + half;
@@ -53,15 +54,15 @@ Box Box::grow(const Vector3& growth) const {
     return Box(nMin, nMax);
 }
 
-const Core::Vector3& Box::getMin() const {
+const Core::Vector3& Box::getMin() const noexcept {
     return min;
 }
 
-const Core::Vector3& Box::getMax() const {
+const Core::Vector3& Box::getMax() const noexcept {
     return max;
 }
 
-size_t Box::toString(StringBase& b) const {
+size_t Box::toString(StringBase& b) const noexcept {
     return b.addFormat(
         "Box([{.2}, {.2}, {.2}], [{.2}, {.2}, {.2}])", min[0], min[1], min[2],
         max[0], max[1], max[2]);

+ 8 - 8
src/Buffer.cpp

@@ -5,10 +5,10 @@ import Core.Utility;
 import Core.Meta;
 import Core.Std;
 
-Core::Buffer::Buffer() : length(0), capacity(0), buffer(nullptr) {
+Core::Buffer::Buffer() noexcept : length(0), capacity(0), buffer(nullptr) {
 }
 
-Core::Buffer::Buffer(const Buffer& other) : Buffer() {
+Core::Buffer::Buffer(const Buffer& other) noexcept : Buffer() {
     add(other.getData(), other.getLength());
 }
 
@@ -16,7 +16,7 @@ Core::Buffer::Buffer(Buffer&& other) noexcept : Buffer() {
     swap(other);
 }
 
-Core::Buffer::~Buffer() {
+Core::Buffer::~Buffer() noexcept {
     deallocateRaw(buffer);
 }
 
@@ -25,11 +25,11 @@ Core::Buffer& Core::Buffer::operator=(Buffer&& other) noexcept {
     return *this;
 }
 
-Core::Buffer& Core::Buffer::operator=(const Buffer& other) {
+Core::Buffer& Core::Buffer::operator=(const Buffer& other) noexcept {
     return add(other.getData(), other.length);
 }
 
-Core::Buffer& Core::Buffer::add(const void* data, size_t size) {
+Core::Buffer& Core::Buffer::add(const void* data, size_t size) noexcept {
     while(length + size > capacity) {
         capacity += Core::max<size_t>(8, capacity / 4);
         buffer = static_cast<char*>(reallocateRaw(buffer, capacity));
@@ -39,11 +39,11 @@ Core::Buffer& Core::Buffer::add(const void* data, size_t size) {
     return *this;
 }
 
-size_t Core::Buffer::getLength() const {
+size_t Core::Buffer::getLength() const noexcept {
     return length;
 }
 
-const char* Core::Buffer::getData() const {
+const char* Core::Buffer::getData() const noexcept {
     return buffer;
 }
 
@@ -53,6 +53,6 @@ void Core::Buffer::swap(Buffer& other) noexcept {
     Core::swap(buffer, other.buffer);
 }
 
-void Core::Buffer::clear() {
+void Core::Buffer::clear() noexcept {
     length = 0;
 }

+ 7 - 7
src/Clock.cpp

@@ -9,10 +9,10 @@ import ErrorSimulator;
 
 using Core::Clock;
 
-Clock::Clock() : index(0), last(0), sum(0), time({}) {
+Clock::Clock() noexcept : index(0), last(0), sum(0), time({}) {
 }
 
-i64 Clock::update() {
+i64 Clock::update() noexcept {
     i64 current = getNanos();
     if(current < 0) {
         return current;
@@ -29,11 +29,11 @@ i64 Clock::update() {
     return time[index];
 }
 
-float Core::Clock::getUpdatesPerSecond() const {
+float Core::Clock::getUpdatesPerSecond() const noexcept {
     return (time.getLength() * 1000000000.0f) / static_cast<float>(sum);
 }
 
-bool Clock::sleepNanos(i64 nanos) {
+bool Clock::sleepNanos(i64 nanos) noexcept {
     try {
         debugThrow();
         std::this_thread::sleep_for(std::chrono::nanoseconds(nanos));
@@ -43,18 +43,18 @@ bool Clock::sleepNanos(i64 nanos) {
     return false;
 }
 
-bool Clock::sleepMillis(i64 millis) {
+bool Clock::sleepMillis(i64 millis) noexcept {
     return sleepNanos(millis * 1'000'000l);
 }
 
-i64 Clock::getNanos(void) {
+i64 Clock::getNanos(void) noexcept {
     try {
         debugThrow();
         using namespace std::chrono;
         return duration_cast<nanoseconds>(
                    high_resolution_clock::now().time_since_epoch())
             .count();
-    } catch(std::exception& e) {
+    } catch(...) {
         return -1;
     }
 }

+ 3 - 7
src/ErrorSimulator.cppm

@@ -1,7 +1,3 @@
-module;
-
-#include <stdexcept>
-
 export module ErrorSimulator;
 
 #ifdef ERROR_SIMULATOR
@@ -9,14 +5,14 @@ export extern int failStep;
 export extern int failStepThrow;
 int failStep = -1;
 int failStepThrow = -1;
-#endif
 
-#define FAIL_STEP (--failStep == 0)
+struct DummyError {};
+#endif
 
 export inline void debugThrow() {
 #ifdef ERROR_SIMULATOR
     if(--failStepThrow == 0) {
-        throw std::runtime_error("not a real error");
+        throw DummyError();
     }
 #endif
 }

+ 3 - 2
src/File.cpp

@@ -9,7 +9,8 @@ import ErrorSimulator;
 
 using Core::LogLevel;
 
-static bool readOpenFile(FILE* file, Core::List<char>& f, const char* path) {
+static bool readOpenFile(
+    FILE* file, Core::List<char>& f, const char* path) noexcept {
     if(doFailStep() || fseek(file, 0, SEEK_END)) {
         Core::report(LogLevel::ERROR, "cannot seek file end of '{}'", path);
         return true;
@@ -37,7 +38,7 @@ static bool readOpenFile(FILE* file, Core::List<char>& f, const char* path) {
     return false;
 }
 
-bool Core::readFile(List<char>& f, const char* path) {
+bool Core::readFile(List<char>& f, const char* path) noexcept {
     FILE* file = fopen(path, "rb");
     if(file == nullptr) {
         report(LogLevel::ERROR, "cannot read file '{}'", path);

+ 5 - 5
src/Frustum.cpp

@@ -6,7 +6,7 @@ using Core::Frustum;
 using V3 = Core::Vector3;
 using V4 = Core::Vector4;
 
-Frustum::Frustum(float fieldOfView, float nearClip, float farClip) :
+Frustum::Frustum(float fieldOfView, float nearClip, float farClip) noexcept :
     projection(), planes(), tan(tanf(fieldOfView * 0.5f)), near(nearClip),
     far(farClip) {
     float diff = 1.0f / (near - far);
@@ -16,7 +16,7 @@ Frustum::Frustum(float fieldOfView, float nearClip, float farClip) :
     projection.set(3, V4(0.0f, 0.0f, -1.0f, 0.0f));
 }
 
-const Core::Matrix& Frustum::updateProjection(const IntVector2& size) {
+const Core::Matrix& Frustum::updateProjection(const IntVector2& size) noexcept {
     projection.set(
         0, V4(static_cast<float>(size[1]) / (tan * static_cast<float>(size[0])),
               0.0f, 0.0f, 0.0f));
@@ -25,7 +25,7 @@ const Core::Matrix& Frustum::updateProjection(const IntVector2& size) {
 
 void Frustum::updatePlanes(
     const V3& pos, const V3& right, const V3& up, const V3& front,
-    const IntVector2& size) {
+    const IntVector2& size) noexcept {
     float aspect = static_cast<float>(size[0]) / static_cast<float>(size[1]);
 
     float hNearHeight = tan * near;
@@ -56,7 +56,7 @@ void Frustum::updatePlanes(
     planes[5] = Plane(fBottomRight, fTopRight, nBottomRight);   // right plane
 }
 
-bool Frustum::isInside(const V3& pos) const {
+bool Frustum::isInside(const V3& pos) const noexcept {
     for(const Plane& p : planes) {
         if(p.signedDistance(pos) < 0.0f) {
             return false;
@@ -65,7 +65,7 @@ bool Frustum::isInside(const V3& pos) const {
     return true;
 }
 
-bool Frustum::isInside(const V3& pos, float radius) const {
+bool Frustum::isInside(const V3& pos, float radius) const noexcept {
     for(const Plane& p : planes) {
         if(p.signedDistance(pos) < -radius) {
             return false;

+ 3 - 3
src/Logger.cpp

@@ -4,19 +4,19 @@ Core::LogLevel Core::logLevel = Core::LogLevel::DEBUG;
 static Core::ReportHandler reportHandler = nullptr;
 static void* reportData = nullptr;
 
-void Core::setReportHandler(ReportHandler h, void* data) {
+void Core::setReportHandler(ReportHandler h, void* data) noexcept {
     reportHandler = h;
     reportData = data;
 }
 
 void Core::callReportHandler(
-    LogLevel l, const char* report, const std::source_location& sl) {
+    LogLevel l, const char* report, const std::source_location& sl) noexcept {
     if(reportHandler != nullptr) {
         reportHandler(l, sl, reportData, report);
     }
 }
 
-const char* Core::getShortFileName(const char* s) {
+const char* Core::getShortFileName(const char* s) noexcept {
     const char* r = s;
     while(*s != '\0') {
         if(*(s++) == '/') {

+ 21 - 21
src/Matrix.cpp

@@ -3,20 +3,20 @@ module Core.Matrix;
 import Core.ToString;
 import Core.Std;
 
-Core::Matrix::Matrix() {
+Core::Matrix::Matrix() noexcept {
     unit();
 }
 
-Core::Matrix& Core::Matrix::unit() {
+Core::Matrix& Core::Matrix::unit() noexcept {
     return translateTo(Vector3(0.0f, 0.0f, 0.0f));
 }
 
-Core::Matrix& Core::Matrix::set(size_t index, const Vector4& v) {
+Core::Matrix& Core::Matrix::set(size_t index, const Vector4& v) noexcept {
     data[index] = v;
     return *this;
 }
 
-Core::Matrix Core::Matrix::transpose() const {
+Core::Matrix Core::Matrix::transpose() const noexcept {
     Matrix m;
     for(size_t x = 0; x < 4; x++) {
         for(size_t y = 0; y < 4; y++) {
@@ -26,11 +26,11 @@ Core::Matrix Core::Matrix::transpose() const {
     return m;
 }
 
-const float* Core::Matrix::getValues() const {
+const float* Core::Matrix::getValues() const noexcept {
     return &(data[0][0]);
 }
 
-Core::Matrix& Core::Matrix::operator*=(const Matrix& m) {
+Core::Matrix& Core::Matrix::operator*=(const Matrix& m) noexcept {
     data[0] = data[0][0] * m.data[0] + data[0][1] * m.data[1] +
               data[0][2] * m.data[2] + data[0][3] * m.data[3];
     data[1] = data[1][0] * m.data[0] + data[1][1] * m.data[1] +
@@ -42,49 +42,49 @@ Core::Matrix& Core::Matrix::operator*=(const Matrix& m) {
     return *this;
 }
 
-Core::Matrix Core::Matrix::operator*(const Matrix& other) const {
+Core::Matrix Core::Matrix::operator*(const Matrix& other) const noexcept {
     Matrix m = *this;
     m *= other;
     return m;
 }
 
-Core::Vector3 Core::Matrix::operator*(const Vector3& v) const {
+Core::Vector3 Core::Matrix::operator*(const Vector3& v) const noexcept {
     Vector4 v4(v[0], v[1], v[2], 1.0f);
     return Vector3(data[0].dot(v4), data[1].dot(v4), data[2].dot(v4)) *
            (1.0f / data[3].dot(v4));
 }
 
-Core::Matrix& Core::Matrix::scale(const Vector3& v) {
+Core::Matrix& Core::Matrix::scale(const Vector3& v) noexcept {
     data[0] *= v[0];
     data[1] *= v[1];
     data[2] *= v[2];
     return *this;
 }
 
-Core::Matrix& Core::Matrix::scale(float s) {
+Core::Matrix& Core::Matrix::scale(float s) noexcept {
     return scale(Vector3(s, s, s));
 }
 
-Core::Matrix& Core::Matrix::translate(const Vector3& v) {
+Core::Matrix& Core::Matrix::translate(const Vector3& v) noexcept {
     return translateX(v[0]).translateY(v[1]).translateZ(v[2]);
 }
 
-Core::Matrix& Core::Matrix::translateX(float tx) {
+Core::Matrix& Core::Matrix::translateX(float tx) noexcept {
     data[0] += data[3] * tx;
     return *this;
 }
 
-Core::Matrix& Core::Matrix::translateY(float ty) {
+Core::Matrix& Core::Matrix::translateY(float ty) noexcept {
     data[1] += data[3] * ty;
     return *this;
 }
 
-Core::Matrix& Core::Matrix::translateZ(float tz) {
+Core::Matrix& Core::Matrix::translateZ(float tz) noexcept {
     data[2] += data[3] * tz;
     return *this;
 }
 
-Core::Matrix& Core::Matrix::translateTo(const Vector3& v) {
+Core::Matrix& Core::Matrix::translateTo(const Vector3& v) noexcept {
     data[0] = Vector4(1.0f, 0.0f, 0.0f, v[0]);
     data[1] = Vector4(0.0f, 1.0f, 0.0f, v[1]);
     data[2] = Vector4(0.0f, 0.0f, 1.0f, v[2]);
@@ -92,7 +92,7 @@ Core::Matrix& Core::Matrix::translateTo(const Vector3& v) {
     return *this;
 }
 
-Core::Matrix& Core::Matrix::rotate(float radians, int a, int b) {
+Core::Matrix& Core::Matrix::rotate(float radians, int a, int b) noexcept {
     float sin = 0.0f;
     float cos = 0.0f;
     sincosf(radians, &sin, &cos);
@@ -102,19 +102,19 @@ Core::Matrix& Core::Matrix::rotate(float radians, int a, int b) {
     return *this;
 }
 
-Core::Matrix& Core::Matrix::rotateX(float degrees) {
+Core::Matrix& Core::Matrix::rotateX(float degrees) noexcept {
     return rotate(degrees, 1, 2);
 }
 
-Core::Matrix& Core::Matrix::rotateY(float degrees) {
+Core::Matrix& Core::Matrix::rotateY(float degrees) noexcept {
     return rotate(-degrees, 0, 2);
 }
 
-Core::Matrix& Core::Matrix::rotateZ(float degrees) {
+Core::Matrix& Core::Matrix::rotateZ(float degrees) noexcept {
     return rotate(degrees, 0, 1);
 }
 
-Core::Matrix& Core::Matrix::rotate(const Quaternion& q) {
+Core::Matrix& Core::Matrix::rotate(const Quaternion& q) noexcept {
     Vector3 a = q * Vector3(data[0][0], data[1][0], data[2][0]);
     Vector3 b = q * Vector3(data[0][1], data[1][1], data[2][1]);
     Vector3 c = q * Vector3(data[0][2], data[1][2], data[2][2]);
@@ -125,6 +125,6 @@ Core::Matrix& Core::Matrix::rotate(const Quaternion& q) {
     return *this;
 }
 
-size_t Core::Matrix::toString(StringBase& b) const {
+size_t Core::Matrix::toString(StringBase& b) const noexcept {
     return b.addFormat("[{}, {}, {}, {}]", data[0], data[1], data[2], data[3]);
 }

+ 4 - 4
src/Plane.cpp

@@ -4,18 +4,18 @@ import Core.Std;
 
 using Core::Plane;
 
-Plane::Plane() : abc(), d(0) {
+Plane::Plane() noexcept : abc(), d(0) {
 }
 
-Plane::Plane(const Vector3& a, const Vector3& b, const Vector3& c) :
+Plane::Plane(const Vector3& a, const Vector3& b, const Vector3& c) noexcept :
     abc(cross(b - a, c - a).normalize()), d(-abc.dot(b)) {
 }
 
-float Plane::signedDistance(const Vector3& v) const {
+float Plane::signedDistance(const Vector3& v) const noexcept {
     return abc.dot(v) + d;
 }
 
-size_t Plane::toString(StringBase& b) const {
+size_t Plane::toString(StringBase& b) const noexcept {
     return b.addFormat(
         "({.3} x + {.3} y + {.3} z + {.3})", abc[0], abc[1], abc[2], d);
 }

+ 9 - 7
src/Quaternion.cpp

@@ -4,10 +4,10 @@ import Core.Math;
 import Core.Std;
 import Core.ToString;
 
-Core::Quaternion::Quaternion() : v(0.0f, 0.0f, 0.0f, 1.0f) {
+Core::Quaternion::Quaternion() noexcept : v(0.0f, 0.0f, 0.0f, 1.0f) {
 }
 
-Core::Quaternion::Quaternion(const Vector3& axis, float angle) :
+Core::Quaternion::Quaternion(const Vector3& axis, float angle) noexcept :
     v(axis[0], axis[1], axis[2], 1.0f) {
     v.xyz().normalize();
     float factor = 0.0f;
@@ -16,14 +16,15 @@ Core::Quaternion::Quaternion(const Vector3& axis, float angle) :
 }
 
 Core::Quaternion Core::Quaternion::lerp(
-    float f, const Quaternion& other) const {
+    float f, const Quaternion& other) const noexcept {
     Quaternion q;
     q.v = interpolate(v, other.v, f);
     q.v.normalize();
     return q;
 }
 
-Core::Quaternion& Core::Quaternion::operator*=(const Quaternion& other) {
+Core::Quaternion& Core::Quaternion::operator*=(
+    const Quaternion& other) noexcept {
     float dot = v.xyz().dot(other.v.xyz());
     v.xyz() = other.v.xyz() * v[3] + v.xyz() * other.v[3] +
               cross(v.xyz(), other.v.xyz());
@@ -31,18 +32,19 @@ Core::Quaternion& Core::Quaternion::operator*=(const Quaternion& other) {
     return *this;
 }
 
-Core::Quaternion Core::Quaternion::operator*(const Quaternion& other) const {
+Core::Quaternion Core::Quaternion::operator*(
+    const Quaternion& other) const noexcept {
     Quaternion q(*this);
     q *= other;
     return q;
 }
 
-Core::Vector3 Core::Quaternion::operator*(const Vector3& v3) const {
+Core::Vector3 Core::Quaternion::operator*(const Vector3& v3) const noexcept {
     Vector3 qv = v3 * v[3] + cross(v.xyz(), v3);
     return v.xyz() * v.xyz().dot(v3) + qv * v[3] - cross(qv, v.xyz());
 }
 
-size_t Core::Quaternion::toString(StringBase& b) const {
+size_t Core::Quaternion::toString(StringBase& b) const noexcept {
     return b.addFormat(
         "({.3} i + {.3} j + {.3} k + {.3})", v[0], v[1], v[2], v[3]);
 }

+ 9 - 9
src/Random.cpp

@@ -2,14 +2,14 @@ module Core.Random;
 
 using Core::Random;
 
-Random::Random(u32 seed) : data(), index(0) {
+Random::Random(u32 seed) noexcept : data(), index(0) {
     for(u32& u : data) {
         u = seed;
         seed = seed * 7 + 31;
     }
 }
 
-void Random::update() {
+void Random::update() noexcept {
     constexpr int M = 7;
     static const u32 map[2] = {0, 0x8EBF'D028};
     for(size_t i = 0; i < data.getLength() - M; i++) {
@@ -22,7 +22,7 @@ void Random::update() {
     index = 0;
 }
 
-u32 Random::nextU32() {
+u32 Random::nextU32() noexcept {
     if(index >= data.getLength()) {
         update();
     }
@@ -34,27 +34,27 @@ u32 Random::nextU32() {
 }
 
 template<typename T>
-T limit(T value, T min, T exclusiveMax) {
+T limit(T value, T min, T exclusiveMax) noexcept {
     return min + value % (exclusiveMax - min);
 }
 
-u32 Random::nextU32(u32 min, u32 exclusiveMax) {
+u32 Random::nextU32(u32 min, u32 exclusiveMax) noexcept {
     return limit(nextU32(), min, exclusiveMax);
 }
 
-i32 Random::nextI32(i32 min, i32 exclusiveMax) {
+i32 Random::nextI32(i32 min, i32 exclusiveMax) noexcept {
     return limit(static_cast<i32>(nextU32() >> 1), min, exclusiveMax);
 }
 
-size_t Core::Random::nextSize(size_t min, size_t exclusiveMax) {
+size_t Core::Random::nextSize(size_t min, size_t exclusiveMax) noexcept {
     return limit<size_t>(nextU32(), min, exclusiveMax);
 }
 
-bool Core::Random::nextBool() {
+bool Core::Random::nextBool() noexcept {
     return nextU32() & 1;
 }
 
-float Core::Random::nextFloat() {
+float Core::Random::nextFloat() noexcept {
     float f = static_cast<float>(nextU32()) / static_cast<float>(0xFFFF'FFFFu);
     return f >= 1.0f ? nextFloat() : f;
 }

+ 19 - 19
src/ReadLine.cpp

@@ -34,7 +34,7 @@ static size_t historyOffset = 0;
 static size_t historyIndex = 0;
 static size_t historyLength = 0;
 
-static void addChar(u64 c) {
+static void addChar(u64 c) noexcept {
     Core::UTF8 u = Core::convertUnicodeToUTF8(static_cast<u32>(c));
     for(u32 k = 0; k < u.length; k++) {
         if(currentBuffer.length >= CONSOLE_BUFFER_SIZE - 1) {
@@ -51,11 +51,11 @@ static void addChar(u64 c) {
     }
 }
 
-static void print(const char* s) {
+static void print(const char* s) noexcept {
     fputs(s, stdout);
 }
 
-static void refreshLine(const char* prefix) {
+static void refreshLine(const char* prefix) noexcept {
     print(prefix);
     print(currentBuffer.data.begin());
     if(cursorMove > 0) {
@@ -65,7 +65,7 @@ static void refreshLine(const char* prefix) {
     Core::clearTerminalLine();
 }
 
-static bool clear() {
+static bool clear() noexcept {
     move = 0;
     cursorMove = 0;
     currentBuffer.length = 0;
@@ -74,7 +74,7 @@ static bool clear() {
     return false;
 }
 
-static void addToHistory() {
+static void addToHistory() noexcept {
     if(historyLength < HISTORY_LENGTH) {
         historyLength++;
     }
@@ -82,14 +82,14 @@ static void addToHistory() {
     historyIndex = (historyIndex + 1) % HISTORY_LENGTH;
 }
 
-static void addLine() {
+static void addLine() noexcept {
     addToHistory();
     Core::MutexGuard mg(bufferMutex);
     buffer.add(currentBuffer);
     clear();
 }
 
-static bool removeChar() {
+static bool removeChar() noexcept {
     size_t pos = currentBuffer.length - move;
     if(pos > 0) {
         size_t l = 1;
@@ -108,7 +108,7 @@ static bool removeChar() {
     return false;
 }
 
-static bool handleControlKey(u64 c) {
+static bool handleControlKey(u64 c) noexcept {
     switch(c) {
         case 3: return clear();
         case 10:
@@ -118,14 +118,14 @@ static bool handleControlKey(u64 c) {
     return false;
 }
 
-static void copyHistory() {
+static void copyHistory() noexcept {
     currentBuffer = history
         [(historyIndex - historyOffset + HISTORY_LENGTH) % HISTORY_LENGTH];
     move = 0;
     cursorMove = 0;
 }
 
-static void handleUpArrow() {
+static void handleUpArrow() noexcept {
     if(historyOffset >= historyLength) {
         return;
     }
@@ -133,7 +133,7 @@ static void handleUpArrow() {
     copyHistory();
 }
 
-static void handleDownArrow() {
+static void handleDownArrow() noexcept {
     if(historyOffset <= 1) {
         return;
     }
@@ -141,11 +141,11 @@ static void handleDownArrow() {
     copyHistory();
 }
 
-static char getMoved() {
+static char getMoved() noexcept {
     return currentBuffer.data[currentBuffer.length - move];
 }
 
-static void handleLeftArrow() {
+static void handleLeftArrow() noexcept {
     if(move < currentBuffer.length) {
         move++;
         while(move < currentBuffer.length &&
@@ -156,7 +156,7 @@ static void handleLeftArrow() {
     }
 }
 
-static void handleRightArrow() {
+static void handleRightArrow() noexcept {
     if(move > 0) {
         move--;
         while(move > 0 && Core::isUTF8Remainder(static_cast<u8>(getMoved()))) {
@@ -166,7 +166,7 @@ static void handleRightArrow() {
     }
 }
 
-static void handleChars() {
+static void handleChars() noexcept {
     while(true) {
         u64 c = Core::getRawChar();
         if(c == 0) {
@@ -195,7 +195,7 @@ static void handleChars() {
     }
 }
 
-static void loop(void*) {
+static void loop(void*) noexcept {
     while(running) {
         handleChars();
         refreshLine("> ");
@@ -203,7 +203,7 @@ static void loop(void*) {
     }
 }
 
-bool Core::startReadLine(void) {
+bool Core::startReadLine(void) noexcept {
     if(enterRawTerminal()) {
         report(LogLevel::WARNING, "cannot set terminal attributes");
     }
@@ -216,7 +216,7 @@ bool Core::startReadLine(void) {
     return false;
 }
 
-bool Core::readLine(char* buffer_, size_t n) {
+bool Core::readLine(char* buffer_, size_t n) noexcept {
     if(buffer.getLength() == 0) {
         return false;
     }
@@ -226,7 +226,7 @@ bool Core::readLine(char* buffer_, size_t n) {
     return true;
 }
 
-void Core::stopReadLine() {
+void Core::stopReadLine() noexcept {
     running = false;
     readThread.join();
     if(Core::leaveRawTerminal()) {

+ 21 - 21
src/Terminal.cpp

@@ -91,19 +91,19 @@ static const Core::Array<EscapeSequence, 175> ESCAPE_SEQUENCES = {{
     KEYS_WITH_MODIFIER("8", K_CTRL | K_ALT | K_SHIFT),
 }};
 
-void Core::enterAlternativeTerminal() {
+void Core::enterAlternativeTerminal() noexcept {
     esc("?1049h");
 }
 
-void Core::leaveAlternativeTerminal() {
+void Core::leaveAlternativeTerminal() noexcept {
     esc("?1049l");
 }
 
-void Core::clearTerminal() {
+void Core::clearTerminal() noexcept {
     esc("2J");
 }
 
-Core::IntVector2 Core::getTerminalSize() {
+Core::IntVector2 Core::getTerminalSize() noexcept {
     winsize w;
     if(ioctl(0, TIOCGWINSZ, &w)) {
         return IntVector2(0, 0);
@@ -111,39 +111,39 @@ Core::IntVector2 Core::getTerminalSize() {
     return IntVector2(w.ws_col, w.ws_row);
 }
 
-void Core::clearTerminalLine() {
+void Core::clearTerminalLine() noexcept {
     esc("2K\r");
 }
 
-void Core::hideCursor() {
+void Core::hideCursor() noexcept {
     esc("?25l");
 }
 
-void Core::showCursor() {
+void Core::showCursor() noexcept {
     esc("?25h");
 }
 
-void Core::resetCursor() {
+void Core::resetCursor() noexcept {
     esc("H");
 }
 
-void Core::moveCursorLeft(int i) {
+void Core::moveCursorLeft(int i) noexcept {
     print(ESC "{}D", i);
 }
 
-void Core::moveCursorRight(int i) {
+void Core::moveCursorRight(int i) noexcept {
     print(ESC "{}C", i);
 }
 
-void Core::moveCursorUp(int i) {
+void Core::moveCursorUp(int i) noexcept {
     print(ESC "{}A", i);
 }
 
-void Core::moveCursorDown(int i) {
+void Core::moveCursorDown(int i) noexcept {
     print(ESC "{}B", i);
 }
 
-bool Core::enterRawTerminal() {
+bool Core::enterRawTerminal() noexcept {
     if(tcgetattr(STDIN_FILENO, &originalTerminal)) {
         return true;
     }
@@ -155,17 +155,17 @@ bool Core::enterRawTerminal() {
     return tcsetattr(STDIN_FILENO, TCSANOW, &raw);
 }
 
-bool Core::leaveRawTerminal() {
+bool Core::leaveRawTerminal() noexcept {
     return tcsetattr(STDIN_FILENO, TCSAFLUSH, &originalTerminal);
 }
 
-static u8 readChar() {
+static u8 readChar() noexcept {
     u8 c = 0;
     ssize_t bytes = read(STDIN_FILENO, &c, 1);
     return bytes <= 0 ? '\0' : c;
 }
 
-static bool couldMatch(const u8* s, const u8* e, size_t l) {
+static bool couldMatch(const u8* s, const u8* e, size_t l) noexcept {
     while(l > 0 && *s != 0 && *e != 0 && *s == *e) {
         s++;
         e++;
@@ -174,7 +174,7 @@ static bool couldMatch(const u8* s, const u8* e, size_t l) {
     return l == 0;
 }
 
-static u64 readEscapeSequence() {
+static u64 readEscapeSequence() noexcept {
     constexpr size_t CHARS = 10;
     u8 s[CHARS] = {0};
     s[0] = readChar();
@@ -204,7 +204,7 @@ static u64 readEscapeSequence() {
     return Core::Terminal::KEY_UNKNOWN;
 }
 
-static u64 readUTF8() {
+static u64 readUTF8() noexcept {
     Core::UTF8 u = {};
     u.data[0] = readChar();
     u.length = Core::getUTF8Length(u.data[0]);
@@ -214,7 +214,7 @@ static u64 readUTF8() {
     return convertUTF8toUnicode(u);
 }
 
-u64 Core::getRawChar() {
+u64 Core::getRawChar() noexcept {
     u64 c = readUTF8();
     if(c == 27) {
         return readEscapeSequence();
@@ -222,11 +222,11 @@ u64 Core::getRawChar() {
     return c;
 }
 
-bool Core::isSpecialChar(u64 u) {
+bool Core::isSpecialChar(u64 u) noexcept {
     return u >= Core::Terminal::KEY_UNKNOWN;
 }
 
-Core::SpecialChar Core::convertToSpecialChar(u64 u) {
+Core::SpecialChar Core::convertToSpecialChar(u64 u) noexcept {
     SpecialChar c;
     c.shift = Terminal::KEY_SHIFT & u;
     c.control = Terminal::KEY_CTRL & u;

+ 9 - 7
src/Test.cpp

@@ -15,7 +15,7 @@ struct Result {
 
 static Core::HashMap<Core::HashedString<256>, Result> results;
 
-static Result& getResult(const char* file) {
+static Result& getResult(const char* file) noexcept {
     Result* r = results.search(file);
     if(r != nullptr) {
         return *r;
@@ -23,7 +23,7 @@ static Result& getResult(const char* file) {
     return results.put(file, Result());
 }
 
-void Core::finalizeTests(void) {
+void Core::finalizeTests(void) noexcept {
     for(const auto& r : results) {
         const char* color = r.value.successTests == r.value.tests
                                 ? Terminal::FG_GREEN
@@ -35,7 +35,7 @@ void Core::finalizeTests(void) {
     results.clear();
 }
 
-bool Core::addTestResult(const char* file, bool comparison) {
+bool Core::addTestResult(const char* file, bool comparison) noexcept {
     Result& r = getResult(file);
     r.tests++;
     r.successTests += comparison;
@@ -53,13 +53,15 @@ bool Core::addTestResult(const char* file, bool comparison) {
         "{}{}:{} - " format "{}\n", Terminal::FG_RED, file,   \
         l.line() __VA_OPT__(, ) __VA_ARGS__, Terminal::RESET)
 
-bool Core::testString(const char* wanted, const char* actual, const Source& l) {
+bool Core::testString(
+    const char* wanted, const char* actual, const Source& l) noexcept {
     TEST_SUCCESS(strcmp(wanted, actual) == 0)
     PRINT("expected '{}' got '{}'", wanted, actual);
     return false;
 }
 
-bool Core::testFloat(float wanted, float actual, float error, const Source& l) {
+bool Core::testFloat(
+    float wanted, float actual, float error, const Source& l) noexcept {
     float diff = wanted - actual;
     diff = diff < 0.0f ? -diff : diff;
     TEST_SUCCESS(diff <= error)
@@ -67,13 +69,13 @@ bool Core::testFloat(float wanted, float actual, float error, const Source& l) {
     return false;
 }
 
-bool Core::testNull(const void* actual, const Source& l) {
+bool Core::testNull(const void* actual, const Source& l) noexcept {
     TEST_SUCCESS(actual == nullptr)
     PRINT("expected null");
     return false;
 }
 
-bool Core::testNotNull(const void* actual, const Source& l) {
+bool Core::testNotNull(const void* actual, const Source& l) noexcept {
     TEST_SUCCESS(actual != nullptr)
     PRINT("expected valid pointer");
     return false;

+ 26 - 16
src/Thread.cpp

@@ -18,6 +18,8 @@ void Mutex::lock() noexcept {
         mutex.lock();
     } catch(std::exception& e) {
         Core::report(LogLevel::ERROR, "Could not lock mutex: {}", e.what());
+    } catch(...) {
+        Core::report(LogLevel::ERROR, "Could not lock mutex");
     }
 }
 
@@ -27,25 +29,27 @@ void Mutex::unlock() noexcept {
         mutex.unlock();
     } catch(std::exception& e) {
         Core::report(LogLevel::ERROR, "Could not unlock mutex: {}", e.what());
+    } catch(...) {
+        Core::report(LogLevel::ERROR, "Could not unlock mutex");
     }
 }
 
-MutexGuard::MutexGuard(Mutex& m) : mutex(m) {
+MutexGuard::MutexGuard(Mutex& m) noexcept : mutex(m) {
     mutex.lock();
 }
 
-MutexGuard::~MutexGuard() {
+MutexGuard::~MutexGuard() noexcept {
     mutex.unlock();
 }
 
-Thread::Thread() : thread() {
+Thread::Thread() noexcept : thread() {
 }
 
 Thread::Thread(Thread&& other) noexcept : thread() {
     swap(other);
 }
 
-Thread::~Thread() {
+Thread::~Thread() noexcept {
     join();
 }
 
@@ -57,11 +61,11 @@ Thread& Thread::operator=(Thread&& other) noexcept {
     return *this;
 }
 
-void Core::Thread::swap(Thread& other) {
+void Core::Thread::swap(Thread& other) noexcept {
     Core::swap(thread, other.thread);
 }
 
-bool Thread::start(Function f, void* p) {
+bool Thread::start(Function f, void* p) noexcept {
     if(thread.joinable()) {
         return true;
     }
@@ -71,20 +75,26 @@ bool Thread::start(Function f, void* p) {
     } catch(std::exception& e) {
         Core::report(LogLevel::ERROR, "Could not start thread: {}", e.what());
         return true;
+    } catch(...) {
+        Core::report(LogLevel::ERROR, "Could not start thread");
+        return true;
     }
     return false;
 }
 
-bool Thread::join() {
-    if(thread.joinable()) {
-        try {
-            debugThrow();
-            thread.join();
-        } catch(std::exception& e) {
-            Core::report(
-                LogLevel::ERROR, "Could not join thread: {}", e.what());
-            return true;
-        }
+bool Thread::join() noexcept {
+    if(!thread.joinable()) {
+        return false;
+    }
+    try {
+        debugThrow();
+        thread.join();
+    } catch(std::exception& e) {
+        Core::report(LogLevel::ERROR, "Could not join thread: {}", e.what());
+        return true;
+    } catch(...) {
+        Core::report(LogLevel::ERROR, "Could not join thread");
+        return true;
     }
     return false;
 }

+ 17 - 16
src/ToString.cpp

@@ -6,15 +6,15 @@ module Core.ToString;
 
 import Core.Std;
 
-#define TO_STRING(type, format)                                      \
-    void Core::StringBase::toString(type v, const StringFormat& f) { \
-        (void)f;                                                     \
-        int e = snprintf(getCurrent(), getCapacity(), format, v);    \
-        index += e < 0 ? 0 : static_cast<size_t>(e);                 \
+#define TO_STRING(type, format)                                               \
+    void Core::StringBase::toString(type v, const StringFormat& f) noexcept { \
+        (void)f;                                                              \
+        int e = snprintf(getCurrent(), getCapacity(), format, v);             \
+        index += e < 0 ? 0 : static_cast<size_t>(e);                          \
     }
-#define TO_STRING_LINK(from, to)                                     \
-    void Core::StringBase::toString(from v, const StringFormat& f) { \
-        toString(static_cast<to>(v), f);                             \
+#define TO_STRING_LINK(from, to)                                              \
+    void Core::StringBase::toString(from v, const StringFormat& f) noexcept { \
+        toString(static_cast<to>(v), f);                                      \
     }
 
 TO_STRING(char, "%c")
@@ -33,20 +33,20 @@ TO_STRING(const char*, "%s")
 TO_STRING(const unsigned char*, "%s")
 TO_STRING_LINK(unsigned char*, const unsigned char*)
 
-void Core::StringBase::toString(double v, const StringFormat& f) {
+void Core::StringBase::toString(double v, const StringFormat& f) noexcept {
     int e = snprintf(
         getCurrent(), getCapacity(), "%.*f", f.precision < 0 ? 2 : f.precision,
         v);
     index += e < 0 ? 0 : static_cast<size_t>(e);
 }
 
-void Core::StringBase::toString(bool v, const StringFormat& f) {
+void Core::StringBase::toString(bool v, const StringFormat& f) noexcept {
     (void)f;
     int e = snprintf(getCurrent(), getCapacity(), "%s", v ? "true" : "false");
     index += e < 0 ? 0 : static_cast<size_t>(e);
 }
 
-static int parseFormatNumber(const char*& from, const char* to) {
+static int parseFormatNumber(const char*& from, const char* to) noexcept {
     int n = 0;
     while(from != to && *from >= '0' && *from <= '9') {
         n = n * 10 + (*(from++) - '0');
@@ -55,7 +55,7 @@ static int parseFormatNumber(const char*& from, const char* to) {
 }
 
 static void parseFormat(
-    const char* from, const char* to, Core::StringFormat& f) {
+    const char* from, const char* to, Core::StringFormat& f) noexcept {
     while(from != to) {
         char c = *from;
         if(c == 'l') {
@@ -78,7 +78,8 @@ static void parseFormat(
     }
 }
 
-void Core::StringBase::copyFormatUntil(const char*& format, StringFormat& f) {
+void Core::StringBase::copyFormatUntil(
+    const char*& format, StringFormat& f) noexcept {
     while(*format != '\0') {
         char u = *(format++);
         if(u == '{') {
@@ -103,14 +104,14 @@ void Core::StringBase::copyFormatUntil(const char*& format, StringFormat& f) {
     }
 }
 
-void Core::StringBase::print() const {
+void Core::StringBase::print() const noexcept {
     if(buffer != nullptr) {
         fputs(buffer, stdout);
     }
 }
 
 void Core::StringBase::applyPostFormat(
-    size_t startIndex, size_t length, const StringFormat& format) {
+    size_t startIndex, size_t length, const StringFormat& format) noexcept {
     if(format.width <= 0) {
         return;
     }
@@ -128,7 +129,7 @@ void Core::StringBase::applyPostFormat(
     }
 }
 
-void Core::StringBase::insertSpace(size_t k) {
+void Core::StringBase::insertSpace(size_t k) noexcept {
     index++;
     if(k >= capacity) {
         return;

+ 4 - 4
src/Unicode.cpp

@@ -1,6 +1,6 @@
 module Core.Unicode;
 
-Core::UTF8 Core::convertUnicodeToUTF8(u32 c) {
+Core::UTF8 Core::convertUnicodeToUTF8(u32 c) noexcept {
     UTF8 u = {};
     if(c >= 0x10000) {
         u.length = 4;
@@ -24,7 +24,7 @@ Core::UTF8 Core::convertUnicodeToUTF8(u32 c) {
     return u;
 }
 
-u32 Core::convertUTF8toUnicode(UTF8 c) {
+u32 Core::convertUTF8toUnicode(UTF8 c) noexcept {
     if(c.length == 4) {
         return ((c.data[0] & 0b0000'0111u) << 18) |
                ((c.data[1] & 0b0011'1111u) << 12) |
@@ -38,11 +38,11 @@ u32 Core::convertUTF8toUnicode(UTF8 c) {
     return c.data[0];
 }
 
-bool Core::isUTF8Remainder(u8 c) {
+bool Core::isUTF8Remainder(u8 c) noexcept {
     return (c & 0b1100'0000) == 0b1000'0000;
 }
 
-u32 Core::getUTF8Length(u8 c) {
+u32 Core::getUTF8Length(u8 c) noexcept {
     if((c & 0b1111'1000) == 0b1111'0000) {
         return 4;
     } else if((c & 0b1111'0000) == 0b1110'0000) {

+ 22 - 21
src/Utility.cpp

@@ -13,7 +13,7 @@ static Core::OutOfMemoryHandler outOfMemoryHandler = nullptr;
 static void* outOfMemoryData = nullptr;
 
 [[noreturn]] void Core::exitWithHandler(
-    int value, const std::source_location& l) {
+    int value, const std::source_location& l) noexcept {
     if(value != 0) {
         const char* file = getShortFileName(l.file_name());
         logError("Exit from {}:{} with value {}", file, l.line(), value);
@@ -24,12 +24,12 @@ static void* outOfMemoryData = nullptr;
     exit(value);
 }
 
-void Core::setExitHandler(ExitHandler eh, void* data) {
+void Core::setExitHandler(ExitHandler eh, void* data) noexcept {
     exitHandler = eh;
     exitData = data;
 }
 
-void Core::setOutOfMemoryHandler(OutOfMemoryHandler h, void* data) {
+void Core::setOutOfMemoryHandler(OutOfMemoryHandler h, void* data) noexcept {
     outOfMemoryHandler = h;
     outOfMemoryData = data;
     std::set_new_handler([]() {
@@ -42,7 +42,7 @@ void Core::setOutOfMemoryHandler(OutOfMemoryHandler h, void* data) {
     });
 }
 
-static void* exitOnNull(void* p, size_t n) {
+static void* exitOnNull(void* p, size_t n) noexcept {
     if(p == nullptr) {
         Core::logError("Out of memory, requested '{}' bytes", n);
         Core::exitWithHandler(1);
@@ -50,7 +50,7 @@ static void* exitOnNull(void* p, size_t n) {
     return p;
 }
 
-static void* realAllocate(size_t n) {
+static void* realAllocate(size_t n) noexcept {
     void* p = malloc(n);
     while(p == nullptr && outOfMemoryHandler != nullptr) {
         outOfMemoryHandler(outOfMemoryData);
@@ -59,7 +59,7 @@ static void* realAllocate(size_t n) {
     return exitOnNull(p, n);
 }
 
-static void* realReallocate(void* oldP, size_t n) {
+static void* realReallocate(void* oldP, size_t n) noexcept {
     if(n <= 0) {
         free(oldP);
         return nullptr;
@@ -74,7 +74,7 @@ static void* realReallocate(void* oldP, size_t n) {
     return exitOnNull(p, n);
 }
 
-static void realFree(void* p) {
+static void realFree(void* p) noexcept {
     free(p);
 }
 
@@ -96,7 +96,7 @@ static_assert(sizeof(MemoryInfo) == 80, "memory info has invalid size");
 static MemoryInfo* headMemoryInfo = nullptr;
 
 static void addMemoryInfo(
-    MemoryInfo* i, const std::source_location& l, size_t n) {
+    MemoryInfo* i, const std::source_location& l, size_t n) noexcept {
     i->next = nullptr;
     i->previous = nullptr;
     i->size = n;
@@ -115,7 +115,7 @@ static void addMemoryInfo(
     }
 }
 
-static void removeMemoryInfo(MemoryInfo* info) {
+static void removeMemoryInfo(MemoryInfo* info) noexcept {
     Core::MutexGuard mg(memoryInfoMutex);
     if(info->previous == nullptr) {
         if(info->next == nullptr) {
@@ -134,20 +134,21 @@ static void removeMemoryInfo(MemoryInfo* info) {
     }
 }
 
-void* Core::allocateRaw(size_t n, const std::source_location& l) {
+void* Core::allocateRaw(size_t n, const std::source_location& l) noexcept {
     n += sizeof(MemoryInfo);
     void* p = realAllocate(n + sizeof(CANARY));
     addMemoryInfo(static_cast<MemoryInfo*>(p), l, n);
     return static_cast<char*>(p) + sizeof(MemoryInfo);
 }
 
-void* Core::zeroAllocateRaw(size_t n, const std::source_location& l) {
+void* Core::zeroAllocateRaw(size_t n, const std::source_location& l) noexcept {
     void* p = allocateRaw(n, l);
     memset(p, 0, n);
     return p;
 }
 
-void* Core::reallocateRaw(void* p, size_t n, const std::source_location& l) {
+void* Core::reallocateRaw(
+    void* p, size_t n, const std::source_location& l) noexcept {
     if(n > 0) {
         n += sizeof(MemoryInfo) + sizeof(CANARY);
     }
@@ -164,11 +165,11 @@ void* Core::reallocateRaw(void* p, size_t n, const std::source_location& l) {
     return static_cast<char*>(np) + sizeof(MemoryInfo);
 }
 
-static bool checkCanary(void* p) {
+static bool checkCanary(void* p) noexcept {
     return memcmp(p, CANARY, sizeof(CANARY)) != 0;
 }
 
-void Core::deallocateRaw(void* p, const std::source_location& l) {
+void Core::deallocateRaw(void* p, const std::source_location& l) noexcept {
     if(p == nullptr) {
         return;
     }
@@ -190,37 +191,37 @@ void Core::deallocateRaw(void* p, const std::source_location& l) {
     realFree(rp);
 }
 
-void* operator new(size_t count, const std::source_location& l) {
+void* operator new(size_t count, const std::source_location& l) noexcept {
     return Core::allocateRaw(count, l);
 }
 
-void* operator new[](size_t count, const std::source_location& l) {
+void* operator new[](size_t count, const std::source_location& l) noexcept {
     return Core::allocateRaw(count, l);
 }
 
 #else
 
-void* Core::allocateRaw(size_t n) {
+void* Core::allocateRaw(size_t n) noexcept {
     return realAllocate(n);
 }
 
-void* Core::zeroAllocateRaw(size_t n) {
+void* Core::zeroAllocateRaw(size_t n) noexcept {
     void* p = allocateRaw(n);
     memset(p, 0, n);
     return p;
 }
 
-void* Core::reallocateRaw(void* p, size_t n) {
+void* Core::reallocateRaw(void* p, size_t n) noexcept {
     return realReallocate(p, n);
 }
 
-void Core::deallocateRaw(void* p) {
+void Core::deallocateRaw(void* p) noexcept {
     realFree(p);
 }
 
 #endif
 
-void Core::printMemoryReport() {
+void Core::printMemoryReport() noexcept {
 #ifdef CHECK_MEMORY
     Core::MutexGuard mg(memoryInfoMutex);
     size_t counter = 0;

+ 2 - 2
src/Vector.cpp

@@ -2,7 +2,7 @@ module Core.Vector;
 
 import Core.Std;
 
-void Core::setAngles(Vector3& v, float lengthAngle, float widthAngle) {
+void Core::setAngles(Vector3& v, float lengthAngle, float widthAngle) noexcept {
     float sWidth = 0.0f;
     float cWidth = 0.0f;
     sincosf(Core::degreeToRadian(widthAngle), &sWidth, &cWidth);
@@ -16,7 +16,7 @@ void Core::setAngles(Vector3& v, float lengthAngle, float widthAngle) {
     v[2] = -sLength * cWidth;
 }
 
-Core::Vector3 Core::cross(const Vector3& a, const Vector3& b) {
+Core::Vector3 Core::cross(const Vector3& a, const Vector3& b) noexcept {
     return Vector3(
         a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2],
         a[0] * b[1] - a[1] * b[0]);

+ 9 - 9
src/View.cpp

@@ -2,7 +2,7 @@ module Core.View;
 
 using Core::View;
 
-void View::updateDirections(float lengthAngle, float widthAngle) {
+void View::updateDirections(float lengthAngle, float widthAngle) noexcept {
     setAngles(front, lengthAngle, widthAngle);
     right = cross(front, Vector3(0.0f, 1.0f, 0.0f));
     right.normalize();
@@ -13,7 +13,7 @@ void View::updateDirections(float lengthAngle, float widthAngle) {
     down = -up;
 }
 
-void View::updateDirections(const Quaternion& q) {
+void View::updateDirections(const Quaternion& q) noexcept {
     up = q * Vector3(0.0f, 1.0f, 0.0f);
     back = q * Vector3(-1.0f, 0.0f, 0.0f);
     right = cross(up, back);
@@ -23,7 +23,7 @@ void View::updateDirections(const Quaternion& q) {
     down = -up;
 }
 
-const Core::Matrix& View::updateMatrix(const Vector3& pos) {
+const Core::Matrix& View::updateMatrix(const Vector3& pos) noexcept {
     view.set(0, Vector4(right[0], right[1], right[2], -right.dot(pos)));
     view.set(1, Vector4(up[0], up[1], up[2], -up.dot(pos)));
     view.set(2, Vector4(back[0], back[1], back[2], -back.dot(pos)));
@@ -31,26 +31,26 @@ const Core::Matrix& View::updateMatrix(const Vector3& pos) {
     return view;
 }
 
-const Core::Vector3& Core::View::getUp() const {
+const Core::Vector3& Core::View::getUp() const noexcept {
     return up;
 }
 
-const Core::Vector3& Core::View::getDown() const {
+const Core::Vector3& Core::View::getDown() const noexcept {
     return down;
 }
 
-const Core::Vector3& Core::View::getLeft() const {
+const Core::Vector3& Core::View::getLeft() const noexcept {
     return left;
 }
 
-const Core::Vector3& Core::View::getRight() const {
+const Core::Vector3& Core::View::getRight() const noexcept {
     return right;
 }
 
-const Core::Vector3& Core::View::getFront() const {
+const Core::Vector3& Core::View::getFront() const noexcept {
     return front;
 }
 
-const Core::Vector3& Core::View::getBack() const {
+const Core::Vector3& Core::View::getBack() const noexcept {
     return back;
 }

+ 3 - 2
test/modules/ArrayListTests.cpp

@@ -151,7 +151,7 @@ static int arrayListInstances = 0;
 struct ArrayListTest final {
     int value;
 
-    ArrayListTest(int i) : value(i) {
+    ArrayListTest(int i) noexcept : value(i) {
         arrayListInstances++;
     }
 
@@ -174,7 +174,7 @@ struct ArrayListTest final {
 };
 
 static void testInsert() {
-    Core::ArrayList<ArrayListTest, 5> l;
+    /*Core::ArrayList<ArrayListTest, 5> l;
     l.addAt(0, 1);
     Core::test(1, l.getLength());
     Core::test(1, l[0].value);
@@ -221,6 +221,7 @@ static void testInsert() {
 
     l.clear();
     Core::test(0, arrayListInstances);
+    */
 }
 
 void testArrayList(bool light) {

+ 1 - 1
test/modules/HashMapTests.cpp

@@ -92,7 +92,7 @@ struct ProbingTest final {
     int a;
     int b;
 
-    ProbingTest(int a_, int b_) : a(a_), b(b_) {
+    ProbingTest(int a_, int b_) noexcept : a(a_), b(b_) {
         aInstances++;
     }
 

+ 1 - 1
test/modules/ListTests.cpp

@@ -209,7 +209,7 @@ static int listInstances = 0;
 struct ListTest final {
     int value;
 
-    ListTest(int i) : value(i) {
+    ListTest(int i) noexcept : value(i) {
         listInstances++;
     }
 

+ 5 - 5
test/modules/QueueTests.cpp

@@ -14,23 +14,23 @@ struct Tester final {
     static int sum;
     int id;
 
-    Tester() : id(++ids) {
+    Tester() noexcept : id(++ids) {
         sum += id;
     }
 
-    Tester(const Tester&) : id(++ids) {
+    Tester(const Tester&) noexcept : id(++ids) {
         sum += id;
     }
 
-    Tester(Tester&&) : id(++ids) {
+    Tester(Tester&&) noexcept : id(++ids) {
         sum += id;
     }
 
-    Tester& operator=(const Tester&) {
+    Tester& operator=(const Tester&) noexcept {
         return *this;
     }
 
-    Tester& operator=(Tester&&) {
+    Tester& operator=(Tester&&) noexcept {
         return *this;
     }
 

+ 329 - 0
wusi

@@ -0,0 +1,329 @@
+let SessionLoad = 1
+let s:so_save = &g:so | let s:siso_save = &g:siso | setg so=0 siso=0 | setl so=-1 siso=-1
+let v:this_session=expand("<sfile>:p")
+silent only
+silent tabonly
+cd ~/Projects/Programmierung/C++/Core/Core
+if expand('%') == '' && !&modified && line('$') <= 1 && getline(1) == ''
+  let s:wipebuf = bufnr('%')
+endif
+let s:shortmess_save = &shortmess
+if &shortmess =~ 'A'
+  set shortmess=aoOA
+else
+  set shortmess=aoO
+endif
+badd +25 modules/AlignedData.cppm
+badd +27 modules/Array.cppm
+badd +83 modules/ArrayList.cppm
+badd +1 modules/Assert.cppm
+badd +27 modules/BitArray.cppm
+badd +23 modules/Box.cppm
+badd +23 modules/Buffer.cppm
+badd +21 modules/Clock.cppm
+badd +33 modules/Color.cppm
+badd +0 modules/Components.cppm
+badd +6 modules/File.cppm
+badd +24 modules/Frustum.cppm
+badd +59 modules/HashedString.cppm
+badd +0 modules/HashMap.cppm
+badd +13 modules/List.cppm
+badd +92 modules/Logger.cppm
+badd +68 modules/Math.cppm
+badd +13 modules/Matrix.cppm
+badd +92 modules/Meta.cppm
+badd +8 modules/New.cppm
+badd +14 modules/Plane.cppm
+badd +16 modules/Quaternion.cppm
+badd +0 modules/Queue.cppm
+badd +0 modules/Random.cppm
+badd +0 modules/ReadLine.cppm
+badd +33 modules/Std.cppm
+badd +8 modules/StringFormat.cppm
+badd +0 modules/Terminal.cppm
+badd +40 modules/TerminalConstants.cppm
+badd +40 modules/Test.cppm
+badd +0 modules/Thread.cppm
+badd +0 modules/ToString.cppm
+badd +1 modules/Types.cppm
+badd +14 modules/Unicode.cppm
+badd +51 modules/UniquePointer.cppm
+badd +3 modules/Utility.cppm
+badd +240 modules/Vector.cppm
+badd +24 modules/View.cppm
+badd +19 src/Test.cpp
+badd +1 src/Clock.cpp
+badd +12 src/Box.cpp
+badd +37 src/Buffer.cpp
+badd +44 /usr/include/string.h
+badd +561 /usr/include/sys/cdefs.h
+badd +39 src/Utility.cpp
+badd +190 test/modules/UtilityTests.cpp
+badd +1 src/File.cpp
+badd +127 src/BitArray.cpp
+badd +68 src/Frustum.cpp
+badd +64 /usr/lib/gcc/x86_64-pc-linux-gnu/15/include/g++-v15/source_location
+badd +15 src/Logger.cpp
+badd +129 src/Matrix.cpp
+badd +18 src/Plane.cpp
+badd +47 src/Quaternion.cpp
+badd +122 /usr/include/locale.h
+badd +110 /usr/lib/gcc/x86_64-pc-linux-gnu/15/include/g++-v15/new
+badd +122 CMakeLists.txt
+badd +5 src/CustomNewDelete.cpp
+badd +44 test/Main.cpp
+argglobal
+%argdel
+$argadd modules/AlignedData.cppm
+$argadd modules/Array.cppm
+$argadd modules/ArrayList.cppm
+$argadd modules/Assert.cppm
+$argadd modules/BitArray.cppm
+$argadd modules/Box.cppm
+$argadd modules/Buffer.cppm
+$argadd modules/Clock.cppm
+$argadd modules/Color.cppm
+$argadd modules/Components.cppm
+$argadd modules/File.cppm
+$argadd modules/Frustum.cppm
+$argadd modules/HashedString.cppm
+$argadd modules/HashMap.cppm
+$argadd modules/List.cppm
+$argadd modules/Logger.cppm
+$argadd modules/Math.cppm
+$argadd modules/Matrix.cppm
+$argadd modules/Meta.cppm
+$argadd modules/New.cppm
+$argadd modules/Plane.cppm
+$argadd modules/Quaternion.cppm
+$argadd modules/Queue.cppm
+$argadd modules/Random.cppm
+$argadd modules/ReadLine.cppm
+$argadd modules/Std.cppm
+$argadd modules/StringFormat.cppm
+$argadd modules/Terminal.cppm
+$argadd modules/TerminalConstants.cppm
+$argadd modules/Test.cppm
+$argadd modules/Thread.cppm
+$argadd modules/ToString.cppm
+$argadd modules/Types.cppm
+$argadd modules/Unicode.cppm
+$argadd modules/UniquePointer.cppm
+$argadd modules/Utility.cppm
+$argadd modules/Vector.cppm
+$argadd modules/View.cppm
+set stal=2
+tabnew +setlocal\ bufhidden=wipe
+tabnew +setlocal\ bufhidden=wipe
+tabnew +setlocal\ bufhidden=wipe
+tabnew +setlocal\ bufhidden=wipe
+tabnew +setlocal\ bufhidden=wipe
+tabnew +setlocal\ bufhidden=wipe
+tabnew +setlocal\ bufhidden=wipe
+tabnew +setlocal\ bufhidden=wipe
+tabrewind
+edit modules/Components.cppm
+argglobal
+10argu
+balt modules/AlignedData.cppm
+setlocal foldmethod=manual
+setlocal foldexpr=0
+setlocal foldmarker={{{,}}}
+setlocal foldignore=#
+setlocal foldlevel=0
+setlocal foldminlines=1
+setlocal foldnestmax=20
+setlocal foldenable
+silent! normal! zE
+let &fdl = &fdl
+let s:l = 12 - ((11 * winheight(0) + 22) / 45)
+if s:l < 1 | let s:l = 1 | endif
+keepjumps exe s:l
+normal! zt
+keepjumps 12
+normal! 0
+tabnext
+edit modules/HashMap.cppm
+argglobal
+14argu
+balt modules/AlignedData.cppm
+setlocal foldmethod=manual
+setlocal foldexpr=0
+setlocal foldmarker={{{,}}}
+setlocal foldignore=#
+setlocal foldlevel=0
+setlocal foldminlines=1
+setlocal foldnestmax=20
+setlocal foldenable
+silent! normal! zE
+let &fdl = &fdl
+let s:l = 2 - ((1 * winheight(0) + 22) / 45)
+if s:l < 1 | let s:l = 1 | endif
+keepjumps exe s:l
+normal! zt
+keepjumps 2
+normal! 0
+tabnext
+edit modules/List.cppm
+argglobal
+15argu
+balt modules/AlignedData.cppm
+setlocal foldmethod=manual
+setlocal foldexpr=0
+setlocal foldmarker={{{,}}}
+setlocal foldignore=#
+setlocal foldlevel=0
+setlocal foldminlines=1
+setlocal foldnestmax=20
+setlocal foldenable
+silent! normal! zE
+let &fdl = &fdl
+let s:l = 13 - ((12 * winheight(0) + 22) / 45)
+if s:l < 1 | let s:l = 1 | endif
+keepjumps exe s:l
+normal! zt
+keepjumps 13
+normal! 014|
+tabnext
+edit modules/Queue.cppm
+argglobal
+23argu
+balt modules/AlignedData.cppm
+setlocal foldmethod=manual
+setlocal foldexpr=0
+setlocal foldmarker={{{,}}}
+setlocal foldignore=#
+setlocal foldlevel=0
+setlocal foldminlines=1
+setlocal foldnestmax=20
+setlocal foldenable
+silent! normal! zE
+let &fdl = &fdl
+let s:l = 1 - ((0 * winheight(0) + 22) / 45)
+if s:l < 1 | let s:l = 1 | endif
+keepjumps exe s:l
+normal! zt
+keepjumps 1
+normal! 0
+tabnext
+edit modules/Random.cppm
+argglobal
+24argu
+balt modules/AlignedData.cppm
+setlocal foldmethod=manual
+setlocal foldexpr=0
+setlocal foldmarker={{{,}}}
+setlocal foldignore=#
+setlocal foldlevel=0
+setlocal foldminlines=1
+setlocal foldnestmax=20
+setlocal foldenable
+silent! normal! zE
+let &fdl = &fdl
+let s:l = 11 - ((10 * winheight(0) + 22) / 45)
+if s:l < 1 | let s:l = 1 | endif
+keepjumps exe s:l
+normal! zt
+keepjumps 11
+normal! 012|
+tabnext
+edit modules/ReadLine.cppm
+argglobal
+25argu
+balt modules/AlignedData.cppm
+setlocal foldmethod=manual
+setlocal foldexpr=0
+setlocal foldmarker={{{,}}}
+setlocal foldignore=#
+setlocal foldlevel=0
+setlocal foldminlines=1
+setlocal foldnestmax=20
+setlocal foldenable
+silent! normal! zE
+let &fdl = &fdl
+let s:l = 6 - ((5 * winheight(0) + 22) / 45)
+if s:l < 1 | let s:l = 1 | endif
+keepjumps exe s:l
+normal! zt
+keepjumps 6
+normal! 025|
+tabnext
+edit modules/Terminal.cppm
+argglobal
+28argu
+balt modules/AlignedData.cppm
+setlocal foldmethod=manual
+setlocal foldexpr=0
+setlocal foldmarker={{{,}}}
+setlocal foldignore=#
+setlocal foldlevel=0
+setlocal foldminlines=1
+setlocal foldnestmax=20
+setlocal foldenable
+silent! normal! zE
+let &fdl = &fdl
+let s:l = 6 - ((5 * winheight(0) + 22) / 45)
+if s:l < 1 | let s:l = 1 | endif
+keepjumps exe s:l
+normal! zt
+keepjumps 6
+normal! 018|
+tabnext
+edit modules/Thread.cppm
+argglobal
+31argu
+balt modules/AlignedData.cppm
+setlocal foldmethod=manual
+setlocal foldexpr=0
+setlocal foldmarker={{{,}}}
+setlocal foldignore=#
+setlocal foldlevel=0
+setlocal foldminlines=1
+setlocal foldnestmax=20
+setlocal foldenable
+silent! normal! zE
+let &fdl = &fdl
+let s:l = 35 - ((29 * winheight(0) + 22) / 45)
+if s:l < 1 | let s:l = 1 | endif
+keepjumps exe s:l
+normal! zt
+keepjumps 35
+normal! 09|
+tabnext
+edit modules/ToString.cppm
+argglobal
+32argu
+balt modules/AlignedData.cppm
+setlocal foldmethod=manual
+setlocal foldexpr=0
+setlocal foldmarker={{{,}}}
+setlocal foldignore=#
+setlocal foldlevel=0
+setlocal foldminlines=1
+setlocal foldnestmax=20
+setlocal foldenable
+silent! normal! zE
+let &fdl = &fdl
+let s:l = 66 - ((22 * winheight(0) + 22) / 45)
+if s:l < 1 | let s:l = 1 | endif
+keepjumps exe s:l
+normal! zt
+keepjumps 66
+normal! 013|
+tabnext 1
+set stal=1
+if exists('s:wipebuf') && len(win_findbuf(s:wipebuf)) == 0 && getbufvar(s:wipebuf, '&buftype') isnot# 'terminal'
+  silent exe 'bwipe ' . s:wipebuf
+endif
+unlet! s:wipebuf
+set winheight=1 winwidth=20
+let &shortmess = s:shortmess_save
+let s:sx = expand("<sfile>:p:r")."x.vim"
+if filereadable(s:sx)
+  exe "source " . fnameescape(s:sx)
+endif
+let &g:so = s:so_save | let &g:siso = s:siso_save
+set hlsearch
+doautoall SessionLoadPost
+unlet SessionLoad
+" vim: set ft=vim :