From a3a4d0aea2efcd1ae3fd988d83cbe9c363f232e5 Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Sun, 23 Jan 2022 13:03:29 +0200 Subject: [PATCH] AK: Make Optional explicitly constructible from Optional As long as T is constructible from U. This allows us to avoid patterns like `abc.has_value() ? Optional(abc.value()) : Optional()`. --- AK/Optional.h | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/AK/Optional.h b/AK/Optional.h index a2d2a7c4e2..d214b17fb6 100644 --- a/AK/Optional.h +++ b/AK/Optional.h @@ -24,6 +24,9 @@ namespace AK { template class [[nodiscard]] Optional { + template + friend class Optional; + public: using ValueType = T; @@ -50,17 +53,31 @@ public: #endif : m_has_value(other.m_has_value) { - if (other.has_value()) { + if (other.has_value()) new (&m_storage) T(other.value()); - } } ALWAYS_INLINE Optional(Optional&& other) : m_has_value(other.m_has_value) { - if (other.has_value()) { + if (other.has_value()) + new (&m_storage) T(other.release_value()); + } + + template + requires(IsConstructible && !IsSpecializationOf && !IsSpecializationOf) ALWAYS_INLINE explicit Optional(Optional const& other) + : m_has_value(other.m_has_value) + { + if (other.has_value()) + new (&m_storage) T(other.value()); + } + + template + requires(IsConstructible && !IsSpecializationOf && !IsSpecializationOf) ALWAYS_INLINE explicit Optional(Optional&& other) + : m_has_value(other.m_has_value) + { + if (other.has_value()) new (&m_storage) T(other.release_value()); - } } template