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>()`.
This commit is contained in:
Idan Horowitz 2022-01-23 13:03:29 +02:00
parent fb06d494f0
commit a3a4d0aea2

View file

@ -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>