crand: raw sample ok

Fortune for cpprng's current commit: Middle blessing − 中吉
lib
Avril 3 years ago
parent ea4538231e
commit c8622410d8
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -6,14 +6,26 @@
#include "common.h" #include "common.h"
namespace mem namespace mem
{ template<typename T> {
template<typename T>
struct aligned_ptr_handle
{
constexpr inline aligned_ptr_handle(){};
constexpr inline ~aligned_ptr_handle(){};
constexpr static inline void delete_object(T** ptr) { (*ptr)->~T(); }
};
template<typename T, typename H = aligned_ptr_handle<T > >
struct aligned_ptr; struct aligned_ptr;
template<> template<>
struct aligned_ptr<void>; struct aligned_ptr<void, void>;
using aligned_ptr_util = aligned_ptr<void>;
using aligned_ptr_util = aligned_ptr<void, void>;
template<> template<>
struct aligned_ptr<void> final struct aligned_ptr<void, void> final
{ {
template<typename T> template<typename T>
static inline T* alloc(T&& value) static inline T* alloc(T&& value)
{ {
@ -29,24 +41,26 @@ namespace mem
template<typename T, typename... Args> template<typename T, typename... Args>
static inline T* make(Args&&... init) { return alloc(T(std::forward<Args>(init)...)); } static inline T* make(Args&&... init) { return alloc(T(std::forward<Args>(init)...)); }
template<typename T> template<typename T, typename H>
static inline void dealloc(T* ptr) { ptr->~T(); _dealloc(reinterpret_cast<void*>(ptr)); } static inline void dealloc(T* ptr) { H::delete_object(&ptr); if(ptr) _dealloc(reinterpret_cast<void*>(ptr)); }
private: private:
static void* _alloc(usize align, usize size); static void* _alloc(usize align, usize size);
static void _dealloc(void* ptr); static void _dealloc(void* ptr);
constexpr inline ~aligned_ptr(){} constexpr inline ~aligned_ptr(){}
}; };
template<typename T> template<typename T, typename H>
struct aligned_ptr final struct aligned_ptr final
{ {
using Handle = H;
inline explicit aligned_ptr(T* raw) : ptr(raw){} inline explicit aligned_ptr(T* raw) : ptr(raw){}
inline aligned_ptr(aligned_ptr<T>&& move) : ptr(move.ptr) { *const_cast<T**>(&move.ptr) = nullptr; } inline aligned_ptr(aligned_ptr<T, H>&& move) : ptr(move.ptr) { *const_cast<T**>(&move.ptr) = nullptr; }
inline aligned_ptr(T&& box) : aligned_ptr(aligned_ptr_util::alloc(std::move(box))){} inline aligned_ptr(T&& box) : aligned_ptr(aligned_ptr_util::alloc(std::move(box))){}
inline aligned_ptr() : aligned_ptr(T()){} inline aligned_ptr() : aligned_ptr(T()){}
inline ~aligned_ptr() { if(ptr) aligned_ptr<void>::dealloc<T>(ptr); } inline ~aligned_ptr() { if(ptr) aligned_ptr_util::dealloc<T, Handle>(ptr); }
inline aligned_ptr<T> clone() const { return aligned_ptr(*this); } inline aligned_ptr<T> clone() const { return aligned_ptr(*this); }
@ -65,20 +79,20 @@ namespace mem
inline operator const T*() const { return get_ptr(); } inline operator const T*() const { return get_ptr(); }
inline operator T*() { return get_ptr(); } inline operator T*() { return get_ptr(); }
inline aligned_ptr<T>& operator=(aligned_ptr<T>&& other) inline aligned_ptr<T>& operator=(aligned_ptr<T, H>&& other)
{ {
if(ptr) aligned_ptr<void>::dealloc<T>(ptr); if(ptr) aligned_ptr_util::dealloc<T, H>(ptr);
*const_cast<T**>(&ptr) = other.ptr; *const_cast<T**>(&ptr) = other.ptr;
*const_cast<T**>(&other.ptr) = nullptr; *const_cast<T**>(&other.ptr) = nullptr;
return *this; return *this;
} }
private: private:
inline aligned_ptr<T>& operator=(const aligned_ptr<T>& other) inline aligned_ptr<T>& operator=(const aligned_ptr<T, H>& other)
{ {
return (*this = other.clone()); return (*this = other.clone());
} }
inline aligned_ptr(const aligned_ptr<T>& copy) : ptr(aligned_ptr<void>::make<T>(copy.get())){} inline aligned_ptr(const aligned_ptr<T, H>& copy) : ptr(aligned_ptr_util::make<T>(copy.get())){}
T* const ptr; T* const ptr;
}; };

@ -1,5 +1,7 @@
#pragma once #pragma once
#include "../common.h"
#include "../rng.h" #include "../rng.h"
#include "../mem.h" #include "../mem.h"
@ -7,7 +9,18 @@ namespace rng
{ {
struct crand final : public Random struct crand final : public Random
{ {
crand();
crand(u64 seed);
inline ~crand(){}
protected:
f64 _sample() override;
private: private:
struct _opaque;
struct _deleter { static void delete_object(_opaque** st); };
mem::aligned_ptr<_opaque, _deleter> _state;
explicit crand(_opaque* raw);
i64 _sample_raw();
}; };
} }

@ -13,7 +13,7 @@ static inline T* not_null(T* ptr)
namespace mem namespace mem
{ {
void* aligned_ptr<void >::_alloc(usize a, usize s) { return not_null<void>( aligned_alloc(a, s) ); } void* aligned_ptr_util::_alloc(usize a, usize s) { return not_null<void>( aligned_alloc(a, s) ); }
void aligned_ptr<void >::_dealloc(void* ptr) { free(ptr); } void aligned_ptr_util::_dealloc(void* ptr) { free(ptr); }
} }

@ -13,8 +13,11 @@ void r(Random& r)
std::array<char, 10> nn = r.next<std::array<char, 10>>(); std::array<char, 10> nn = r.next<std::array<char, 10>>();
} }
void rng_test();
int main() int main()
{ {
rng_test();
return 0; return 0;
} }

@ -67,6 +67,13 @@ struct jr_state* _jr_alloc()
return bx; return bx;
} }
struct jr_state* _jr_new(unsigned long with)
{
struct jr_state* state = _jr_alloc();
_jr_seed(state, with);
return state;
}
void _jr_free(struct jr_state* restrict state) void _jr_free(struct jr_state* restrict state)
{ {
free(state); free(state);

@ -1,3 +1,7 @@
#include <bit>
#include <climits>
#include <rng.h> #include <rng.h>
#include <mem.h> #include <mem.h>
@ -6,10 +10,21 @@
namespace rng namespace rng
{ {
//struct crand::_inner { void crand::_deleter::delete_object(_opaque** state) { _jr_free(reinterpret_cast<jr_state*>(*state)); *state = nullptr; }
//
// jr_state st; crand::crand(_opaque* raw) :_state(mem::aligned_ptr<_opaque, _deleter>(raw)){}
//};
crand::crand(u64 seed) : crand(reinterpret_cast<_opaque*>(_jr_new(seed))){}
//TODO: Make header for rng::crand, a derived type of `Random`. crand::crand() : crand(0xabad1dea){}
i64 crand::_sample_raw() { return _jr_proc(reinterpret_cast<jr_state*>(_state.get_ptr())); }
//TODO: properly implemet this f64 crand::_sample() { return (f64)std::bit_cast<u64>(_sample_raw()) / (f64)UINT64_MAX; }
}
void rng_test()
{
rng::crand r(123);
printf("%lu %lu %lu\n", r.next_u64(), r.next_u64(), r.next_u64());
} }

@ -18,6 +18,8 @@ long _jr_proc(struct jr_state* restrict state);
struct jr_state* _jr_alloc(); struct jr_state* _jr_alloc();
void _jr_free(struct jr_state* restrict state); void _jr_free(struct jr_state* restrict state);
struct jr_state* _jr_new(unsigned long with);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

Loading…
Cancel
Save