Kajetan Johannes Hammerle 2 mēneši atpakaļ
vecāks
revīzija
0c424760e3

+ 3 - 2
CMakeLists.txt

@@ -15,7 +15,7 @@ set(SRC
     "src/Matrix.cpp"
     #"src/Plane.cpp"
     "src/Quaternion.cpp"
-    #"src/Random.cpp"
+    "src/Random.cpp"
     #"src/ReadLine.cpp"
     #"src/SpinLock.cpp"
     #"src/Terminal.cpp"
@@ -42,7 +42,7 @@ set(SRC_TESTS
     #"test/modules/PlaneTests.cpp"
     "test/modules/QuaternionTests.cpp"
     #"test/modules/QueueTests.cpp"
-    #"test/modules/RandomTests.cpp"
+    "test/modules/RandomTests.cpp"
     #"test/modules/ReadLineTests.cpp"
     #"test/modules/SpinLockTests.cpp"
     #"test/modules/TerminalTests.cpp"
@@ -55,6 +55,7 @@ set(SRC_TESTS
     "test/modules/UniquePointerTests.cpp"
     "test/modules/VectorTests.cpp"
     "test/modules/MathTests.cpp"
+    "test/modules/ArrayTests.cpp"
 )
 
 set(SRC_PERFORMANCE

+ 1 - 5
include/core/Array.hpp

@@ -1,7 +1,7 @@
 #ifndef CORE_ARRAY_HPP
 #define CORE_ARRAY_HPP
 
-#include "core/utils/ArrayString.hpp"
+#include <cstddef>
 
 namespace Core {
     template<typename T, size_t N>
@@ -48,10 +48,6 @@ namespace Core {
         static constexpr size_t getLength() {
             return N;
         }
-
-        void toString(BufferString& s) const {
-            Core::toString(s, *this);
-        }
     };
 }
 

+ 19 - 10
include/core/Random.hpp

@@ -1,18 +1,27 @@
 #ifndef CORE_RANDOM_H
 #define CORE_RANDOM_H
 
+#include "core/Array.hpp"
 #include "core/Types.hpp"
 
-typedef struct {
-    u32 data[25];
-    size_t index;
-} Random;
+namespace Core {
+    class Random final {
+        Array<u32, 25> data;
+        size_t index;
 
-void initRandom(Random* r, u32 seed);
-u32 randomU32(Random* r, u32 min, u32 exclusiveMax);
-i32 randomI32(Random* r, i32 min, i32 exclusiveMax);
-size_t randomSize(Random* r, size_t min, size_t exclusiveMax);
-bool randomBool(Random* r);
-float randomFloat(Random* r);
+    public:
+        Random(u32 seed);
+
+        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();
+
+    private:
+        void update();
+    };
+}
 
 #endif

+ 0 - 79
old/Random.cpp

@@ -1,79 +0,0 @@
-#include "core/utils/Random.hpp"
-
-#include <stdio.h>
-
-constexpr static int M = 7;
-
-Core::Random::Random(Seed seed) : data(), index(0) {
-    for(size_t i = 0; i < data.getLength(); i++) {
-        data[i] = seed;
-        seed = seed * 7 + 31;
-    }
-}
-
-void Core::Random::update() {
-    static const Seed map[2] = {0, 0x8EBFD028};
-    for(size_t i = 0; i < data.getLength() - M; i++) {
-        data[i] = data[i + M] ^ (data[i] >> 1) ^ map[data[i] & 1];
-    }
-    for(size_t i = data.getLength() - M; i < data.getLength(); i++) {
-        data[i] = data[i + (M - data.getLength())] ^ (data[i] >> 1) ^
-                  map[data[i] & 1];
-    }
-    index = 0;
-}
-
-Core::Random::Seed Core::Random::next() {
-    if(index >= data.getLength()) {
-        update();
-    }
-    Seed r = data[index++];
-    r ^= (r << 7) & 0x2B5B2500;
-    r ^= (r << 15) & 0xDB8B0000;
-    r ^= (r >> 16);
-    return r;
-}
-
-template<typename T>
-T limit(T value, T min, T inclusiveMax) {
-    return min + value % (inclusiveMax - min + 1);
-}
-
-Core::Random::Seed Core::Random::next(Seed min, Seed inclusiveMax) {
-    return limit(next(), min, inclusiveMax);
-}
-
-i32 Core::Random::nextI32() {
-    return static_cast<i32>(next() >> 1);
-}
-
-i32 Core::Random::nextI32(i32 min, i32 inclusiveMax) {
-    return limit(nextI32(), min, inclusiveMax);
-}
-
-size_t Core::Random::nextSize() {
-    if constexpr(sizeof(size_t) <= sizeof(Seed)) {
-        return static_cast<size_t>(next());
-    } else {
-        return static_cast<size_t>(next()) |
-               (static_cast<size_t>(next()) >> 32);
-    }
-}
-
-size_t Core::Random::nextSize(size_t min, size_t inclusiveMax) {
-    return limit(nextSize(), min, inclusiveMax);
-}
-
-bool Core::Random::nextBool() {
-    return next() & 1;
-}
-
-float Core::Random::nextFloat() {
-    static constexpr i32 m = 0x7FFFFFFF;
-    float f = static_cast<float>(next() & m) * (1.0f / static_cast<float>(m));
-    return f >= 1.0f ? nextFloat() : f;
-}
-
-float Core::Random::nextFloat(float min, float exclusiveMax) {
-    return min + nextFloat() * (exclusiveMax - min);
-}

+ 0 - 33
old/Random.hpp

@@ -1,33 +0,0 @@
-#ifndef CORE_RANDOM_HPP
-#define CORE_RANDOM_HPP
-
-#include "core/data/Array.hpp"
-#include "core/utils/Types.hpp"
-
-namespace Core {
-    struct Random final {
-        using Seed = u32;
-
-    private:
-        Array<Seed, 25> data;
-        size_t index;
-
-    public:
-        Random(Seed seed);
-
-        Seed next();
-        Seed next(Seed min, Seed inclusiveMax);
-        i32 nextI32();
-        i32 nextI32(i32 min, i32 inclusiveMax);
-        size_t nextSize();
-        size_t nextSize(size_t min, size_t inclusiveMax);
-        bool nextBool();
-        float nextFloat();
-        float nextFloat(float min, float exclusiveMax);
-
-    private:
-        void update();
-    };
-}
-
-#endif

+ 0 - 106
old/RandomTests.cpp

@@ -1,106 +0,0 @@
-#include "../Tests.hpp"
-#include "core/data/Array.hpp"
-#include "core/utils/Random.hpp"
-
-static void testAverage(bool light) {
-    int limit = light ? 100000 : 1000000;
-    Core::Random r(553);
-    float sum = 0;
-    for(int i = 0; i < limit; i++) {
-        sum += static_cast<float>(r.next(2, 10));
-    }
-    sum /= static_cast<float>(limit);
-    CORE_TEST_FLOAT(6.0f, sum, 0.01f);
-}
-
-static void testCoin(bool light) {
-    int limit = light ? 100000 : 1000000;
-    Core::Random r(5533);
-    Core::Array<int, 2> c(0);
-    for(int i = 0; i < limit; i++) {
-        c[r.nextBool()]++;
-    }
-    CORE_TEST_FLOAT(0.0f,
-                    static_cast<float>(c[0] - c[1]) / static_cast<float>(limit),
-                    0.003f);
-}
-
-static void testDistribution(bool light) {
-    size_t limit = light ? 100000 : 1000000;
-    Core::Random r(553);
-    Core::Array<int, 102> c(0);
-    for(size_t i = 0; i < limit; i++) {
-        c[r.nextSize(1, c.getLength() - 2)]++;
-    }
-    CORE_TEST_EQUAL(0, c[0]);
-    CORE_TEST_EQUAL(0, c[c.getLength() - 1]);
-    for(size_t i = 1; i < c.getLength() - 1; i++) {
-        CORE_TEST_FLOAT(0.01f,
-                        static_cast<float>(c[i]) / static_cast<float>(limit),
-                        0.001f);
-    }
-}
-
-static void testFloatAverage(bool light) {
-    int limit = light ? 100000 : 1000000;
-    Core::Random r(553);
-    float sum = 0;
-    for(int i = 0; i < limit; i++) {
-        sum += r.nextFloat();
-    }
-    sum /= static_cast<float>(limit);
-    CORE_TEST_FLOAT(0.5f, sum, 0.001f);
-}
-
-static void testFloatCoin(bool light) {
-    int limit = light ? 100000 : 1000000;
-    Core::Random r(5534);
-    Core::Array<int, 2> c(0);
-    for(int i = 0; i < limit; i++) {
-        c[r.nextFloat() < 0.5f]++;
-    }
-    CORE_TEST_FLOAT(0.0f,
-                    static_cast<float>(c[0] - c[1]) / static_cast<float>(limit),
-                    0.003f);
-}
-
-static void testFloatDistribution(bool light) {
-    int limit = light ? 100000 : 1000000;
-    Core::Random r(553);
-    Core::Array<int, 102> c(0);
-    for(int i = 0; i < limit; i++) {
-        c[static_cast<size_t>(r.nextFloat(1.0f, c.getLength() - 1))]++;
-    }
-    CORE_TEST_EQUAL(0, c[0]);
-    CORE_TEST_EQUAL(0, c[c.getLength() - 1]);
-    for(size_t i = 1; i < c.getLength() - 1; i++) {
-        CORE_TEST_FLOAT(0.01f,
-                        static_cast<float>(c[i]) / static_cast<float>(limit),
-                        0.003f);
-    }
-}
-
-static void testRandomI32() {
-    Core::Random r(56346);
-    Core::Array<int, 7> c;
-    c.fill(0);
-    for(int i = 0; i < 10'000; i++) {
-        i32 index = r.nextI32(-2, 2) + 3;
-        if(CORE_TEST_TRUE(index >= 0)) {
-            c[static_cast<size_t>(index)]++;
-        }
-    }
-    for(size_t i = 0; i < c.getLength(); i++) {
-        CORE_TEST_EQUAL(i != 0 && i != c.getLength() - 1, c[i] > 0);
-    }
-}
-
-void Core::testRandom(bool light) {
-    testAverage(light);
-    testCoin(light);
-    testDistribution(light);
-    testFloatAverage(light);
-    testFloatCoin(light);
-    testFloatDistribution(light);
-    testRandomI32();
-}

+ 34 - 34
src/Random.cpp

@@ -1,62 +1,62 @@
 #include "core/Random.hpp"
 
-static const size_t M = 7;
+#include <cstring>
 
-void initRandom(Random* r, u32 seed) {
-    r->index = 0;
-    for(size_t i = 0; i < ARRAY_LENGTH(r->data); i++) {
-        r->data[i] = seed;
+using Core::Random;
+
+Random::Random(u32 seed) : data(), index(0) {
+    for(u32& u : data) {
+        u = seed;
         seed = seed * 7 + 31;
     }
 }
 
-static void update(Random* r) {
+void Random::update() {
+    constexpr int M = 7;
     static const u32 map[2] = {0, 0x8EBF'D028};
-    static const size_t LENGTH = ARRAY_LENGTH(r->data);
-    for(size_t i = 0; i < LENGTH - M; i++) {
-        r->data[i] = r->data[i + M] ^ (r->data[i] >> 1) ^ map[r->data[i] & 1];
+    for(size_t i = 0; i < data.getLength() - M; i++) {
+        data[i] = data[i + M] ^ (data[i] >> 1) ^ map[data[i] & 1];
     }
-    for(size_t i = LENGTH - M; i < LENGTH; i++) {
-        r->data[i] =
-            r->data[i + (M - LENGTH)] ^ (r->data[i] >> 1) ^ map[r->data[i] & 1];
+    for(size_t i = data.getLength() - M; i < data.getLength(); i++) {
+        data[i] = data[i + (M - data.getLength())] ^ (data[i] >> 1) ^
+                  map[data[i] & 1];
     }
-    r->index = 0;
+    index = 0;
 }
 
-#define LIMIT(value, min, max) (min + value % (max - min))
-
-static u32 next(Random* r) {
-    if(r->index >= ARRAY_LENGTH(r->data)) {
-        update(r);
+u32 Random::nextU32() {
+    if(index >= data.getLength()) {
+        update();
     }
-    u32 u = r->data[r->index++];
+    u32 u = data[index++];
     u ^= (u << 7) & 0x2B5B'2500;
     u ^= (u << 15) & 0xDB8B'0000;
     u ^= (u >> 16);
     return u;
 }
 
-u32 randomU32(Random* r, u32 min, u32 exclusiveMax) {
-    u32 u = next(r);
-    return LIMIT(u, min, exclusiveMax);
+template<typename T>
+T limit(T value, T min, T exclusiveMax) {
+    return min + value % (exclusiveMax - min);
+}
+
+u32 Random::nextU32(u32 min, u32 exclusiveMax) {
+    return limit(nextU32(), min, exclusiveMax);
 }
 
-i32 randomI32(Random* r, i32 min, i32 exclusiveMax) {
-    i32 i = (i32)(next(r) >> 1);
-    return LIMIT(i, min, exclusiveMax);
+i32 Random::nextI32(i32 min, i32 exclusiveMax) {
+    return limit(static_cast<i32>(nextU32() >> 1), min, exclusiveMax);
 }
 
-size_t randomSize(Random* r, size_t min, size_t exclusiveMax) {
-    size_t s = next(r);
-    return LIMIT(s, min, exclusiveMax);
+size_t Core::Random::nextSize(size_t min, size_t exclusiveMax) {
+    return limit<size_t>(nextU32(), min, exclusiveMax);
 }
 
-bool randomBool(Random* r) {
-    return next(r) & 1;
+bool Core::Random::nextBool() {
+    return nextU32() & 1;
 }
 
-float randomFloat(Random* r) {
-    u32 u = next(r);
-    float f = (float)u / (float)0xFFFFFFF;
-    return f >= 1.0f ? randomFloat(r) : f;
+float Core::Random::nextFloat() {
+    float f = static_cast<float>(nextU32()) / static_cast<float>(0xFFFF'FFFFu);
+    return f >= 1.0f ? nextFloat() : f;
 }

+ 2 - 1
test/Main.cpp

@@ -66,6 +66,7 @@ int main(int argAmount, const char** args) {
     testUniquePointer();
     testVector();
     testMath();
+    testArray();
     // testBitArray();
     // testBox();
     // testBuffer(light);
@@ -78,7 +79,7 @@ int main(int argAmount, const char** args) {
     // testPlane();
     testQuaternion();
     // testQueue();
-    // testRandom(light);
+    testRandom(light);
     if(light) {
         // testReadLine();
     }

+ 7 - 6
old/ArrayTests.cpp → test/modules/ArrayTests.cpp

@@ -1,5 +1,6 @@
 #include "../Tests.hpp"
-#include "core/data/Array.hpp"
+#include "core/Array.hpp"
+#include "core/Test.hpp"
 
 template class Core::Array<size_t, 3>;
 using TestArray = Core::Array<size_t, 3>;
@@ -9,13 +10,13 @@ static void testToString1() {
     a[0] = 1;
     a[1] = 243;
     a[2] = 423;
-    CORE_TEST_STRING("[1, 243, 423]", a);
+    TEST_STRING("[1, 243, 423]", a);
 }
 
 static void testToString2() {
     Core::Array<int, 1> a;
     a[0] = 1;
-    CORE_TEST_STRING("[1]", a);
+    TEST_STRING("[1]", a);
 }
 
 static void testReadConst() {
@@ -25,7 +26,7 @@ static void testReadConst() {
     }
     const TestArray& c = a;
     for(size_t i = 0; i < c.getLength(); i++) {
-        CORE_TEST_EQUAL(i, c[i]);
+        TEST(i, c[i]);
     }
 }
 
@@ -38,11 +39,11 @@ static void testRangeFor() {
         i++;
     }
     for(size_t i = 0; i < a.getLength(); i++) {
-        CORE_TEST_EQUAL(i + 1, a[i]);
+        TEST(i + 1, a[i]);
     }
 }
 
-void Core::testArray() {
+void testArray() {
     testToString1();
     testToString2();
     testReadConst();

+ 48 - 44
test/modules/RandomTests.cpp

@@ -1,95 +1,99 @@
-#include "../Tests.h"
-#include "core/Random.h"
+#include "../Tests.hpp"
+#include "core/Random.hpp"
+#include "core/Test.hpp"
+
+using Core::Random;
 
 static void testAverage(bool light) {
     int limit = light ? 100'000 : 1'000'000;
-    Random r;
-    initRandom(&r, 553);
+    Random r(553);
     float sum = 0;
     for(int i = 0; i < limit; i++) {
-        u32 u = randomU32(&r, 2, 11);
-        sum += (float)u;
+        sum += static_cast<float>(r.nextU32(2, 11));
     }
-    sum /= (float)limit;
+    sum /= static_cast<float>(limit);
     TEST_FLOAT(6.0f, sum, 0.01f);
 }
 
 static void testCoin(bool light) {
     int limit = light ? 100'000 : 1'000'000;
-    Random r;
-    initRandom(&r, 5533);
+    Random r(5533);
     int c[2] = {0, 0};
     for(int i = 0; i < limit; i++) {
-        c[randomBool(&r)]++;
+        c[r.nextBool()]++;
     }
-    TEST_FLOAT(0.0f, (float)(c[0] - c[1]) / (float)limit, 0.003f);
+    TEST_FLOAT(
+        0.0f, static_cast<float>(c[0] - c[1]) / static_cast<float>(limit),
+        0.003f);
 }
 
 static void testDistribution(bool light) {
     size_t limit = light ? 100'000 : 1'000'000;
-    Random r;
-    initRandom(&r, 553);
-    int c[102] = {0};
+    Random r(553);
+    Core::Array<int, 102> c(0);
     for(size_t i = 0; i < limit; i++) {
-        c[randomSize(&r, 1, 101)]++;
+        c[r.nextSize(1, c.getLength() - 1)]++;
     }
-    TEST_INT(0, c[0]);
-    TEST_INT(0, c[101]);
-    for(size_t i = 1; i < 101; i++) {
-        TEST_FLOAT(0.01f, (float)c[i] / (float)limit, 0.001f);
+    TEST(0, c[0]);
+    TEST(0, c[c.getLength() - 1]);
+    for(size_t i = 1; i < c.getLength() - 1; i++) {
+        TEST_FLOAT(
+            0.01f, static_cast<float>(c[i]) / static_cast<float>(limit),
+            0.001f);
     }
 }
 
 static void testFloatAverage(bool light) {
     int limit = light ? 100'000 : 1'000'000;
-    Random r;
-    initRandom(&r, 553);
+    Core::Random r(553);
     float sum = 0;
     for(int i = 0; i < limit; i++) {
-        sum += randomFloat(&r);
+        sum += r.nextFloat();
     }
-    sum /= (float)limit;
+    sum /= static_cast<float>(limit);
     TEST_FLOAT(0.5f, sum, 0.001f);
 }
 
 static void testFloatCoin(bool light) {
     int limit = light ? 100'000 : 1'000'000;
-    Random r;
-    initRandom(&r, 5534);
-    int c[2] = {0, 0};
+    Random r(5535);
+    Core::Array<int, 2> c(0);
     for(int i = 0; i < limit; i++) {
-        c[randomFloat(&r) < 0.5f]++;
+        c[r.nextFloat() < 0.5f]++;
     }
-    TEST_FLOAT(0.0f, (float)(c[0] - c[1]) / (float)limit, 0.003f);
+    TEST_FLOAT(
+        0.0f, static_cast<float>(c[0] - c[1]) / static_cast<float>(limit),
+        0.003f);
 }
 
 static void testFloatDistribution(bool light) {
     int limit = light ? 100'000 : 1'000'000;
-    Random r;
-    initRandom(&r, 553);
-    int c[102] = {0};
+    Random r(553);
+    Core::Array<int, 102> c(0);
     for(int i = 0; i < limit; i++) {
-        c[(size_t)(1.0f + randomFloat(&r) * 100.0f)]++;
+        c[static_cast<size_t>(1.0f + r.nextFloat() * (c.getLength() - 2))]++;
     }
-    TEST_INT(0, c[0]);
-    TEST_INT(0, c[101]);
-    for(size_t i = 1; i < 101; i++) {
-        TEST_FLOAT(0.01f, (float)c[i] / (float)limit, 0.003f);
+    TEST(0, c[0]);
+    TEST(0, c[c.getLength() - 1]);
+    for(size_t i = 1; i < c.getLength() - 1; i++) {
+        TEST_FLOAT(
+            0.01f, static_cast<float>(c[i]) / static_cast<float>(limit),
+            0.003f);
     }
 }
 
 static void testRandomI32() {
-    Random r;
-    initRandom(&r, 56'346);
-    int c[7] = {0};
+    Random r(56'346);
+    Core::Array<int, 7> c;
+    c.fill(0);
     for(int i = 0; i < 10'000; i++) {
-        i32 index = randomI32(&r, -2, 3) + 3;
-        if(TEST_TRUE(index >= 0 && index < 7)) {
-            c[index]++;
+        i32 index = r.nextI32(-2, 3) + 3;
+        if(TEST_TRUE(index >= 0)) {
+            c[static_cast<size_t>(index)]++;
         }
     }
-    for(size_t i = 0; i < 7; i++) {
-        TEST_BOOL(i != 0 && i != 6, c[i] > 0);
+    for(size_t i = 0; i < c.getLength(); i++) {
+        TEST(i != 0 && i != c.getLength() - 1, c[i] > 0);
     }
 }