Skip to content

Instantly share code, notes, and snippets.

Created June 1, 2016 03:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/6d5e58c6e5fa1d821e7adf1c13733312 to your computer and use it in GitHub Desktop.
Save anonymous/6d5e58c6e5fa1d821e7adf1c13733312 to your computer and use it in GitHub Desktop.
#include <type_traits>
#if defined(_MSC_VER) && _MSC_VER <= 1800
#define WEBUI_ALIGNOF __alignof // VC++ 2013 doesn't support alignof
#else
#define WEBUI_ALIGNOF alignof
#endif
template<typename T>
struct StackObject {
StackObject() = default;
~StackObject() {
clean();
}
template<typename... Args>
void init(Args&&... args) {
ensureDestroyed();
new (&buffer_) T(std::forward<Args>(args)...);
initialized_ = true;
}
void destroy() {
get()->T::~T();
initialized_ = false;
}
StackObject(const StackObject&) = delete;
void operator=(const StackObject&) = delete;
StackObject(StackObject&& object) {
take(std::move(object));
}
void operator=(StackObject&& object) {
clean();
take(std::move(object));
}
bool initialized() const {
return initialized_;
}
T* get() {
ensureInitialized();
return reinterpret_cast<T*>(&buffer_);
}
const T* get() const {
ensureInitialized();
return reinterpret_cast<const T*>(&buffer_);
}
T& operator*() {
return *get();
}
const T& operator*() const {
return *get();
}
T* operator->() {
return get();
}
const T* operator->() const {
return get();
}
private:
void ensureInitialized() const {
if (!initialized_) {
throw std::logic_error("Object is not initialized_");
}
}
void ensureDestroyed() const {
if (initialized_) {
throw std::logic_error("Object is already initialized_.");
}
}
void clean() {
if (initialized_) {
destroy();
}
}
void take(StackObject&& object) {
if (object.initialized_) {
init(std::move(*object));
object.destroy();
}
}
typename std::aligned_storage<sizeof(T), WEBUI_ALIGNOF(T)>::type buffer_;
bool initialized_ = false;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment