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
> >>
> >
>

Reply via email to