diff --git a/Makefile b/Makefile index bbdf4d1..be77b62 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ LDFLAGS += STRIP=strip -RELEASE_COMMON_FLAGS+= -Werror +RELEASE_COMMON_FLAGS+= # -Werror DEBUG_COMMON_FLAGS+= -fanalyzer ifneq ($(TARGET_SPEC_FLAGS),no) diff --git a/include/mem.h b/include/mem.h new file mode 100644 index 0000000..eb20f29 --- /dev/null +++ b/include/mem.h @@ -0,0 +1,87 @@ +#pragma once + +#include +#include + +#include "common.h" + +namespace mem +{ template + struct aligned_ptr; + template<> + struct aligned_ptr; + using aligned_ptr_util = aligned_ptr; + template<> + struct aligned_ptr final + { + template + static inline T* alloc(T&& value) + { + u8* ptr = reinterpret_cast(_alloc(alignof(T), sizeof(T))); + new(ptr) T(std::move(value)); + return reinterpret_cast(ptr); + } + template + static inline T* alloc() + { + return alloc(T()); + } + 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)); } + private: + static void* _alloc(usize align, usize size); + static void _dealloc(void* ptr); + constexpr inline ~aligned_ptr(){} + }; + template + struct aligned_ptr final + { + 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(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 clone() const { return aligned_ptr(*this); } + + inline const T & get() const { if(ptr) return *ptr; else throw "TODO: moved"; } + inline T & get() { if(ptr) return *ptr; else throw "TODO: moved"; } + + inline const T * get_ptr() const { if(ptr) return ptr; else throw "TODO: moved"; } + inline T * get_ptr() { if(ptr) return ptr; else throw "TODO: moved"; } + + inline const T * operator->() const { return get_ptr(); } + inline T * operator->() { return get_ptr(); } + + inline const T & operator*() const { return get(); } + inline T & operator*() { return get(); } + + inline operator const T*() const { return get_ptr(); } + inline operator T*() { return get_ptr(); } + + inline aligned_ptr& operator=(aligned_ptr&& other) + { + if(ptr) aligned_ptr::dealloc(ptr); + *const_cast(&ptr) = other.ptr; + *const_cast(&other.ptr) = nullptr; + + return *this; + } + private: + 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())){} + T* const ptr; + }; + + template + inline aligned_ptr make_aligned(Args&&... init) { return aligned_ptr(aligned_ptr_util::template make(std::forward(init)...)); } +} diff --git a/src/aligned_ptr.cpp b/src/aligned_ptr.cpp new file mode 100644 index 0000000..436dc6b --- /dev/null +++ b/src/aligned_ptr.cpp @@ -0,0 +1,26 @@ +#include + +#include + +#include + +template +static inline T* not_null(T* ptr) +{ + if(!ptr) throw "TODO: Nullptr except"; + return 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 test() +{ + auto ptr = mem::make_aligned("hello"); + auto len = ptr->size(); + + printf("Stirng: %s, %lu\n", ptr->c_str(), (usize)len); +} diff --git a/src/main.cpp b/src/main.cpp index 6026bc0..a2d9974 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,8 +12,11 @@ void r(Random& r) std::array nn = r.next>(); } +void test(); + int main() { + test(); return 0; } diff --git a/src/rng/crand.c b/src/rng/crand.c index 164b94d..f76a31a 100644 --- a/src/rng/crand.c +++ b/src/rng/crand.c @@ -9,13 +9,17 @@ struct jr_state struct drand48_data data; union { unsigned short xsubi[3]; - unsigned int xsubh; + struct { + unsigned int xsubh : 24; + unsigned char _xsub : 8; + }; + unsigned int xsubl; } st; }; void _jr_seed(struct jr_state* restrict state, unsigned int with) { - state->st.xsubh = with & JR_MAX; + state->st.xsubh = with; seed48_r(state->st.xsubi, &state->data); }