Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
Avril | e0518f2115 | 3 years ago |
@ -1,14 +0,0 @@
|
|||||||
#ifndef _RNGXX_DCTOR_HACK_H
|
|
||||||
#define _RNGXX_DCTOR_HACK_H
|
|
||||||
|
|
||||||
#include <rngxx.hpp>
|
|
||||||
#include <rngxx/crand.h>
|
|
||||||
#include <rngxx/sm64.h>
|
|
||||||
|
|
||||||
#include <init.hpp>
|
|
||||||
// For some reason, dctors defined in some files do not work??!
|
|
||||||
|
|
||||||
RNGXX_APPLY_CTOR(rng, sm64, u64);
|
|
||||||
RNGXX_APPLY_CTOR(rng, crand, u64);
|
|
||||||
|
|
||||||
#endif /* _RNGXX_DCTOR_HACK_H */
|
|
@ -0,0 +1,62 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace rng::util
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct uninit final
|
||||||
|
{
|
||||||
|
inline static T* align_buffer(unsigned char* buffer) { return reinterpret_cast<T*>(buffer + alignof(T) - reinterpret_cast<intptr_t>(buffer) % alignof(T)); }
|
||||||
|
inline static const T* align_buffer(const unsigned char* buffer) { return reinterpret_cast<const T*>(buffer + alignof(T) - reinterpret_cast<intptr_t>(buffer) % alignof(T)); }
|
||||||
|
|
||||||
|
inline T* ptr() { return align_buffer(&a_data[0]); }
|
||||||
|
inline const T* ptr() const { return align_buffer(&a_data[0]); }
|
||||||
|
|
||||||
|
inline unsigned char* bytes() { return &a_data[0]; }
|
||||||
|
inline const unsigned char* bytes() const { return &a_data[0]; }
|
||||||
|
|
||||||
|
inline uninit(T&& value) { give(std::move(value)); }
|
||||||
|
inline uninit(){}
|
||||||
|
|
||||||
|
inline void drop() { ptr()->~T(); }
|
||||||
|
|
||||||
|
inline T&& take() { return std::move(*ptr()); }
|
||||||
|
inline void give(T&& value) { new (ptr()) T(std::move(value)); }
|
||||||
|
|
||||||
|
inline T& operator=(T&& value) { give(std::move(value)); return *ptr(); }
|
||||||
|
|
||||||
|
inline T replace(T&& value) {
|
||||||
|
auto x = take();
|
||||||
|
drop();
|
||||||
|
give(std::move(value));
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static uninit<T> move(uninit<T>&& m) { return uninit<T>(std::move(m)); }
|
||||||
|
inline static uninit<T> copy(const uninit<T>& c) { return uninit<T>(c); }
|
||||||
|
inline uninit<T> bitwise_copy() const {
|
||||||
|
uninit u;
|
||||||
|
u.a_data = a_data;
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
inline uninit(const uninit<T>& copy) : uninit(T(*copy.ptr())){}
|
||||||
|
inline uninit(uninit<T>&& move) : uninit(std::move(*move.ptr())){}
|
||||||
|
std::array<unsigned char, sizeof(T)+alignof(T)> a_data;
|
||||||
|
};
|
||||||
|
template<typename T>
|
||||||
|
struct generic_iterator
|
||||||
|
{
|
||||||
|
inline T try_next()
|
||||||
|
{
|
||||||
|
uninit<T> v;
|
||||||
|
if(next(v)) { return v.take(); }
|
||||||
|
else throw "c++ sucks"; //XXX: eh... this is too draining
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
virtual bool next(uninit<T>& output) = 0;
|
||||||
|
};
|
||||||
|
}
|
@ -1,37 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
namespace rng
|
|
||||||
{
|
|
||||||
template<typename T>
|
|
||||||
struct seed_gen
|
|
||||||
{
|
|
||||||
virtual T generate_seed() = 0;
|
|
||||||
|
|
||||||
inline virtual ~seed_gen(){}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace seed
|
|
||||||
{
|
|
||||||
struct splitmix64 : public virtual seed_gen<u64>
|
|
||||||
{
|
|
||||||
inline splitmix64(const splitmix64&) = default;
|
|
||||||
explicit inline splitmix64(seed_gen<u64>& from) : m_state(from.generate_seed()){}
|
|
||||||
splitmix64(u64 i);
|
|
||||||
|
|
||||||
u64 generate_seed() override;
|
|
||||||
f64 generate_f64();
|
|
||||||
|
|
||||||
inline virtual ~splitmix64() override{}
|
|
||||||
|
|
||||||
static u64 oneshot(u64& state);
|
|
||||||
inline static u64 oneshot(const u64& state) { u64 s = state; return oneshot(s); }
|
|
||||||
static f64 oneshotf(u64& state);
|
|
||||||
inline static f64 oneshotf(const u64& state) { u64 s = state; return oneshotf(s); }
|
|
||||||
static splitmix64 random();
|
|
||||||
private:
|
|
||||||
u64 m_state;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <rngxx.hpp>
|
|
||||||
|
|
||||||
#include "internal/seed.h"
|
|
||||||
|
|
||||||
namespace rng
|
|
||||||
{
|
|
||||||
struct sm64 final : public Random
|
|
||||||
{
|
|
||||||
inline sm64() : m_generator(seed::splitmix64::random()){}
|
|
||||||
inline sm64(const seed::splitmix64& g) : m_generator(g){}
|
|
||||||
explicit inline sm64(seed_gen<u64>& generator) : m_generator(generator){}
|
|
||||||
inline sm64(u64 seed) : Random(), m_generator(seed){}
|
|
||||||
|
|
||||||
RNG_OVERRIDE(inline u64, next_u64, ()) { return m_generator.generate_seed(); }
|
|
||||||
protected:
|
|
||||||
inline f64 _sample() override { return m_generator.generate_f64(); }
|
|
||||||
private:
|
|
||||||
seed::splitmix64 m_generator;
|
|
||||||
};
|
|
||||||
}
|
|
@ -0,0 +1,17 @@
|
|||||||
|
#include <rngxx.hpp>
|
||||||
|
#include <iter.h>
|
||||||
|
|
||||||
|
void d(rng::util::generic_iterator<int>& i)
|
||||||
|
{
|
||||||
|
i.try_next();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//XXX: Doing this is not going to work ...
|
||||||
|
#if 0
|
||||||
|
void t(Random& r)
|
||||||
|
{
|
||||||
|
for(auto&& i : r.iter<int>()) (void)i;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -1,14 +0,0 @@
|
|||||||
#include <bit>
|
|
||||||
|
|
||||||
#include <climits>
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include <rngxx.hpp>
|
|
||||||
#include <mem.h>
|
|
||||||
#include <init.hpp>
|
|
||||||
|
|
||||||
#include <rngxx/crand.h>
|
|
||||||
#include <rngxx/sm64.h>
|
|
||||||
#include "crand.h"
|
|
||||||
|
|
||||||
//TODO: Why does dynctors defined in this TU not function properly? Is it because there's nothing else in here?
|
|
@ -1,31 +0,0 @@
|
|||||||
#include <cmath>
|
|
||||||
#include <ctime>
|
|
||||||
|
|
||||||
#include <seed.h>
|
|
||||||
|
|
||||||
#include <common.h>
|
|
||||||
|
|
||||||
static u64 _sm64_next(u64& x)
|
|
||||||
{
|
|
||||||
u64 z = (x += 0x9e3779b97f4a7c15);
|
|
||||||
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
|
|
||||||
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
|
|
||||||
return z ^ (z >> 31);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace rng::seed
|
|
||||||
{
|
|
||||||
splitmix64::splitmix64(u64 u) : m_state(u){}
|
|
||||||
|
|
||||||
u64 splitmix64::generate_seed() { return _sm64_next(m_state); }
|
|
||||||
f64 splitmix64::generate_f64() { return generate_seed() / pow(2.0, 64); }
|
|
||||||
|
|
||||||
u64 splitmix64::oneshot(u64& state) { return _sm64_next(state); }
|
|
||||||
f64 splitmix64::oneshotf(u64& state) { return _sm64_next(state) / pow(2.0, 64); }
|
|
||||||
|
|
||||||
splitmix64 splitmix64::random()
|
|
||||||
{
|
|
||||||
splitmix64 r (oneshot(time(NULL)));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in new issue