[libcxx] r305536 - Allow coroutine_handle<const T> to support creation from const references to the promise_type

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 15 17:36:17 PDT 2017


Author: ericwf
Date: Thu Jun 15 19:36:17 2017
New Revision: 305536

URL: http://llvm.org/viewvc/llvm-project?rev=305536&view=rev
Log:
Allow coroutine_handle<const T> to support creation from const references to the promise_type

It seems conceivable that a user would need to get a coroutine handle
having only a const reference to the promise_type, for example from
within a const member function of the promise.

This patch allows that use case. A coroutine_handle<const T> can be used
in essentially the same way a coroutine_handle<T>, ie to start and destroy
the coroutine. The constness of the promise doesn't/shouldn't propagate
to the handle.

Modified:
    libcxx/trunk/include/experimental/coroutine
    libcxx/trunk/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp

Modified: libcxx/trunk/include/experimental/coroutine
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/experimental/coroutine?rev=305536&r1=305535&r2=305536&view=diff
==============================================================================
--- libcxx/trunk/include/experimental/coroutine (original)
+++ libcxx/trunk/include/experimental/coroutine Thu Jun 15 19:36:17 2017
@@ -250,9 +250,11 @@ public:
 
     _LIBCPP_ALWAYS_INLINE
     static coroutine_handle from_promise(_Promise& __promise) _NOEXCEPT {
+        typedef typename remove_cv<_Promise>::type _RawPromise;
         coroutine_handle __tmp;
-        __tmp.__handle_ = __builtin_coro_promise(_VSTD::addressof(__promise),
-                                                 __alignof(_Promise), true);
+        __tmp.__handle_ = __builtin_coro_promise(
+            _VSTD::addressof(const_cast<_RawPromise&>(__promise)),
+             __alignof(_Promise), true);
         return __tmp;
     }
 };

Modified: libcxx/trunk/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp?rev=305536&r1=305535&r2=305536&view=diff
==============================================================================
--- libcxx/trunk/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp (original)
+++ libcxx/trunk/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp Thu Jun 15 19:36:17 2017
@@ -28,6 +28,39 @@
 
 namespace coro = std::experimental;
 
+struct MyCoro {
+  struct promise_type {
+    void unhandled_exception() {}
+    void return_void() {}
+    coro::suspend_never initial_suspend() { return {}; }
+    coro::suspend_never final_suspend() { return {}; }
+    MyCoro get_return_object() {
+      do_runtime_test();
+      return {};
+    }
+    void do_runtime_test() {
+      // Test that a coroutine_handle<const T> can be created from a const
+      // promise_type and that it represents the same coroutine as
+      // coroutine_handle<T>
+      using CH = coro::coroutine_handle<promise_type>;
+      using CCH = coro::coroutine_handle<const promise_type>;
+      const auto &cthis = *this;
+      CH h = CH::from_promise(*this);
+      CCH h2 = CCH::from_promise(*this);
+      CCH h3 = CCH::from_promise(cthis);
+      assert(&h.promise() == this);
+      assert(&h2.promise() == this);
+      assert(&h3.promise() == this);
+      assert(h.address() == h2.address());
+      assert(h2.address() == h3.address());
+    }
+  };
+};
+
+MyCoro do_runtime_test() {
+  co_await coro::suspend_never{};
+}
+
 template <class Promise>
 void do_test(coro::coroutine_handle<Promise>&& H) {
 
@@ -46,4 +79,6 @@ void do_test(coro::coroutine_handle<Prom
 int main()
 {
   do_test(coro::coroutine_handle<int>{});
+  do_test(coro::coroutine_handle<const int>{});
+  do_runtime_test();
 }




More information about the cfe-commits mailing list