From cce2f3e19ab8890cbb0857711acb58547ad55e42 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Sun, 11 Jun 2023 21:00:25 +0300 Subject: [PATCH] BAN: Add basic Optional --- BAN/include/BAN/Optional.h | 119 +++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 BAN/include/BAN/Optional.h diff --git a/BAN/include/BAN/Optional.h b/BAN/include/BAN/Optional.h new file mode 100644 index 0000000000..c3304491f6 --- /dev/null +++ b/BAN/include/BAN/Optional.h @@ -0,0 +1,119 @@ +#pragma once + +#include +#include + +#include + +namespace BAN +{ + + template + class Optional + { + public: + Optional(); + Optional(const T&); + Optional(T&&); + ~Optional(); + + Optional& operator=(const Optional&); + Optional& operator=(Optional&&); + + bool has_value() const; + + T&& release_value(); + const T& value() const; + T& value(); + + void clear(); + + private: + alignas(T) uint8_t m_storage[sizeof(T)]; + bool m_has_value { false }; + }; + + template + Optional::Optional() + : m_has_value(false) + {} + + template + Optional::Optional(const T& value) + : m_has_value(true) + { + new (m_storage) T(value); + } + + template + Optional::Optional(T&& value) + : m_has_value(true) + { + new (m_storage) T(BAN::move(value)); + } + + template + Optional::~Optional() + { + clear(); + } + + template + Optional& Optional::operator=(const Optional& other) + { + clear(); + if (other.has_value()) + { + m_has_value = true; + new (m_storage) T(other.value()); + } + } + + template + Optional& Optional::operator=(Optional&& other) + { + clear(); + if (other.has_value) + { + m_has_value = true; + new (m_storage) T(BAN::move(other.relase_value())); + } + } + + template + bool Optional::has_value() const + { + return m_has_value; + } + + template + T&& Optional::release_value() + { + ASSERT(has_value()); + m_has_value = false; + return BAN::move((T&)m_storage); + } + + template + const T& Optional::value() const + { + ASSERT(has_value()); + return (const T&)m_storage; + } + + template + T& Optional::value() + { + ASSERT(has_value()); + return (T&)m_storage; + } + + template + void Optional::clear() + { + if (m_has_value) + value().~T(); + m_has_value = false; + } + +} \ No newline at end of file