diff --git a/BAN/include/BAN/Optional.h b/BAN/include/BAN/Optional.h index 51f9927ed3..862fee78ac 100644 --- a/BAN/include/BAN/Optional.h +++ b/BAN/include/BAN/Optional.h @@ -13,6 +13,8 @@ namespace BAN { public: Optional(); + Optional(Optional&&); + Optional(const Optional&); Optional(const T&); Optional(T&&); template @@ -20,8 +22,8 @@ namespace BAN ~Optional(); - Optional& operator=(const Optional&); Optional& operator=(Optional&&); + Optional& operator=(const Optional&); template Optional& emplace(Args&&...); @@ -34,9 +36,9 @@ namespace BAN bool has_value() const; - T&& release_value(); - const T& value() const; + T release_value(); T& value(); + const T& value() const; void clear(); @@ -50,6 +52,22 @@ namespace BAN : m_has_value(false) {} + template + Optional::Optional(Optional&& other) + : m_has_value(other.has_value()) + { + if (other.has_value()) + new (m_storage) T(move(other.release_value())); + } + + template + Optional::Optional(const Optional& other) + : m_has_value(other.has_value()) + { + if (other.has_value()) + new (m_storage) T(other.value()); + } + template Optional::Optional(const T& value) : m_has_value(true) @@ -61,7 +79,7 @@ namespace BAN Optional::Optional(T&& value) : m_has_value(true) { - new (m_storage) T(BAN::move(value)); + new (m_storage) T(move(value)); } template @@ -69,7 +87,7 @@ namespace BAN Optional::Optional(Args&&... args) : m_has_value(true) { - new (m_storage) T(BAN::forward(args)...); + new (m_storage) T(forward(args)...); } template @@ -79,26 +97,22 @@ namespace BAN } template - Optional& Optional::operator=(const Optional& other) + Optional& Optional::operator=(Optional&& other) { clear(); + m_has_value = other.has_value(); if (other.has_value()) - { - m_has_value = true; - new (m_storage) T(other.value()); - } + new (m_storage) T(move(other.release_value())); return *this; } template - Optional& Optional::operator=(Optional&& other) + Optional& Optional::operator=(const Optional& other) { clear(); - if (other.has_value()) - { - m_has_value = true; - new (m_storage) T(BAN::move(other.release_value())); - } + m_has_value = other.has_value(); + if (other.has_value) + new (m_storage) T(other.value()); return *this; } @@ -108,7 +122,7 @@ namespace BAN { clear(); m_has_value = true; - new (m_storage) T(BAN::forward(args)...); + new (m_storage) T(forward(args)...); return *this; } @@ -147,18 +161,13 @@ namespace BAN } template - T&& Optional::release_value() + T Optional::release_value() { ASSERT(has_value()); + T released_value = move(value()); + value().~T(); m_has_value = false; - return BAN::move((T&)m_storage); - } - - template - const T& Optional::value() const - { - ASSERT(has_value()); - return (const T&)m_storage; + return move(released_value); } template @@ -168,6 +177,13 @@ namespace BAN return (T&)m_storage; } + template + const T& Optional::value() const + { + ASSERT(has_value()); + return (const T&)m_storage; + } + template void Optional::clear() {