]> git.localhorst.tv Git - blank.git/blobdiff - src/rand/GaloisLFSR.hpp
test for random [sic] utility methods
[blank.git] / src / rand / GaloisLFSR.hpp
index 395ff8f0546cc7b75cf111a4b996a7705052f29b..001173919c1214a6b0931e788f2130c6bdac312f 100644 (file)
@@ -12,7 +12,11 @@ class GaloisLFSR {
 public:
        // seed should be non-zero
        explicit GaloisLFSR(std::uint64_t seed) noexcept
-       : state(seed) { }
+       : state(seed) {
+               if (state == 0) {
+                       state = 1;
+               }
+       }
 
        // get the next bit
        bool operator ()() noexcept {
@@ -38,12 +42,36 @@ public:
                return out = static_cast<T>(state);
        }
 
+       /// special case for randrom(boolean), since static_cast<bool>(0b10) == true
+       bool operator ()(bool &out) noexcept {
+               return out = operator ()();
+       }
+
        template<class T>
        T Next() noexcept {
                T next;
                return (*this)(next);
        }
 
+       float SNorm() noexcept {
+               return float(Next<std::uint32_t>()) * (1.0f / 2147483647.5f) - 1.0f;
+       }
+
+       float UNorm() noexcept {
+               return float(Next<std::uint32_t>()) * (1.0f / 4294967295.0f);
+       }
+
+       template<class Container>
+       typename Container::reference From(Container &c) {
+               assert(c.size() > 0);
+               return c[Next<typename Container::size_type>() % c.size()];
+       }
+       template<class Container>
+       typename Container::const_reference From(const Container &c) {
+               assert(c.size() > 0);
+               return c[Next<typename Container::size_type>() % c.size()];
+       }
+
 private:
        std::uint64_t state;
        // bits 64, 63, 61, and 60 set to 1 (counting from 1 lo to hi)