AK: Allow Optional<T&> to be constructed from Optional<T>&

Attempting this resulted in an error because the `m_pointer` field does
not exist on `Optional<T>`. Creating a shared `ptr()` function and
adding the necessairy overloads solves this issue.
This commit is contained in:
Jonne Ransijn 2024-10-27 10:13:43 +01:00 committed by Andreas Kling
parent be03002780
commit e76064e67f
Notes: github-actions[bot] 2024-10-27 12:27:30 +00:00

View file

@ -202,6 +202,16 @@ public:
[[nodiscard]] ALWAYS_INLINE bool has_value() const { return m_has_value; }
[[nodiscard]] ALWAYS_INLINE T* ptr() &
{
return m_has_value ? __builtin_launder(reinterpret_cast<T*>(&m_storage)) : nullptr;
}
[[nodiscard]] ALWAYS_INLINE T const* ptr() const&
{
return m_has_value ? __builtin_launder(reinterpret_cast<T const*>(&m_storage)) : nullptr;
}
[[nodiscard]] ALWAYS_INLINE T& value() &
{
VERIFY(m_has_value);
@ -362,20 +372,33 @@ public:
}
template<typename U>
ALWAYS_INLINE Optional(Optional<U> const& other)
ALWAYS_INLINE Optional(Optional<U>& other)
requires(CanBePlacedInOptional<U>)
: m_pointer(other.m_pointer)
: m_pointer(other.ptr())
{
}
template<typename U>
ALWAYS_INLINE Optional(Optional<U> const& other)
requires(CanBePlacedInOptional<U const>)
: m_pointer(other.ptr())
{
}
template<typename U>
ALWAYS_INLINE Optional(Optional<U>&& other)
requires(CanBePlacedInOptional<U>)
: m_pointer(other.m_pointer)
: m_pointer(other.ptr())
{
other.m_pointer = nullptr;
}
ALWAYS_INLINE Optional& operator=(Optional& other)
{
m_pointer = other.m_pointer;
return *this;
}
ALWAYS_INLINE Optional& operator=(Optional const& other)
{
m_pointer = other.m_pointer;
@ -390,16 +413,24 @@ public:
}
template<typename U>
ALWAYS_INLINE Optional& operator=(Optional<U> const& other)
ALWAYS_INLINE Optional& operator=(Optional<U>& other)
requires(CanBePlacedInOptional<U>)
{
m_pointer = other.m_pointer;
m_pointer = other.ptr();
return *this;
}
template<typename U>
ALWAYS_INLINE Optional& operator=(Optional<U> const& other)
requires(CanBePlacedInOptional<U const>)
{
m_pointer = other.ptr();
return *this;
}
template<typename U>
ALWAYS_INLINE Optional& operator=(Optional<U>&& other)
requires(CanBePlacedInOptional<U>)
requires(CanBePlacedInOptional<U> && IsLvalueReference<U>)
{
m_pointer = other.m_pointer;
other.m_pointer = nullptr;
@ -423,6 +454,16 @@ public:
[[nodiscard]] ALWAYS_INLINE bool has_value() const { return m_pointer != nullptr; }
[[nodiscard]] ALWAYS_INLINE RemoveReference<T>* ptr()
{
return m_pointer;
}
[[nodiscard]] ALWAYS_INLINE RemoveReference<T> const* ptr() const
{
return m_pointer;
}
[[nodiscard]] ALWAYS_INLINE T value()
{
VERIFY(m_pointer);