Bug 1850723 - Make mozilla::Result constructor take another result with convertible value. r=emilio,glandium

Differential Revision: https://phabricator.services.mozilla.com/D191538
This commit is contained in:
Tooru Fujisawa 2023-11-03 08:13:19 +00:00
parent 42681ab6e5
commit 3cea1dc675
2 changed files with 54 additions and 5 deletions

View File

@ -561,11 +561,13 @@ class [[nodiscard]] Result final {
}
/**
* Create a (success/error) result from another (success/error) result with a
* different but convertible error type. */
template <typename E2,
typename = std::enable_if_t<std::is_convertible_v<E2, E>>>
MOZ_IMPLICIT constexpr Result(Result<V, E2>&& aOther)
* Create a (success/error) result from another (success/error) result with
* different but convertible value and error types.
*/
template <typename V2, typename E2,
typename = std::enable_if_t<std::is_convertible_v<V2, V> &&
std::is_convertible_v<E2, E>>>
MOZ_IMPLICIT constexpr Result(Result<V2, E2>&& aOther)
: mImpl(aOther.isOk() ? Impl{aOther.unwrap()}
: Impl{aOther.unwrapErr()}) {}

View File

@ -806,6 +806,52 @@ static void ZeroIsEmptyErrorTest() {
}
}
class Foo {};
class C1 {};
class C2 : public C1 {};
class E1 {};
class E2 : public E1 {};
void UpcastTest() {
{
C2 c2;
mozilla::Result<C2*, Failed> result(&c2);
mozilla::Result<C1*, Failed> copied(std::move(result));
MOZ_RELEASE_ASSERT(copied.inspect() == &c2);
}
{
E2 e2;
mozilla::Result<Foo, E2*> result(Err(&e2));
mozilla::Result<Foo, E1*> copied(std::move(result));
MOZ_RELEASE_ASSERT(copied.inspectErr() == &e2);
}
{
C2 c2;
mozilla::Result<C2*, E2*> result(&c2);
mozilla::Result<C1*, E1*> copied(std::move(result));
MOZ_RELEASE_ASSERT(copied.inspect() == &c2);
}
{
E2 e2;
mozilla::Result<C2*, E2*> result(Err(&e2));
mozilla::Result<C1*, E1*> copied(std::move(result));
MOZ_RELEASE_ASSERT(copied.inspectErr() == &e2);
}
}
/* * */
int main() {
@ -819,5 +865,6 @@ int main() {
AndThenTest();
UniquePtrTest();
ZeroIsEmptyErrorTest();
UpcastTest();
return 0;
}