HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
xorshift128p.hpp
1// Copyright Take Vos 2021.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "seed.hpp"
8#include "../rapid/numeric_array.hpp"
9#include "../required.hpp"
10#include <random>
11
12namespace hi::inline v1 {
13
17public:
18 constexpr xorshift128p(xorshift128p const &) noexcept = default;
19 constexpr xorshift128p(xorshift128p &&) noexcept = default;
20 constexpr xorshift128p &operator=(xorshift128p const &) noexcept = default;
21 constexpr xorshift128p &operator=(xorshift128p &&) noexcept = default;
22
23 [[nodiscard]] constexpr explicit xorshift128p(u64x2 new_state) noexcept : _state(new_state) {}
24
25 [[nodiscard]] xorshift128p() noexcept : _state{}
26 {
27 while (_state.x() == 0 or _state.y() == 0) {
28 _state = seed<u64x2>{}();
29 }
30 }
31
32 template<typename T>
33 [[nodiscard]] T next() noexcept;
34
37 template<>
38 [[nodiscard]] uint64_t next() noexcept
39 {
40 auto s = _state[0];
41 hilet t = _state[1];
42
43 s ^= s << 23; // a
44 s ^= s >> 17; // b
45 s ^= t ^ (t >> 26); // c
46
47 _state[0] = t;
48 _state[1] = s;
49 return s + t;
50 }
51
57 template<>
58 u64x2 next() noexcept
59 {
60 // scalar: uint64_t x = _state[0];
61 // scalar: uint64_t y = y_ = _state[1];
62 auto s = _state;
63 auto t = s.yx();
64
65 // scalar: x ^= x << 23;
66 // scalar: y ^= y << 23;
67 s ^= (s << 23);
68
69 // scalar: x ^= x >> 17;
70 // scalar: y ^= y >> 17;
71 s ^= (s >> 17);
72
73 // scalar: x ^= y_ ^ (y_ >> 26)
74 hilet tmp = s ^ t ^ (t >> 26);
75
76 // scalar: auto x_ = x;
77 // scalar: t.y() = tmp.x();
78 t = insert<0, 1>(t, tmp);
79
80 // scalar: y ^= x_ ^ (x_ >> 26);
81 s ^= t ^ (t >> 26);
82
83 // scalar: state[0] = x
84 // scalar: state[1] = y
85 _state = s;
86
87 // scalar: return {x + y_, y + x_}
88 return s + t;
89 }
90
91 template<>
92 [[nodiscard]] u32x4 next() noexcept
93 {
94 return bit_cast<u32x4>(next<u64x2>());
95 }
96
97 template<>
98 [[nodiscard]] i32x4 next() noexcept
99 {
100 return bit_cast<i32x4>(next<u64x2>());
101 }
102
103 template<>
104 [[nodiscard]] i16x8 next() noexcept
105 {
106 return bit_cast<i16x8>(next<u64x2>());
107 }
108
109private:
110 u64x2 _state;
111};
112
113} // namespace hi::inline v1
Cryptographically secure entropy.
This file includes required definitions.
#define hilet
Invariant should be the default for variables.
Definition required.hpp:23
Randomly generate an object.
Definition seed.hpp:35
xorshift128+
Definition xorshift128p.hpp:16
uint64_t next() noexcept
Get the next 64 bit of random value.
Definition xorshift128p.hpp:38
u64x2 next() noexcept
Get next 128 bit of random value.
Definition xorshift128p.hpp:58
T next(T... args)