diff options
author | Idan Horowitz <idan.horowitz@gmail.com> | 2022-01-23 13:03:29 +0200 |
---|---|---|
committer | Idan Horowitz <idan.horowitz@gmail.com> | 2022-01-23 18:53:42 +0200 |
commit | a3a4d0aea2efcd1ae3fd988d83cbe9c363f232e5 (patch) | |
tree | 27d75572c4b52b83e5454802154d9f7dffa69cc0 /AK/Optional.h | |
parent | fb06d494f00849f385bd7c2d5e5470ae838da4df (diff) | |
download | serenity-a3a4d0aea2efcd1ae3fd988d83cbe9c363f232e5.zip |
AK: Make Optional<T> explicitly constructible from Optional<U>
As long as T is constructible from U. This allows us to avoid patterns
like `abc.has_value() ? Optional<U>(abc.value()) : Optional<U>()`.
Diffstat (limited to 'AK/Optional.h')
-rw-r--r-- | AK/Optional.h | 25 |
1 files 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<typename T> class [[nodiscard]] Optional { + template<typename U> + 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<typename U> + requires(IsConstructible<T, U const&> && !IsSpecializationOf<T, Optional> && !IsSpecializationOf<U, Optional>) ALWAYS_INLINE explicit Optional(Optional<U> const& other) + : m_has_value(other.m_has_value) + { + if (other.has_value()) + new (&m_storage) T(other.value()); + } + + template<typename U> + requires(IsConstructible<T, U&&> && !IsSpecializationOf<T, Optional> && !IsSpecializationOf<U, Optional>) ALWAYS_INLINE explicit Optional(Optional<U>&& other) + : m_has_value(other.m_has_value) + { + if (other.has_value()) new (&m_storage) T(other.release_value()); - } } template<typename U = T> |