Will move the function, thanks. As for the DR situation, let's see what the discussion you started will lead to. I will adjust the patch accordingly once there is a conclusion - please loop me in.
My personal opinion is that this should have always been in std::expected and was simply missed by the committee back then, hence can be viewed as a defect. Having that said i also can't disagree that this technically is a new API. Fwiw libc++ did merge it as a DR so we are in a bit of an awkward situation now. Nothing is set in stone so let's discuss and see. Regards, Alex > On 23 Jun 2026, at 18:48, Jonathan Wakely <[email protected]> wrote: > > On Tue, 23 Jun 2026 at 17:54, Alex Kremer <[email protected]> wrote: >> >> This PR attempts to implement P3798 (The unexpected in std::expected). > > Thanks! > >> LEWG recommended this as DR for C++23 >> (https://github.com/cplusplus/papers/issues/2403, see poll). > > I'm unconvinced this should be a DR, I've started some discussions about it. > >> Implementation in libc++ is merged here: >> https://github.com/llvm/llvm-project/pull/204826 >> >> Please advise on any documentation, tests and/or other changes that are >> needed to successfully land this change. >> >> Thanks, >> Alex >> --- >> libstdc++-v3/include/bits/version.def | 5 +++-- >> libstdc++-v3/include/bits/version.h | 4 ++-- >> libstdc++-v3/include/std/expected | 6 ++++++ >> .../testsuite/20_util/expected/observers.cc | 18 ++++++++++++++++++ >> .../testsuite/20_util/expected/synopsis.cc | 2 +- >> .../testsuite/20_util/expected/version.cc | 4 ++-- >> 6 files changed, 32 insertions(+), 7 deletions(-) >> >> diff --git a/libstdc++-v3/include/bits/version.def >> b/libstdc++-v3/include/bits/version.def >> index 40baefab4e4..d54f331d9f2 100644 >> --- a/libstdc++-v3/include/bits/version.def >> +++ b/libstdc++-v3/include/bits/version.def >> @@ -1594,9 +1594,10 @@ ftms = { >> >> ftms = { >> name = expected; >> + // 202606 P3798R1 The unexpected in std::expected >> values = { >> - v = 202211; >> - cxxmin = 23; >> + v = 202606; >> + cxxmin = 23; // P3798R1 is C++29 but is accepted as DR for C++23 >> extra_cond = "__cpp_concepts >= 202002L"; >> }; >> }; >> diff --git a/libstdc++-v3/include/bits/version.h >> b/libstdc++-v3/include/bits/version.h >> index de1d71fa935..fe79f448938 100644 >> --- a/libstdc++-v3/include/bits/version.h >> +++ b/libstdc++-v3/include/bits/version.h >> @@ -1743,9 +1743,9 @@ >> >> #if !defined(__cpp_lib_expected) >> # if (__cplusplus >= 202100L) && (__cpp_concepts >= 202002L) >> -# define __glibcxx_expected 202211L >> +# define __glibcxx_expected 202606L >> # if defined(__glibcxx_want_all) || defined(__glibcxx_want_expected) >> -# define __cpp_lib_expected 202211L >> +# define __cpp_lib_expected 202606L >> # endif >> # endif >> #endif /* !defined(__cpp_lib_expected) */ >> diff --git a/libstdc++-v3/include/std/expected >> b/libstdc++-v3/include/std/expected >> index fe4e1ecbf0e..7f8d0d37501 100644 >> --- a/libstdc++-v3/include/std/expected >> +++ b/libstdc++-v3/include/std/expected >> @@ -855,6 +855,9 @@ namespace __expected >> _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex))); >> } >> >> + [[nodiscard]] >> + constexpr bool has_error() const noexcept { return !has_value(); } >> + > > I think I'd prefer to have this new function immediately after > has_value(), as shown in the wording in P3798R1. > >> constexpr const _Er& >> error() const & noexcept >> { >> @@ -1642,6 +1645,9 @@ namespace __expected >> _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex))); >> } >> >> + [[nodiscard]] >> + constexpr bool has_error() const noexcept { return !has_value(); } >> + >> constexpr const _Er& >> error() const & noexcept >> { >> diff --git a/libstdc++-v3/testsuite/20_util/expected/observers.cc >> b/libstdc++-v3/testsuite/20_util/expected/observers.cc >> index 31aaca352ae..84bce2eca52 100644 >> --- a/libstdc++-v3/testsuite/20_util/expected/observers.cc >> +++ b/libstdc++-v3/testsuite/20_util/expected/observers.cc >> @@ -59,6 +59,22 @@ test_has_value() >> return true; >> } >> >> +constexpr bool >> +test_has_error() >> +{ >> + std::expected<int, int> e; >> + VERIFY( ! e.has_error() ); >> + e = std::unexpected(1); >> + VERIFY( e.has_error() ); >> + >> + std::expected<void, int> v; >> + VERIFY( ! v.has_error() ); >> + v = std::unexpected(1); >> + VERIFY( v.has_error() ); >> + >> + return true; >> +} >> + >> constexpr bool >> test_value() >> { >> @@ -222,6 +238,8 @@ int main() >> test_star(); >> static_assert( test_has_value() ); >> test_has_value(); >> + static_assert( test_has_error() ); >> + test_has_error(); >> static_assert( test_value() ); >> test_value(); >> #if __cpp_lib_constexpr_exceptions >= 202502L >> diff --git a/libstdc++-v3/testsuite/20_util/expected/synopsis.cc >> b/libstdc++-v3/testsuite/20_util/expected/synopsis.cc >> index a0d2d5bea22..8866af7887f 100644 >> --- a/libstdc++-v3/testsuite/20_util/expected/synopsis.cc >> +++ b/libstdc++-v3/testsuite/20_util/expected/synopsis.cc >> @@ -6,7 +6,7 @@ >> >> #ifndef __cpp_lib_expected >> # error "Feature-test macro for expected missing in <expected>" >> -#elif __cpp_lib_expected != 202211L >> +#elif __cpp_lib_expected != 202606L >> # error "Feature-test macro for expected has wrong value in <expected>" >> #endif >> >> diff --git a/libstdc++-v3/testsuite/20_util/expected/version.cc >> b/libstdc++-v3/testsuite/20_util/expected/version.cc >> index 17c7fe4a5d6..f9b3011727f 100644 >> --- a/libstdc++-v3/testsuite/20_util/expected/version.cc >> +++ b/libstdc++-v3/testsuite/20_util/expected/version.cc >> @@ -5,7 +5,7 @@ >> >> #ifndef __cpp_lib_expected >> # error "Feature-test macro for expected missing in <version>" >> -#elif __cpp_lib_expected != 202211L >> +#elif __cpp_lib_expected != 202606L >> # error "Feature-test macro for expected has wrong value in <version>" >> #endif >> >> @@ -30,7 +30,7 @@ >> >> #ifndef __cpp_lib_expected >> # error "Feature-test macro for expected missing in <expected>" >> -#elif __cpp_lib_expected != 202211L >> +#elif __cpp_lib_expected != 202606L >> # error "Feature-test macro for expected has wrong value in <expected>" >> #endif >> >> -- >> 2.51.0 >> >
