This PR attempts to implement P3798 (The unexpected in std::expected).
LEWG recommended this as DR for C++23
(https://github.com/cplusplus/papers/issues/2403, see poll).
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(); }
+
       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