| /* { dg-additional-options "-std=c++23" } */ | |
| /* expected/optional */ | |
| #include <optional> | |
| #include <expected> | |
| #include "target-flex-common.h" | |
| std::optional<unsigned> make_optional(bool b, unsigned arg = 0u) noexcept | |
| { | |
| if (!b) | |
| return std::nullopt; | |
| return {arg}; | |
| } | |
| bool test_optional(unsigned arg) | |
| { | |
| bool ok; | |
| #pragma omp target map(from: ok) map(to: arg) | |
| { | |
| bool inner_ok = true; | |
| { | |
| auto null_opt = make_optional(false); | |
| VERIFY (!null_opt); | |
| VERIFY (!null_opt.has_value()); | |
| VERIFY (null_opt.value_or(arg * 2u) == arg * 2u); | |
| VERIFY (null_opt.or_else([&](){ return std::optional<unsigned>{arg}; }) | |
| .transform([](int a){ return a * 2u; }) | |
| .value_or(0) == arg * 2u); | |
| auto opt = make_optional(true, arg); | |
| VERIFY (opt); | |
| VERIFY (opt.has_value()); | |
| VERIFY (opt.value() == arg); | |
| VERIFY (*opt == arg); | |
| VERIFY (opt.value_or(arg + 42) == arg); | |
| VERIFY (opt.or_else([&](){ return std::optional<unsigned>{arg + 42}; }) | |
| .transform([](int a){ return a * 2u; }) | |
| .value_or(0) == arg * 2u); | |
| } | |
| end: | |
| ok = inner_ok; | |
| } | |
| return ok; | |
| } | |
| struct my_error | |
| { | |
| int _e; | |
| }; | |
| std::expected<unsigned, my_error> make_expected(bool b, unsigned arg = 0u) noexcept | |
| { | |
| if (!b) | |
| return std::unexpected{my_error{-1}}; | |
| return {arg}; | |
| } | |
| bool test_expected(unsigned arg) | |
| { | |
| bool ok; | |
| #pragma omp target map(from: ok) map(to: arg) | |
| { | |
| bool inner_ok = true; | |
| { | |
| auto unexpected = make_expected(false); | |
| VERIFY (!unexpected); | |
| VERIFY (!unexpected.has_value()); | |
| VERIFY (unexpected.error()._e == -1); | |
| VERIFY (unexpected.value_or(arg * 2u) == arg * 2u); | |
| VERIFY (unexpected.or_else([&](my_error e){ return std::expected<unsigned, my_error>{arg}; }) | |
| .transform([](int a){ return a * 2u; }) | |
| .value_or(0) == arg * 2u); | |
| auto expected = make_expected(true, arg); | |
| VERIFY (expected); | |
| VERIFY (expected.has_value()); | |
| VERIFY (expected.value() == arg); | |
| VERIFY (*expected == arg); | |
| VERIFY (expected.value_or(arg + 42) == arg); | |
| VERIFY (expected.or_else([&](my_error e){ return std::expected<unsigned, my_error>{std::unexpected{e}}; }) | |
| .transform([](int a){ return a * 2u; }) | |
| .value_or(0) == arg * 2u); | |
| } | |
| end: | |
| ok = inner_ok; | |
| } | |
| return ok; | |
| } | |
| int main() | |
| { | |
| volatile unsigned arg = 42; | |
| return test_optional(arg) | |
| && test_expected(arg) ? 0 : 1; | |
| } |