]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Remove constraints from std::optional monadic ops [PR102863]
authorJonathan Wakely <jwakely@redhat.com>
Thu, 21 Oct 2021 00:19:45 +0000 (01:19 +0100)
committerJonathan Wakely <jwakely@redhat.com>
Thu, 21 Oct 2021 00:23:22 +0000 (01:23 +0100)
The constraints on transform and and_then can cause errors when checking
satisfaction. The constraints that were present in R6 of the paper were
moved for he final F8 revision, and so should have been included in the
implementation.

libstdc++-v3/ChangeLog:

PR libstdc++/102863
* include/std/optional (optional::and_then, optional::transform):
Remove requires-clause.
* testsuite/20_util/optional/monadic/and_then.cc: Check
overload resolution doesn't cause errors.
* testsuite/20_util/optional/monadic/transform.cc: Likewise.

libstdc++-v3/include/std/optional
libstdc++-v3/testsuite/20_util/optional/monadic/and_then.cc
libstdc++-v3/testsuite/20_util/optional/monadic/transform.cc

index eac91d3c160c931567e3b3e2658563fbf4e82699..783d7ca1b64b56dff64e9e658c57e746b5e97c2e 100644 (file)
@@ -1048,7 +1048,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       // [optional.monadic]
 
-      template<typename _Fn> requires invocable<_Fn, _Tp&>
+      template<typename _Fn>
        constexpr auto
        and_then(_Fn&& __f) &
        {
@@ -1060,7 +1060,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            return _Up();
        }
 
-      template<typename _Fn> requires invocable<_Fn, const _Tp&>
+      template<typename _Fn>
        constexpr auto
        and_then(_Fn&& __f) const &
        {
@@ -1072,7 +1072,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            return _Up();
        }
 
-      template<typename _Fn> requires invocable<_Fn, _Tp>
+      template<typename _Fn>
        constexpr auto
        and_then(_Fn&& __f) &&
        {
@@ -1084,7 +1084,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            return _Up();
        }
 
-      template<typename _Fn> requires invocable<_Fn, const _Tp>
+      template<typename _Fn>
        constexpr auto
        and_then(_Fn&& __f) const &&
        {
@@ -1096,7 +1096,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            return _Up();
        }
 
-      template<typename _Fn> requires invocable<_Fn, _Tp&>
+      template<typename _Fn>
        constexpr auto
        transform(_Fn&& __f) &
        {
@@ -1107,7 +1107,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            return optional<_Up>();
        }
 
-      template<typename _Fn> requires invocable<_Fn, const _Tp&>
+      template<typename _Fn>
        constexpr auto
        transform(_Fn&& __f) const &
        {
@@ -1118,7 +1118,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            return optional<_Up>();
        }
 
-      template<typename _Fn> requires invocable<_Fn, _Tp>
+      template<typename _Fn>
        constexpr auto
        transform(_Fn&& __f) &&
        {
@@ -1129,7 +1129,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            return optional<_Up>();
        }
 
-      template<typename _Fn> requires invocable<_Fn, const _Tp>
+      template<typename _Fn>
        constexpr auto
        transform(_Fn&& __f) const &&
        {
index 02dcafe6c580b0f474ad9028594da9ee45464fb4..f69ab952643f9df1aa84f3d02b4e3e0874d8dd43 100644 (file)
@@ -113,8 +113,20 @@ test_forwarding()
 
 static_assert( test_forwarding() );
 
+void f(int&) { }
+
+void
+test_unconstrained()
+{
+  // PR libstc++/102863 - Optional monadic ops should not be constrained
+  std::optional<int> x;
+  auto answer = x.and_then([](auto& y) { f(y); return std::optional<int>{42}; });
+  VERIFY( !answer );
+}
+
 int main()
 {
   test_and_then();
   test_forwarding();
+  test_unconstrained();
 }
index 13977b8ba8d409292ef43b3b03419ebc95c86ff3..356c94de6d090a250dc2aa8913a945fbdd1efb1e 100644 (file)
@@ -132,9 +132,21 @@ test_copy_elision()
 
 static_assert( test_copy_elision() );
 
+void f(int&) { }
+
+void
+test_unconstrained()
+{
+  // PR libstc++/102863 - Optional monadic ops should not be constrained
+  std::optional<int> x;
+  auto answer = x.transform([](auto& y) { f(y); return 42; });
+  VERIFY( !answer );
+}
+
 int main()
 {
   test_transform();
   test_forwarding();
   test_copy_elision();
+  test_unconstrained();
 }