summaryrefslogtreecommitdiff
path: root/AK/Optional.h
diff options
context:
space:
mode:
authorIdan Horowitz <idan.horowitz@gmail.com>2022-01-23 13:03:29 +0200
committerIdan Horowitz <idan.horowitz@gmail.com>2022-01-23 18:53:42 +0200
commita3a4d0aea2efcd1ae3fd988d83cbe9c363f232e5 (patch)
tree27d75572c4b52b83e5454802154d9f7dffa69cc0 /AK/Optional.h
parentfb06d494f00849f385bd7c2d5e5470ae838da4df (diff)
downloadserenity-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.h25
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>