1 | // [Blend2D] |
2 | // 2D Vector Graphics Powered by a JIT Compiler. |
3 | // |
4 | // [License] |
5 | // Zlib - See LICENSE.md file in the package. |
6 | |
7 | #ifndef BLEND2D_BLRANDOM_H |
8 | #define BLEND2D_BLRANDOM_H |
9 | |
10 | #include "./blapi.h" |
11 | |
12 | //! \addtogroup blend2d_api_globals |
13 | //! \{ |
14 | |
15 | // ============================================================================ |
16 | // [BLRandom] |
17 | // ============================================================================ |
18 | |
19 | //! Simple pseudo random number generator. |
20 | //! |
21 | //! The current implementation uses a PRNG called `XORSHIFT+`, which has 64-bit |
22 | //! seed, 128 bits of state, and full period `2^128 - 1`. |
23 | //! |
24 | //! Based on a paper by Sebastiano Vigna: |
25 | //! http://vigna.di.unimi.it/ftp/papers/xorshiftplus.pdf |
26 | struct BLRandom { |
27 | uint64_t data[2]; |
28 | |
29 | // -------------------------------------------------------------------------- |
30 | #ifdef __cplusplus |
31 | //! \name Construction & Destruction |
32 | //! \{ |
33 | |
34 | BL_INLINE BLRandom() noexcept = default; |
35 | BL_INLINE BLRandom(const BLRandom&) noexcept = default; |
36 | |
37 | BL_INLINE explicit BLRandom(uint64_t seed) noexcept { reset(seed); } |
38 | |
39 | //! \} |
40 | |
41 | //! \name Overloaded Operators |
42 | //! \{ |
43 | |
44 | BL_INLINE bool operator==(const BLRandom& other) const noexcept { return equals(other); } |
45 | BL_INLINE bool operator!=(const BLRandom& other) const noexcept { return !equals(other); } |
46 | |
47 | //! \} |
48 | |
49 | //! \name Common Functionality |
50 | //! \{ |
51 | |
52 | //! Resets the random number generator to the given `seed`. |
53 | BL_INLINE void reset(uint64_t seed = 0) noexcept { blRandomReset(this, seed); } |
54 | |
55 | //! Tests whether the random number generator is equivalent to `other`. |
56 | BL_INLINE bool equals(const BLRandom& other) const noexcept { |
57 | return blEquals(this->data[0], other.data[0]) & |
58 | blEquals(this->data[1], other.data[1]); |
59 | } |
60 | |
61 | //! \} |
62 | |
63 | //! \name Random Numbers |
64 | //! \{ |
65 | |
66 | //! Returns the next `uint64_t` value. |
67 | BL_INLINE uint64_t nextUInt64() noexcept { return blRandomNextUInt64(this); } |
68 | //! Returns the next `uint32_t` value. |
69 | BL_INLINE uint32_t nextUInt32() noexcept { return blRandomNextUInt32(this); } |
70 | //! Returns the next `double` precision floating point in [0..1) range. |
71 | BL_INLINE double nextDouble() noexcept { return blRandomNextDouble(this); } |
72 | |
73 | //! \} |
74 | #endif |
75 | // -------------------------------------------------------------------------- |
76 | }; |
77 | |
78 | //! \} |
79 | |
80 | #endif // BLEND2D_BLRANDOM_H |
81 | |