diff --git a/include/rngxx/internal/iter.h b/include/rngxx/internal/iter.h new file mode 100644 index 0000000..1fec7fe --- /dev/null +++ b/include/rngxx/internal/iter.h @@ -0,0 +1,62 @@ +#pragma once + +#include +#include + +namespace rng::util +{ + + template + struct uninit final + { + inline static T* align_buffer(unsigned char* buffer) { return reinterpret_cast(buffer + alignof(T) - reinterpret_cast(buffer) % alignof(T)); } + inline static const T* align_buffer(const unsigned char* buffer) { return reinterpret_cast(buffer + alignof(T) - reinterpret_cast(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 move(uninit&& m) { return uninit(std::move(m)); } + inline static uninit copy(const uninit& c) { return uninit(c); } + inline uninit bitwise_copy() const { + uninit u; + u.a_data = a_data; + return u; + } + private: + inline uninit(const uninit& copy) : uninit(T(*copy.ptr())){} + inline uninit(uninit&& move) : uninit(std::move(*move.ptr())){} + std::array a_data; + }; + template + struct generic_iterator + { + inline T try_next() + { + uninit v; + if(next(v)) { return v.take(); } + else throw "c++ sucks"; //XXX: eh... this is too draining + } + protected: + virtual bool next(uninit& output) = 0; + }; +} diff --git a/src/iter.cpp b/src/iter.cpp index 65d5824..81dec7f 100644 --- a/src/iter.cpp +++ b/src/iter.cpp @@ -1,4 +1,11 @@ #include +#include + +void d(rng::util::generic_iterator& i) +{ + i.try_next(); + +} //XXX: Doing this is not going to work ... #if 0