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(); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits