-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
AK: Add an OptionalBase helper, and allow specializing Optional with dedicated empty values #25894
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Ah wait the CI containers dont ship gcc-14? |
48ca83b
to
fa1f40e
Compare
3f18ba3
to
5654981
Compare
5654981
to
13f16f2
Compare
@@ -4,6 +4,7 @@ set -e | |||
|
|||
script_path=$(cd -P -- "$(dirname -- "$0")" && pwd -P) | |||
|
|||
# shellcheck source=/dev/null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC these don't fail in CI, but only in the pre-commit check, because we only pass the changed scripts to shellcheck
, which doesn't include shell_include.sh
.
So most (if not all) # shellcheck source=/dev/null
we already have in master might be unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well it failed CI without the one in this exact file you point out....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weird, I have no idea why it fails here then.
I'm 99% sure that the build-image-raspberry-pi.sh
one only failed in the pre-commit hook.
Whoops, this breaks jakt builds |
Also Something in the NNRP code still seems off, will continue to test |
This also makes the monadic helpers a bit stricter with their value types, hence the drive-by changes.
This will be needed in the next commit, as Optional then starts to call into Traits, and the affected Ts initialize their own Optional so Traits specialization also already needs to be declared.
b40676b
to
fd5a34f
Compare
// FIXME: What to do here when we should not move empties around, | ||
// But don't have a swap method to place it in? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I just add an static_assert(dont_move_empty | has_swap)
in the mean time?
requires(dont_move_empty && has_swap) | ||
{ | ||
VERIFY(has_value()); | ||
T value = the_empty_value(); | ||
value.swap(m_value); | ||
return value; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yay back to shenanigans
(although this looks like a normal move constructor)
if (this == &other) | ||
return *this; | ||
swap(m_value, other.m_value); | ||
other.clear(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clear
is needed to be clearing on move, which the other optional promises
with non trivial types, which we definitely hit here
AK/Optional.h
Outdated
// Note: Some types don't like to be moved when in their empty state, | ||
// so we need to special case them | ||
constexpr static bool dont_move_empty = requires { | ||
Traits<T>::optional_dont_move_empty; | ||
requires(Traits<T>::optional_dont_move_empty); | ||
}; | ||
// Note: Some types don't like to get their empty values assigned | ||
// but provide a swap method, which usually does not go through | ||
// that check, so let's try to leverage that when we cant move empty values | ||
constexpr static bool has_swap = requires(T& t1, T& t2) { t1.swap(t2); }; | ||
|
||
// FIXME: We should investigate if we could guess trivial swappability | ||
// based on attributes the T has (see trivially relocatable/replaceable) | ||
// This might also be useful for the normal Optional implementation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please read during review
especially if you have better ideas
ALWAYS_INLINE constexpr void emplace(Ts&&... parameters) | ||
{ | ||
clear(); | ||
m_value = T(forward<Ts>(parameters)...); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure if construct_at
is nicer here as m_value
is usually in a replaceable state here
AK/Optional.h
Outdated
// This might also be useful for the normal Optional implementation | ||
|
||
public: | ||
ALWAYS_INLINE constexpr Optional() {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to self: = default
The new Optional implementation is chosen when a `Traits<T>::special_optional_empty_value` exists, this can be an immediate value or a function optionally taking a Badge<Optional<T>>. You can also define a custom specialization of `Traits<T>::optional_has_value`, as otherwise the default goes through the `==`/`!=` operators, which may not be defined.
fd5a34f
to
4d8dcfe
Compare
CC: @LucasChollet
CC: @nico to cross check if apple-clang really supports this or if wikipedia is weird
CC: Whoever knows if the CI changes are correct
Based on LadybirdBrowser/ladybird#2032
But still need to cherry-pick and adapt the String changes
Depends on #25891 for the GCC version bump