Skip to content

Commit

Permalink
Added code to take advantage of C++20 (or greater)
Browse files Browse the repository at this point in the history
With a C++20 (or greater) compiler we use:
- default comparisons;
- `[[nodiscard]]` where appropriate;
- standard `std::rotl` function

Source remains fully compatible with C++11.
  • Loading branch information
morinim committed Mar 29, 2024
1 parent 2cddc76 commit 1013ba2
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 12 deletions.
4 changes: 2 additions & 2 deletions xoshiro256ss.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace
/// to seed the xoroshiro / xoroshift1024* PRNGs (i.e. fill their initial
/// state).
///
/// \see http://dx.doi.org/10.1145/2714064.2660195
/// \see https://dx.doi.org/10.1145/2714064.2660195
///
class splitmix64
{
Expand Down Expand Up @@ -56,7 +56,7 @@ void seed_with_sm64(std::uint64_t seed, T &state)
std::generate(state.begin(), state.end(), [&sm]{ return sm.next(); });
}

} // unnamed namespace
} // namespace



Expand Down
32 changes: 22 additions & 10 deletions xoshiro256ss.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
// Original and permanent links:
// - http://xoroshiro.di.unimi.it/
// - http://xoshiro.di.unimi.it/
//
// Written in 2016-2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
//
// To the extent possible under law, the author has dedicated all copyright
Expand Down Expand Up @@ -31,6 +27,10 @@
#include <limits>
#include <random>

#if __cplusplus >= 202002L // C++20 (and later) code
# include <bit>
#endif

///
/// The main 64-bit proposal for an all-purpose, rock-solid generator is
/// xoshiro256**. It has excellent speed, a state space that is large enough
Expand All @@ -50,12 +50,16 @@
namespace vigna
{

#if __cplusplus < 202002L
// Most compilers will turn this simulated rotate operation into a single
// instruction.
constexpr std::uint64_t rotl(std::uint64_t x, int k) noexcept
{
return (x << k) | (x >> (64 - k));
}
#else
using std::rotl;
#endif

///
/// xoshiro256** v1.0, an all-purpose, rock-solid generator.
Expand All @@ -77,8 +81,7 @@ class xoshiro256ss
using result_type = std::uint64_t;

// If one doesn't specify a seed for the PRNG, it uses a default one.
explicit xoshiro256ss(result_type s = def_seed) noexcept : state()
{ seed(s); }
explicit xoshiro256ss(result_type s = def_seed) noexcept { seed(s); }

/// \return the smallest value that `operator()` may return. The value is
/// strictly less than `max()`
Expand Down Expand Up @@ -112,18 +115,23 @@ class xoshiro256ss
void seed(result_type) noexcept;
void seed(const std::array<std::uint64_t, 4> &) noexcept;

#if __cplusplus >= 202002L
[[nodiscard]] bool operator==(const xoshiro256ss &) const noexcept = default;
[[nodiscard]] bool operator!=(const xoshiro256ss &) const noexcept = default;
#else
bool operator==(const xoshiro256ss &rhs) const noexcept
{ return state == rhs.state; }
bool operator!=(const xoshiro256ss &rhs) const noexcept
{ return !(*this == rhs); }
#endif

friend std::ostream &operator<<(std::ostream &, const xoshiro256ss &);
friend std::istream &operator>>(std::istream &, xoshiro256ss &);

private:
static constexpr result_type def_seed = 0xcced1fc561884152;

std::array<std::uint64_t, 4> state;
std::array<std::uint64_t, 4> state {};
}; // class xoshiro256ss


Expand Down Expand Up @@ -151,8 +159,7 @@ class xoroshiro128p
using result_type = std::uint64_t;

// If one doesn't specify a seed for the PRNG, it uses a default one.
explicit xoroshiro128p(result_type s = def_seed) noexcept : state()
{ seed(s); }
explicit xoroshiro128p(result_type s = def_seed) noexcept { seed(s); }

/// \return the smallest value that `operator()` may return. The value is
/// strictly less than `max()`
Expand Down Expand Up @@ -181,18 +188,23 @@ class xoroshiro128p
void seed() noexcept ;
void seed(result_type) noexcept;

#if __cplusplus >= 202002L
[[nodiscard]] bool operator==(const xoroshiro128p &) const noexcept = default;
[[nodiscard]] bool operator!=(const xoroshiro128p &) const noexcept = default;
#else
bool operator==(const xoroshiro128p &rhs) const noexcept
{ return state == rhs.state; }
bool operator!=(const xoroshiro128p &rhs) const noexcept
{ return !(*this == rhs); }
#endif

friend std::ostream &operator<<(std::ostream &, const xoroshiro128p &);
friend std::istream &operator>>(std::istream &, xoroshiro128p &);

private:
static constexpr result_type def_seed = 0xcced1fc561884152;

std::array<std::uint64_t, 2> state;
std::array<std::uint64_t, 2> state {};
}; // class xoroshiro128p

} // namespace vigna
Expand Down

0 comments on commit 1013ba2

Please sign in to comment.