Fortune for rngxx's current commit: Small blessing − 小吉iter
parent
3ff3db0e3e
commit
e0518f2115
@ -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;
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in new issue