Please resubmit the patch with this as a C++29 feature (GCC and libstdc++ have -std=c++29 support now) - thanks.
On Tue, 23 Jun 2026 at 19:16, Alexander Kremer <[email protected]> wrote: > > 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 > >> > > >
