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