Skip to content

Instantly share code, notes, and snippets.

@lagner
Last active August 29, 2015 13:59
Show Gist options
  • Save lagner/40e7c3960bf4194e9c19 to your computer and use it in GitHub Desktop.
Save lagner/40e7c3960bf4194e9c19 to your computer and use it in GitHub Desktop.
#ifndef UNIQUE_H
#define UNIQUE_H
#include <stdexcept>
#include <utility>
template<class T>
class unique {
public:
unique() noexcept : buffer_{0}, instance_(nullptr) {
}
unique(T&& from) noexcept(std::is_nothrow_move_constructible<T>::value) {
instance_ = new(buffer_) T(std::forward<T>(from));
}
~unique() noexcept(std::is_nothrow_destructible<T>::value) {
if (instance_) {
instance_->T::~T();
}
}
void reset() noexcept(std::is_nothrow_destructible<T>::value) {
if (instance_) {
instance_->T::~T();
instance_=nullptr;
}
}
void reset(T&& from) noexcept(std::is_nothrow_destructible<T>::value &&
std::is_nothrow_move_constructible<T>::value) {
if (instance_) {
instance_->T::~T();
}
instance_ = new(buffer_) T(std::forward<T>(from));
}
explicit operator bool() const noexcept {
return instance_;
}
T* operator->() const {
if (!instance_)
throw std::logic_error(u8"instance should be initialized before usage");
return instance_;
}
inline T* get() const noexcept {
return instance_;
}
T& operator*() {
if (!instance_)
throw std::logic_error(u8"instance should be initialized before usage");
return *instance_;
}
private:
char buffer_[sizeof(T)];
T* instance_;
};
#endif // UNIQUE_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment