diff --git a/include/mem.h b/include/mem.h index eb20f29..2fea0bb 100644 --- a/include/mem.h +++ b/include/mem.h @@ -6,14 +6,26 @@ #include "common.h" namespace mem -{ template +{ + template + 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 > struct aligned_ptr; template<> - struct aligned_ptr; - using aligned_ptr_util = aligned_ptr; + struct aligned_ptr; + + using aligned_ptr_util = aligned_ptr; + template<> - struct aligned_ptr final + struct aligned_ptr final { + template static inline T* alloc(T&& value) { @@ -29,24 +41,26 @@ namespace mem template static inline T* make(Args&&... init) { return alloc(T(std::forward(init)...)); } - template - static inline void dealloc(T* ptr) { ptr->~T(); _dealloc(reinterpret_cast(ptr)); } + template + static inline void dealloc(T* ptr) { H::delete_object(&ptr); if(ptr) _dealloc(reinterpret_cast(ptr)); } private: static void* _alloc(usize align, usize size); static void _dealloc(void* ptr); constexpr inline ~aligned_ptr(){} }; - template + template struct aligned_ptr final { + using Handle = H; + inline explicit aligned_ptr(T* raw) : ptr(raw){} - inline aligned_ptr(aligned_ptr&& move) : ptr(move.ptr) { *const_cast(&move.ptr) = nullptr; } + inline aligned_ptr(aligned_ptr&& move) : ptr(move.ptr) { *const_cast(&move.ptr) = nullptr; } inline aligned_ptr(T&& box) : aligned_ptr(aligned_ptr_util::alloc(std::move(box))){} inline aligned_ptr() : aligned_ptr(T()){} - inline ~aligned_ptr() { if(ptr) aligned_ptr::dealloc(ptr); } + inline ~aligned_ptr() { if(ptr) aligned_ptr_util::dealloc(ptr); } inline aligned_ptr clone() const { return aligned_ptr(*this); } @@ -65,20 +79,20 @@ namespace mem inline operator const T*() const { return get_ptr(); } inline operator T*() { return get_ptr(); } - inline aligned_ptr& operator=(aligned_ptr&& other) + inline aligned_ptr& operator=(aligned_ptr&& other) { - if(ptr) aligned_ptr::dealloc(ptr); + if(ptr) aligned_ptr_util::dealloc(ptr); *const_cast(&ptr) = other.ptr; *const_cast(&other.ptr) = nullptr; return *this; } private: - inline aligned_ptr& operator=(const aligned_ptr& other) + inline aligned_ptr& operator=(const aligned_ptr& other) { return (*this = other.clone()); } - inline aligned_ptr(const aligned_ptr& copy) : ptr(aligned_ptr::make(copy.get())){} + inline aligned_ptr(const aligned_ptr& copy) : ptr(aligned_ptr_util::make(copy.get())){} T* const ptr; }; diff --git a/include/rng/crand.h b/include/rng/crand.h index 50ce02f..33f0331 100644 --- a/include/rng/crand.h +++ b/include/rng/crand.h @@ -1,5 +1,7 @@ #pragma once +#include "../common.h" + #include "../rng.h" #include "../mem.h" @@ -7,7 +9,18 @@ namespace rng { struct crand final : public Random { - + crand(); + crand(u64 seed); + + inline ~crand(){} + protected: + f64 _sample() override; private: + struct _opaque; + struct _deleter { static void delete_object(_opaque** st); }; + mem::aligned_ptr<_opaque, _deleter> _state; + + explicit crand(_opaque* raw); + i64 _sample_raw(); }; } diff --git a/src/aligned_ptr.cpp b/src/aligned_ptr.cpp index d0b010e..8179a7d 100644 --- a/src/aligned_ptr.cpp +++ b/src/aligned_ptr.cpp @@ -13,7 +13,7 @@ static inline T* not_null(T* ptr) namespace mem { - void* aligned_ptr::_alloc(usize a, usize s) { return not_null( aligned_alloc(a, s) ); } - void aligned_ptr::_dealloc(void* ptr) { free(ptr); } + void* aligned_ptr_util::_alloc(usize a, usize s) { return not_null( aligned_alloc(a, s) ); } + void aligned_ptr_util::_dealloc(void* ptr) { free(ptr); } } diff --git a/src/main.cpp b/src/main.cpp index a081a35..5713278 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,8 +13,11 @@ void r(Random& r) std::array nn = r.next>(); } +void rng_test(); + int main() { + rng_test(); return 0; } diff --git a/src/rng/crand.c b/src/rng/crand.c index 183d1b1..4540a54 100644 --- a/src/rng/crand.c +++ b/src/rng/crand.c @@ -67,6 +67,13 @@ struct jr_state* _jr_alloc() 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) { free(state); diff --git a/src/rng/crand.cpp b/src/rng/crand.cpp index d0040da..178ad9d 100644 --- a/src/rng/crand.cpp +++ b/src/rng/crand.cpp @@ -1,3 +1,7 @@ +#include + +#include + #include #include @@ -6,10 +10,21 @@ namespace rng { - //struct crand::_inner { - // - // jr_state st; - //}; - -//TODO: Make header for rng::crand, a derived type of `Random`. + void crand::_deleter::delete_object(_opaque** state) { _jr_free(reinterpret_cast(*state)); *state = nullptr; } + + crand::crand(_opaque* raw) :_state(mem::aligned_ptr<_opaque, _deleter>(raw)){} + + crand::crand(u64 seed) : crand(reinterpret_cast<_opaque*>(_jr_new(seed))){} + crand::crand() : crand(0xabad1dea){} + + i64 crand::_sample_raw() { return _jr_proc(reinterpret_cast(_state.get_ptr())); } + + //TODO: properly implemet this f64 crand::_sample() { return (f64)std::bit_cast(_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()); } diff --git a/src/rng/crand.h b/src/rng/crand.h index 18d2dc2..af70e67 100644 --- a/src/rng/crand.h +++ b/src/rng/crand.h @@ -18,6 +18,8 @@ long _jr_proc(struct jr_state* restrict state); struct jr_state* _jr_alloc(); void _jr_free(struct jr_state* restrict state); +struct jr_state* _jr_new(unsigned long with); + #ifdef __cplusplus } #endif