rand: conform to the std generator concept
This commit is contained in:
parent
7746463c5a
commit
8f88569f61
20
rand/lcg.cpp
20
rand/lcg.cpp
@ -3,7 +3,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||
* Copyright 2015-2019 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#include "lcg.hpp"
|
||||
@ -50,24 +50,6 @@ lcg<T,M,A,C>::operator() (void)
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, T M, T A, T C>
|
||||
typename lcg<T,M,A,C>::result_type
|
||||
lcg<T,M,A,C>::min (void)
|
||||
{
|
||||
return std::numeric_limits<result_type>::min ();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T, T M, T A, T C>
|
||||
typename lcg<T,M,A,C>::result_type
|
||||
lcg<T,M,A,C>::max (void)
|
||||
{
|
||||
return std::numeric_limits<result_type>::max ();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, T M, T A, T C>
|
||||
void
|
||||
|
22
rand/lcg.hpp
22
rand/lcg.hpp
@ -3,14 +3,15 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||
* Copyright 2015-2019 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#ifndef __UTIL_RAND_LCG_HPP
|
||||
#define __UTIL_RAND_LCG_HPP
|
||||
#pragma once
|
||||
|
||||
#include "../std.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
#include <limits>
|
||||
|
||||
|
||||
namespace cruft::rand {
|
||||
@ -25,14 +26,13 @@ namespace cruft::rand {
|
||||
public:
|
||||
using result_type = T;
|
||||
|
||||
static_assert (std::is_unsigned<T>::value,
|
||||
"LCG generates integer overflow which is undefined behaviour for signed types");
|
||||
static_assert (std::is_unsigned_v<T>);
|
||||
explicit lcg (T seed);
|
||||
|
||||
result_type operator() (void);
|
||||
|
||||
static result_type min (void);
|
||||
static result_type max (void);
|
||||
static constexpr auto min (void) { return std::numeric_limits<T>::min (); }
|
||||
static constexpr auto max (void) { return std::numeric_limits<T>::max (); }
|
||||
|
||||
void discard (unsigned);
|
||||
|
||||
@ -40,8 +40,6 @@ namespace cruft::rand {
|
||||
T m_x;
|
||||
};
|
||||
|
||||
// glibc: typedef lcg<uint32_t, pow2(31), 1103515245, 12345> lcg_t;
|
||||
using lcg_t = lcg<uint64_t,0u,6364136223846793005ul, 1ul>;
|
||||
// glibc: typedef lcg<u64, pow2(31), 1103515245, 12345> lcg_t;
|
||||
using lcg_t = lcg<u64,0u,6364136223846793005ul, 1ul>;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -23,7 +23,7 @@ mwc64x::mwc64x (seed_type _seed):
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
mwc64x::value_type
|
||||
mwc64x::result_type
|
||||
mwc64x::operator() (void)
|
||||
{
|
||||
CHECK_NEZ (m_state);
|
||||
|
@ -3,13 +3,16 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2016 Danny Robson <danny@nerdcruft.net>
|
||||
* Copyright 2016-2019 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#ifndef __UTIL_RAND_MWC64X_HPP
|
||||
#define __UTIL_RAND_MWC64X_HPP
|
||||
#pragma once
|
||||
|
||||
#include "../std.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
|
||||
namespace cruft::rand {
|
||||
// multiply-with-carry style generator suitable for rapid seeking and
|
||||
@ -19,17 +22,17 @@ namespace cruft::rand {
|
||||
// don't allow either half of the uint64_t to be zero.
|
||||
struct mwc64x {
|
||||
public:
|
||||
using value_type = uint32_t;
|
||||
using seed_type = uint64_t;
|
||||
using result_type = u32;
|
||||
using seed_type = u64;
|
||||
|
||||
explicit mwc64x (seed_type);
|
||||
|
||||
value_type operator() (void);
|
||||
result_type operator() (void);
|
||||
|
||||
static constexpr auto max (void) noexcept { return std::numeric_limits<result_type>::max (); }
|
||||
static constexpr auto min (void) noexcept { return std::numeric_limits<result_type>::min (); }
|
||||
|
||||
private:
|
||||
uint64_t m_state;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -3,7 +3,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2015-2016 Danny Robson <danny@nerdcruft.net>
|
||||
* Copyright 2015-2019 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#include "xorshift.hpp"
|
||||
@ -63,23 +63,6 @@ xorshift<T>::operator() (void)
|
||||
|
||||
CHECK_NEZ (m_state);
|
||||
return m_state;
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
typename xorshift<T>::result_type
|
||||
xorshift<T>::min (void)
|
||||
{
|
||||
return 1u;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
typename xorshift<T>::result_type
|
||||
xorshift<T>::max (void)
|
||||
{
|
||||
return std::numeric_limits<T>::max ();
|
||||
}
|
||||
|
||||
|
||||
|
@ -3,35 +3,33 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2015-2016 Danny Robson <danny@nerdcruft.net>
|
||||
* Copyright 2015-2019 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#ifndef __UTIL_RAND_XORSHIFT_HPP
|
||||
#define __UTIL_RAND_XORSHIFT_HPP
|
||||
#pragma once
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace cruft::rand {
|
||||
// implements a naive xorshift random generator.
|
||||
//
|
||||
// * does not comply with the c++11 rng class requirements
|
||||
// * users may not rely on identical output across executions or library
|
||||
// updates. internal constants may change across releases
|
||||
template <typename T>
|
||||
template <typename ValueT>
|
||||
struct xorshift {
|
||||
public:
|
||||
using result_type = T;
|
||||
using result_type = ValueT;
|
||||
|
||||
explicit xorshift (T seed);
|
||||
explicit xorshift (ValueT seed);
|
||||
|
||||
result_type operator() (void);
|
||||
|
||||
static result_type min (void);
|
||||
static result_type max (void);
|
||||
static constexpr result_type min (void) noexcept { return 1u; }
|
||||
static constexpr auto max (void) noexcept { return std::numeric_limits<result_type>::max (); }
|
||||
|
||||
void discard (unsigned);
|
||||
|
||||
private:
|
||||
T m_state;
|
||||
ValueT m_state;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -34,15 +34,15 @@ test_buckets (cruft::TAP::logger &tap, Args&& ...args)
|
||||
{
|
||||
constexpr unsigned BUCKET_BITS = 8u;
|
||||
constexpr size_t BUCKET_COUNT = 1u << BUCKET_BITS;
|
||||
constexpr unsigned BUCKET_MASK = BUCKET_COUNT - 1u;
|
||||
constexpr unsigned EXPECTED = 1024u;
|
||||
constexpr unsigned ITERATIONS = BUCKET_COUNT * EXPECTED;
|
||||
|
||||
unsigned buckets[BUCKET_COUNT] = {};
|
||||
G gen (std::forward<Args> (args)...);
|
||||
std::uniform_int_distribution<int> dist (0, BUCKET_COUNT - 1);
|
||||
|
||||
unsigned buckets[BUCKET_COUNT] = {};
|
||||
for (unsigned i = 0; i < ITERATIONS; ++i)
|
||||
++buckets[gen () & BUCKET_MASK];
|
||||
++buckets[dist (gen)];
|
||||
|
||||
tap.expect (
|
||||
std::find_if (std::cbegin (buckets),
|
||||
|
Loading…
Reference in New Issue
Block a user