#pragma once #include "glacier/memory/move.h" namespace glcr { template class Optional { public: Optional() : empty_(nullptr), has_value_(false) {} Optional(const T& value) : value_(value), has_value_(true) {} Optional(T&& value) : value_(Move(value)), has_value_(true) {} Optional(const Optional&) = default; Optional(Optional&&) = default; ~Optional() { if (has_value_) { value_.~T(); } } bool empty() const { return !has_value_; } explicit operator bool() { return has_value_; } const T& value() const { return value_; } T&& release_value() { has_value_ = false; return Move(value_); } T* operator->() { return &value_; } T& operator*() { return value_; } private: union { T value_; void* empty_; }; bool has_value_; }; } // namespace glcr