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