diff options
| author | Eric Fiselier <eric@efcs.ca> | 2017-06-16 00:36:17 +0000 |
|---|---|---|
| committer | Eric Fiselier <eric@efcs.ca> | 2017-06-16 00:36:17 +0000 |
| commit | f9bc0589353e8e478d798aa9b8790978f6b2432e (patch) | |
| tree | b2ccafbe0a05b3d7dc093657f5c1457fe8fb119d /libcxx | |
| parent | f63d41469caa0930be1954f105267ee802134b69 (diff) | |
| download | bcm5719-llvm-f9bc0589353e8e478d798aa9b8790978f6b2432e.tar.gz bcm5719-llvm-f9bc0589353e8e478d798aa9b8790978f6b2432e.zip | |
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.
llvm-svn: 305536
Diffstat (limited to 'libcxx')
| -rw-r--r-- | libcxx/include/experimental/coroutine | 6 | ||||
| -rw-r--r-- | libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp | 35 |
2 files changed, 39 insertions, 2 deletions
diff --git a/libcxx/include/experimental/coroutine b/libcxx/include/experimental/coroutine index 21c1ea56640..ce795ad452c 100644 --- a/libcxx/include/experimental/coroutine +++ b/libcxx/include/experimental/coroutine @@ -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; } }; diff --git a/libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp b/libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp index 4a61047a830..f996886c4ca 100644 --- a/libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp +++ b/libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp @@ -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<Promise>&& H) { int main() { do_test(coro::coroutine_handle<int>{}); + do_test(coro::coroutine_handle<const int>{}); + do_runtime_test(); } |

