/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
// V is trivially default-constructible, and E has UnusedZero<E>::value == true, // for a reference type and for a non-reference type
static_assert(mozilla::detail::SelectResultImpl<uintptr_t, Failed>::value ==
mozilla::detail::PackingStrategy::NullIsOk);
static_assert(
mozilla::detail::SelectResultImpl<Ok, TestUnusedZeroEnum>::value ==
mozilla::detail::PackingStrategy::NullIsOk);
static_assert(mozilla::detail::SelectResultImpl<Ok, Failed>::value ==
mozilla::detail::PackingStrategy::LowBitTagIsError);
static_assert( sizeof(Result<bool, TestUnusedZeroEnum>) <= sizeof(uintptr_t), "Result with bool value type should not be larger than pointer-sized");
static_assert(sizeof(Result<Ok, Failed>) == sizeof(uint8_t), "Result with empty value type should be size 1");
static_assert(sizeof(Result<int*, Failed>) == sizeof(uintptr_t), "Result with two aligned pointer types should be pointer-sized");
static_assert( sizeof(Result<char*, Failed*>) > sizeof(char*), "Result with unaligned success type `char*` must not be pointer-sized");
static_assert( sizeof(Result<int*, char*>) > sizeof(char*), "Result with unaligned error type `char*` must not be pointer-sized");
enum Foo8 : uint8_t {}; enum Foo16 : uint16_t {}; enum Foo32 : uint32_t {};
static_assert(sizeof(Result<Ok, Foo8>) <= sizeof(uintptr_t), "Result with small types should be pointer-sized");
static_assert(sizeof(Result<Ok, Foo16>) <= sizeof(uintptr_t), "Result with small types should be pointer-sized");
static_assert(sizeof(Foo32) >= sizeof(uintptr_t) || sizeof(Result<Ok, Foo32>) <= sizeof(uintptr_t), "Result with small types should be pointer-sized");
static_assert(sizeof(Result<Foo16, Foo8>) <= sizeof(uintptr_t), "Result with small types should be pointer-sized");
static_assert(sizeof(Result<Foo8, Foo16>) <= sizeof(uintptr_t), "Result with small types should be pointer-sized");
static_assert(sizeof(Foo32) >= sizeof(uintptr_t) || sizeof(Result<Foo32, Foo16>) <= sizeof(uintptr_t), "Result with small types should be pointer-sized");
static_assert(sizeof(Foo32) >= sizeof(uintptr_t) || sizeof(Result<Foo16, Foo32>) <= sizeof(uintptr_t), "Result with small types should be pointer-sized");
static constexpr Result<Ok, Failed> Task1(bool pass) { if (!pass) { return Fail(); // implicit conversion from GenericErrorResult to Result
} return Ok();
}
static constexpr Result<Ok, TestUnusedZeroEnum> Task1UnusedZeroEnumErr( bool pass) { if (!pass) { return FailTestUnusedZeroEnum(); // implicit conversion from // GenericErrorResult to Result
} return Ok();
}
static constexpr Result<int, Failed> Task2(bool pass, int value) {
MOZ_TRY(
Task1(pass)); // converts one type of result to another in the error case return value; // implicit conversion from T to Result<T, E>
}
static constexpr Result<int, TestUnusedZeroEnum> Task2UnusedZeroEnumErr( bool pass, int value) {
MOZ_TRY(Task1UnusedZeroEnumErr(
pass)); // converts one type of result to another in the error case return value; // implicit conversion from T to Result<T, E>
}
static Result<int, Failed> Task3(bool pass1, bool pass2, int value) { int x, y;
MOZ_TRY_VAR(x, Task2(pass1, value));
MOZ_TRY_VAR(y, Task2(pass2, value)); return x + y;
}
staticvoid EmptyValueTest() { struct Fine {};
mozilla::Result<Fine, Failed> res((Fine()));
res.unwrap();
MOZ_RELEASE_ASSERT(res.isOk());
static_assert(sizeof(res) == sizeof(uint8_t), "Result with empty value and error types should be size 1");
}
staticvoid MapTest() { struct MyError { int x;
explicit MyError(int y) : x(y) {}
};
// Mapping over success values, to the same success type.
{
Result<int, MyError> res(5); bool invoked = false; auto res2 = res.map([&invoked](int x) {
MOZ_RELEASE_ASSERT(x == 5);
invoked = true; return 6;
});
MOZ_RELEASE_ASSERT(res2.isOk());
MOZ_RELEASE_ASSERT(invoked);
MOZ_RELEASE_ASSERT(res2.unwrap() == 6);
}
// Mapping over success values, to a different success type.
{
Result<int, MyError> res(5); bool invoked = false; auto res2 = res.map([&invoked](int x) {
MOZ_RELEASE_ASSERT(x == 5);
invoked = true; return"hello";
});
MOZ_RELEASE_ASSERT(res2.isOk());
MOZ_RELEASE_ASSERT(invoked);
MOZ_RELEASE_ASSERT(strcmp(res2.unwrap(), "hello") == 0);
}
// Function pointers instead of lambdas as the mapping function.
{
Result<constchar*, MyError> res("hello"); auto res2 = res.map(strlen);
MOZ_RELEASE_ASSERT(res2.isOk());
MOZ_RELEASE_ASSERT(res2.unwrap() == 5);
}
}
staticvoid MapErrTest() { struct MyError { int x;
explicit MyError(int y) : x(y) {}
};
struct MyError2 { int a;
explicit MyError2(int b) : a(b) {}
};
// Mapping over error values, to the same error type.
{
MyError err(1);
Result<char, MyError> res(err);
MOZ_RELEASE_ASSERT(res.isErr()); bool invoked = false; auto res2 = res.mapErr([&invoked](constauto err) {
MOZ_RELEASE_ASSERT(err.x == 1);
invoked = true; return MyError(2);
});
MOZ_RELEASE_ASSERT(res2.isErr());
MOZ_RELEASE_ASSERT(invoked);
MOZ_RELEASE_ASSERT(res2.unwrapErr().x == 2);
}
// Mapping over error values, to a different error type.
{
MyError err(1);
Result<char, MyError> res(err);
MOZ_RELEASE_ASSERT(res.isErr()); bool invoked = false; auto res2 = res.mapErr([&invoked](constauto err) {
MOZ_RELEASE_ASSERT(err.x == 1);
invoked = true; return MyError2(2);
});
MOZ_RELEASE_ASSERT(res2.isErr());
MOZ_RELEASE_ASSERT(invoked);
MOZ_RELEASE_ASSERT(res2.unwrapErr().a == 2);
}
// Function pointers instead of lambdas as the mapping function.
{
Result<Ok, constchar*> res("hello"); auto res2 = res.mapErr(strlen);
MOZ_RELEASE_ASSERT(res2.isErr());
MOZ_RELEASE_ASSERT(res2.unwrapErr() == 5);
}
}
// Function pointers instead of lambdas as the `orElse`ing function.
{
Result<Ok, constchar*> res("hello"); auto res2 = res.orElse(strlen_ResultWrapper);
MOZ_RELEASE_ASSERT(res2.isErr());
MOZ_RELEASE_ASSERT(res2.unwrapErr() == 5);
}
}
staticvoid UniquePtrTest() {
{ auto result = UniqueTask();
MOZ_RELEASE_ASSERT(result.isOk()); auto ptr = result.unwrap();
MOZ_RELEASE_ASSERT(ptr);
MOZ_RELEASE_ASSERT(*ptr == 3); auto moved = result.unwrap();
MOZ_RELEASE_ASSERT(!moved);
}
{ auto err = UniqueTaskError();
MOZ_RELEASE_ASSERT(err.isErr()); auto ptr = err.unwrapOr(mozilla::MakeUnique<int>(4));
MOZ_RELEASE_ASSERT(ptr);
MOZ_RELEASE_ASSERT(*ptr == 4);
}
{ auto result = UniqueTaskError();
result = UniqueResult(mozilla::MakeUnique<int>(6));
MOZ_RELEASE_ASSERT(result.isOk());
MOZ_RELEASE_ASSERT(result.inspect() && *result.inspect() == 6);
}
{ auto result = UniqueError();
MOZ_RELEASE_ASSERT(result.isErr());
MOZ_RELEASE_ASSERT(result.inspectErr());
MOZ_RELEASE_ASSERT(*result.inspectErr() == 4); auto err = result.unwrapErr();
MOZ_RELEASE_ASSERT(!result.inspectErr());
MOZ_RELEASE_ASSERT(err);
MOZ_RELEASE_ASSERT(*err == 4);
result = UniqueErrorResult(0);
MOZ_RELEASE_ASSERT(result.isOk() && result.unwrap() == 0);
}
{ auto result = TryUniqueErrorResult();
MOZ_RELEASE_ASSERT(result.isErr()); auto err = result.unwrapErr();
MOZ_RELEASE_ASSERT(err && *err == 4);
MOZ_RELEASE_ASSERT(!result.inspectErr());
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.